diff options
author | Richard Linden <none@none> | 2013-03-22 00:44:59 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2013-03-22 00:44:59 -0700 |
commit | 68f9f656cd22332e46959a90347e38f79c19a66c (patch) | |
tree | 531d87287b69f500c5901f785e60483555b415f9 /indra/newview | |
parent | e87000ba0750e55d9d6b55feccc4124f5d2b4b74 (diff) | |
parent | 368dd542bec7c31e14673b83d3342c35717d2920 (diff) |
merge with viewer-release
Diffstat (limited to 'indra/newview')
134 files changed, 7040 insertions, 6831 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e93d73ad0e..718a8c710f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -216,7 +216,6 @@ set(viewer_SOURCE_FILES llfloaterinspect.cpp llfloaterinventory.cpp llfloaterjoystick.cpp - llfloaterlagmeter.cpp llfloaterland.cpp llfloaterlandholdings.cpp llfloatermap.cpp @@ -241,6 +240,7 @@ set(viewer_SOURCE_FILES llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp llfloaterreporter.cpp + llfloatersceneloadstats.cpp llfloaterscriptdebug.cpp llfloaterscriptlimits.cpp llfloatersearch.cpp @@ -464,6 +464,7 @@ set(viewer_SOURCE_FILES llremoteparcelrequest.cpp llsavedsettingsglue.cpp llsaveoutfitcombobtn.cpp + llscenemonitor.cpp llsceneview.cpp llscreenchannel.cpp llscriptfloater.cpp @@ -588,6 +589,7 @@ set(viewer_SOURCE_FILES llviewernetwork.cpp llviewerobject.cpp llviewerobjectlist.cpp + llvieweroctree.cpp llviewerparcelmedia.cpp llviewerparcelmediaautoplay.cpp llviewerparcelmgr.cpp @@ -792,7 +794,6 @@ set(viewer_HEADER_FILES llfloaterinspect.h llfloaterinventory.h llfloaterjoystick.h - llfloaterlagmeter.h llfloaterland.h llfloaterlandholdings.h llfloatermap.h @@ -817,6 +818,7 @@ set(viewer_HEADER_FILES llfloaterregiondebugconsole.h llfloaterregioninfo.h llfloaterreporter.h + llfloatersceneloadstats.h llfloaterscriptdebug.h llfloaterscriptlimits.h llfloatersearch.h @@ -1031,6 +1033,7 @@ set(viewer_HEADER_FILES llrootview.h llsavedsettingsglue.h llsaveoutfitcombobtn.h + llscenemonitor.h llsceneview.h llscreenchannel.h llscriptfloater.h @@ -1155,6 +1158,7 @@ set(viewer_HEADER_FILES llviewernetwork.h llviewerobject.h llviewerobjectlist.h + llvieweroctree.h llviewerparcelmedia.h llviewerparcelmediaautoplay.h llviewerparcelmgr.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2e91d10cd3..94a8550938 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6389,6 +6389,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>ObjectCacheViewCullingEnabled</key> + <map> + <key>Comment</key> + <string>Enable the object cache view culling. Needs to restart viewer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>OpenDebugStatAdvanced</key> <map> <key>Comment</key> @@ -9447,6 +9458,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>SceneLoadingMonitorEnabled</key> + <map> + <key>Comment</key> + <string>Enabled scene loading monitor if set</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ScriptHelpFollowsCursor</key> <map> <key>Comment</key> @@ -10853,7 +10875,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <integer>0.0</integer> + <real>0.0</real> </map> <key>TextureFetchUpdateSkipLowPriority</key> <map> @@ -12492,6 +12514,7 @@ <key>Type</key> <string>LLSD</string> <key>Value</key> + <array /> </map> <key>VFSOldSize</key> <map> @@ -14070,7 +14093,7 @@ <real>1.0</real> </array> </map> - + <key>HideUIControls</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl new file mode 100644 index 0000000000..f1400c9b44 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl @@ -0,0 +1,49 @@ +/** + * @file onetexturefilterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D tex0; +uniform float tolerance; + +VARYING vec2 vary_texcoord0; + +void main() +{ + frag_color = texture2D(tex0, vary_texcoord0.xy); + + if(frag_color[0] + frag_color[1] + frag_color[2] < tolerance) + { + discard; + } + else + { + frag_color[3] = 0.95f; + } +} diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl new file mode 100644 index 0000000000..a33ef7e92c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl @@ -0,0 +1,38 @@ +/** + * @file onetexturefilterV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 vary_texcoord0; + +void main() +{ + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_texcoord0 = texcoord0; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl new file mode 100644 index 0000000000..050114b37e --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl @@ -0,0 +1,41 @@ +/** + * @file twotexturecompareF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D tex0; +uniform sampler2D tex1; + +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; + +void main() +{ + frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy)); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl new file mode 100644 index 0000000000..67c6674f0c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl @@ -0,0 +1,41 @@ +/** + * @file twotexturecompareV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; + +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; + +void main() +{ + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_texcoord0 = texcoord0; + vary_texcoord1 = texcoord1; +} + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index b6fd7bc9c2..4e60127ef3 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -752,7 +752,7 @@ void LLAgent::setFlying(BOOL fly) } if( !was_flying ) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT); + add(LLStatViewer::FLY, 1); } setControlFlags(AGENT_CONTROL_FLY); } @@ -1046,6 +1046,14 @@ const LLVector3d &LLAgent::getPositionGlobal() const return mPositionGlobal; } +bool LLAgent::isPositionChanged() const +{ + LLVector3d diff; + diff = mPositionGlobal - mLastPositionGlobal; + + return diff.lengthSquared() > 1.0; +} + //----------------------------------------------------------------------------- // getPositionAgent() //----------------------------------------------------------------------------- @@ -3806,7 +3814,7 @@ bool LLAgent::teleportCore(bool is_local) gAgentCamera.resetView(FALSE); // local logic - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT); + add(LLStatViewer::TELEPORT, 1); if (is_local) { gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL ); @@ -4123,7 +4131,7 @@ void LLAgent::setTeleportState(ETeleportState state) case TELEPORT_ARRIVING: // First two position updates after a teleport tend to be weird - LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2; + //LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2; // Let the interested parties know we've teleported. LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal()); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 99904e118c..a1e899b45d 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -250,6 +250,8 @@ public: const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; } void setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; } + + bool isPositionChanged() const; private: std::set<U64> mRegionsVisited; // Stat - what distinct regions has the avatar been to? F64 mDistanceTraveled; // Stat - how far has the avatar moved? diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 9025c7af8b..420220d21a 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -337,7 +337,7 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) LLVector3 agent_at_axis = gAgent.getAtAxis(); agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector()); agent_at_axis.normalize(); - gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f))); + gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f))); } setFocusOnAvatar(TRUE, ANIMATE); @@ -1082,8 +1082,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation(); LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation(); - if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) && - (root_at * last_at_axis > 0.95f)) + if (LLTrace::get_frame_recording().getLastRecordingPeriod().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f + && (root_at * last_at_axis > 0.95f)) { LLVector3 vel = gAgentAvatarp->getVelocity(); if (vel.magVecSquared() > 4.f) @@ -1138,13 +1138,14 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) } } +static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Camera"); + //----------------------------------------------------------------------------- // updateCamera() //----------------------------------------------------------------------------- void LLAgentCamera::updateCamera() { - static LLFastTimer::DeclareTimer ftm("Camera"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_UPDATE_CAMERA); // - changed camera_skyward to the new global "mCameraUpVector" mCameraUpVector = LLVector3::z_axis; @@ -1246,7 +1247,7 @@ void LLAgentCamera::updateCamera() gAgentCamera.clearPanKeys(); // lerp camera focus offset - mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); + mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); if ( mCameraMode == CAMERA_MODE_FOLLOW ) { @@ -1364,7 +1365,7 @@ void LLAgentCamera::updateCamera() { const F32 SMOOTHING_HALF_LIFE = 0.02f; - F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE); + F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE); if (!mFocusObject) // we differentiate on avatar mode { @@ -1394,7 +1395,7 @@ void LLAgentCamera::updateCamera() } - mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE)); + mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE)); // llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl; @@ -1809,7 +1810,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) if (mTargetCameraDistance != mCurrentCameraDistance) { - F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE); + F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE); mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt); } @@ -1827,7 +1828,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) if (isAgentAvatarValid()) { LLVector3d camera_lag_d; - F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE); + F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE); LLVector3 target_lag; LLVector3 vel = gAgent.getVelocity(); @@ -1872,7 +1873,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) } else { - mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f)); + mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f)); } camera_lag_d.setVec(mCameraLag); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1000c0e1e8..3e61787c13 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -60,7 +60,8 @@ #include "llcurl.h" #include "llcalc.h" #include "lltexturestats.h" -#include "lltexturestats.h" +#include "lltrace.h" +#include "lltracethreadrecorder.h" #include "llviewerwindow.h" #include "llviewerdisplay.h" #include "llviewermedia.h" @@ -277,7 +278,7 @@ LLPumpIO* gServicePump = NULL; U64 gFrameTime = 0; F32 gFrameTimeSeconds = 0.f; -F32 gFrameIntervalSeconds = 0.f; +LLUnit<LLUnits::Seconds, F32> gFrameIntervalSeconds = 0.f; F32 gFPSClamped = 10.f; // Pretend we start at target rate. F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds @@ -591,7 +592,7 @@ public: while (!LLAppViewer::instance()->isQuitting()) { - LLFastTimer::writeLog(os); + LLTrace::TimeBlock::writeLog(os); os.flush(); ms_sleep(32); } @@ -679,7 +680,6 @@ bool LLAppViewer::init() // into the log files during normal startup until AFTER // we run the "program crashed last time" error handler below. // - LLFastTimer::reset(); // initialize SSE options LLVector4a::initClass(); @@ -1033,9 +1033,9 @@ bool LLAppViewer::init() if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) { if (gGLManager.mIsIntel) - { - LLNotificationsUtil::add("IntelOldDriver"); - } + { + LLNotificationsUtil::add("IntelOldDriver"); + } else if (gGLManager.mIsNVIDIA) { LLNotificationsUtil::add("NVIDIAOldDriver"); @@ -1238,7 +1238,10 @@ bool LLAppViewer::mainLoop() while (!LLApp::isExiting()) { LLFastTimer _(FTM_FRAME); - LLFastTimer::nextFrame(); + LLTrace::get_frame_recording().nextPeriod(); + LLTrace::TimeBlock::logStats(); + + LLTrace::getMasterThreadRecorder().pullFromSlaveThreads(); //clear call stack records llclearcallstacks; @@ -1355,7 +1358,6 @@ bool LLAppViewer::mainLoop() LLFloaterSnapshot::update(); // take snapshots gGLActive = FALSE; } - } pingMainloopTimeout("Main:Sleep"); @@ -1410,7 +1412,7 @@ bool LLAppViewer::mainLoop() { S32 work_pending = 0; S32 io_pending = 0; - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); { LLFastTimer ftm(FTM_TEXTURE_CACHE); @@ -1567,9 +1569,9 @@ bool LLAppViewer::cleanup() if (LLFastTimerView::sAnalyzePerformance) { llinfos << "Analyzing performance" << llendl; - std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; - std::string current_name = LLFastTimer::sLogName + ".slp"; - std::string report_name = LLFastTimer::sLogName + "_report.csv"; + std::string baseline_name = LLTrace::TimeBlock::sLogName + "_baseline.slp"; + std::string current_name = LLTrace::TimeBlock::sLogName + ".slp"; + std::string report_name = LLTrace::TimeBlock::sLogName + "_report.csv"; LLFastTimerView::doAnalysis( gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), @@ -1928,9 +1930,9 @@ bool LLAppViewer::cleanup() { llinfos << "Analyzing performance" << llendl; - std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; - std::string current_name = LLFastTimer::sLogName + ".slp"; - std::string report_name = LLFastTimer::sLogName + "_report.csv"; + std::string baseline_name = LLTrace::TimeBlock::sLogName + "_baseline.slp"; + std::string current_name = LLTrace::TimeBlock::sLogName + ".slp"; + std::string report_name = LLTrace::TimeBlock::sLogName + "_report.csv"; LLFastTimerView::doAnalysis( gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), @@ -2053,10 +2055,10 @@ bool LLAppViewer::initThreads() enable_threads && true, app_metrics_qa_mode); - if (LLFastTimer::sLog || LLFastTimer::sMetricLog) + if (LLTrace::TimeBlock::sLog || LLTrace::TimeBlock::sMetricLog) { - LLFastTimer::sLogLock = new LLMutex(NULL); - mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName); + LLTrace::TimeBlock::setLogLock(new LLMutex(NULL)); + mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::TimeBlock::sLogName); mFastTimerLogThread->start(); } @@ -2465,13 +2467,13 @@ bool LLAppViewer::initConfiguration() if (clp.hasOption("logperformance")) { - LLFastTimer::sLog = TRUE; - LLFastTimer::sLogName = std::string("performance"); + LLTrace::TimeBlock::sLog = true; + LLTrace::TimeBlock::sLogName = std::string("performance"); } if (clp.hasOption("logmetrics")) { - LLFastTimer::sMetricLog = TRUE ; + LLTrace::TimeBlock::sMetricLog = true ; // '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test // In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...) std::string test_name = clp.getOption("logmetrics")[0]; @@ -2479,11 +2481,11 @@ bool LLAppViewer::initConfiguration() if (test_name == "") { llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl; - LLFastTimer::sLogName = DEFAULT_METRIC_NAME; + LLTrace::TimeBlock::sLogName = DEFAULT_METRIC_NAME; } else { - LLFastTimer::sLogName = test_name; + LLTrace::TimeBlock::sLogName = test_name; } } @@ -3752,7 +3754,7 @@ U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update // format changes. JC - const U32 INDRA_OBJECT_CACHE_VERSION = 14; + const U32 INDRA_OBJECT_CACHE_VERSION = 15; return INDRA_OBJECT_CACHE_VERSION; } @@ -4193,6 +4195,8 @@ static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World"); static LLFastTimer::DeclareTimer FTM_NETWORK("Network"); static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network"); static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager"); +static LLFastTimer::DeclareTimer FTM_AGENT_POSITION("Agent Position"); +static LLFastTimer::DeclareTimer FTM_HUD_EFFECTS("HUD Effects"); /////////////////////////////////////////////////////// // idle() @@ -4211,7 +4215,7 @@ void LLAppViewer::idle() LLFrameTimer::updateFrameCount(); LLEventTimer::updateClass(); LLNotificationsUI::LLToast::updateClass(); - LLCriticalDamp::updateInterpolants(); + LLSmoothInterpolation::updateInterpolants(); LLMortician::updateClass(); LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() @@ -4334,21 +4338,12 @@ void LLAppViewer::idle() llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl; gObjectList.mNumDeadObjectUpdates = 0; } - if (gObjectList.mNumUnknownKills) - { - llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl; - gObjectList.mNumUnknownKills = 0; - } if (gObjectList.mNumUnknownUpdates) { llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl; gObjectList.mNumUnknownUpdates = 0; } - // ViewerMetrics FPS piggy-backing on the debug timer. - // The 5-second interval is nice for this purpose. If the object debug - // bit moves or is disabled, please give this a suitable home. - LLViewerAssetStatsFF::record_fps_main(gFPSClamped); LLViewerAssetStatsFF::record_avatar_stats(); } } @@ -4430,8 +4425,7 @@ void LLAppViewer::idle() { // Handle pending gesture processing - static LLFastTimer::DeclareTimer ftm("Agent Position"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_AGENT_POSITION); LLGestureMgr::instance().update(); gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); @@ -4478,8 +4472,7 @@ void LLAppViewer::idle() // { - static LLFastTimer::DeclareTimer ftm("HUD Effects"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_HUD_EFFECTS); LLSelectMgr::getInstance()->updateEffects(); LLHUDManager::getInstance()->cleanupEffects(); LLHUDManager::getInstance()->sendEffects(); @@ -4877,7 +4870,7 @@ void LLAppViewer::idleNetwork() gPrintMessagesThisFrame = FALSE; } } - LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); + add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); // Retransmit unacknowledged packets. gXferManager->retransmitUnackedPackets(); @@ -5287,17 +5280,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle) { if (0 != region_handle) { - LLViewerAssetStatsFF::set_region_main(region_handle); - if (LLAppViewer::sTextureFetch) - { - // Send a region update message into 'thread1' to get the new region. - LLAppViewer::sTextureFetch->commandSetRegion(region_handle); - } - else - { - // No 'thread1', a.k.a. TextureFetch, so update directly - LLViewerAssetStatsFF::set_region_thread1(region_handle); - } + LLViewerAssetStatsFF::set_region(region_handle); } } @@ -5308,7 +5291,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle) */ void LLAppViewer::metricsSend(bool enable_reporting) { - if (! gViewerAssetStatsMain) + if (! gViewerAssetStats) return; if (LLAppViewer::sTextureFetch) @@ -5321,7 +5304,10 @@ void LLAppViewer::metricsSend(bool enable_reporting) // Make a copy of the main stats to send into another thread. // Receiving thread takes ownership. - LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain)); + LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats)); + main_stats->stop(); + + main_stats->updateStats(); // Send a report request into 'thread1' to get the rest of the data // and provide some additional parameters while here. @@ -5340,6 +5326,6 @@ void LLAppViewer::metricsSend(bool enable_reporting) // 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. - gViewerAssetStatsMain->reset(); + gViewerAssetStats->reset(); } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 7563d672e3..85a29925fb 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -32,6 +32,7 @@ #include "llsys.h" // for LLOSInfo #include "lltimer.h" #include "llappcorehttp.h" +#include "llunit.h" class LLCommandLineParser; class LLFrameTimer; @@ -329,7 +330,7 @@ extern LLPumpIO* gServicePump; extern U64 gFrameTime; // The timestamp of the most-recently-processed frame extern F32 gFrameTimeSeconds; // Loses msec precision after ~4.5 hours... -extern F32 gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds +extern LLUnit<LLUnits::Seconds, F32> gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds extern F32 gFPSClamped; // Frames per second, smoothed, weighted toward last frame extern F32 gFrameDTClamped; extern U64 gStartTime; diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index d6095cce07..f6bad18070 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -618,24 +618,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL send_chat_from_viewer(utf8_out_text, type, channel); } -/* -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ChatFromViewer); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ChatData); - msg->addStringFast(_PREHASH_Message, utf8_out_text); - msg->addU8Fast(_PREHASH_Type, type); - msg->addS32("Channel", channel); - - gAgent.sendReliableMessage(); - - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); -} -*/ void LLChatBar::onCommitGesture(LLUICtrl* ctrl) { diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 4f5f9e22b6..033c8f4865 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -436,8 +436,6 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) { LLSD args; diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index aeecf054b8..1264f05d77 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -40,7 +40,7 @@ #include "llsceneview.h" #include "llviewertexture.h" #include "llfloaterreg.h" - +#include "llscenemonitor.h" // // Globals // @@ -66,6 +66,7 @@ LLDebugView::~LLDebugView() gDebugView = NULL; gTextureView = NULL; gSceneView = NULL; + gSceneMonitorView = NULL; } void LLDebugView::init() @@ -99,6 +100,13 @@ void LLDebugView::init() addChild(gSceneView); gSceneView->setRect(rect); + gSceneMonitorView = new LLSceneMonitorView(r); + gSceneMonitorView->setFollowsTop(); + gSceneMonitorView->setFollowsLeft(); + gSceneMonitorView->setVisible(FALSE); + addChild(gSceneMonitorView); + gSceneMonitorView->setRect(rect); + r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index d041baea90..4d72dd1343 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -49,6 +49,7 @@ #include "llspatialpartition.h" #include "llviewerobjectlist.h" #include "llviewerwindow.h" +#include "llvocache.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -58,6 +59,7 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f; static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); extern bool gShiftFrame; +LLTrace::MemStatHandle LLDrawable::sMemStat("LLDrawable"); //////////////////////// @@ -75,7 +77,6 @@ extern bool gShiftFrame; // // static -U32 LLDrawable::sCurVisible = 0; U32 LLDrawable::sNumZombieDrawables = 0; F32 LLDrawable::sCurPixelAngle = 0; LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList; @@ -85,33 +86,59 @@ LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList; // static void LLDrawable::incrementVisible() { - sCurVisible++; + LLViewerOctreeEntryData::incrementVisible(); sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView(); } -void LLDrawable::init() +LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE), + mVObjp(vobj) +{ + init(new_entry); +} + +void LLDrawable::init(bool new_entry) { // mXform mParent = NULL; mRenderType = 0; mCurrentScale = LLVector3(1,1,1); mDistanceWRTCamera = 0.0f; - mPositionGroup.clear(); - mExtents[0].clear(); - mExtents[1].clear(); - mState = 0; - mVObjp = NULL; + // mFaces - mSpatialGroupp = NULL; - mVisible = sCurVisible - 2;//invisible for the current frame and the last frame. mRadius = 0.f; + mGeneration = -1; + mSpatialBridge = NULL; + + LLViewerOctreeEntry* entry = NULL; + LLVOCacheEntry* vo_entry = NULL; + if(!new_entry && mVObjp && getRegion() != NULL) + { + vo_entry = getRegion()->getCacheEntryForOctree(mVObjp->getLocalID()); + if(vo_entry) + { + entry = vo_entry->getEntry(); + } + } + setOctreeEntry(entry); + if(vo_entry) + { + if(!entry) + { + vo_entry->setOctreeEntry(mEntry); + } + else if(vo_entry->getNumOfChildren() > 0) + { + getRegion()->addVisibleCacheEntry(vo_entry); //to load all children. + } - mGeneration = -1; - mBinRadius = 1.f; - mBinIndex = -1; + getRegion()->addActiveCacheEntry(vo_entry); + } - mSpatialBridge = NULL; + llassert(!vo_entry || vo_entry->getEntry() == mEntry); + + initVisible(sCurVisible - 2);//invisible for the current frame and the last frame. } // static @@ -155,6 +182,7 @@ void LLDrawable::markDead() llwarns << "Warning! Marking dead multiple times!" << llendl; return; } + setState(DEAD); if (mSpatialBridge) { @@ -165,7 +193,6 @@ void LLDrawable::markDead() sNumZombieDrawables++; // We're dead. Free up all of our references to other objects - setState(DEAD); cleanupReferences(); // sDeadList.put(this); } @@ -219,6 +246,8 @@ void LLDrawable::cleanupReferences() gPipeline.unlinkDrawable(this); + removeFromOctree(); + { LLFastTimer t(FTM_DEREF_DRAWABLE); // Cleanup references to other objects @@ -227,6 +256,21 @@ void LLDrawable::cleanupReferences() } } +void LLDrawable::removeFromOctree() +{ + if(!mEntry) + { + return; + } + + mEntry->removeData(this); + if(mEntry->hasVOCacheEntry()) + { + getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this); + } + mEntry = NULL; +} + void LLDrawable::cleanupDeadDrawables() { /* @@ -287,10 +331,10 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { LLFace *face; - + { LLFastTimer t(FTM_ALLOCATE_FACE); - face = new LLFace(this, mVObjp); + face = new LLFace(this, mVObjp); } face->setTEOffset(mFaces.size()); @@ -439,6 +483,12 @@ void LLDrawable::makeActive() } updatePartition(); } + else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does... + { + mParent->makeActive(); + //NOTE: linked set will now NEVER become static + mParent->setState(LLDrawable::ACTIVE_CHILD); + } llassert(isAvatar() || isRoot() || mParent->isActive()); } @@ -519,7 +569,7 @@ F32 LLDrawable::updateXform(BOOL undamped) if (damped && isVisible()) { - F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); + F32 lerp_amt = llclamp(LLSmoothInterpolation::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); dist_squared = dist_vec_squared(new_pos, target_pos); @@ -738,7 +788,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLVOVolume* volume = getVOVolume(); if (volume) { - if (getSpatialGroup()) + if (getGroup()) { pos.set(getPositionGroup().getF32ptr()); } @@ -856,9 +906,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) } } - mExtents[0].add(shift_vector); - mExtents[1].add(shift_vector); - mPositionGroup.add(shift_vector); + shift(shift_vector); } else if (mSpatialBridge) { @@ -866,9 +914,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) } else if (isAvatar()) { - mExtents[0].add(shift_vector); - mExtents[1].add(shift_vector); - mPositionGroup.add(shift_vector); + shift(shift_vector); } mVObjp->onShift(shift_vector); @@ -880,40 +926,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const return mXform.getPositionW(); } -const LLVector4a* LLDrawable::getSpatialExtents() const -{ - return mExtents; -} - -void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max) -{ - mExtents[0].load3(min.mV); - mExtents[1].load3(max.mV); -} - -void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) -{ - mExtents[0] = min; - mExtents[1] = max; -} - -void LLDrawable::setPositionGroup(const LLVector4a& pos) -{ - mPositionGroup = pos; -} - void LLDrawable::updateSpatialExtents() { if (mVObjp) { - mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]); + const LLVector4a* exts = getSpatialExtents(); + LLVector4a extents[2]; + extents[0] = exts[0]; + extents[1] = exts[1]; + + mVObjp->updateSpatialExtents(extents[0], extents[1]); + setSpatialExtents(extents[0], extents[1]); } updateBinRadius(); if (mSpatialBridge.notNull()) { - mPositionGroup.splat(0.f); + getGroupPosition().splat(0.f); } } @@ -922,11 +952,11 @@ void LLDrawable::updateBinRadius() { if (mVObjp.notNull()) { - mBinRadius = llmin(mVObjp->getBinRadius(), 256.f); + setBinRadius(llmin(mVObjp->getBinRadius(), 256.f)); } else { - mBinRadius = llmin(getRadius()*4.f, 256.f); + setBinRadius(llmin(getRadius()*4.f, 256.f)); } } @@ -960,26 +990,56 @@ void LLDrawable::updateUVMinMax() { } -LLSpatialGroup* LLDrawable::getSpatialGroup() const +//virtual +bool LLDrawable::isVisible() const +{ + if (LLViewerOctreeEntryData::isVisible()) { - llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); - return mSpatialGroupp; + return true; } -void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { - //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this - llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this)); + LLviewerOctreeGroup* group = mEntry->getGroup(); + if (group && group->isVisible()) + { + LLViewerOctreeEntryData::setVisible(); + return true; + } + } - //precondition: groupp MUST be null or groupp MUST contain this - llassert(!groupp || groupp->hasElement(this)); + return false; +} -/*if (mSpatialGroupp && (groupp != mSpatialGroupp)) +//virtual +bool LLDrawable::isRecentlyVisible() const +{ + //currently visible or visible in the previous frame. + bool vis = LLViewerOctreeEntryData::isRecentlyVisible(); + + if(!vis) { - mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); - }*/ + LLviewerOctreeGroup* group = getGroup(); + if (group && group->isRecentlyVisible()) + { + LLViewerOctreeEntryData::setVisible(); + vis = TRUE ; + } + } + + return vis ; +} + +void LLDrawable::setGroup(LLviewerOctreeGroup *groupp) + { + LLSpatialGroup* cur_groupp = (LLSpatialGroup*)getGroup(); + + //precondition: mGroupp MUST be null or DEAD or mGroupp MUST NOT contain this + //llassert(!cur_groupp || cur_groupp->isDead() || !cur_groupp->hasElement(this)); - if (mSpatialGroupp != groupp && getVOVolume()) + //precondition: groupp MUST be null or groupp MUST contain this + llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this)); + + if (cur_groupp != groupp && getVOVolume()) { //NULL out vertex buffer references for volumes on spatial group change to maintain //requirement that every face vertex buffer is either NULL or points to a vertex buffer //contained by its drawable's spatial group @@ -995,10 +1055,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) //postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1 //postcondition: if next group is NOT NULL, binIndex must not be -1 - llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 : - getBinIndex() != -1); + //llassert(groupp == NULL ? (cur_groupp == NULL || cur_groupp->isDead()) || (!getEntry() || getEntry()->getBinIndex() == -1) : + // (getEntry() && getEntry()->getBinIndex() != -1)); - mSpatialGroupp = groupp; + LLViewerOctreeEntryData::setGroup(groupp); } LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1017,11 +1077,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() { if (mVObjp->isHUDAttachment()) { - setSpatialBridge(new LLHUDBridge(this)); + setSpatialBridge(new LLHUDBridge(this, getRegion())); } else { - setSpatialBridge(new LLVolumeBridge(this)); + setSpatialBridge(new LLVolumeBridge(this, getRegion())); } } return mSpatialBridge->asPartition(); @@ -1040,89 +1100,26 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() return retval; } -const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. -//static -S32 LLDrawable::getMinVisFrameRange() -{ - return MIN_VIS_FRAME_RANGE ; -} - -BOOL LLDrawable::isRecentlyVisible() const +//virtual +S32 LLDrawable::getMinVisFrameRange() const { - //currently visible or visible in the previous frame. - BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ; - - if(!vis) - { - LLSpatialGroup* group = getSpatialGroup(); - if (group && group->isRecentlyVisible()) - { - mVisible = sCurVisible; - vis = TRUE ; - } - } - - return vis ; -} - -BOOL LLDrawable::isVisible() const -{ - if (mVisible == sCurVisible) - { - return TRUE; - } - -#if 0 - //disabling this code fixes DEV-20105. Leaving in place in case some other bug pops up as a a result. - //should be safe to just always ask the spatial group for visibility. - if (isActive()) - { - if (isRoot()) - { - LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() : - getSpatialGroup(); - if (group && group->isVisible()) - { - mVisible = sCurVisible; - return TRUE; - } - } - else - { - if (getParent()->isVisible()) - { - mVisible = sCurVisible; - return TRUE; - } - } - } - else -#endif - { - LLSpatialGroup* group = getSpatialGroup(); - if (group && group->isVisible()) - { - mVisible = sCurVisible; - return TRUE; - } - } +const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. - return FALSE; + return MIN_VIS_FRAME_RANGE ; } //======================================= // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) -: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) : + LLDrawable(root->getVObj(), true), + LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp) { mBridge = this; mDrawable = root; root->setSpatialBridge(this); - mBinIndex = -1; - mRenderType = mDrawable->mRenderType; mDrawableType = mDrawable->mRenderType; @@ -1143,11 +1140,14 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLSpatialBridge::~LLSpatialBridge() { + if(mEntry) + { LLSpatialGroup* group = getSpatialGroup(); if (group) { group->mSpatialPartition->remove(this, group); } + } //delete octree here so listeners will still be able to access bridge specific state destroyTree(); @@ -1168,8 +1168,9 @@ void LLSpatialBridge::updateSpatialExtents() root->rebound(); } + const LLVector4a* root_bounds = root->getBounds(); LLVector4a offset; - LLVector4a size = root->mBounds[1]; + LLVector4a size = root_bounds[1]; //VECTORIZE THIS LLMatrix4a mat; @@ -1181,7 +1182,7 @@ void LLSpatialBridge::updateSpatialExtents() LLVector4a center; mat.affineTransform(t, center); - mat.rotate(root->mBounds[0], offset); + mat.rotate(root_bounds[0], offset); center.add(offset); LLVector4a v[4]; @@ -1203,12 +1204,9 @@ void LLSpatialBridge::updateSpatialExtents() scale.mul(size); mat.rotate(scale, v[3]); - - LLVector4a& newMin = mExtents[0]; - LLVector4a& newMax = mExtents[1]; - + LLVector4a newMin; + LLVector4a newMax; newMin = newMax = center; - for (U32 i = 0; i < 4; i++) { LLVector4a delta; @@ -1221,19 +1219,21 @@ void LLSpatialBridge::updateSpatialExtents() newMin.setMin(newMin, min); newMax.setMax(newMax, max); } + setSpatialExtents(newMin, newMax); LLVector4a diagonal; diagonal.setSub(newMax, newMin); mRadius = diagonal.getLength3().getF32() * 0.5f; - mPositionGroup.setAdd(newMin,newMax); - mPositionGroup.mul(0.5f); + LLVector4a& pos = getGroupPosition(); + pos.setAdd(newMin,newMax); + pos.mul(0.5f); updateBinRadius(); } void LLSpatialBridge::updateBinRadius() { - mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f); + setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f)); } LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) @@ -1268,7 +1268,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select) { - mVisible = sCurVisible; + LLViewerOctreeEntryData::setVisible(); #if 0 && !LL_RELEASE_FOR_DOWNLOAD //crazy paranoid rules checking @@ -1303,21 +1303,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, #endif } -class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable> +class LLOctreeMarkNotCulled: public OctreeTraveler { public: LLCamera* mCamera; LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { } - virtual void traverse(const LLOctreeNode<LLDrawable>* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); group->setVisible(); - LLOctreeTraveler<LLDrawable>::traverse(node); + OctreeTraveler::traverse(node); } - void visit(const LLOctreeNode<LLDrawable>* branch) + void visit(const OctreeNode* branch) { gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera); } @@ -1361,7 +1361,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* } if (!group || - LLDrawable::getCurrentFrame() - av->mVisible > 1 || + LLDrawable::getCurrentFrame() - av->getVisible() > 1 || impostor || !loaded) { @@ -1375,16 +1375,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* group->rebound(); LLVector4a center; - center.setAdd(mExtents[0], mExtents[1]); + const LLVector4a* exts = getSpatialExtents(); + center.setAdd(exts[0], exts[1]); center.mul(0.5f); LLVector4a size; - size.setSub(mExtents[1], mExtents[0]); + size.setSub(exts[1], exts[0]); size.mul(0.5f); if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || LLPipeline::sImpostorRender || (camera_in.AABBInFrustumNoFarClip(center, size) && - AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) + AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) { if (!LLPipeline::sImpostorRender && !LLPipeline::sShadowRender && @@ -1499,9 +1500,7 @@ BOOL LLSpatialBridge::updateMove() void LLSpatialBridge::shiftPos(const LLVector4a& vec) { - mExtents[0].add(vec); - mExtents[1].add(vec); - mPositionGroup.add(vec); + LLDrawable::shift(vec); } void LLSpatialBridge::cleanupReferences() @@ -1509,11 +1508,8 @@ void LLSpatialBridge::cleanupReferences() LLDrawable::cleanupReferences(); if (mDrawable) { - /* - - DON'T DO THIS -- this should happen through octree destruction + mDrawable->setGroup(NULL); - mDrawable->setSpatialGroup(NULL); if (mDrawable->getVObj()) { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1524,10 +1520,10 @@ void LLSpatialBridge::cleanupReferences() LLDrawable* drawable = child->mDrawable; if (drawable) { - drawable->setSpatialGroup(NULL); + drawable->setGroup(NULL); + } } } - }*/ LLDrawable* drawablep = mDrawable; mDrawable = NULL; @@ -1596,8 +1592,8 @@ void LLDrawable::updateFaceSize(S32 idx) } } -LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, FALSE, 0) +LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, 0, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; @@ -1605,8 +1601,8 @@ LLBridgePartition::LLBridgePartition() mSlopRatio = 0.25f; } -LLHUDBridge::LLHUDBridge(LLDrawable* drawablep) -: LLVolumeBridge(drawablep) +LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +: LLVolumeBridge(drawablep, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_HUD; mPartitionType = LLViewerRegion::PARTITION_HUD; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 4608d16fec..26796b92d0 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -42,6 +42,7 @@ #include "llviewerobject.h" #include "llrect.h" #include "llappviewer.h" // for gFrameTimeSeconds +#include "llvieweroctree.h" class LLCamera; class LLDrawPool; @@ -59,10 +60,12 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. LL_ALIGN_PREFIX(16) -class LLDrawable : public LLRefCount +class LLDrawable +: public LLViewerOctreeEntryData, + public LLTrace::MemTrackable<LLDrawable> { public: - LLDrawable(const LLDrawable& rhs) + LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs) { *this = rhs; } @@ -75,17 +78,7 @@ public: static void initClass(); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - LLDrawable() { init(); } + LLDrawable(LLViewerObject *vobj, bool new_entry = false); void markDead(); // Mark this drawable as dead BOOL isDead() const { return isState(DEAD); } @@ -93,11 +86,9 @@ public: BOOL isLight() const; - BOOL isVisible() const; - BOOL isRecentlyVisible() const; virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE); - + LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();} LLViewerRegion* getRegion() const { return mVObjp->getRegion(); } const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); } LLPointer<LLViewerObject>& getVObj() { return mVObjp; } @@ -110,16 +101,12 @@ public: const LLVector3& getPosition() const { return mXform.getPosition(); } const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } const LLVector3 getPositionAgent() const; - const LLVector4a& getPositionGroup() const { return mPositionGroup; } const LLVector3& getScale() const { return mCurrentScale; } void setScale(const LLVector3& scale) { mCurrentScale = scale; } const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); } const LLQuaternion& getRotation() const { return mXform.getRotation(); } F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - F32 getBinRadius() const { return mBinRadius; } - S32 getBinIndex() const { return mBinIndex; } - void setBinIndex(S32 index) const { mBinIndex = index; } void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -150,7 +137,7 @@ public: void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); void mergeFaces(LLDrawable* src); - void init(); + void init(bool new_entry); void destroy(); void update(); @@ -181,8 +168,12 @@ public: BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; } void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); } + bool isVisible() const; + bool isRecentlyVisible() const; + virtual void cleanupReferences(); + void setGroup(LLviewerOctreeGroup* group); void setRadius(const F32 radius); F32 getRadius() const { return mRadius; } F32 getVisibilityRadius() const; @@ -192,11 +183,6 @@ public: const LLVector3& getBounds(LLVector3& min, LLVector3& max) const; virtual void updateSpatialExtents(); virtual void updateBinRadius(); - const LLVector4a* getSpatialExtents() const; - void setSpatialExtents(const LLVector3& min, const LLVector3& max); - void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); - - void setPositionGroup(const LLVector4a& pos); void setRenderType(S32 type) { mRenderType = type; } BOOL isRenderType(S32 type) { return mRenderType == type; } @@ -205,10 +191,14 @@ public: // Debugging methods S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... - void setSpatialGroup(LLSpatialGroup *groupp); - LLSpatialGroup *getSpatialGroup() const; LLSpatialPartition* getSpatialPartition(); + virtual S32 getMinVisFrameRange()const; + void removeFromOctree(); + + void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } + LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } + // Statics static void incrementVisible(); static void cleanupDeadDrawables(); @@ -293,10 +283,6 @@ public: ACTIVE_CHILD = 0x40000000, } EDrawableFlags; -private: //aligned members - LL_ALIGN_16(LLVector4a mExtents[2]); - LL_ALIGN_16(LLVector4a mPositionGroup); - public: LLXformMatrix mXform; @@ -305,13 +291,8 @@ public: F32 mDistanceWRTCamera; - static S32 getCurrentFrame() { return sCurVisible; } - static S32 getMinVisFrameRange(); - - void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } - LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } - static F32 sCurPixelAngle; //current pixels per radian + static LLTrace::MemStatHandle sMemStat; private: typedef std::vector<LLFace*> face_list_t; @@ -320,19 +301,13 @@ private: S32 mRenderType; LLPointer<LLViewerObject> mVObjp; face_list_t mFaces; - LLSpatialGroup* mSpatialGroupp; LLPointer<LLDrawable> mSpatialBridge; - mutable U32 mVisible; F32 mRadius; - F32 mBinRadius; - mutable S32 mBinIndex; S32 mGeneration; LLVector3 mCurrentScale; - static U32 sCurVisible; // Counter for what value of mVisible means currently visible - static U32 sNumZombieDrawables; static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList; } LL_ALIGN_POSTFIX(16); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 4f6eaa5a5b..61f5ecc46f 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -463,7 +463,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face) gGL.getTexUnit(0)->bind(mHBTex[dr]); - LLOverrideFaceColor override(this, face->getFaceColor().mV); + LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV)); face->renderIndexed(); } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index de4d03351c..15c9e7856f 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -262,11 +262,11 @@ public: LLVector2 mTexExtents[2]; F32 mDistance; - F32 mLastUpdateTime; - F32 mLastSkinTime; - F32 mLastMoveTime; - LLMatrix4* mTextureMatrix; - LLDrawInfo* mDrawInfo; + F32 mLastUpdateTime; + F32 mLastSkinTime; + F32 mLastMoveTime; + LLMatrix4* mTextureMatrix; + LLDrawInfo* mDrawInfo; private: LLPointer<LLVertexBuffer> mVertexBuffer; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4dfb93f1bc..80d845c70e 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -46,7 +46,6 @@ #include "llviewertexturelist.h" #include "llui.h" #include "llviewercontrol.h" -#include "llstat.h" #include "llfasttimer.h" #include "lltreeiterators.h" @@ -55,24 +54,23 @@ ////////////////////////////////////////////////////////////////////////////// +using namespace LLTrace; + static const S32 MAX_VISIBLE_HISTORY = 10; static const S32 LINE_GRAPH_HEIGHT = 240; +static const S32 MIN_BAR_HEIGHT = 3; -//static const int FTV_DISPLAY_NUM = (sizeof(ft_display_table)/sizeof(ft_display_table[0])); -static S32 FTV_NUM_TIMERS; -const S32 FTV_MAX_DEPTH = 8; - -std::vector<LLFastTimer::NamedTimer*> ft_display_idx; // line of table entry for display purposes (for collapse) +std::vector<TimeBlock*> ft_display_idx; // line of table entry for display purposes (for collapse) -typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_iterator_t; +typedef LLTreeDFSIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_iterator_t; BOOL LLFastTimerView::sAnalyzePerformance = FALSE; -static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id) +static timer_tree_iterator_t begin_timer_tree(TimeBlock& id) { return timer_tree_iterator_t(&id, - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1), - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); + boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1), + boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1)); } static timer_tree_iterator_t end_timer_tree() @@ -80,37 +78,74 @@ static timer_tree_iterator_t end_timer_tree() return timer_tree_iterator_t(); } +S32 get_depth(const TimeBlock* blockp) +{ + S32 depth = 0; + TimeBlock* timerp = blockp->getParent(); + while(timerp) + { + depth++; + if (timerp->getParent() == timerp) break; + timerp = timerp->getParent(); + } + return depth; +} + LLFastTimerView::LLFastTimerView(const LLSD& key) : LLFloater(key), - mHoverTimer(NULL) + mHoverTimer(NULL), + mDisplayMode(0), + mDisplayCenter(ALIGN_CENTER), + mDisplayCalls(false), + mDisplayHz(false), + mScrollIndex(0), + mHoverID(NULL), + mHoverBarIndex(-1), + mPrintStats(-1), + mRecording(&get_frame_recording()), + mPauseHistory(false) { - mDisplayMode = 0; - mAvgCountTotal = 0; - mMaxCountTotal = 0; - mDisplayCenter = ALIGN_CENTER; - mDisplayCalls = 0; - mDisplayHz = 0; - mScrollIndex = 0; - mHoverID = NULL; - mHoverBarIndex = -1; - FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount(); - mPrintStats = -1; + mTimerBars = new std::vector<TimerBar>[MAX_VISIBLE_HISTORY + 1]; +} + +LLFastTimerView::~LLFastTimerView() +{ + if (mRecording != &get_frame_recording()) + { + delete mRecording; + } + mRecording = NULL; + delete [] mTimerBars; } void LLFastTimerView::onPause() { - LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory; + setPauseState(!mPauseHistory); +} + +void LLFastTimerView::setPauseState(bool pause_state) +{ + if (pause_state == mPauseHistory) return; + // reset scroll to bottom when unpausing - if (!LLFastTimer::sPauseHistory) + if (!pause_state) { - mScrollIndex = 0; - LLFastTimer::sResetHistory = true; + if (mRecording != &get_frame_recording()) + { + delete mRecording; + } + mRecording = &get_frame_recording(); getChild<LLButton>("pause_btn")->setLabel(getString("pause")); } else { + mRecording = new PeriodicRecording(get_frame_recording()); + mScrollIndex = 0; + getChild<LLButton>("pause_btn")->setLabel(getString("run")); } + + mPauseHistory = pause_state; } BOOL LLFastTimerView::postBuild() @@ -140,15 +175,15 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) { S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()); bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY); - mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx; + mPrintStats = mScrollIndex + bar_idx; return TRUE; } return LLFloater::handleRightMouseDown(x, y, mask); } -LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) +TimeBlock* LLFastTimerView::getLegendID(S32 y) { - S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5; + S32 idx = (mBarRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 1; if (idx >= 0 && idx < (S32)ft_display_idx.size()) { @@ -160,7 +195,7 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) { - for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); it != end_timer_tree(); ++it) { @@ -173,7 +208,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) { if (x < mBarRect.mLeft) { - LLFastTimer::NamedTimer* idp = getLegendID(y); + TimeBlock* idp = getLegendID(y); if (idp) { idp->setCollapsed(!idp->getCollapsed()); @@ -209,16 +244,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) gFocusMgr.setMouseCapture(this); return TRUE; } - //else - //{ - // // pause/unpause - // LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory; - // // reset scroll to bottom when unpausing - // if (!LLFastTimer::sPauseHistory) - // { - // mScrollIndex = 0; - // } - //} + return LLFloater::handleMouseDown(x, y, mask); } @@ -236,17 +262,18 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) if (hasMouseCapture()) { F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f); - mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); - mScrollIndex = llclamp( mScrollIndex, 0, LLFastTimer::getLastFrameIndex()); + mScrollIndex = llround( lerp * (F32)(mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY)); + mScrollIndex = llclamp( mScrollIndex, 0, (S32)mRecording->getNumPeriods()); return TRUE; } mHoverTimer = NULL; mHoverID = NULL; - if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y)) + if(mPauseHistory && mBarRect.pointInRect(x, y)) { - mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1, - MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight())); + mHoverBarIndex = llmin((mBarRect.mTop - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1, + (S32)mRecording->getNumPeriods() - 1, + MAX_VISIBLE_HISTORY); if (mHoverBarIndex == 0) { return TRUE; @@ -257,13 +284,12 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); it != end_timer_tree(); ++it, ++i) { // is mouse over bar for this timer? - if (x > mBarStart[mHoverBarIndex][i] && - x < mBarEnd[mHoverBarIndex][i]) + if (mTimerBars[mHoverBarIndex][i].mVisibleRect.pointInRect(x, y)) { mHoverID = (*it); if (mHoverTimer != *it) @@ -275,10 +301,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) mHoverTimer = (*it); } - mToolTipRect.set(mBarStart[mHoverBarIndex][i], - mBarRect.mBottom + llround(((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex + 1)) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))), - mBarEnd[mHoverBarIndex][i], - mBarRect.mBottom + llround((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f)))); + mToolTipRect = mTimerBars[mHoverBarIndex][i].mVisibleRect; } if ((*it)->getCollapsed()) @@ -289,7 +312,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } else if (x < mBarRect.mLeft) { - LLFastTimer::NamedTimer* timer_id = getLegendID(y); + TimeBlock* timer_id = getLegendID(y); if (timer_id) { mHoverID = timer_id; @@ -300,9 +323,24 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } +static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicRecording& frame_recording) +{ + std::string tooltip; + if (history_index == 0) + { + // by default, show average number of call + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<LLUnits::Milliseconds, F64>(frame_recording.getPeriodMean(timer)).value(), (S32)frame_recording.getPeriodMean(timer.callCount())); + } + else + { + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<LLUnits::Milliseconds, F64>(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount())); + } + return tooltip; +} + BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) { - if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y)) + if(mPauseHistory && mBarRect.pointInRect(x, y)) { // tooltips for timer bars if (mHoverTimer) @@ -310,8 +348,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) LLRect screen_rect; localRectToScreen(mToolTipRect, &screen_rect); + std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, *mRecording); + LLToolTipMgr::instance().show(LLToolTip::Params() - .message(mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex)) + .message(tooltip) .sticky_rect(screen_rect) .delay_time(0.f)); @@ -323,10 +363,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) // tooltips for timer legend if (x < mBarRect.mLeft) { - LLFastTimer::NamedTimer* idp = getLegendID(y); + TimeBlock* idp = getLegendID(y); if (idp) { - LLToolTipMgr::instance().show(idp->getToolTip()); + LLToolTipMgr::instance().show(get_tooltip(*idp, 0, *mRecording)); return TRUE; } @@ -338,707 +378,54 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks) { - LLFastTimer::sPauseHistory = TRUE; + setPauseState(true); mScrollIndex = llclamp( mScrollIndex + clicks, 0, - llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); + llmin((S32)mRecording->getNumPeriods(), (S32)mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY)); return TRUE; } -static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true); +static TimeBlock FTM_RENDER_TIMER("Timers", true); +static const S32 MARGIN = 10; +static const S32 LEGEND_WIDTH = 220; -static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors; +static std::map<TimeBlock*, LLColor4> sTimerColors; void LLFastTimerView::draw() { LLFastTimer t(FTM_RENDER_TIMER); - std::string tdesc; - - F64 clock_freq = (F64)LLFastTimer::countsPerSecond(); - F64 iclock_freq = 1000.0 / clock_freq; - - S32 margin = 10; - S32 height = getRect().getHeight(); - S32 width = getRect().getWidth(); - - LLRect new_rect; - new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); - setRect(new_rect); - - S32 left, top, right, bottom; - S32 x, y, barw, barh, dx, dy; - S32 texth, textw; - LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square"); + generateUniqueColors(); // Draw the window background gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); - - S32 xleft = margin; - S32 ytop = margin; + gl_rect_2d(getLocalRect(), LLColor4(0.f, 0.f, 0.f, 0.25f)); - // Draw some help - { - - x = xleft; - y = height - ytop; - texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); - - char modedesc[][32] = { - "2 x Average ", - "Max ", - "Recent Max ", - "100 ms " - }; - char centerdesc[][32] = { - "Left ", - "Centered ", - "Ordered " - }; - - tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - textw = LLFontGL::getFontMonospace()->getWidth(tdesc); - - x = xleft, y -= (texth + 2); - tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - y -= (texth + 2); - - LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"), - 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - y -= (texth + 2); - } - - S32 histmax = llmin(LLFastTimer::getLastFrameIndex()+1, MAX_VISIBLE_HISTORY); - - // Draw the legend - xleft = margin; - ytop = y; - - y -= (texth + 2); - - sTimerColors[&getFrameTimer()] = LLColor4::grey; - - F32 hue = 0.f; - - for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); - it != timer_tree_iterator_t(); - ++it) - { - LLFastTimer::NamedTimer* idp = (*it); - - const F32 HUE_INCREMENT = 0.23f; - hue = fmodf(hue + HUE_INCREMENT, 1.f); - // saturation increases with depth - F32 saturation = clamp_rescale((F32)idp->getDepth(), 0.f, 3.f, 0.f, 1.f); - // lightness alternates with depth - F32 lightness = idp->getDepth() % 2 ? 0.5f : 0.6f; - - LLColor4 child_color; - child_color.setHSL(hue, saturation, lightness); - - sTimerColors[idp] = child_color; - } - - const S32 LEGEND_WIDTH = 220; - { - LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin)); - S32 cur_line = 0; - ft_display_idx.clear(); - std::map<LLFastTimer::NamedTimer*, S32> display_line; - for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); - it != timer_tree_iterator_t(); - ++it) - { - LLFastTimer::NamedTimer* idp = (*it); - display_line[idp] = cur_line; - ft_display_idx.push_back(idp); - cur_line++; - - x = xleft; - - left = x; right = x + texth; - top = y; bottom = y - texth; - S32 scale_offset = 0; - if (idp == mHoverID) - { - scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f); - } - gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, sTimerColors[idp]); - - F32 ms = 0; - S32 calls = 0; - if (mHoverBarIndex > 0 && mHoverID) - { - S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex; - U64 ticks = idp->getHistoricalCount(hidx); - ms = (F32)((F64)ticks * iclock_freq); - calls = (S32)idp->getHistoricalCalls(hidx); - } - else - { - U64 ticks = idp->getCountAverage(); - ms = (F32)((F64)ticks * iclock_freq); - calls = (S32)idp->getCallAverage(); - } - - if (mDisplayCalls) - { - tdesc = llformat("%s (%d)",idp->getName().c_str(),calls); - } - else - { - tdesc = llformat("%s [%.1f]",idp->getName().c_str(),ms); - } - dx = (texth+4) + idp->getDepth()*8; - - LLColor4 color = LLColor4::white; - if (idp->getDepth() > 0) - { - S32 line_start_y = (top + bottom) / 2; - S32 line_end_y = line_start_y + ((texth + 2) * (cur_line - display_line[idp->getParent()])) - texth; - gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color); - S32 line_x = x + (texth + 4) + ((idp->getDepth() - 1) * 8); - gl_line_2d(line_x, line_start_y, line_x, line_end_y, color); - if (idp->getCollapsed() && !idp->getChildren().empty()) - { - gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color); - } - } - - x += dx; - BOOL is_child_of_hover_item = (idp == mHoverID); - LLFastTimer::NamedTimer* next_parent = idp->getParent(); - while(!is_child_of_hover_item && next_parent) - { - is_child_of_hover_item = (mHoverID == next_parent); - if (next_parent->getParent() == next_parent) break; - next_parent = next_parent->getParent(); - } - - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, - x, y, - color, - LLFontGL::LEFT, LLFontGL::TOP, - is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL); - - y -= (texth + 2); - - textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40; - - if (idp->getCollapsed()) - { - it.skipDescendants(); - } - } - } - - xleft += LEGEND_WIDTH + 8; - // ytop = ytop; + S32 y = drawHelp(getRect().getHeight() - MARGIN); + drawLegend(y - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 2)); // update rectangle that includes timer bars - mBarRect.mLeft = xleft; - mBarRect.mRight = getRect().getWidth(); - mBarRect.mTop = ytop - (LLFontGL::getFontMonospace()->getLineHeight() + 4); - mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT; - - y = ytop; - barh = (ytop - margin - LINE_GRAPH_HEIGHT) / (MAX_VISIBLE_HISTORY + 2); - dy = barh>>2; // spacing between bars - if (dy < 1) dy = 1; - barh -= dy; - barw = width - xleft - margin; - - // Draw the history bars - if (LLFastTimer::getLastFrameIndex() >= 0) - { - LLLocalClipRect clip(LLRect(xleft, ytop, getRect().getWidth() - margin, margin)); - - U64 totalticks; - if (!LLFastTimer::sPauseHistory) - { - U64 ticks = getFrameTimer().getHistoricalCount(mScrollIndex); - - if (LLFastTimer::getCurFrameIndex() >= 10) - { - U64 framec = LLFastTimer::getCurFrameIndex(); - U64 avg = (U64)mAvgCountTotal; - mAvgCountTotal = (avg*framec + ticks) / (framec + 1); - if (ticks > mMaxCountTotal) - { - mMaxCountTotal = ticks; - } - } - - if (ticks < mAvgCountTotal/100 || ticks > mAvgCountTotal*100) - { - LLFastTimer::sResetHistory = true; - } - - if (LLFastTimer::getCurFrameIndex() < 10 || LLFastTimer::sResetHistory) - { - mAvgCountTotal = ticks; - mMaxCountTotal = ticks; - LLFastTimer::sResetHistory = false; - } - } - - if (mDisplayMode == 0) - { - totalticks = mAvgCountTotal*2; - } - else if (mDisplayMode == 1) - { - totalticks = mMaxCountTotal; - } - else if (mDisplayMode == 2) - { - // Calculate the max total ticks for the current history - totalticks = 0; - for (S32 j=0; j<histmax; j++) - { - U64 ticks = getFrameTimer().getHistoricalCount(j); - - if (ticks > totalticks) - totalticks = ticks; - } - } - else - { - totalticks = (U64)(clock_freq * .1); // 100 ms - } - - // Draw MS ticks - { - U32 ms = (U32)((F64)totalticks * iclock_freq) ; - - tdesc = llformat("%.1f ms |", (F32)ms*.25f); - x = xleft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tdesc); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - tdesc = llformat("%.1f ms |", (F32)ms*.50f); - x = xleft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tdesc); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - tdesc = llformat("%.1f ms |", (F32)ms*.75f); - x = xleft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tdesc); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - tdesc = llformat( "%d ms |", ms); - x = xleft + barw - LLFontGL::getFontMonospace()->getWidth(tdesc); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - } - - // Draw borders - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f(0.5f,0.5f,0.5f,0.5f); - - S32 by = y + 2; - - y -= ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); - - //heading - gl_rect_2d(xleft-5, by, getRect().getWidth()-5, y+5, FALSE); - - //tree view - gl_rect_2d(5, by, xleft-10, 5, FALSE); - - by = y + 5; - //average bar - gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-5, FALSE); - - by -= barh*2+dy; - - //current frame bar - gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-2, FALSE); - - by -= barh+dy+1; - - //history bars - gl_rect_2d(xleft-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-barh-dy-2, FALSE); - - by = LINE_GRAPH_HEIGHT-barh-dy-7; - - //line graph - mGraphRect = LLRect(xleft-5, by, getRect().getWidth()-5, 5); - - gl_rect_2d(mGraphRect, FALSE); - } - - mBarStart.clear(); - mBarEnd.clear(); - - // Draw bars for each history entry - // Special: -1 = show running average - gGL.getTexUnit(0)->bind(box_imagep->getImage()); - for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++) - { - mBarStart.push_back(std::vector<S32>()); - mBarEnd.push_back(std::vector<S32>()); - int sublevel_dx[FTV_MAX_DEPTH]; - int sublevel_left[FTV_MAX_DEPTH]; - int sublevel_right[FTV_MAX_DEPTH]; - S32 tidx; - if (j >= 0) - { - tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex; - } - else - { - tidx = -1; - } - - x = xleft; - - // draw the bars for each stat - std::vector<S32> xpos; - std::vector<S32> deltax; - xpos.push_back(xleft); - - LLFastTimer::NamedTimer* prev_id = NULL; - - S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); - it != end_timer_tree(); - ++it, ++i) - { - LLFastTimer::NamedTimer* idp = (*it); - F32 frac = tidx == -1 - ? (F32)idp->getCountAverage() / (F32)totalticks - : (F32)idp->getHistoricalCount(tidx) / (F32)totalticks; - - dx = llround(frac * (F32)barw); - S32 prev_delta_x = deltax.empty() ? 0 : deltax.back(); - deltax.push_back(dx); - - int level = idp->getDepth() - 1; - - while ((S32)xpos.size() > level + 1) - { - xpos.pop_back(); - } - left = xpos.back(); - - if (level == 0) - { - sublevel_left[level] = xleft; - sublevel_dx[level] = dx; - sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; - } - else if (prev_id && prev_id->getDepth() < idp->getDepth()) - { - U64 sublevelticks = 0; - - for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren(); - it != prev_id->endChildren(); - ++it) - { - sublevelticks += (tidx == -1) - ? (*it)->getCountAverage() - : (*it)->getHistoricalCount(tidx); - } - - F32 subfrac = (F32)sublevelticks / (F32)totalticks; - sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f); - - if (mDisplayCenter == ALIGN_CENTER) - { - left += (prev_delta_x - sublevel_dx[level])/2; - } - else if (mDisplayCenter == ALIGN_RIGHT) - { - left += (prev_delta_x - sublevel_dx[level]); - } - - sublevel_left[level] = left; - sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; - } - - right = left + dx; - xpos.back() = right; - xpos.push_back(left); - - mBarStart.back().push_back(left); - mBarEnd.back().push_back(right); - - top = y; - bottom = y - barh; - - if (right > left) - { - //U32 rounded_edges = 0; - LLColor4 color = sTimerColors[idp];//*ft_display_table[i].color; - S32 scale_offset = 0; - - BOOL is_child_of_hover_item = (idp == mHoverID); - LLFastTimer::NamedTimer* next_parent = idp->getParent(); - while(!is_child_of_hover_item && next_parent) - { - is_child_of_hover_item = (mHoverID == next_parent); - if (next_parent->getParent() == next_parent) break; - next_parent = next_parent->getParent(); - } - - if (idp == mHoverID) - { - scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); - //color = lerp(color, LLColor4::black, -0.4f); - } - else if (mHoverID != NULL && !is_child_of_hover_item) - { - color = lerp(color, LLColor4::grey, 0.8f); - } - - gGL.color4fv(color.mV); - F32 start_fragment = llclamp((F32)(left - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); - F32 end_fragment = llclamp((F32)(right - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); - gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment); - - } - - if ((*it)->getCollapsed()) - { - it.skipDescendants(); - } - - prev_id = idp; - } - y -= (barh + dy); - if (j < 0) - y -= barh; - } - - //draw line graph history - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLLocalClipRect clip(mGraphRect); - - //normalize based on last frame's maximum - static U64 last_max = 0; - static F32 alpha_interp = 0.f; - U64 max_ticks = llmax(last_max, (U64) 1); - F32 ms = (F32)((F64)max_ticks * iclock_freq); - - //display y-axis range - std::string tdesc; - if (mDisplayCalls) - tdesc = llformat("%d calls", (int)max_ticks); - else if (mDisplayHz) - tdesc = llformat("%d Hz", (int)max_ticks); - else - tdesc = llformat("%4.2f ms", ms); - - x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5; - y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); - - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - //highlight visible range - { - S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex; - S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; - - F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1); - - F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; - F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; - - gGL.color4f(0.5f,0.5f,0.5f,0.3f); - gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom); - - if (mHoverBarIndex >= 0) - { - S32 bar_frame = first_frame - mHoverBarIndex; - F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame; - - gGL.color4f(0.5f,0.5f,0.5f,1); - - gGL.begin(LLRender::LINES); - gGL.vertex2i((S32)bar, mGraphRect.mBottom); - gGL.vertex2i((S32)bar, mGraphRect.mTop); - gGL.end(); - } - } - - U64 cur_max = 0; - for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); - it != end_timer_tree(); - ++it) - { - LLFastTimer::NamedTimer* idp = (*it); - - //fatten highlighted timer - if (mHoverID == idp) - { - gGL.flush(); - glLineWidth(3); - } - - const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV; - - F32 alpha = 1.f; - - if (mHoverID != NULL && - idp != mHoverID) - { //fade out non-highlighted timers - if (idp->getParent() != mHoverID) - { - alpha = alpha_interp; - } - } - - gGL.color4f(col[0], col[1], col[2], alpha); - gGL.begin(LLRender::TRIANGLE_STRIP); - for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex()); - j < LLFastTimer::NamedTimer::HISTORY_NUM; - j++) - { - U64 ticks = idp->getHistoricalCount(j); - - if (mDisplayHz) - { - F64 tc = (F64) (ticks+1) * iclock_freq; - tc = 1000.f/tc; - ticks = llmin((U64) tc, (U64) 1024); - } - else if (mDisplayCalls) - { - ticks = (S32)idp->getHistoricalCalls(j); - } - - if (alpha == 1.f) - { - //normalize to highlighted timer - cur_max = llmax(cur_max, ticks); - } - F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j; - F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks; - gGL.vertex2f(x,y); - gGL.vertex2f(x,mGraphRect.mBottom); - } - gGL.end(); - - if (mHoverID == idp) - { - gGL.flush(); - glLineWidth(1); - } - - if (idp->getCollapsed()) - { - //skip hidden timers - it.skipDescendants(); - } - } - - //interpolate towards new maximum - last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f)); - if (last_max - cur_max <= 1 || cur_max - last_max <= 1) - { - last_max = cur_max; - } - F32 alpha_target = last_max > cur_max ? - llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) : - llmin((F32) cur_max/ (F32) last_max - 1.f,1.f); - alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f)); - - if (mHoverID != NULL) - { - x = (mGraphRect.mRight + mGraphRect.mLeft)/2; - y = mGraphRect.mBottom + 8; - - LLFontGL::getFontMonospace()->renderUTF8( - mHoverID->getName(), - 0, - x, y, - LLColor4::white, - LLFontGL::LEFT, LLFontGL::BOTTOM); - } - } - } - - // Output stats for clicked bar to log - if (mPrintStats >= 0) - { - std::string legend_stat; - bool first = true; - for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); - it != end_timer_tree(); - ++it) - { - LLFastTimer::NamedTimer* idp = (*it); - - if (!first) - { - legend_stat += ", "; - } - first = false; - legend_stat += idp->getName(); - - if (idp->getCollapsed()) - { - it.skipDescendants(); - } - } - llinfos << legend_stat << llendl; - - std::string timer_stat; - first = true; - for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); - it != end_timer_tree(); - ++it) - { - LLFastTimer::NamedTimer* idp = (*it); - - if (!first) - { - timer_stat += ", "; - } - first = false; - - U64 ticks; - if (mPrintStats > 0) - { - ticks = idp->getHistoricalCount(mPrintStats); - } - else - { - ticks = idp->getCountAverage(); - } - F32 ms = (F32)((F64)ticks * iclock_freq); + const S32 LEGEND_WIDTH = 220; - timer_stat += llformat("%.1f",ms); + mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8; + mBarRect.mTop = y; + mBarRect.mRight = getRect().getWidth() - MARGIN; + mBarRect.mBottom = MARGIN + LINE_GRAPH_HEIGHT; - if (idp->getCollapsed()) - { - it.skipDescendants(); - } - } - llinfos << timer_stat << llendl; - mPrintStats = -1; - } + drawBars(); + drawLineGraph(); + printLineStats(); + LLView::draw(); + mAllTimeMax = llmax(mAllTimeMax, mRecording->getLastRecordingPeriod().getSum(FTM_FRAME)); mHoverID = NULL; mHoverBarIndex = -1; - - LLView::draw(); } F64 LLFastTimerView::getTime(const std::string& name) { - const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name); - if (timerp) - { - return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond(); - } + //TODO: replace calls to this with use of timer object directly + //llstatic_assert(false, "TODO: implement"); return 0.0; } @@ -1536,13 +923,13 @@ void LLFastTimerView::outputAllMetrics() //static void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output) { - if(LLFastTimer::sLog) + if(TimeBlock::sLog) { doAnalysisDefault(baseline, target, output) ; return ; } - if(LLFastTimer::sMetricLog) + if(TimeBlock::sMetricLog) { LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ; return ; @@ -1553,9 +940,660 @@ void LLFastTimerView::onClickCloseBtn() setVisible(false); } -LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer() +void LLFastTimerView::printLineStats() { - return FTM_FRAME.getNamedTimer(); + // Output stats for clicked bar to log + if (mPrintStats >= 0) + { + std::string legend_stat; + bool first = true; + for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); + it != end_timer_tree(); + ++it) + { + TimeBlock* idp = (*it); + + if (!first) + { + legend_stat += ", "; + } + first = false; + legend_stat += idp->getName(); + + if (idp->getCollapsed()) + { + it.skipDescendants(); + } + } + llinfos << legend_stat << llendl; + + std::string timer_stat; + first = true; + for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); + it != end_timer_tree(); + ++it) + { + TimeBlock* idp = (*it); + + if (!first) + { + timer_stat += ", "; + } + first = false; + + LLUnit<LLUnits::Seconds, F32> ticks; + if (mPrintStats > 0) + { + ticks = mRecording->getPrevRecordingPeriod(mPrintStats).getSum(*idp); + } + else + { + ticks = mRecording->getPeriodMean(*idp); + } + LLUnit<LLUnits::Milliseconds, F32> ms = ticks; + + timer_stat += llformat("%.1f",ms.value()); + + if (idp->getCollapsed()) + { + it.skipDescendants(); + } + } + llinfos << timer_stat << llendl; + mPrintStats = -1; + } } +static LLFastTimer::DeclareTimer FTM_DRAW_LINE_GRAPH("Draw line graph"); + +void LLFastTimerView::drawLineGraph() +{ + LLFastTimer _(FTM_DRAW_LINE_GRAPH); + //draw line graph history + S32 x = mBarRect.mLeft; + S32 y = LINE_GRAPH_HEIGHT; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLLocalClipRect clip(mGraphRect); + + //normalize based on last frame's maximum + static LLUnit<LLUnits::Seconds, F32> max_time = 0.000001; + static U32 max_calls = 0; + static F32 alpha_interp = 0.f; + + //display y-axis range + std::string axis_label; + if (mDisplayCalls) + axis_label = llformat("%d calls", (int)max_calls); + else if (mDisplayHz) + axis_label = llformat("%d Hz", (int)(1.f / max_time.value())); + else + axis_label = llformat("%4.2f ms", LLUnit<LLUnits::Milliseconds, F32>(max_time).value()); + + x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(axis_label)-5; + y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); + + LLFontGL::getFontMonospace()->renderUTF8(axis_label, 0, x, y, LLColor4::white, + LLFontGL::LEFT, LLFontGL::TOP); + + //highlight visible range + { + S32 first_frame = mRecording->getNumPeriods() - mScrollIndex; + S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; + + F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording->getNumPeriods()-1); + + F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; + F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; + + gGL.color4f(0.5f,0.5f,0.5f,0.3f); + gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom); + + if (mHoverBarIndex > 0) + { + S32 bar_frame = first_frame - mHoverBarIndex - 1; + F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame; + + gGL.color4f(0.5f,0.5f,0.5f,1); + + gGL.begin(LLRender::LINES); + gGL.vertex2i((S32)bar, mGraphRect.mBottom); + gGL.vertex2i((S32)bar, mGraphRect.mTop); + gGL.end(); + } + } + LLUnit<LLUnits::Seconds, F32> cur_max = 0; + U32 cur_max_calls = 0; + for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); + it != end_timer_tree(); + ++it) + { + TimeBlock* idp = (*it); + + //fatten highlighted timer + if (mHoverID == idp) + { + gGL.flush(); + glLineWidth(3); + } + + const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV; + + F32 alpha = 1.f; + + if (mHoverID != NULL && + mHoverID != idp) + { //fade out non-highlighted timers + if (idp->getParent() != mHoverID) + { + alpha = alpha_interp; + } + } + + gGL.color4f(col[0], col[1], col[2], alpha); + gGL.begin(LLRender::TRIANGLE_STRIP); + for (U32 j = mRecording->getNumPeriods(); + j > 0; + j--) + { + LLUnit<LLUnits::Seconds, F32> time = llmax(mRecording->getPrevRecordingPeriod(j).getSum(*idp), LLUnit<LLUnits::Seconds, F64>(0.000001)); + U32 calls = mRecording->getPrevRecordingPeriod(j).getSum(idp->callCount()); + + if (alpha == 1.f) + { + //normalize to highlighted timer + cur_max = llmax(cur_max, time); + cur_max_calls = llmax(cur_max_calls, calls); + } + F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording->getNumPeriods()-1); + F32 y = mDisplayHz + ? mGraphRect.mBottom + (1.f / time.value()) * ((F32) mGraphRect.getHeight() / (1.f / max_time.value())) + : mGraphRect.mBottom + time / max_time * (F32)mGraphRect.getHeight(); + gGL.vertex2f(x,y); + gGL.vertex2f(x,mGraphRect.mBottom); + } + gGL.end(); + + if (mHoverID == idp) + { + gGL.flush(); + glLineWidth(1); + } + + if (idp->getCollapsed()) + { + //skip hidden timers + it.skipDescendants(); + } + } + + //interpolate towards new maximum + max_time = lerp(max_time.value(), cur_max.value(), LLSmoothInterpolation::getInterpolant(0.1f)); + if (max_time - cur_max <= 1 || cur_max - max_time <= 1) + { + max_time = llmax(LLUnit<LLUnits::Microseconds, F32>(1), LLUnit<LLUnits::Microseconds, F32>(cur_max)); + } + + max_calls = llround(lerp((F32)max_calls, (F32) cur_max_calls, LLSmoothInterpolation::getInterpolant(0.1f))); + if (llabs((S32)(max_calls - cur_max_calls)) <= 1) + { + max_calls = cur_max_calls; + } + + // TODO: make sure alpha is correct in DisplayHz mode + F32 alpha_target = (max_time > cur_max) + ? llmin(max_time / cur_max - 1.f,1.f) + : llmin(cur_max/ max_time - 1.f,1.f); + alpha_interp = lerp(alpha_interp, alpha_target, LLSmoothInterpolation::getInterpolant(0.1f)); + + if (mHoverID != NULL) + { + x = (mGraphRect.mRight + mGraphRect.mLeft)/2; + y = mGraphRect.mBottom + 8; + + LLFontGL::getFontMonospace()->renderUTF8( + mHoverID->getName(), + 0, + x, y, + LLColor4::white, + LLFontGL::LEFT, LLFontGL::BOTTOM); + } +} + +void LLFastTimerView::drawLegend( S32 y ) +{ + // draw legend + S32 dx; + S32 x = MARGIN; + const S32 TEXT_HEIGHT = (S32)LLFontGL::getFontMonospace()->getLineHeight(); + + { + LLLocalClipRect clip(LLRect(MARGIN, y, LEGEND_WIDTH, MARGIN)); + S32 cur_line = 0; + ft_display_idx.clear(); + std::map<TimeBlock*, S32> display_line; + for (timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); + it != timer_tree_iterator_t(); + ++it) + { + TimeBlock* idp = (*it); + display_line[idp] = cur_line; + ft_display_idx.push_back(idp); + cur_line++; + + x = MARGIN; + + LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT); + S32 scale_offset = 0; + if (idp == mHoverID) + { + scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f); + } + bar_rect.stretch(scale_offset); + gl_rect_2d(bar_rect, sTimerColors[idp]); + + LLUnit<LLUnits::Milliseconds, F32> ms = 0; + S32 calls = 0; + if (mHoverBarIndex > 0 && mHoverID) + { + S32 hidx = mScrollIndex + mHoverBarIndex; + ms = mRecording->getPrevRecordingPeriod(hidx).getSum(*idp); + calls = mRecording->getPrevRecordingPeriod(hidx).getSum(idp->callCount()); + } + else + { + ms = LLUnit<LLUnits::Seconds, F64>(mRecording->getPeriodMean(*idp)); + calls = (S32)mRecording->getPeriodMean(idp->callCount()); + } + + std::string timer_label; + if (mDisplayCalls) + { + timer_label = llformat("%s (%d)",idp->getName().c_str(),calls); + } + else + { + timer_label = llformat("%s [%.1f]",idp->getName().c_str(),ms.value()); + } + dx = (TEXT_HEIGHT+4) + get_depth(idp)*8; + + LLColor4 color = LLColor4::white; + if (get_depth(idp) > 0) + { + S32 line_start_y = bar_rect.getCenterY(); + S32 line_end_y = line_start_y + ((TEXT_HEIGHT + 2) * (cur_line - display_line[idp->getParent()])) - TEXT_HEIGHT; + gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color); + S32 line_x = x + (TEXT_HEIGHT + 4) + ((get_depth(idp) - 1) * 8); + gl_line_2d(line_x, line_start_y, line_x, line_end_y, color); + if (idp->getCollapsed() && !idp->getChildren().empty()) + { + gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color); + } + } + + x += dx; + BOOL is_child_of_hover_item = (idp == mHoverID); + TimeBlock* next_parent = idp->getParent(); + while(!is_child_of_hover_item && next_parent) + { + is_child_of_hover_item = (mHoverID == next_parent); + if (next_parent->getParent() == next_parent) break; + next_parent = next_parent->getParent(); + } + + LLFontGL::getFontMonospace()->renderUTF8(timer_label, 0, + x, y, + color, + LLFontGL::LEFT, LLFontGL::TOP, + is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL); + + y -= (TEXT_HEIGHT + 2); + + if (idp->getCollapsed()) + { + it.skipDescendants(); + } + } + } +} + +void LLFastTimerView::generateUniqueColors() +{ + // generate unique colors + { + sTimerColors[&FTM_FRAME] = LLColor4::grey; + + F32 hue = 0.f; + + for (timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); + it != timer_tree_iterator_t(); + ++it) + { + TimeBlock* idp = (*it); + + const F32 HUE_INCREMENT = 0.23f; + hue = fmodf(hue + HUE_INCREMENT, 1.f); + // saturation increases with depth + F32 saturation = clamp_rescale((F32)get_depth(idp), 0.f, 3.f, 0.f, 1.f); + // lightness alternates with depth + F32 lightness = get_depth(idp) % 2 ? 0.5f : 0.6f; + + LLColor4 child_color; + child_color.setHSL(hue, saturation, lightness); + + sTimerColors[idp] = child_color; + } + } +} + +S32 LLFastTimerView::drawHelp( S32 y ) +{ + // Draw some help + const S32 texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); + + char modedesc[][32] = { + "2 x Average ", + "Max ", + "Recent Max ", + "100 ms " + }; + char centerdesc[][32] = { + "Left ", + "Centered ", + "Ordered " + }; + + std::string text; + text = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + + y -= (texth + 2); + text = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + y -= (texth + 2); + + LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"), + 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + y -= (texth + 2); + return y; +} + +void LLFastTimerView::drawTicks() +{ + // Draw MS ticks + { + LLUnit<LLUnits::Milliseconds, U32> ms = mTotalTimeDisplay; + std::string tick_label; + S32 x; + S32 barw = mBarRect.getWidth(); + + tick_label = llformat("%.1f ms |", (F32)ms.value()*.25f); + x = mBarRect.mLeft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tick_label); + LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, + LLFontGL::LEFT, LLFontGL::TOP); + + tick_label = llformat("%.1f ms |", (F32)ms.value()*.50f); + x = mBarRect.mLeft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tick_label); + LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, + LLFontGL::LEFT, LLFontGL::TOP); + + tick_label = llformat("%.1f ms |", (F32)ms.value()*.75f); + x = mBarRect.mLeft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tick_label); + LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, + LLFontGL::LEFT, LLFontGL::TOP); + + tick_label = llformat( "%d ms |", (U32)ms.value()); + x = mBarRect.mLeft + barw - LLFontGL::getFontMonospace()->getWidth(tick_label); + LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, + LLFontGL::LEFT, LLFontGL::TOP); + } +} + +void LLFastTimerView::drawBorders( S32 y, const S32 x_start, S32 bar_height, S32 dy ) +{ + // Draw borders + { + S32 by = y + 6 + (S32)LLFontGL::getFontMonospace()->getLineHeight(); + + //heading + gl_rect_2d(x_start-5, by, getRect().getWidth()-5, y+5, LLColor4::grey, FALSE); + + //tree view + gl_rect_2d(5, by, x_start-10, 5, LLColor4::grey, FALSE); + + by = y + 5; + //average bar + gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-5, LLColor4::grey, FALSE); + + by -= bar_height*2+dy; + + //current frame bar + gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-2, LLColor4::grey, FALSE); + + by -= bar_height+dy+1; + + //history bars + gl_rect_2d(x_start-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-bar_height-dy-2, LLColor4::grey, FALSE); + + by = LINE_GRAPH_HEIGHT-bar_height-dy-7; + + //line graph + mGraphRect = LLRect(x_start-5, by, getRect().getWidth()-5, 5); + + gl_rect_2d(mGraphRect, FALSE); + } +} + +void LLFastTimerView::updateTotalTime() +{ + switch(mDisplayMode) + { + case 0: + mTotalTimeDisplay = mRecording->getPeriodMean(FTM_FRAME)*2; + break; + case 1: + mTotalTimeDisplay = mAllTimeMax; + break; + case 2: + // Calculate the max total ticks for the current history + mTotalTimeDisplay = mRecording->getPeriodMax(FTM_FRAME); + break; + default: + mTotalTimeDisplay = LLUnit<LLUnits::Milliseconds, F32>(100); + break; + } + + mTotalTimeDisplay = LLUnit<LLUnits::Milliseconds, F32>(llceil(mTotalTimeDisplay.as<LLUnits::Milliseconds>().value() / 20.f) * 20.f); +} + +void LLFastTimerView::drawBars() +{ + updateTotalTime(); + if (mTotalTimeDisplay <= 0.0) return; + + LLLocalClipRect clip(mBarRect); + + S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2); + S32 vpad = llmax(1, bar_height / 4); // spacing between bars + bar_height -= vpad; + + drawTicks(); + S32 y = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); + drawBorders(y, mBarRect.mLeft, bar_height, vpad); + + // Draw bars for each history entry + // Special: -1 = show running average + LLPointer<LLUIImage> bar_image = LLUI::getUIImage("Rounded_Square"); + gGL.getTexUnit(0)->bind(bar_image->getImage()); + const S32 histmax = llmin((S32)mRecording->getNumPeriods(), MAX_VISIBLE_HISTORY) + 1; + + for (S32 bar_index = 0; bar_index < histmax && y > LINE_GRAPH_HEIGHT; bar_index++) + { + S32 history_index = (bar_index > 0) + ? bar_index + mScrollIndex + : -1; + mTimerBars[bar_index].clear(); + mTimerBars[bar_index].reserve(LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()); + + updateTimerBarWidths(&FTM_FRAME, mTimerBars[bar_index], history_index, true); + LLRect frame_bar_rect(mBarRect.mLeft, y, mBarRect.mLeft + mTimerBars[bar_index][0].mWidth, y-bar_height); + mTimerBars[bar_index][0].mVisibleRect = frame_bar_rect; + updateTimerBarFractions(&FTM_FRAME, 0, mTimerBars[bar_index]); + drawBar(&FTM_FRAME, frame_bar_rect, mTimerBars[bar_index], 0, bar_image); + + y -= (bar_height + vpad); + if (bar_index == 0) + y -= bar_height; + } + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +} + +static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths"); + +S32 LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector<TimerBar>& bars, S32 history_index, bool visible) +{ + LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS); + F32 self_time_frame_fraction = history_index == -1 + ? (mRecording->getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay) + : (mRecording->getPrevRecordingPeriod(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); + + S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); + S32 full_width = self_time_width; + + bool children_visible = visible; + + // reserve a spot for this bar to be rendered before its children + // even though we don't know its size yet + S32 bar_rect_index = bars.size(); + if (visible) + { + bars.push_back(TimerBar()); + } + + if (time_block->getCollapsed()) + { + children_visible = false; + } + for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) + { + full_width += updateTimerBarWidths(*it, bars, history_index, children_visible); + } + + if (visible) + { + TimerBar& timer_bar = bars[bar_rect_index]; + + timer_bar.mWidth = full_width; + timer_bar.mSelfWidth = self_time_width; + timer_bar.mColor = sTimerColors[time_block]; + + BOOL is_child_of_hover_item = (time_block == mHoverID); + TimeBlock* next_parent = time_block->getParent(); + while(!is_child_of_hover_item && next_parent) + { + is_child_of_hover_item = (mHoverID == next_parent); + if (next_parent->getParent() == next_parent) break; + next_parent = next_parent->getParent(); + } + + if (mHoverID != NULL + && time_block != mHoverID + && !is_child_of_hover_item) + { + timer_bar.mColor = lerp(timer_bar.mColor, LLColor4::grey, 0.8f); + } + } + return full_width; +} + +static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions"); + +S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector<TimerBar>& bars) +{ + LLFastTimer _(FTM_UPDATE_TIMER_BAR_FRACTIONS); + TimerBar& timer_bar = bars[timer_bar_index]; + S32 child_time_width = timer_bar.mWidth - timer_bar.mSelfWidth; + LLRect children_rect = timer_bar.mVisibleRect; + + if (mDisplayCenter == ALIGN_CENTER) + { + children_rect.mLeft += timer_bar.mSelfWidth / 2; + } + else if (mDisplayCenter == ALIGN_RIGHT) + { + children_rect.mLeft += timer_bar.mSelfWidth; + } + children_rect.mRight = children_rect.mLeft + timer_bar.mWidth - timer_bar.mSelfWidth; + + if (children_rect.getHeight() > MIN_BAR_HEIGHT) + { + children_rect.mTop -= 1; + children_rect.mBottom += 1; + } + timer_bar.mChildrenRect = children_rect; + + //now loop through children and figure out portion of bar image covered by each bar, now that we know the + //sum of all children + if (!time_block->getCollapsed()) + { + F32 bar_fraction_start = 0.f; + for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); + it != end_it; + ++it) + { + timer_bar_index++; + + TimerBar& child_timer_bar = bars[timer_bar_index]; + TimeBlock* child_time_block = *it; + + child_timer_bar.mStartFraction = bar_fraction_start; + child_timer_bar.mEndFraction = child_time_width > 0 + ? bar_fraction_start + (F32)child_timer_bar.mWidth / child_time_width + : 1.f; + child_timer_bar.mVisibleRect.set(children_rect.mLeft + llround(child_timer_bar.mStartFraction * children_rect.getWidth()), + children_rect.mTop, + children_rect.mLeft + llround(child_timer_bar.mEndFraction * children_rect.getWidth()), + children_rect.mBottom); + + timer_bar_index = updateTimerBarFractions(child_time_block, timer_bar_index, bars); + + bar_fraction_start = child_timer_bar.mEndFraction; + } + } + return timer_bar_index; +} + +S32 LLFastTimerView::drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 bar_index, LLPointer<LLUIImage>& bar_image) +{ + TimerBar& timer_bar = bars[bar_index]; + + // animate scale of bar when hovering over that particular timer + if (bar_rect.getWidth() > 0) + { + LLRect render_rect(bar_rect); + S32 scale_offset = 0; + if (time_block == mHoverID) + { + scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); + render_rect.mTop += scale_offset; + render_rect.mBottom -= scale_offset; + } + + gGL.color4fv(timer_bar.mColor.mV); + gl_segmented_rect_2d_fragment_tex(render_rect, + bar_image->getTextureWidth(), bar_image->getTextureHeight(), + 16, + timer_bar.mStartFraction, timer_bar.mEndFraction); + } + + if (!time_block->getCollapsed()) + { + for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) + { + ++bar_index; + bar_index = drawBar(*it, timer_bar.mChildrenRect, bars, bar_index, bar_image); + } + } + + return bar_index; +} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 5766cfa0b0..8b9ad290bc 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -29,11 +29,14 @@ #include "llfloater.h" #include "llfasttimer.h" +#include "llunit.h" +#include "lltracerecording.h" class LLFastTimerView : public LLFloater { public: LLFastTimerView(const LLSD&); + ~LLFastTimerView(); BOOL postBuild(); static BOOL sAnalyzePerformance; @@ -46,7 +49,6 @@ private: static LLSD analyzePerformanceLogDefault(std::istream& is) ; static void exportCharts(const std::string& base, const std::string& target); void onPause(); - LLFastTimer::NamedTimer& getFrameTimer(); public: @@ -59,15 +61,48 @@ public: virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual void draw(); - LLFastTimer::NamedTimer* getLegendID(S32 y); + LLTrace::TimeBlock* getLegendID(S32 y); F64 getTime(const std::string& name); protected: virtual void onClickCloseBtn(); + private: - typedef std::vector<std::vector<S32> > bar_positions_t; - bar_positions_t mBarStart; - bar_positions_t mBarEnd; + void drawTicks(); + void drawLineGraph(); + void drawLegend(S32 y); + S32 drawHelp(S32 y); + void drawBorders( S32 y, const S32 x_start, S32 barh, S32 dy); + void drawBars(); + + void printLineStats(); + void generateUniqueColors(); + void updateTotalTime(); + + struct TimerBar + { + TimerBar() + : mWidth(0), + mSelfWidth(0), + mVisible(true), + mStartFraction(0.f), + mEndFraction(1.f) + {} + S32 mWidth; + S32 mSelfWidth; + LLRect mVisibleRect, + mChildrenRect; + LLColor4 mColor; + bool mVisible; + F32 mStartFraction, + mEndFraction; + }; + S32 updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector<TimerBar>& bars, S32 history_index, bool visible); + S32 updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector<TimerBar>& bars); + S32 drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 bar_index, LLPointer<LLUIImage>& bar_image); + void setPauseState(bool pause_state); + + std::vector<TimerBar>* mTimerBars; S32 mDisplayMode; typedef enum child_alignment @@ -79,19 +114,21 @@ private: } ChildAlignment; ChildAlignment mDisplayCenter; - S32 mDisplayCalls; - S32 mDisplayHz; - U64 mAvgCountTotal; - U64 mMaxCountTotal; + bool mDisplayCalls, + mDisplayHz; + LLUnit<LLUnits::Seconds, F64> mAllTimeMax, + mTotalTimeDisplay; LLRect mBarRect; S32 mScrollIndex; - LLFastTimer::NamedTimer* mHoverID; - LLFastTimer::NamedTimer* mHoverTimer; + LLTrace::TimeBlock* mHoverID; + LLTrace::TimeBlock* mHoverTimer; LLRect mToolTipRect; S32 mHoverBarIndex; LLFrameTimer mHighlightTimer; S32 mPrintStats; LLRect mGraphRect; + LLTrace::PeriodicRecording* mRecording; + bool mPauseHistory; }; #endif diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 83fb887d81..58701ca3c9 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -296,7 +296,8 @@ LLSD LLFloaterAbout::getInfo() if (gPacketsIn > 0) { - info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent(); + LLTrace::Recording cur_frame = LLTrace::get_frame_recording().snapshotCurRecordingPeriod(); + info["PACKETS_LOST"] = cur_frame.getSum(LLStatViewer::PACKETS_LOST); info["PACKETS_IN"] = F32(gPacketsIn); info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal(); } diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index d6ebe44daa..06681f5fd5 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -525,11 +525,11 @@ void LLFloaterColorPicker::draw() if (gFocusMgr.childHasMouseCapture(getDragHandle())) { - mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); + mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME)); } else { - mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); + mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME)); } mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index d0c22d25f2..7fcebc965a 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -33,7 +33,7 @@ #include "llerror.h" #include "llrect.h" #include "llstring.h" -#include "llstat.h" +#include "lltrace.h" // project includes #include "lluictrlfactory.h" @@ -42,6 +42,22 @@ #include "llviewerjoystick.h" #include "llcheckboxctrl.h" +static LLTrace::MeasurementStatHandle<> sJoystickAxis1("Joystick axis 1"), + sJoystickAxis2("Joystick axis 2"), + sJoystickAxis3("Joystick axis 3"), + sJoystickAxis4("Joystick axis 4"), + sJoystickAxis5("Joystick axis 5"), + sJoystickAxis6("Joystick axis 6"); +static LLTrace::MeasurementStatHandle<>* sJoystickAxes[6] = +{ + &sJoystickAxis1, + &sJoystickAxis2, + &sJoystickAxis3, + &sJoystickAxis4, + &sJoystickAxis5, + &sJoystickAxis6 +}; + LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) : LLFloater(data) { @@ -61,7 +77,7 @@ void LLFloaterJoystick::draw() for (U32 i = 0; i < 6; i++) { F32 value = joystick->getJoystickAxis(i); - mAxisStats[i]->addValue(value * gFrameIntervalSeconds); + sample(*sJoystickAxes[i], value * gFrameIntervalSeconds.value()); if (mAxisStatsBar[i]) { F32 minbar, maxbar; @@ -85,12 +101,11 @@ BOOL LLFloaterJoystick::postBuild() for (U32 i = 0; i < 6; i++) { std::string stat_name(llformat("Joystick axis %d", i)); - mAxisStats[i] = new LLStat(stat_name, 4); std::string axisname = llformat("axis%d", i); mAxisStatsBar[i] = getChild<LLStatBar>(axisname); if (mAxisStatsBar[i]) { - mAxisStatsBar[i]->setStat(mAxisStats[i]); + mAxisStatsBar[i]->setStat(stat_name); mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f); } } diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index dfdb108ff8..9c3752540d 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -84,7 +84,6 @@ private: LLCheckBoxCtrl *mCheckFlycamEnabled; // stats view - LLStat* mAxisStats[6]; LLStatBar* mAxisStatsBar[6]; }; diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp deleted file mode 100644 index 68b1770bb2..0000000000 --- a/indra/newview/llfloaterlagmeter.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/** - * @file llfloaterlagmeter.cpp - * @brief The "Lag-o-Meter" floater used to tell users what is causing lag. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterlagmeter.h" - -#include "lluictrlfactory.h" -#include "llviewerstats.h" -#include "llviewertexture.h" -#include "llviewercontrol.h" -#include "llappviewer.h" - -#include "lltexturefetch.h" - -#include "llbutton.h" -#include "llfocusmgr.h" -#include "lltextbox.h" - -const std::string LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga"; -const std::string LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga"; -const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga"; - -LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key) - : LLFloater(key) -{ - mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this)); -} - -BOOL LLFloaterLagMeter::postBuild() -{ - // Don't let this window take keyboard focus -- it's confusing to - // lose arrow-key driving when testing lag. - setIsChrome(TRUE); - - // were we shrunk last time? - if (isShrunk()) - { - onClickShrink(); - } - - mClientButton = getChild<LLButton>("client_lagmeter"); - mClientText = getChild<LLTextBox>("client_text"); - mClientCause = getChild<LLTextBox>("client_lag_cause"); - - mNetworkButton = getChild<LLButton>("network_lagmeter"); - mNetworkText = getChild<LLTextBox>("network_text"); - mNetworkCause = getChild<LLTextBox>("network_lag_cause"); - - mServerButton = getChild<LLButton>("server_lagmeter"); - mServerText = getChild<LLTextBox>("server_text"); - mServerCause = getChild<LLTextBox>("server_lag_cause"); - - std::string config_string = getString("client_frame_rate_critical_fps", mStringArgs); - mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() ); - config_string = getString("client_frame_rate_warning_fps", mStringArgs); - mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() ); - - config_string = getString("network_packet_loss_critical_pct", mStringArgs); - mNetworkPacketLossCritical = (float)atof( config_string.c_str() ); - config_string = getString("network_packet_loss_warning_pct", mStringArgs); - mNetworkPacketLossWarning = (float)atof( config_string.c_str() ); - - config_string = getString("network_ping_critical_ms", mStringArgs); - mNetworkPingCritical = (float)atof( config_string.c_str() ); - config_string = getString("network_ping_warning_ms", mStringArgs); - mNetworkPingWarning = (float)atof( config_string.c_str() ); - config_string = getString("server_frame_rate_critical_fps", mStringArgs); - - mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() ); - config_string = getString("server_frame_rate_warning_fps", mStringArgs); - mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() ); - config_string = getString("server_single_process_max_time_ms", mStringArgs); - mServerSingleProcessMaxTime = (float)atof( config_string.c_str() ); - -// mShrunk = false; - config_string = getString("max_width_px", mStringArgs); - mMaxWidth = atoi( config_string.c_str() ); - config_string = getString("min_width_px", mStringArgs); - mMinWidth = atoi( config_string.c_str() ); - - mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps"); - mStringArgs["[CLIENT_FRAME_RATE_WARNING]"] = getString("client_frame_rate_warning_fps"); - - mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct"); - mStringArgs["[NETWORK_PACKET_LOSS_WARNING]"] = getString("network_packet_loss_warning_pct"); - - mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms"); - mStringArgs["[NETWORK_PING_WARNING]"] = getString("network_ping_warning_ms"); - - mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps"); - mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps"); - -// childSetAction("minimize", onClickShrink, this); - updateControls(isShrunk()); // if expanded append colon to the labels (EXT-4079) - - return TRUE; -} -LLFloaterLagMeter::~LLFloaterLagMeter() -{ - // save shrunk status for next time -// gSavedSettings.setBOOL("LagMeterShrunk", mShrunk); - // expand so we save the large window rectangle - if (isShrunk()) - { - onClickShrink(); - } -} - -void LLFloaterLagMeter::draw() -{ - determineClient(); - determineNetwork(); - determineServer(); - - LLFloater::draw(); -} - -void LLFloaterLagMeter::determineClient() -{ - F32 client_frame_time = LLViewerStats::getInstance()->mFPSStat.getMeanDuration(); - bool find_cause = false; - - if (!gFocusMgr.getAppHasFocus()) - { - mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); - mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) ); - mClientCause->setText( LLStringUtil::null ); - } - else if(client_frame_time >= mClientFrameTimeCritical) - { - mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); - mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) ); - find_cause = true; - } - else if(client_frame_time >= mClientFrameTimeWarning) - { - mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); - mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) ); - find_cause = true; - } - else - { - mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); - mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) ); - mClientCause->setText( LLStringUtil::null ); - } - - if(find_cause) - { - if(gSavedSettings.getF32("RenderFarClip") > 128) - { - mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) ); - } - else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2) - { - mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); - } - else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes) - { - mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); - } - else - { - mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) ); - } - } -} - -void LLFloaterLagMeter::determineNetwork() -{ - F32 packet_loss = LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean(); - F32 ping_time = LLViewerStats::getInstance()->mSimPingStat.getMean(); - bool find_cause_loss = false; - bool find_cause_ping = false; - - // *FIXME: We can't blame a large ping time on anything in - // particular if the frame rate is low, because a low frame - // rate is a sure recipe for bad ping times right now until - // the network handlers are de-synched from the rendering. - F32 client_frame_time_ms = 1000.0f * LLViewerStats::getInstance()->mFPSStat.getMeanDuration(); - - if(packet_loss >= mNetworkPacketLossCritical) - { - mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); - mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) ); - find_cause_loss = true; - } - else if(ping_time >= mNetworkPingCritical) - { - mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); - if (client_frame_time_ms < mNetworkPingCritical) - { - mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) ); - find_cause_ping = true; - } - } - else if(packet_loss >= mNetworkPacketLossWarning) - { - mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); - mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) ); - find_cause_loss = true; - } - else if(ping_time >= mNetworkPingWarning) - { - mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); - if (client_frame_time_ms < mNetworkPingWarning) - { - mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) ); - find_cause_ping = true; - } - } - else - { - mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); - mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) ); - } - - if(find_cause_loss) - { - mNetworkCause->setText( getString("network_packet_loss_cause_msg", mStringArgs) ); - } - else if(find_cause_ping) - { - mNetworkCause->setText( getString("network_ping_cause_msg", mStringArgs) ); - } - else - { - mNetworkCause->setText( LLStringUtil::null ); - } -} - -void LLFloaterLagMeter::determineServer() -{ - F32 sim_frame_time = LLViewerStats::getInstance()->mSimFrameMsec.getCurrent(); - bool find_cause = false; - - if(sim_frame_time >= mServerFrameTimeCritical) - { - mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); - mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) ); - find_cause = true; - } - else if(sim_frame_time >= mServerFrameTimeWarning) - { - mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); - mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) ); - find_cause = true; - } - else - { - mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); - mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) ); - mServerCause->setText( LLStringUtil::null ); - } - - if(find_cause) - { - if(LLViewerStats::getInstance()->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime) - { - mServerCause->setText( getString("server_physics_cause_msg", mStringArgs) ); - } - else if(LLViewerStats::getInstance()->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime) - { - mServerCause->setText( getString("server_scripts_cause_msg", mStringArgs) ); - } - else if(LLViewerStats::getInstance()->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime) - { - mServerCause->setText( getString("server_net_cause_msg", mStringArgs) ); - } - else if(LLViewerStats::getInstance()->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime) - { - mServerCause->setText( getString("server_agent_cause_msg", mStringArgs) ); - } - else if(LLViewerStats::getInstance()->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime) - { - mServerCause->setText( getString("server_images_cause_msg", mStringArgs) ); - } - else - { - mServerCause->setText( getString("server_generic_cause_msg", mStringArgs) ); - } - } -} - -void LLFloaterLagMeter::updateControls(bool shrink) -{ -// LLFloaterLagMeter * self = (LLFloaterLagMeter*)data; - - LLButton * button = getChild<LLButton>("minimize"); - S32 delta_width = mMaxWidth -mMinWidth; - LLRect r = getRect(); - - if(!shrink) - { - setTitle(getString("max_title_msg", mStringArgs) ); - // make left edge appear to expand - r.translate(-delta_width, 0); - setRect(r); - reshape(mMaxWidth, getRect().getHeight()); - - getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) + ":"); - getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) + ":"); - getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) + ":"); - - // usually "<<" - button->setLabel( getString("smaller_label", mStringArgs) ); - } - else - { - setTitle( getString("min_title_msg", mStringArgs) ); - // make left edge appear to collapse - r.translate(delta_width, 0); - setRect(r); - reshape(mMinWidth, getRect().getHeight()); - - getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) ); - getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) ); - getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) ); - - // usually ">>" - button->setLabel( getString("bigger_label", mStringArgs) ); - } - // Don't put keyboard focus on the button - button->setFocus(FALSE); - -// self->mClientText->setVisible(self->mShrunk); -// self->mClientCause->setVisible(self->mShrunk); -// self->getChildView("client_help")->setVisible( self->mShrunk); - -// self->mNetworkText->setVisible(self->mShrunk); -// self->mNetworkCause->setVisible(self->mShrunk); -// self->getChildView("network_help")->setVisible( self->mShrunk); - -// self->mServerText->setVisible(self->mShrunk); -// self->mServerCause->setVisible(self->mShrunk); -// self->getChildView("server_help")->setVisible( self->mShrunk); - -// self->mShrunk = !self->mShrunk; -} - -BOOL LLFloaterLagMeter::isShrunk() -{ - return gSavedSettings.getBOOL("LagMeterShrunk"); -} - -void LLFloaterLagMeter::onClickShrink() // toggle "LagMeterShrunk" -{ - bool shrunk = isShrunk(); - updateControls(!shrunk); - gSavedSettings.setBOOL("LagMeterShrunk", !shrunk); -} diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h deleted file mode 100644 index eef6955601..0000000000 --- a/indra/newview/llfloaterlagmeter.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file llfloaterlagmeter.h - * @brief The "Lag-o-Meter" floater used to tell users what is causing lag. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LLFLOATERLAGMETER_H -#define LLFLOATERLAGMETER_H - -#include "llfloater.h" - -class LLTextBox; - -class LLFloaterLagMeter : public LLFloater -{ - friend class LLFloaterReg; - -public: - /*virtual*/ void draw(); - /*virtual*/ BOOL postBuild(); -private: - - LLFloaterLagMeter(const LLSD& key); - /*virtual*/ ~LLFloaterLagMeter(); - void determineClient(); - void determineNetwork(); - void determineServer(); - void updateControls(bool shrink); - BOOL isShrunk(); - - void onClickShrink(); - - bool mShrunk; - S32 mMaxWidth, mMinWidth; - - F32 mClientFrameTimeCritical; - F32 mClientFrameTimeWarning; - LLButton * mClientButton; - LLTextBox * mClientText; - LLTextBox * mClientCause; - - F32 mNetworkPacketLossCritical; - F32 mNetworkPacketLossWarning; - F32 mNetworkPingCritical; - F32 mNetworkPingWarning; - LLButton * mNetworkButton; - LLTextBox * mNetworkText; - LLTextBox * mNetworkCause; - - F32 mServerFrameTimeCritical; - F32 mServerFrameTimeWarning; - F32 mServerSingleProcessMaxTime; - LLButton * mServerButton; - LLTextBox * mServerText; - LLTextBox * mServerCause; - - LLStringUtil::format_map_t mStringArgs; -}; - -#endif diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ea839e6f5a..69986f6789 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -113,8 +113,6 @@ #include "llviewernetwork.h" #include "llviewershadermgr.h" #include "glod/glod.h" -#include <boost/algorithm/string.hpp> - const S32 SLM_SUPPORTED_VERSION = 3; @@ -3890,21 +3888,21 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter) { for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) - { + { LLModel* mdl = instance->mModel; if (mdl) - { + { instanced_triangle_count += mdl->getNumTriangles(); } } - } + } //get the triangle count for the non-instanced set of models for (U32 i = 0; i < mBaseModel.size(); ++i) { triangle_count += mBaseModel[i]->getNumTriangles(); } - + //get ratio of uninstanced triangles to instanced triangles F32 triangle_ratio = (F32) triangle_count / (F32) instanced_triangle_count; @@ -4238,28 +4236,28 @@ void LLModelPreview::updateStatusMessages() if (model) { //for each model in the lod - S32 cur_tris = 0; - S32 cur_verts = 0; + S32 cur_tris = 0; + S32 cur_verts = 0; S32 cur_submeshes = model->getNumVolumeFaces(); - for (S32 j = 0; j < cur_submeshes; ++j) - { //for each submesh (face), add triangles and vertices to current total + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total const LLVolumeFace& face = model->getVolumeFace(j); - cur_tris += face.mNumIndices/3; - cur_verts += face.mNumVertices; - } + cur_tris += face.mNumIndices/3; + cur_verts += face.mNumVertices; + } - //add this model to the lod total - total_tris[lod] += cur_tris; - total_verts[lod] += cur_verts; - total_submeshes[lod] += cur_submeshes; + //add this model to the lod total + total_tris[lod] += cur_tris; + total_verts[lod] += cur_verts; + total_submeshes[lod] += cur_submeshes; - //store this model's counts to asset data - tris[lod].push_back(cur_tris); - verts[lod].push_back(cur_verts); - submeshes[lod].push_back(cur_submeshes); - } - } + //store this model's counts to asset data + tris[lod].push_back(cur_tris); + verts[lod].push_back(cur_verts); + submeshes[lod].push_back(cur_submeshes); + } + } } } @@ -4448,28 +4446,28 @@ void LLModelPreview::updateStatusMessages() LLModel* model = instance->mModel; if (model) { - S32 cur_submeshes = model->getNumVolumeFaces(); + S32 cur_submeshes = model->getNumVolumeFaces(); - LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; + LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; - if (!decomp.empty()) - { - phys_hulls += decomp.size(); - for (U32 i = 0; i < decomp.size(); ++i) - { - phys_points += decomp[i].size(); - } - } - else - { //choose physics shape OR decomposition, can't use both - for (S32 j = 0; j < cur_submeshes; ++j) - { //for each submesh (face), add triangles and vertices to current total - const LLVolumeFace& face = model->getVolumeFace(j); - phys_tris += face.mNumIndices/3; - } - } + if (!decomp.empty()) + { + phys_hulls += decomp.size(); + for (U32 i = 0; i < decomp.size(); ++i) + { + phys_points += decomp[i].size(); } } + else + { //choose physics shape OR decomposition, can't use both + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = model->getVolumeFace(j); + phys_tris += face.mNumIndices/3; + } + } + } + } } if (phys_tris > 0) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index fe29bb38c7..6cce013105 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2491,8 +2491,6 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llfloatersceneloadstats.cpp b/indra/newview/llfloatersceneloadstats.cpp new file mode 100644 index 0000000000..8aa93eae96 --- /dev/null +++ b/indra/newview/llfloatersceneloadstats.cpp @@ -0,0 +1,40 @@ +/** + * @file llfloatersceneloadstats.cpp + * @author Richard Nelson + * @brief debug floater for measuring various scene load statistics + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatersceneloadstats.h" + + +LLFloaterSceneLoadStats::LLFloaterSceneLoadStats( const LLSD& key ) +: LLFloater(key) +{} + +BOOL LLFloaterSceneLoadStats::postBuild() +{ + return TRUE; +} diff --git a/indra/newview/llfloatersceneloadstats.h b/indra/newview/llfloatersceneloadstats.h new file mode 100644 index 0000000000..aa414bf544 --- /dev/null +++ b/indra/newview/llfloatersceneloadstats.h @@ -0,0 +1,43 @@ +/** + * @file llfloatersceneloadstats.h + * @brief debug floater for measuring various scene load statistics + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, 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_FLOATERSCENELOADSTATS_H +#define LL_FLOATERSCENELOADSTATS_H + +#include "llfloater.h" + +class LLFloaterSceneLoadStats : public LLFloater +{ + friend class LLFloaterReg; +private: + LLFloaterSceneLoadStats(const LLSD& key); + +public: + BOOL postBuild(); + +}; + +#endif // LL_FLOATERSCENELOADSTATS_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index d8d62e5bbb..285f52fcd6 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -478,7 +478,7 @@ void LLSnapshotLivePreview::draw() { if (mFlashAlpha < 1.f) { - mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f)); + mFlashAlpha = lerp(mFlashAlpha, 1.f, LLSmoothInterpolation::getInterpolant(0.02f)); } else { @@ -487,7 +487,7 @@ void LLSnapshotLivePreview::draw() } else { - mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f)); + mFlashAlpha = lerp(mFlashAlpha, 0.f, LLSmoothInterpolation::getInterpolant(0.15f)); } // Draw shining animation if appropriate. @@ -992,7 +992,7 @@ void LLSnapshotLivePreview::saveTexture() llwarns << "Error encoding snapshot" << llendl; } - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); + add(LLStatViewer::SNAPSHOT, 1); mDataSize = 0; } diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 3aa16b4413..4eb84224bc 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -1293,7 +1293,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) // animate current height towards target height if (llabs(mCurHeight - mTargetHeight) > 1.f) { - mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); + mCurHeight = lerp(mCurHeight, mTargetHeight, LLSmoothInterpolation::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); requestArrange(); @@ -2538,11 +2538,11 @@ void LLFolderViewFolder::draw() } else if (mIsOpen) { - mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); + mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLSmoothInterpolation::getInterpolant(0.04f)); } else { - mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); + mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLSmoothInterpolation::getInterpolant(0.025f)); } bool possibly_has_children = false; diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp index b670af1782..d6dc964802 100644 --- a/indra/newview/llfollowcam.cpp +++ b/indra/newview/llfollowcam.cpp @@ -328,11 +328,11 @@ void LLFollowCam::update() F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance; */ - F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag ); + F32 focusLagLerp = LLSmoothInterpolation::getInterpolant( mFocusLag ); focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp ); mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent); } - mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f)); + mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLSmoothInterpolation::getInterpolant(0.05f)); }// if focus is not locked --------------------------------------------- @@ -415,7 +415,7 @@ void LLFollowCam::update() //------------------------------------------------------------------------------------------------- if ( distanceFromPositionToIdealPosition > mPositionThreshold ) { - F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag ); + F32 positionPullLerp = LLSmoothInterpolation::getInterpolant( mPositionLag ); simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp ); } @@ -435,7 +435,7 @@ void LLFollowCam::update() updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent); mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent); - mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f)); + mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLSmoothInterpolation::getInterpolant(0.05f)); } // if position is not locked ----------------------------------------------------------- @@ -490,7 +490,7 @@ BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_pos if ( cameraOffsetAngle > mBehindnessMaxAngle ) { - F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag); + F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLSmoothInterpolation::getInterpolant(mBehindnessLag); cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT)); cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it constraint_active = TRUE; diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 66ca76bfb0..27a29d3ace 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -1137,8 +1137,6 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 482294c8a6..3ac11f906b 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -30,6 +30,7 @@ #include "llhudnametag.h" #include "llrender.h" +#include "lltracerecording.h" #include "llagent.h" #include "llviewercontrol.h" @@ -899,8 +900,8 @@ void LLHUDNameTag::updateAll() // } } - LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); - F32 camera_vel = camera_vel_stat->getCurrent(); + LLTrace::CountStatHandle<>* camera_vel_stat = LLViewerCamera::getVelocityStat(); + F32 camera_vel = LLTrace::get_frame_recording().getLastRecordingPeriod().getPerSec(*camera_vel_stat); if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) { return; @@ -980,7 +981,7 @@ void LLHUDNameTag::updateAll() // { // continue; // } - (*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC)); + (*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLSmoothInterpolation::getInterpolant(POSITION_DAMPING_TC)); } } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index f7567baa2b..4c10717ce8 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -396,9 +396,10 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() return getFilter()->getShowFolderState(); } +static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); + void LLInventoryPanel::modelChanged(U32 mask) { - static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); LLFastTimer t2(FTM_REFRESH); bool handled = false; diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index dd402de394..2a131eff58 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -141,7 +141,6 @@ void LLLandmarkList::processGetAssetReply( } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); // SJB: No use case for a notification here. Use lldebugs instead if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) { diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 826e8d560a..0468560e96 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -240,7 +240,7 @@ void LLManipRotate::render() if (mManipPart == LL_ROT_Z) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.pushMatrix(); { // selected part @@ -251,7 +251,7 @@ void LLManipRotate::render() } else if (mManipPart == LL_ROT_Y) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.pushMatrix(); { gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); @@ -262,7 +262,7 @@ void LLManipRotate::render() } else if (mManipPart == LL_ROT_X) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.pushMatrix(); { gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); @@ -273,13 +273,13 @@ void LLManipRotate::render() } else if (mManipPart == LL_ROT_ROLL) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); } else if (mManipPart == LL_NO_PART) { if (mHighlightedPart == LL_NO_PART) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); } LLGLEnable cull_face(GL_CULL_FACE); @@ -294,7 +294,7 @@ void LLManipRotate::render() { if (mHighlightedPart == LL_ROT_Z) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]); // hovering over part gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i); @@ -312,7 +312,7 @@ void LLManipRotate::render() gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); if (mHighlightedPart == LL_ROT_Y) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]); // hovering over part gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i); @@ -330,7 +330,7 @@ void LLManipRotate::render() gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); if (mHighlightedPart == LL_ROT_X) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]); // hovering over part @@ -346,7 +346,7 @@ void LLManipRotate::render() if (mHighlightedPart == LL_ROT_ROLL) { - mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); } } diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 00a0bf8894..2d09fb6fe5 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -535,11 +535,11 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) { if (mHighlightedPart == MANIPULATOR_IDS[i]) { - mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); } else { - mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); + mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); } } diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 362308c176..cf5c646893 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1921,18 +1921,18 @@ void LLManipTranslate::renderTranslationHandles() { if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW) { - mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); } else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE) { - mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); } else { - mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); - mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); + mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); } } diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index c00dc4bc89..142aaa795b 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -638,7 +638,7 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 gAgent.sendReliableMessage(); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); + add(LLStatViewer::CHAT_COUNT, 1); } class LLChatCommandHandler : public LLCommandHandler diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1bda7640bd..0abfb59ffd 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -162,7 +162,7 @@ void LLNetMap::draw() static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); if (auto_center) { - mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f)); + mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f)); } // Prepare a scissor region diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 202be9671b..88f2c5ff52 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1049,7 +1049,7 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item) void LLPanelFace::onCommitTexture( const LLSD& data ) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); + add(LLStatViewer::EDIT_TEXTURE, 1); sendTexture(); } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index e641370d2e..4e6128018d 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -915,7 +915,6 @@ bool callback_deed_to_group(const LLSD& notification, const LLSD& response) if(group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))) { LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -// LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); } } return false; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index f47928b131..cbb4d5f964 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -883,8 +883,6 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 3a9360fd23..97c9de4b72 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -339,8 +339,6 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 9c25e69db0..f87a958fbc 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -942,7 +942,7 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata) void LLScriptEdCore::doSave( BOOL close_after_save ) { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); + add(LLStatViewer::LSL_SAVES, 1); if( mSaveCallback ) { @@ -1146,8 +1146,7 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) void LLScriptEdCore::onBtnSaveToFile( void* userdata ) { - - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); + add(LLStatViewer::LSL_SAVES, 1); LLScriptEdCore* self = (LLScriptEdCore*) userdata; @@ -1670,8 +1669,6 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { @@ -1902,8 +1899,6 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp new file mode 100644 index 0000000000..c69f276aa2 --- /dev/null +++ b/indra/newview/llscenemonitor.cpp @@ -0,0 +1,566 @@ +/** + * @file llscenemonitor.cpp + * @brief monitor the scene loading process. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llrendertarget.h" +#include "llscenemonitor.h" +#include "llviewerwindow.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewershadermgr.h" +#include "llui.h" +#include "llstartup.h" +#include "llappviewer.h" +#include "llwindow.h" +#include "llpointer.h" +#include "llspatialpartition.h" +#include "llagent.h" +#include "pipeline.h" + +LLSceneMonitorView* gSceneMonitorView = NULL; + +// +//The procedures of monitoring when the scene finishes loading visually, +//i.e., no pixel differences among frames, are: +//1, freeze all dynamic objects and avatars; +//2, (?) disable all sky and water; +//3, capture frames periodically, by calling "capture()"; +//4, compute pixel differences between two latest captured frames, by calling "compare()", results are stored at mDiff; +//5, compute the number of pixels in mDiff above some tolerance threshold in GPU, by calling "queryDiff() -> calcDiffAggregate()"; +//6, use gl occlusion query to fetch the result from GPU, by calling "fetchQueryResult()"; +//END. +// + +LLSceneMonitor::LLSceneMonitor() : + mEnabled(FALSE), + mDiff(NULL), + mDiffResult(0.f), + mDiffTolerance(0.1f), + mCurTarget(NULL), + mNeedsUpdateDiff(FALSE), + mHasNewDiff(FALSE), + mHasNewQueryResult(FALSE), + mDebugViewerVisible(FALSE), + mQueryObject(0), + mSamplingTime(1.0f), + mDiffPixelRatio(0.5f) +{ + mFrames[0] = NULL; + mFrames[1] = NULL; + + mRecording = new LLTrace::ExtendableRecording(); + mRecording->start(); +} + +LLSceneMonitor::~LLSceneMonitor() +{ + destroyClass(); +} + +void LLSceneMonitor::destroyClass() +{ + reset(); + + delete mRecording; + mRecording = NULL; + mDitheringTexture = NULL; +} + +void LLSceneMonitor::reset() +{ + delete mFrames[0]; + delete mFrames[1]; + delete mDiff; + + mFrames[0] = NULL; + mFrames[1] = NULL; + mDiff = NULL; + mCurTarget = NULL; + + unfreezeScene(); + + if(mQueryObject > 0) + { + release_occlusion_query_object_name(mQueryObject); + mQueryObject = 0; + } +} + +void LLSceneMonitor::generateDitheringTexture(S32 width, S32 height) +{ +#if 1 + //4 * 4 matrix + mDitherMatrixWidth = 4; + S32 dither_matrix[4][4] = + { + {1, 9, 3, 11}, + {13, 5, 15, 7}, + {4, 12, 2, 10}, + {16, 8, 14, 6} + }; + + mDitherScale = 255.f / 17; +#else + //8 * 8 matrix + mDitherMatrixWidth = 16; + S32 dither_matrix[16][16] = + { + {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64}, + {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32}, + {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56}, + {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24}, + {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62}, + {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30}, + {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54}, + {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22}, + {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64}, + {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32}, + {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56}, + {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24}, + {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62}, + {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30}, + {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54}, + {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22} + }; + + mDitherScale = 255.f / 65; +#endif + + LLPointer<LLImageRaw> image_raw = new LLImageRaw(mDitherMatrixWidth, mDitherMatrixWidth, 3); + U8* data = image_raw->getData(); + for (S32 i = 0; i < mDitherMatrixWidth; i++) + { + for (S32 j = 0; j < mDitherMatrixWidth; j++) + { + U8 val = dither_matrix[i][j]; + *data++ = val; + *data++ = val; + *data++ = val; + } + } + + mDitheringTexture = LLViewerTextureManager::getLocalTexture(image_raw.get(), FALSE) ; + mDitheringTexture->setAddressMode(LLTexUnit::TAM_WRAP); + mDitheringTexture->setFilteringOption(LLTexUnit::TFO_POINT); + + mDitherScaleS = (F32)width / mDitherMatrixWidth; + mDitherScaleT = (F32)height / mDitherMatrixWidth; +} + +void LLSceneMonitor::setDebugViewerVisible(BOOL visible) +{ + mDebugViewerVisible = visible; +} + +bool LLSceneMonitor::preCapture() +{ + static LLCachedControl<bool> monitor_enabled(gSavedSettings,"SceneLoadingMonitorEnabled"); + static LLFrameTimer timer; + + mCurTarget = NULL; + if (!LLGLSLShader::sNoFixedFunction) + { + return false; + } + + BOOL enabled = (BOOL)monitor_enabled || mDebugViewerVisible; + if(mEnabled != enabled) + { + if(mEnabled) + { + reset(); + unfreezeScene(); + } + else + { + freezeScene(); + } + + mEnabled = enabled; + } + + if(!mEnabled) + { + return false; + } + + if(gAgent.isPositionChanged()) + { + mRecording->reset(); + } + + if(timer.getElapsedTimeF32() < mSamplingTime) + { + return false; + } + timer.reset(); + + S32 width = gViewerWindow->getWorldViewWidthRaw(); + S32 height = gViewerWindow->getWorldViewHeightRaw(); + + if(!mFrames[0]) + { + mFrames[0] = new LLRenderTarget(); + mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true); + gGL.getTexUnit(0)->bind(mFrames[0]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + mCurTarget = mFrames[0]; + } + else if(!mFrames[1]) + { + mFrames[1] = new LLRenderTarget(); + mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true); + gGL.getTexUnit(0)->bind(mFrames[1]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + mCurTarget = mFrames[1]; + } + else //swap + { + mCurTarget = mFrames[0]; + mFrames[0] = mFrames[1]; + mFrames[1] = mCurTarget; + } + + if(mCurTarget->getWidth() != width || mCurTarget->getHeight() != height) //size changed + { + mCurTarget->resize(width, height, GL_RGB); + } + + return true; +} + +void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp) +{ + mAvatarPauseHandles.push_back(avatarp->requestPause()); +} + +void LLSceneMonitor::freezeScene() +{ + //freeze all avatars + for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + freezeAvatar((LLCharacter*)(*iter)); + } + + // freeze everything else + gSavedSettings.setBOOL("FreezeTime", TRUE); + + gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); +} + +void LLSceneMonitor::unfreezeScene() +{ + //thaw all avatars + mAvatarPauseHandles.clear(); + + // thaw everything else + gSavedSettings.setBOOL("FreezeTime", FALSE); + + gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); +} + +void LLSceneMonitor::capture() +{ + static U32 last_capture_time = 0; + + if(last_capture_time == gFrameCount) + { + return; + } + last_capture_time = gFrameCount; + + preCapture(); + + if(!mCurTarget) + { + return; + } + + U32 old_FBO = LLRenderTarget::sCurFBO; + + gGL.getTexUnit(0)->bind(mCurTarget); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer. + + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, mCurTarget->getWidth(), mCurTarget->getHeight()); //copy the content + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, old_FBO); + + mCurTarget = NULL; + mNeedsUpdateDiff = TRUE; +} + +bool LLSceneMonitor::needsUpdate() const +{ + return mNeedsUpdateDiff; +} + +void LLSceneMonitor::compare() +{ + if(!mNeedsUpdateDiff) + { + return; + } + mNeedsUpdateDiff = FALSE; + + if(!mFrames[0] || !mFrames[1]) + { + return; + } + if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight()) + { + return; //size does not match + } + + S32 width = gViewerWindow->getWindowWidthRaw(); + S32 height = gViewerWindow->getWindowHeightRaw(); + if(!mDiff) + { + mDiff = new LLRenderTarget(); + mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true); + + generateDitheringTexture(width, height); + } + else if(mDiff->getWidth() != width || mDiff->getHeight() != height) + { + mDiff->resize(width, height, GL_RGBA); + generateDitheringTexture(width, height); + } + + mDiff->bindTarget(); + mDiff->clear(); + + gTwoTextureCompareProgram.bind(); + + gTwoTextureCompareProgram.uniform1f("dither_scale", mDitherScale); + gTwoTextureCompareProgram.uniform1f("dither_scale_s", mDitherScaleS); + gTwoTextureCompareProgram.uniform1f("dither_scale_t", mDitherScaleT); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->bind(mFrames[0]); + gGL.getTexUnit(0)->activate(); + + gGL.getTexUnit(1)->activate(); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->bind(mFrames[1]); + gGL.getTexUnit(1)->activate(); + + gGL.getTexUnit(2)->activate(); + gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->bind(mDitheringTexture); + gGL.getTexUnit(2)->activate(); + + gl_rect_2d_simple_tex(width, height); + + mDiff->flush(); + + gTwoTextureCompareProgram.unbind(); + + gGL.getTexUnit(0)->disable(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->disable(); + gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE); + + mHasNewDiff = TRUE; + + //send out the query request. + queryDiff(); +} + +void LLSceneMonitor::queryDiff() +{ + if(mDebugViewerVisible) + { + return; + } + + calcDiffAggregate(); +} + +//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it. +void LLSceneMonitor::calcDiffAggregate() +{ + if(!mHasNewDiff && !mDebugViewerVisible) + { + return; + } + + if(!mQueryObject) + { + mQueryObject = get_new_occlusion_query_object_name(); + } + + LLGLDepthTest depth(true, false, GL_ALWAYS); + if(!mDebugViewerVisible) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + LLGLSLShader* cur_shader = NULL; + + cur_shader = LLGLSLShader::sCurBoundShaderPtr; + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1f("tolerance", mDiffTolerance); + + if(mHasNewDiff) + { + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject); + } + + gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); + + if(mHasNewDiff) + { + glEndQueryARB(GL_SAMPLES_PASSED_ARB); + mHasNewDiff = FALSE; + mHasNewQueryResult = TRUE; + } + + gOneTextureFilterProgram.unbind(); + + if(cur_shader != NULL) + { + cur_shader->bind(); + } + + if(!mDebugViewerVisible) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } +} + +static LLTrace::MeasurementStatHandle<> sFramePixelDiff("FramePixelDifference"); +void LLSceneMonitor::fetchQueryResult() +{ + if(!mHasNewQueryResult) + { + return; + } + mHasNewQueryResult = FALSE; + + GLuint available = 0; + glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + if(!available) + { + return; + } + + GLuint count = 0; + glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count); + + mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio); //0.5 -> (front face + back face) + + if(mDiffResult > 0.01f) + { + mRecording->extend(); + sample(sFramePixelDiff, mDiffResult); + } + //llinfos << count << " : " << mDiffResult << llendl; +} +//------------------------------------------------------------------------------------------------------------- +//definition of class LLSceneMonitorView +//------------------------------------------------------------------------------------------------------------- +LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect) + : LLFloater(LLSD()) +{ + setRect(rect); + setVisible(FALSE); + + setCanMinimize(false); + setCanClose(true); +} + +void LLSceneMonitorView::onClickCloseBtn() +{ + setVisible(false); +} + +void LLSceneMonitorView::setVisible(BOOL visible) +{ + LLSceneMonitor::getInstance()->setDebugViewerVisible(visible); + + LLView::setVisible(visible); +} + +void LLSceneMonitorView::draw() +{ + const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget(); + if(!target) + { + return; + } + + F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio(); + S32 height = (S32)(target->getHeight() * ratio); + S32 width = (S32)(target->getWidth() * ratio); + //S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.5f); + //S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.5f); + + LLRect new_rect; + new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); + setRect(new_rect); + + //draw background + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + + LLSceneMonitor::getInstance()->calcDiffAggregate(); + + //show some texts + LLColor4 color = LLColor4::white; + S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); + + S32 lines = 0; + std::string num_str = llformat("Frame difference: %.6f", LLSceneMonitor::getInstance()->getDiffResult()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + num_str = llformat("Pixel tolerance: (R+G+B) < %.4f", LLSceneMonitor::getInstance()->getDiffTolerance()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + num_str = llformat("Sampling time: %.3f seconds", LLSceneMonitor::getInstance()->getSamplingTime()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + num_str = llformat("Scene Loading time: %.3f seconds", (F32)LLSceneMonitor::getInstance()->getRecording()->getAcceptedRecording().getDuration().value()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + LLView::draw(); +} + diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h new file mode 100644 index 0000000000..709650e206 --- /dev/null +++ b/indra/newview/llscenemonitor.h @@ -0,0 +1,119 @@ +/** + * @file llscenemonitor.h + * @brief monitor the process of scene loading + * + * $LicenseInfo:firstyear=2003&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_LLSCENE_MONITOR_H +#define LL_LLSCENE_MONITOR_H + +#include "llsingleton.h" +#include "llmath.h" +#include "llfloater.h" +#include "llcharacter.h" +#include "lltracerecording.h" + +class LLCharacter; +class LLRenderTarget; +class LLViewerTexture; + +class LLSceneMonitor : public LLSingleton<LLSceneMonitor> +{ +public: + LLSceneMonitor(); + ~LLSceneMonitor(); + + void destroyClass(); + + void freezeAvatar(LLCharacter* avatarp); + void setDebugViewerVisible(BOOL visible); + + void capture(); //capture the main frame buffer + void compare(); //compare the stored two buffers. + void queryDiff(); + void fetchQueryResult(); + void calcDiffAggregate(); + void setDiffTolerance(F32 tol) {mDiffTolerance = tol;} + + const LLRenderTarget* getDiffTarget() const {return mDiff;} + F32 getDiffTolerance() const {return mDiffTolerance;} + F32 getDiffResult() const { return mDiffResult;} + F32 getSamplingTime() const { return mSamplingTime;} + F32 getDiffPixelRatio() const { return mDiffPixelRatio;} + bool isEnabled()const {return mEnabled;} + bool needsUpdate() const; + + LLTrace::ExtendableRecording* getRecording() const {return mRecording;} + +private: + void freezeScene(); + void unfreezeScene(); + void reset(); + bool preCapture(); + void generateDitheringTexture(S32 width, S32 height); + +private: + BOOL mEnabled; + BOOL mNeedsUpdateDiff; + BOOL mHasNewDiff; + BOOL mHasNewQueryResult; + BOOL mDebugViewerVisible; + + LLRenderTarget* mFrames[2]; + LLRenderTarget* mDiff; + LLRenderTarget* mCurTarget; + + GLuint mQueryObject; //used for glQuery + F32 mDiffResult; //aggregate results of mDiff. + F32 mDiffTolerance; //pixels are filtered out when R+G+B < mDiffTolerance + + F32 mSamplingTime; //time interval to capture frames, in seconds + F32 mDiffPixelRatio; //ratio of pixels used for comparison against the original mDiff size along one dimension + + LLPointer<LLViewerTexture> mDitheringTexture; + S32 mDitherMatrixWidth; + F32 mDitherScale; + F32 mDitherScaleS; + F32 mDitherScaleT; + + std::vector<LLAnimPauseRequest> mAvatarPauseHandles; + + LLTrace::ExtendableRecording* mRecording; +}; + +class LLSceneMonitorView : public LLFloater +{ +public: + LLSceneMonitorView(const LLRect& rect); + + virtual void draw(); + virtual void setVisible(BOOL visible); + +protected: + virtual void onClickCloseBtn(); +}; + +extern LLSceneMonitorView* gSceneMonitorView; + +#endif + diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 343316d30a..0079b3bab8 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1547,7 +1547,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) } // apply texture for the selected faces - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); + add(LLStatViewer::EDIT_TEXTURE, 1); object->setTEImage(te, image); dialog_refresh_all(); @@ -2968,10 +2968,10 @@ struct LLSelectGetFirstTest // continue testing. return true; } - + bool mIdentical; LLUUID mFirstValue; - + protected: virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0; @@ -2982,18 +2982,18 @@ private: void LLSelectMgr::getFirst(LLSelectGetFirstTest* test) { if (gSavedSettings.getBOOL("EditLinkedParts")) - { +{ for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); iter != getSelection()->valid_end(); ++iter ) - { + { if (!test->checkMatchingNode(*iter)) - { + { break; } } - } - else - { + } + else + { for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin(); iter != getSelection()->root_object_end(); ++iter ) { @@ -3003,31 +3003,31 @@ void LLSelectMgr::getFirst(LLSelectGetFirstTest* test) } } } -} + } //----------------------------------------------------------------------------- // selectGetCreator() // Creator information only applies to roots unless editing linked parts. //----------------------------------------------------------------------------- struct LLSelectGetFirstCreator : public LLSelectGetFirstTest -{ + { protected: virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { + { return node->mPermissions->getCreator(); - } + } }; BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) -{ + { LLSelectGetFirstCreator test; getFirst(&test); if (test.mFirstValue.isNull()) - { - name = LLTrans::getString("AvatarNameNobody"); + { + name = LLTrans::getString("AvatarNameNobody"); return FALSE; - } + } result_id = test.mFirstValue; @@ -3048,18 +3048,18 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) // Owner information only applies to roots unless editing linked parts. //----------------------------------------------------------------------------- struct LLSelectGetFirstOwner : public LLSelectGetFirstTest -{ + { protected: virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { + { // Don't use 'getOwnership' since we return a reference, not a copy. // Will return LLUUID::null if unowned (which is not allowed and should never happen.) return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner(); - } + } }; BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) -{ + { LLSelectGetFirstOwner test; getFirst(&test); @@ -3098,34 +3098,34 @@ struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest { protected: virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { +{ return node->mPermissions->getLastOwner(); } }; BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) -{ + { LLSelectGetFirstLastOwner test; getFirst(&test); if (test.mFirstValue.isNull()) - { - return FALSE; - } + { + return FALSE; + } result_id = test.mFirstValue; if (test.mIdentical) - { + { name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); - } - else - { + } + else + { name.assign( "" ); - } + } return test.mIdentical; -} + } //----------------------------------------------------------------------------- // selectGetGroup() @@ -3155,16 +3155,16 @@ BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id) // Returns TRUE if the first selected is group owned. //----------------------------------------------------------------------------- struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest -{ + { protected: virtual const LLUUID& getValueFromNode(LLSelectNode* node) - { + { if (node->mPermissions->isGroupOwned()) { return node->mPermissions->getGroup(); } return LLUUID::null; - } + } }; BOOL LLSelectMgr::selectIsGroupOwned() @@ -3414,9 +3414,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); // Keep track of how many objects have been deleted. - F64 obj_delete_count = LLViewerStats::getInstance()->getStat(LLViewerStats::ST_OBJECT_DELETE_COUNT); - obj_delete_count += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount(); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_OBJECT_DELETE_COUNT, obj_delete_count ); + add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount()); } break; case 1: diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 5532bdc71a..986ac14140 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -947,7 +947,6 @@ static bool callback_deed_to_group(const LLSD& notification, const LLSD& respons if (group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))) { LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -// LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); } } return FALSE; diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h index 9d7780c4f9..80ce99b774 100644 --- a/indra/newview/llsimplestat.h +++ b/indra/newview/llsimplestat.h @@ -99,43 +99,43 @@ public: * values back to zero. */ void reset() - { - mCount = 0; - mMin = Value(0); - mMax = Value(0); - mTotal = Value(0); - } + { + mCount = 0; + mMin = Value(0); + mMax = Value(0); + mTotal = Value(0); + } void record(Value v) + { + if (mCount) + { + mMin = llmin(mMin, v); + mMax = llmax(mMax, v); + } + else { - if (mCount) - { - mMin = llmin(mMin, v); - mMax = llmax(mMax, v); - } - else - { - mMin = v; - mMax = v; - } - mTotal += v; - ++mCount; + mMin = v; + mMax = v; } + mTotal += v; + ++mCount; + } void merge(const LLSimpleStatMMM<VALUE_T> & src) + { + if (! mCount) + { + *this = src; + } + else if (src.mCount) { - if (! mCount) - { - *this = src; - } - else if (src.mCount) - { - mMin = llmin(mMin, src.mMin); - mMax = llmax(mMax, src.mMax); - mCount += src.mCount; - mTotal += src.mTotal; - } + mMin = llmin(mMin, src.mMin); + mMax = llmax(mMax, src.mMax); + mCount += src.mCount; + mTotal += src.mTotal; } + } inline U32 getCount() const { return mCount; } inline Value getMin() const { return mMin; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index af740fe73d..53f5658815 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -126,106 +126,28 @@ protected: static LLOcclusionQueryPool sQueryPool; -//static counter for frame to switch LOD on - -void sg_assert(BOOL expr) +GLuint get_new_occlusion_query_object_name() { -#if LL_OCTREE_PARANOIA_CHECK - if (!expr) - { - llerrs << "Octree invalid!" << llendl; - } -#endif + return sQueryPool.allocate(); } -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) +void release_occlusion_query_object_name(GLuint name) { - return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) -{ - F32 d = 0.f; - F32 t; - - if ((min-origin).magVecSquared() < r && - (max-origin).magVecSquared() < r) - { - return 2; - } - - for (U32 i = 0; i < 3; i++) - { - if (origin.mV[i] < min.mV[i]) - { - t = min.mV[i] - origin.mV[i]; - d += t*t; - } - else if (origin.mV[i] > max.mV[i]) - { - t = origin.mV[i] - max.mV[i]; - d += t*t; - } - - if (d > r) - { - return 0; - } - } - - return 1; + sQueryPool.release(name); } +//static counter for frame to switch LOD on -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) -{ - return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) +void sg_assert(BOOL expr) { - F32 d = 0.f; - F32 t; - - LLVector4a origina; - origina.load3(origin.mV); - - LLVector4a v; - v.setSub(min, origina); - - if (v.dot3(v) < r) - { - v.setSub(max, origina); - if (v.dot3(v) < r) - { - return 2; - } - } - - - for (U32 i = 0; i < 3; i++) +#if LL_OCTREE_PARANOIA_CHECK + if (!expr) { - if (origin.mV[i] < min[i]) - { - t = min[i] - origin.mV[i]; - d += t*t; - } - else if (origin.mV[i] > max[i]) - { - t = origin.mV[i] - max[i]; - d += t*t; - } - - if (d > r) - { - return 0; - } + llerrs << "Octree invalid!" << llendl; } - - return 1; +#endif } - typedef enum { b000 = 0x00, @@ -358,7 +280,7 @@ LLSpatialGroup::~LLSpatialGroup() gPipeline.checkReferences(this); } - if (isState(DEAD)) + if (hasState(DEAD)) { sZombieGroups--; } @@ -371,7 +293,7 @@ LLSpatialGroup::~LLSpatialGroup() { if (mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); } } } @@ -514,17 +436,8 @@ BOOL LLSpatialGroup::isHUDGroup() BOOL LLSpatialGroup::isRecentlyVisible() const { - return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ; -} - -BOOL LLSpatialGroup::isVisible() const -{ - return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE; -} - -void LLSpatialGroup::setVisible() -{ - mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame(); + const S32 MIN_VIS_FRAME_RANGE = 2; + return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ; } void LLSpatialGroup::validate() @@ -619,7 +532,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) OctreeNode* parent = mOctreeNode->getOctParent(); if (mOctreeNode->isInside(drawablep->getPositionGroup()) && - (mOctreeNode->contains(drawablep) || + (mOctreeNode->contains(drawablep->getEntry()) || (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { @@ -633,15 +546,14 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) } -BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree) +BOOL LLSpatialGroup::addObject(LLDrawable *drawablep) { - if (!from_octree) + if(!drawablep) { - mOctreeNode->insert(drawablep); + return FALSE; } - else { - drawablep->setSpatialGroup(this); + drawablep->setGroup(this); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -664,7 +576,7 @@ void LLSpatialGroup::rebuildGeom() { mSpatialPartition->rebuildGeom(this); - if (isState(LLSpatialGroup::MESH_DIRTY)) + if (hasState(LLSpatialGroup::MESH_DIRTY)) { gPipeline.markMeshDirty(this); } @@ -686,7 +598,7 @@ static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry"); void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -751,103 +663,6 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) -{ - const OctreeNode* node = mOctreeNode; - - if (node->isEmpty()) - { //don't do anything if there are no objects - if (empty && mOctreeNode->getParent()) - { //only root is allowed to be empty - OCT_ERRS << "Empty leaf found in octree." << llendl; - } - return FALSE; - } - - LLVector4a& newMin = mObjectExtents[0]; - LLVector4a& newMax = mObjectExtents[1]; - - if (isState(OBJECT_DIRTY)) - { //calculate new bounding box - clearState(OBJECT_DIRTY); - - //initialize bounding box to first element - OctreeNode::const_element_iter i = node->getDataBegin(); - LLDrawable* drawablep = *i; - const LLVector4a* minMax = drawablep->getSpatialExtents(); - - newMin = minMax[0]; - newMax = minMax[1]; - - for (++i; i != node->getDataEnd(); ++i) - { - drawablep = *i; - minMax = drawablep->getSpatialExtents(); - - update_min_max(newMin, newMax, minMax[0]); - update_min_max(newMin, newMax, minMax[1]); - - //bin up the object - /*for (U32 i = 0; i < 3; i++) - { - if (minMax[0].mV[i] < newMin.mV[i]) - { - newMin.mV[i] = minMax[0].mV[i]; - } - if (minMax[1].mV[i] > newMax.mV[i]) - { - newMax.mV[i] = minMax[1].mV[i]; - } - }*/ - } - - mObjectBounds[0].setAdd(newMin, newMax); - mObjectBounds[0].mul(0.5f); - mObjectBounds[1].setSub(newMax, newMin); - mObjectBounds[1].mul(0.5f); - } - - if (empty) - { - minOut = newMin; - maxOut = newMax; - } - else - { - minOut.setMin(minOut, newMin); - maxOut.setMax(maxOut, newMax); - } - - return TRUE; -} - -void LLSpatialGroup::unbound() -{ - if (isState(DIRTY)) - { - return; - } - - setState(DIRTY); - - //all the parent nodes need to rebound this child - if (mOctreeNode) - { - OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); - while (parent != NULL) - { - LLSpatialGroup* group = (LLSpatialGroup*) parent->getListener(0); - if (group->isState(DIRTY)) - { - return; - } - - group->setState(DIRTY); - parent = (OctreeNode*) parent->getParent(); - } - } -} - LLSpatialGroup* LLSpatialGroup::getParent() { if (isDead()) @@ -871,17 +686,19 @@ LLSpatialGroup* LLSpatialGroup::getParent() BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { + if(!drawablep) + { + return FALSE; + } + unbound(); if (mOctreeNode && !from_octree) { - if (!mOctreeNode->remove(drawablep)) - { - OCT_ERRS << "Could not remove drawable from spatial group" << llendl; - } + drawablep->setGroup(NULL); } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -928,12 +745,12 @@ void LLSpatialGroup::shift(const LLVector4a &offset) } } -class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetState : public OctreeTraveler { public: U32 mState; LLSpatialSetState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } }; class LLSpatialSetStateDiff : public LLSpatialSetState @@ -941,24 +758,17 @@ class LLSpatialSetStateDiff : public LLSpatialSetState public: LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (!group->isState(mState)) + if (!group->hasState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; -void LLSpatialGroup::setState(U32 state) -{ - mState |= state; - - llassert(state <= LLSpatialGroup::STATE_MASK); -} - void LLSpatialGroup::setState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); @@ -982,12 +792,12 @@ void LLSpatialGroup::setState(U32 state, S32 mode) } } -class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearState : public OctreeTraveler { public: U32 mState; LLSpatialClearState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } }; class LLSpatialClearStateDiff : public LLSpatialClearState @@ -995,24 +805,17 @@ class LLSpatialClearStateDiff : public LLSpatialClearState public: LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (group->isState(mState)) + if (group->hasState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; -void LLSpatialGroup::clearState(U32 state) -{ - llassert(state <= LLSpatialGroup::STATE_MASK); - - mState &= ~state; -} - void LLSpatialGroup::clearState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); @@ -1036,22 +839,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) } } -BOOL LLSpatialGroup::isState(U32 state) const -{ - llassert(state <= LLSpatialGroup::STATE_MASK); - - return mState & state ? TRUE : FALSE; -} - //===================================== // Occlusion State Set/Clear //===================================== -class LLSpatialSetOcclusionState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetOcclusionState : public OctreeTraveler { public: U32 mState; LLSpatialSetOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } }; class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState @@ -1059,13 +855,13 @@ class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState public: LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); if (!group->isOcclusionState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; @@ -1093,7 +889,7 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); mOcclusionQuery[i] = 0; } } @@ -1104,19 +900,19 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) mOcclusionState[LLViewerCamera::sCurCameraID] |= state; if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; } } } -class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearOcclusionState : public OctreeTraveler { public: U32 mState; LLSpatialClearOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } }; class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState @@ -1124,13 +920,13 @@ class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState public: LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); if (group->isOcclusionState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; @@ -1166,13 +962,11 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) // Octree Listener Implementation //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLviewerOctreeGroup(node), mObjectBoxSize(1.f), - mState(0), mGeometryBytes(0), mSurfaceArea(0.f), mBuilt(0.f), - mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), mBufferUsage(part->mBufferUsage), @@ -1191,17 +985,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mViewAngle.splat(0.f); mLastUpdateViewAngle.splat(-1.f); - mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = - mObjectExtents[0] = mObjectExtents[1] = mViewAngle; sg_assert(mOctreeNode->getListenerCount() == 0); - mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - mBounds[0] = node->getCenter(); - mBounds[1] = node->getSize(); - part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; @@ -1235,7 +1023,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) } #if !LL_RELEASE_FOR_DOWNLOAD - if (isState(LLSpatialGroup::OBJECT_DIRTY)) + if (hasState(LLSpatialGroup::OBJECT_DIRTY)) { llerrs << "Spatial group dirty on distance update." << llendl; } @@ -1266,7 +1054,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) dist = eye.getLength3().getF32(); eye.normalize3fast(); - if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) + if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) { if (!group->mSpatialPartition->isBridge()) { @@ -1343,7 +1131,7 @@ BOOL LLSpatialGroup::needsUpdate() BOOL LLSpatialGroup::changeLOD() { - if (isState(ALPHA_DIRTY | OBJECT_DIRTY)) + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { ///a rebuild is going to happen, update distance and LoD return TRUE; } @@ -1371,17 +1159,17 @@ BOOL LLSpatialGroup::changeLOD() return FALSE; } -void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep) +void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry) { - addObject(drawablep, FALSE, TRUE); + addObject((LLDrawable*)entry->getDrawable()); unbound(); setState(OBJECT_DIRTY); } -void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable) +void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry) { - removeObject(drawable, TRUE); - setState(OBJECT_DIRTY); + removeObject((LLDrawable*)entry->getDrawable(), TRUE); + LLviewerOctreeGroup::handleRemoval(node, entry); } void LLSpatialGroup::handleDestruction(const TreeNode* node) @@ -1390,10 +1178,17 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { - LLDrawable* drawable = *i; - if (drawable->getSpatialGroup() == this) + LLViewerOctreeEntry* entry = *i; + if (entry->getGroup() == this) { - drawable->setSpatialGroup(NULL); + if(entry->hasDrawable()) + { + ((LLDrawable*)entry->getDrawable())->setGroup(NULL); + } + else + { + llerrs << "No Drawable found in the entry." << llendl; + } } } @@ -1415,16 +1210,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) mOctreeNode = NULL; } -void LLSpatialGroup::handleStateChange(const TreeNode* node) -{ - //drop bounding box upon state change - if (mOctreeNode != node) - { - mOctreeNode = (OctreeNode*) node; - } - unbound(); -} - void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { if (child->getListenerCount() == 0) @@ -1441,11 +1226,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c assert_states_valid(this); } -void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) -{ - unbound(); -} - void LLSpatialGroup::destroyGL(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1467,7 +1247,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) { if (mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); mOcclusionQuery[i] = 0; } } @@ -1476,7 +1256,11 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* facep = drawable->getFace(j); @@ -1488,69 +1272,6 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) } } -BOOL LLSpatialGroup::rebound() -{ - if (!isState(DIRTY)) - { //return TRUE if we're not empty - return TRUE; - } - - if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) - { - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); - group->rebound(); - - //copy single child's bounding box - mBounds[0] = group->mBounds[0]; - mBounds[1] = group->mBounds[1]; - mExtents[0] = group->mExtents[0]; - mExtents[1] = group->mExtents[1]; - - group->setState(SKIP_FRUSTUM_CHECK); - } - else if (mOctreeNode->isLeaf()) - { //copy object bounding box if this is a leaf - boundObjects(TRUE, mExtents[0], mExtents[1]); - mBounds[0] = mObjectBounds[0]; - mBounds[1] = mObjectBounds[1]; - } - else - { - LLVector4a& newMin = mExtents[0]; - LLVector4a& newMax = mExtents[1]; - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); - group->clearState(SKIP_FRUSTUM_CHECK); - group->rebound(); - //initialize to first child - newMin = group->mExtents[0]; - newMax = group->mExtents[1]; - - //first, rebound children - for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) - { - group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); - group->clearState(SKIP_FRUSTUM_CHECK); - group->rebound(); - const LLVector4a& max = group->mExtents[1]; - const LLVector4a& min = group->mExtents[0]; - - newMax.setMax(newMax, max); - newMin.setMin(newMin, min); - } - - boundObjects(FALSE, newMin, newMax); - - mBounds[0].setAdd(newMin, newMax); - mBounds[0].mul(0.5f); - mBounds[1].setSub(newMax, newMin); - mBounds[1].mul(0.5f); - } - - clearState(DIRTY); - - return TRUE; -} - static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); @@ -1580,7 +1301,7 @@ void LLSpatialGroup::checkOcclusion() LLFastTimer t(FTM_OCCLUSION_WAIT); while (!available && max_loop-- > 0) { - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); //do some usefu work while we wait LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread @@ -1607,7 +1328,7 @@ void LLSpatialGroup::checkOcclusion() } else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { //delete the query to avoid holding onto hundreds of pending queries - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; } @@ -1679,7 +1400,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) { LLFastTimer t(FTM_OCCLUSION_ALLOCATE); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = get_new_occlusion_query_object_name(); } // Depth clamp all water to avoid it being culled as a result of being @@ -1769,9 +1490,10 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) : mRenderByGroup(render_by_group), mBridge(NULL) { + mRegionp = regionp; mOcclusionEnabled = TRUE; mDrawableType = 0; mPartitionType = LLViewerRegion::PARTITION_NONE; @@ -1783,23 +1505,14 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mSlopRatio = 0.25f; mInfiniteFarClip = FALSE; - LLVector4a center, size; - center.splat(0.f); - size.splat(1.f); - - mOctree = new LLSpatialGroup::OctreeRoot(center,size, - NULL); new LLSpatialGroup(mOctree, this); } LLSpatialPartition::~LLSpatialPartition() { - delete mOctree; - mOctree = NULL; } - LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { drawablep->updateSpatialExtents(); @@ -1807,11 +1520,15 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) //keep drawable from being garbage collected LLPointer<LLDrawable> ptr = drawablep; + if(!drawablep->getGroup()) + { assert_octree_valid(mOctree); - mOctree->insert(drawablep); + mOctree->insert(drawablep->getEntry()); assert_octree_valid(mOctree); + } LLSpatialGroup* group = drawablep->getSpatialGroup(); + llassert(group != NULL); if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) { @@ -1829,11 +1546,9 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); } - drawablep->setSpatialGroup(NULL); - assert_octree_valid(mOctree); return TRUE; @@ -1883,13 +1598,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL put(drawablep, was_visible); } -class LLSpatialShift : public LLSpatialGroup::OctreeTraveler +class LLSpatialShift : public OctreeTraveler { public: const LLVector4a& mOffset; LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } @@ -1901,17 +1616,17 @@ void LLSpatialPartition::shift(const LLVector4a &offset) shifter.traverse(mOctree); } -class LLOctreeCull : public LLSpatialGroup::OctreeTraveler +class LLOctreeCull : public LLViewerOctreeCull { public: - LLOctreeCull(LLCamera* camera) - : mCamera(camera), mRes(0) { } + LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {} - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; group->checkOcclusion(); - if (group->mOctreeNode->getParent() && //never occlusion cull the root node + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { @@ -1922,78 +1637,29 @@ public: return false; } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (earlyFail(group)) - { - return; - } - - if (mRes == 2 || - (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK))) - { //fully in, just add everything - LLSpatialGroup::OctreeTraveler::traverse(n); - } - else - { - mRes = frustumCheck(group); - - if (mRes) - { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); - } - - mRes = 0; - } - } - - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + S32 res = AABBInFrustumNoFarClipGroupBounds(group); if (res != 0) { - res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + res = llmin(res, AABBSphereIntersectGroupExtents(group)); } return res; } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + S32 res = AABBInFrustumNoFarClipObjectBounds(group); if (res != 0) { - res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + res = llmin(res, AABBSphereIntersectObjectExtents(group)); } return res; } - virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group) - { - if (branch->getElementCount() == 0) //no elements - { - return false; - } - else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box - { - return true; - } - else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum - { - return false; - } - - return true; - } - - virtual void preprocess(LLSpatialGroup* group) - { - - } - - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) { @@ -2001,21 +1667,6 @@ public: } gPipeline.markNotCulled(group, *mCamera); } - - virtual void visit(const LLSpatialGroup::OctreeNode* branch) - { - LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - preprocess(group); - - if (checkObjects(branch, group)) - { - processGroup(group); - } - } - - LLCamera *mCamera; - S32 mRes; }; class LLOctreeCullNoFarClip : public LLOctreeCull @@ -2024,14 +1675,14 @@ public: LLOctreeCullNoFarClip(LLCamera* camera) : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + return AABBInFrustumNoFarClipGroupBounds(group); } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + S32 res = AABBInFrustumNoFarClipObjectBounds(group); return res; } }; @@ -2042,14 +1693,14 @@ public: LLOctreeCullShadow(LLCamera* camera) : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); + return AABBInFrustumGroupBounds(group); } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); + return AABBInFrustumObjectBounds(group); } }; @@ -2059,9 +1710,11 @@ public: LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { - if (group->mOctreeNode->getParent() && //never occlusion cull the root node + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { @@ -2071,7 +1724,7 @@ public: return false; } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -2080,10 +1733,10 @@ public: return; } - if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || + if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || mRes == 2) { //don't need to do frustum check - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } else { @@ -2091,31 +1744,35 @@ public: if (mRes) { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } mRes = 0; } } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty()) + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty()) if (mRes < 2) { - if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) + if (AABBInFrustumObjectBounds(group) > 0) { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); + const LLVector4a* exts = group->getObjectExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); } } else { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mExtents[0]); - update_min_max(mMin, mMax, group->mExtents[1]); + const LLVector4a* exts = group->getExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); } } @@ -2130,10 +1787,12 @@ public: LLOctreeCullDetectVisible(LLCamera* camera) : LLOctreeCullShadow(camera), mResult(FALSE) { } - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + if (mResult || //already found a node, don't check any more - (group->mOctreeNode->getParent() && //never occlusion cull the root node + (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED))) { @@ -2143,9 +1802,9 @@ public: return false; } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - if (group->isVisible()) + if (base_group->isVisible()) { mResult = TRUE; } @@ -2160,17 +1819,21 @@ public: LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results) : LLOctreeCull(camera), mResults(results) { } - virtual bool earlyFail(LLSpatialGroup* group) { return false; } - virtual void preprocess(LLSpatialGroup* group) { } + virtual bool earlyFail(LLviewerOctreeGroup* group) { return false; } + virtual void preprocess(LLviewerOctreeGroup* group) { } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + OctreeNode* branch = group->getOctreeNode(); - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (!drawable->isDead()) { if (drawable->isSpatialBridge()) @@ -2283,17 +1946,21 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size)); } -class LLOctreeDirty : public LLOctreeTraveler<LLDrawable> +class LLOctreeDirty : public OctreeTraveler { public: - virtual void visit(const LLOctreeNode<LLDrawable>* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); group->destroyGL(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); @@ -2365,13 +2032,28 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif + LLOctreeSelect selecter(&camera, results); + selecter.traverse(mOctree); - if (for_select) + return 0; +} + +S32 LLSpatialPartition::cull(LLCamera &camera) +{ +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); +#endif { - LLOctreeSelect selecter(&camera, results); - selecter.traverse(mOctree); + LLFastTimer ftm(FTM_CULL_REBOUND); + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); } - else if (LLPipeline::sShadowRender) + +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->validate(); +#endif + + if (LLPipeline::sShadowRender) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); @@ -2404,9 +2086,10 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) LLVector4a fudge; fudge.splat(vel); - const LLVector4a& c = group->mBounds[0]; + const LLVector4a* bounds = group->getBounds(); + const LLVector4a& c = bounds[0]; LLVector4a r; - r.setAdd(group->mBounds[1], fudge); + r.setAdd(bounds[1], fudge); /*if (r.magVecSquared() > 1024.0*1024.0) { @@ -2531,7 +2214,8 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask) } else { - drawBox(group->mBounds[0], group->mBounds[1]); + const LLVector4a* bounds = group->getBounds(); + drawBox(bounds[0], bounds[1]); } } @@ -2576,7 +2260,7 @@ void renderOctree(LLSpatialGroup* group) LLVector4 col; if (group->mBuilt > 0.f) { - group->mBuilt -= 2.f * gFrameIntervalSeconds; + group->mBuilt -= 2.f * gFrameIntervalSeconds.value(); if (group->mBufferUsage == GL_STATIC_DRAW_ARB) { col.setVec(1.0f, 0, 0, group->mBuilt*0.5f); @@ -2595,13 +2279,19 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4f(1,0,0,group->mBuilt); gGL.flush(); glLineWidth(5.f); - drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + + const LLVector4a* bounds = group->getObjectBounds(); + drawBoxOutline(bounds[0], bounds[1]); gGL.flush(); glLineWidth(1.f); gGL.flush(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (!group->mSpatialPartition->isBridge()) { gGL.pushMatrix(); @@ -2659,9 +2349,10 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4fv(col.mV); LLVector4a fudge; fudge.splat(0.001f); - LLVector4a size = group->mObjectBounds[1]; - size.mul(1.01f); - size.add(fudge); + + //LLVector4a size = group->mObjectBounds[1]; + //size.mul(1.01f); + //size.add(fudge); //{ // LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -2677,7 +2368,9 @@ void renderOctree(LLSpatialGroup* group) //drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); gGL.diffuseColor4f(0,1,1,1); - drawBoxOutline(group->mBounds[0],group->mBounds[1]); + + const LLVector4a* bounds = group->getBounds(); + drawBoxOutline(bounds[0], bounds[1]); //draw bounding box for draw info /*if (group->mSpatialPartition->mRenderByGroup) @@ -3444,9 +3137,13 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) void renderPhysicsShapes(LLSpatialGroup* group) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } LLVOVolume* volume = drawable->getVOVolume(); if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) { @@ -4003,17 +3700,18 @@ void renderAgentTarget(LLVOAvatar* avatar) } } -class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> +class LLOctreeRenderNonOccluded : public OctreeTraveler { public: LLCamera* mCamera; LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) { node->accept(this); stop_glerror(); @@ -4053,17 +3751,17 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) { return; } - LLVector4a nodeCenter = group->mBounds[0]; - LLVector4a octCenter = group->mOctreeNode->getCenter(); + LLVector4a nodeCenter = bounds[0]; + LLVector4a octCenter = group->getOctreeNode()->getCenter(); group->rebuildGeom(); group->rebuildMesh(); @@ -4073,14 +3771,19 @@ public: if (!group->isEmpty()) { gGL.diffuseColor3f(0,0,1); - drawBoxOutline(group->mObjectBounds[0], - group->mObjectBounds[1]); + + const LLVector4a* obj_bounds = group->getObjectBounds(); + drawBoxOutline(obj_bounds[0], obj_bounds[1]); } } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) { - LLDrawable* drawable = *i; + continue; + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { @@ -4203,17 +3906,18 @@ public: }; -class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable> +class LLOctreeRenderPhysicsShapes : public OctreeTraveler { public: LLCamera* mCamera; LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) { node->accept(this); stop_glerror(); @@ -4231,23 +3935,24 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { } }; -class LLOctreePushBBoxVerts : public LLOctreeTraveler<LLDrawable> +class LLOctreePushBBoxVerts : public OctreeTraveler { public: LLCamera* mCamera; LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1])) { node->accept(this); @@ -4258,19 +3963,23 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) { return; } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } renderBoundingBox(drawable, FALSE); } } @@ -4282,7 +3991,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> +class LLOctreeStateCheck : public OctreeTraveler { public: U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; @@ -4295,7 +4004,7 @@ public: } } - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); @@ -4322,7 +4031,7 @@ public: } - virtual void visit(const LLOctreeNode<LLDrawable>* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); @@ -4334,7 +4043,7 @@ public: } } - if (group->isState(LLSpatialGroup::DIRTY)) + if (group->hasState(LLSpatialGroup::DIRTY)) { assert_parent_state(group, LLSpatialGroup::DIRTY); } @@ -4345,7 +4054,7 @@ public: LLSpatialGroup* parent = group->getParent(); while (parent) { - if (!parent->isState(state)) + if (!parent->hasState(state)) { llerrs << "Spatial group failed parent state check." << llendl; } @@ -4460,7 +4169,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) return TRUE; } -class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler +class LLOctreeIntersect : public OctreeTraveler { public: LLVector3 mStart; @@ -4487,21 +4196,21 @@ public: { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { check(*i); } } - virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) + virtual LLDrawable* check(const OctreeNode* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) { - const LLSpatialGroup::OctreeNode* child = node->getChild(i); + const OctreeNode* child = node->getChild(i); LLVector3 res; LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); @@ -4509,8 +4218,9 @@ public: LLVector4a size; LLVector4a center; - size = group->mBounds[1]; - center = group->mBounds[0]; + const LLVector4a* bounds = group->getBounds(); + size = bounds[1]; + center = bounds[0]; LLVector3 local_start = mStart; LLVector3 local_end = mEnd; @@ -4537,8 +4247,9 @@ public: return mHit; } - virtual bool check(LLDrawable* drawable) + virtual bool check(LLViewerOctreeEntry* entry) { + LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); LLVector3 local_start = mStart; LLVector3 local_end = mEnd; @@ -4932,5 +4643,3 @@ void LLCullResult::assertDrawMapsEmpty() } } - - diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b1706d9d35..b592e73403 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -45,22 +45,21 @@ #define SG_STATE_INHERIT_MASK (OCCLUDED) #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) +class LLViewerOctreePartition; class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; class LLTextureAtlas; class LLTextureAtlasSlot; +class LLViewerRegion; -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); - -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); void pushVerts(LLFace* face, U32 mask); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); +GLuint get_new_occlusion_query_object_name(); +void release_occlusion_query_object_name(GLuint name); class LLDrawInfo : public LLRefCount { @@ -192,13 +191,13 @@ public: }; LL_ALIGN_PREFIX(16) -class LLSpatialGroup : public LLOctreeListener<LLDrawable> +class LLSpatialGroup : public LLviewerOctreeGroup { friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: - LLSpatialGroup(const LLSpatialGroup& rhs) + LLSpatialGroup(const LLSpatialGroup& rhs) : LLviewerOctreeGroup(rhs) { *this = rhs; } @@ -231,15 +230,6 @@ public: typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t; typedef std::map<U32, buffer_texture_map_t> buffer_map_t; - typedef LLOctreeListener<LLDrawable> BaseType; - typedef LLOctreeListener<LLDrawable> OctreeListener; - typedef LLTreeNode<LLDrawable> TreeNode; - typedef LLOctreeNode<LLDrawable> OctreeNode; - typedef LLOctreeRoot<LLDrawable> OctreeRoot; - typedef LLOctreeTraveler<LLDrawable> OctreeTraveler; - typedef LLOctreeNode<LLDrawable>::element_iter element_iter; - typedef LLOctreeNode<LLDrawable>::element_list element_list; - struct CompareDistanceGreater { bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) @@ -275,18 +265,15 @@ public: typedef enum { - DEAD = 0x00000001, - DIRTY = 0x00000002, - OBJECT_DIRTY = 0x00000004, - GEOM_DIRTY = 0x00000008, - ALPHA_DIRTY = 0x00000010, - SKIP_FRUSTUM_CHECK = 0x00000020, - IN_IMAGE_QUEUE = 0x00000040, - IMAGE_DIRTY = 0x00000080, - MESH_DIRTY = 0x00000100, - NEW_DRAWINFO = 0x00000200, - IN_BUILD_Q1 = 0x00000400, - IN_BUILD_Q2 = 0x00000800, + DEAD = LLviewerOctreeGroup::INVALID_STATE, + GEOM_DIRTY = (DEAD << 1), + ALPHA_DIRTY = (GEOM_DIRTY << 1), + IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1), + IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1), + MESH_DIRTY = (IMAGE_DIRTY << 1), + NEW_DRAWINFO = (MESH_DIRTY << 1), + IN_BUILD_Q1 = (NEW_DRAWINFO << 1), + IN_BUILD_Q2 = (IN_BUILD_Q1 << 1), STATE_MASK = 0x0000FFFF, } eSpatialState; @@ -301,12 +288,8 @@ public: LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); BOOL isHUDGroup() ; - BOOL isDead() { return isState(DEAD); } - BOOL isState(U32 state) const; + BOOL isDead() { return hasState(DEAD); } BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } - U32 getState() { return mState; } - void setState(U32 state); - void clearState(U32 state); void clearDrawMap(); void validate(); @@ -315,23 +298,18 @@ public: void setState(U32 state, S32 mode); void clearState(U32 state, S32 mode); + void clearState(U32 state) {mState &= ~state;} void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); LLSpatialGroup* getParent(); - - BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE); + BOOL addObject(LLDrawable *drawablep); BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group - BOOL isVisible() const; BOOL isRecentlyVisible() const; - void setVisible(); void shift(const LLVector4a &offset); - BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax); - void unbound(); - BOOL rebound(); void checkOcclusion(); //read back last occlusion query (if any) void doOcclusion(LLCamera* camera); //issue occlusion query void destroyGL(bool keep_occlusion = false); @@ -343,27 +321,17 @@ public: void rebuildGeom(); void rebuildMesh(); + void setState(U32 state) {mState |= state;} void dirtyGeom() { setState(GEOM_DIRTY); } void dirtyMesh() { setState(MESH_DIRTY); } - //octree wrappers to make code more readable - element_list& getData() { return mOctreeNode->getData(); } - element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } - element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } - bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); } - - U32 getElementCount() const { return mOctreeNode->getElementCount(); } - bool isEmpty() const { return mOctreeNode->isEmpty(); } - void drawObjectBox(LLColor4 col); //LISTENER FUNCTIONS - virtual void handleInsertion(const TreeNode* node, LLDrawable* face); - virtual void handleRemoval(const TreeNode* node, LLDrawable* face); + virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face); + virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face); virtual void handleDestruction(const TreeNode* node); - virtual void handleStateChange(const TreeNode* node); virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); - virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); //------------------- //for atlas use @@ -386,21 +354,6 @@ public: public: - typedef enum - { - BOUNDS = 0, - EXTENTS = 2, - OBJECT_BOUNDS = 4, - OBJECT_EXTENTS = 6, - VIEW_ANGLE = 8, - LAST_VIEW_ANGLE = 9, - V4_COUNT = 10 - } eV4Index; - - LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) - LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children - LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node - LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node LL_ALIGN_16(LLVector4a mViewAngle); LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); @@ -421,7 +374,6 @@ private: protected: virtual ~LLSpatialGroup(); - U32 mState; U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; @@ -436,7 +388,6 @@ public: F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node F32 mBuilt; - OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; LLPointer<LLVertexBuffer> mVertexBuffer; @@ -445,7 +396,6 @@ public: U32 mBufferUsage; draw_map_t mDrawMap; - S32 mVisible[LLViewerCamera::NUM_CAMERAS]; F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; @@ -468,10 +418,10 @@ public: virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; -class LLSpatialPartition: public LLGeometryManager +class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager { public: - LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage); + LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -498,7 +448,8 @@ public: virtual void rebuildMesh(LLSpatialGroup* group); BOOL visibleObjectsInFrustum(LLCamera& camera); - S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum + /*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum + S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum BOOL isVisible(const LLVector3& v); bool isHUDPartition() ; @@ -515,21 +466,19 @@ public: BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); public: - LLSpatialGroup::OctreeNode* mOctree; LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe // to call asBridge() from the destructor BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; + U32 mDrawableType; const BOOL mRenderByGroup; U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25); BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering - U32 mDrawableType; - U32 mPartitionType; }; // class for creating bridges between spatial partitions @@ -541,7 +490,7 @@ protected: public: typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t; - LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); + LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp); void destroyTree(); @@ -663,7 +612,7 @@ private: class LLWaterPartition : public LLSpatialPartition { public: - LLWaterPartition(); + LLWaterPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group) { } virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } }; @@ -672,14 +621,14 @@ public: class LLVoidWaterPartition : public LLWaterPartition { public: - LLVoidWaterPartition(); + LLVoidWaterPartition(LLViewerRegion* regionp); }; //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp) class LLTerrainPartition : public LLSpatialPartition { public: - LLTerrainPartition(); + LLTerrainPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group); virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; @@ -688,7 +637,7 @@ public: class LLTreePartition : public LLSpatialPartition { public: - LLTreePartition(); + LLTreePartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group) { } virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } @@ -698,7 +647,7 @@ public: class LLParticlePartition : public LLSpatialPartition { public: - LLParticlePartition(); + LLParticlePartition(LLViewerRegion* regionp); virtual void rebuildGeom(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); @@ -710,14 +659,14 @@ protected: class LLHUDParticlePartition : public LLParticlePartition { public: - LLHUDParticlePartition(); + LLHUDParticlePartition(LLViewerRegion* regionp); }; //spatial partition for grass (implemented in LLVOGrass.cpp) class LLGrassPartition : public LLSpatialPartition { public: - LLGrassPartition(); + LLGrassPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group); virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); protected: @@ -747,7 +696,7 @@ class LLVolumeGeometryManager: public LLGeometryManager class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager { public: - LLVolumePartition(); + LLVolumePartition(LLViewerRegion* regionp); virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); } virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); } virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); } @@ -758,7 +707,7 @@ public: class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager { public: - LLVolumeBridge(LLDrawable* drawable); + LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp); virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); } virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); } virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); } @@ -768,7 +717,7 @@ public: class LLHUDBridge : public LLVolumeBridge { public: - LLHUDBridge(LLDrawable* drawablep); + LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp); virtual void shiftPos(const LLVector4a& vec); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); }; @@ -777,7 +726,7 @@ public: class LLBridgePartition : public LLSpatialPartition { public: - LLBridgePartition(); + LLBridgePartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group) { } virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } }; @@ -785,7 +734,7 @@ public: class LLHUDPartition : public LLBridgePartition { public: - LLHUDPartition(); + LLHUDPartition(LLViewerRegion* regionp); virtual void shift(const LLVector4a &offset); }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0e3007724b..cf2b491d6c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1947,7 +1947,7 @@ bool idle_startup() llinfos << "gAgentStartLocation : " << gAgentStartLocation << llendl; LLSLURL start_slurl = LLStartUp::getStartSLURL(); LL_DEBUGS("AppInit") << "start slurl "<<start_slurl.asString()<<LL_ENDL; - + if (((start_slurl.getType() == LLSLURL::LOCATION) && (gAgentStartLocation == "url")) || ((start_slurl.getType() == LLSLURL::LAST_LOCATION) && (gAgentStartLocation == "last")) || ((start_slurl.getType() == LLSLURL::HOME_LOCATION) && (gAgentStartLocation == "home"))) @@ -2071,7 +2071,7 @@ bool idle_startup() if (wearables_time > MAX_WEARABLES_TIME) { LLNotificationsUtil::add("ClothingLoading"); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG); + add(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, 1); LLStartUp::setStartupState( STATE_CLEANUP ); return TRUE; } @@ -2183,9 +2183,6 @@ bool idle_startup() LLAppViewer::instance()->handleLoginComplete(); - // reset timers now that we are running "logged in" logic - LLFastTimer::reset(); - LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); LLIMFloater::initIMFloater(); @@ -2294,7 +2291,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response) // break; case 2: // Teleport // Restart the login process, starting at our home locaton - LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); + LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); break; default: diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index ff69c6e9fd..b945ec2318 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -37,7 +37,6 @@ #include "llviewercontrol.h" #include "llfloaterbuycurrency.h" #include "llbuycurrencyhtml.h" -#include "llfloaterlagmeter.h" #include "llpanelnearbymedia.h" #include "llpanelvolumepulldown.h" #include "llfloaterregioninfo.h" @@ -199,10 +198,10 @@ BOOL LLStatusBar::postBuild() sgp.rect(r); sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); sgp.mouse_opaque(false); + sgp.stat.count_stat_float(&LLStatViewer::KBIT); + sgp.units("Kbps"); + sgp.precision(0); mSGBandwidth = LLUICtrlFactory::create<LLStatGraph>(sgp); - mSGBandwidth->setStat(&LLViewerStats::getInstance()->mKBitStat); - mSGBandwidth->setUnits("Kbps"); - mSGBandwidth->setPrecision(0); addChild(mSGBandwidth); x -= SIM_STAT_WIDTH + 2; @@ -213,17 +212,20 @@ BOOL LLStatusBar::postBuild() pgp.rect(r); pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); pgp.mouse_opaque(false); + pgp.stat.measurement_stat_float(&LLStatViewer::PACKETS_LOST_PERCENT); + pgp.units("%"); + pgp.min(0.f); + pgp.max(5.f); + pgp.precision(1); + pgp.per_sec(false); + LLStatGraph::Thresholds thresholds; + thresholds.threshold.add(LLStatGraph::ThresholdParams().value(0.1).color(LLColor4::green)) + .add(LLStatGraph::ThresholdParams().value(0.25f).color(LLColor4::yellow)) + .add(LLStatGraph::ThresholdParams().value(0.6f).color(LLColor4::red)); + + pgp.thresholds(thresholds); mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp); - mSGPacketLoss->setStat(&LLViewerStats::getInstance()->mPacketsLostPercentStat); - mSGPacketLoss->setUnits("%"); - mSGPacketLoss->setMin(0.f); - mSGPacketLoss->setMax(5.f); - mSGPacketLoss->setThreshold(0, 0.5f); - mSGPacketLoss->setThreshold(1, 1.f); - mSGPacketLoss->setThreshold(2, 3.f); - mSGPacketLoss->setPrecision(1); - mSGPacketLoss->mPerSec = FALSE; addChild(mSGPacketLoss); mPanelVolumePulldown = new LLPanelVolumePulldown(); @@ -253,9 +255,9 @@ void LLStatusBar::refresh() F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f; mSGBandwidth->setMin(0.f); mSGBandwidth->setMax(bwtotal*1.25f); - mSGBandwidth->setThreshold(0, bwtotal*0.75f); - mSGBandwidth->setThreshold(1, bwtotal); - mSGBandwidth->setThreshold(2, bwtotal); + //mSGBandwidth->setThreshold(0, bwtotal*0.75f); + //mSGBandwidth->setThreshold(1, bwtotal); + //mSGBandwidth->setThreshold(2, bwtotal); } // update clock every 10 seconds diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 9d24bf8771..33a64ae7d5 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -45,7 +45,6 @@ class LLTimer; class LLUUID; class LLAgent; -class LLStat; static const U8 NO_EDGE = 0x00; static const U8 EAST_EDGE = 0x01; diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index ad09af6594..d6cd881894 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -460,7 +460,7 @@ BOOL LLTexLayerSetBuffer::requestUpdateImmediate() void LLTexLayerSetBuffer::doUpload() { llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl; - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); + add(LLStatViewer::TEX_BAKES, 1); // Don't need caches since we're baked now. (note: we won't *really* be baked // until this image is sent to the server and the Avatar Appearance message is received.) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ec36cf48c2..e227722b29 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -549,11 +549,11 @@ void LLFloaterTexturePicker::draw() if (gFocusMgr.childHasMouseCapture(getDragHandle())) { - mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); + mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME)); } else { - mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); + mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME)); } updateImageStats(); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 41bfbae86e..8bf7bcc398 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -53,6 +53,7 @@ #include "llviewerstatsrecorder.h" #include "llviewerassetstats.h" #include "llworld.h" +#include "llsdparam.h" #include "llsdutil.h" #include "llstartup.h" #include "llsdserialize.h" @@ -64,8 +65,8 @@ #include "bufferstream.h" bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); -LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); +LLTrace::MeasurementStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); +LLTrace::MeasurementStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); ////////////////////////////////////////////////////////////////////////////// @@ -1236,7 +1237,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; - LLTextureFetch::sCacheHitRate.addValue(100.f); + sample(LLTextureFetch::sCacheHitRate, 100.f); } else { @@ -1253,7 +1254,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } // fall through - LLTextureFetch::sCacheHitRate.addValue(0.f); + sample(LLTextureFetch::sCacheHitRate, 0.f); } } @@ -2281,7 +2282,7 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http) { mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType); } @@ -2292,13 +2293,13 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http) { if (mMetricsStartTime) { - LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType, LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); mMetricsStartTime = 0; } - LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType); } @@ -2359,6 +2360,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mHttpMetricsHeaders = new LLCore::HttpHeaders; mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml"); mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault(); + + //reset the texture timer. + gTextureTimer.reset(); + gTextureTimer.pause(); } LLTextureFetch::~LLTextureFetch() @@ -2703,7 +2708,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, F32 cache_read_time = worker->mCacheReadTime; if (cache_read_time != 0.f) { - sCacheReadLatency.addValue(cache_read_time * 1000.f); + sample(sCacheReadLatency, cache_read_time * 1000.f); } res = true; LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; @@ -2829,7 +2834,7 @@ S32 LLTextureFetch::update(F32 max_time_ms) mNetworkQueueMutex.lock(); // +Mfnq mMaxBandwidth = band_width; - gTextureList.sTextureBits += mHTTPTextureBits; + add(LLStatViewer::TEXTURE_KBIT, mHTTPTextureBits); mHTTPTextureBits = 0; mNetworkQueueMutex.unlock(); // -Mfnq @@ -3258,7 +3263,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 mNetworkQueueMutex.unlock(); // -Mfnq return false; } - + LLViewerStatsRecorder::instance().textureFetch(data_size); LLViewerStatsRecorder::instance().log(0.1f); @@ -3711,7 +3716,7 @@ AssetReportHandler stats_handler; bool TFReqSetRegion::doWork(LLTextureFetch *) { - LLViewerAssetStatsFF::set_region_thread1(mRegionHandle); + LLViewerAssetStatsFF::set_region(mRegionHandle); return true; } @@ -3736,8 +3741,8 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) static const U32 report_priority(1); static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL); - if (! gViewerAssetStatsThread1) - return true; + //if (! gViewerAssetStatsThread1) + // return true; static volatile bool reporting_started(false); static volatile S32 report_sequence(0); @@ -3747,17 +3752,21 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // but leave it in 'this'. Destructor will rid us of it. LLViewerAssetStats & main_stats = *mMainStats; - // Merge existing stats into those from main, convert to LLSD - main_stats.merge(*gViewerAssetStatsThread1); - LLSD merged_llsd = main_stats.asLLSD(true); - - // Add some additional meta fields to the content - merged_llsd["session_id"] = mSessionID; - merged_llsd["agent_id"] = mAgentID; - merged_llsd["message"] = "ViewerAssetMetrics"; // Identifies the type of metrics - merged_llsd["sequence"] = report_sequence; // Sequence number - merged_llsd["initial"] = ! reporting_started; // Initial data from viewer - merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak; // Break in data prior to this report + LLViewerAssetStats::AssetStats stats; + main_stats.getStats(stats, true); + //LLSD merged_llsd = main_stats.asLLSD(); + + bool initial_report = !reporting_started; + stats.session_id = mSessionID; + stats.agent_id = mAgentID; + stats.message = "ViewerAssetMetrics"; + stats.sequence = static_cast<bool>(report_sequence); + stats.initial = initial_report; + stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); + + LLSD sd; + LLParamSDParser parser; + parser.writeSD(sd, stats); // Update sequence number if (S32_MAX == ++report_sequence) @@ -3765,13 +3774,14 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) reporting_started = true; // Limit the size of the stats report if necessary. - merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd); + + sd["truncated"] = truncate_viewer_metrics(10, sd); if (! mCapsURL.empty()) { LLCore::BufferArray * ba = new LLCore::BufferArray; LLCore::BufferArrayStream bas(ba); - LLSDSerialize::toXML(merged_llsd, bas); + LLSDSerialize::toXML(sd, bas); fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(), report_priority, @@ -3791,11 +3801,9 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // In QA mode, Metrics submode, log the result for ease of testing if (fetcher->isQAMode()) { - LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL; + LL_INFOS("Textures") << ll_pretty_print_sd(sd) << LL_ENDL; } - gViewerAssetStatsThread1->reset(); - return true; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 1e58ba35d4..4dcb9dd4b8 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -37,13 +37,12 @@ #include "lltextureinfo.h" #include "llapr.h" #include "llimageworker.h" -#include "llstat.h" #include "llcurl.h" -#include "llstat.h" #include "httprequest.h" #include "httpoptions.h" #include "httpheaders.h" #include "httphandler.h" +#include "lltrace.h" class LLViewerTexture; class LLTextureFetchWorker; @@ -309,8 +308,8 @@ private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. - static LLStat sCacheHitRate; - static LLStat sCacheReadLatency; + static LLTrace::MeasurementStatHandle<> sCacheHitRate; + static LLTrace::MeasurementStatHandle<> sCacheReadLatency; LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; @@ -330,7 +329,7 @@ private: LLTextureInfo mTextureInfo; // XXX possible delete - U32 mHTTPTextureBits; // Mfnq + LLUnit<LLUnits::Bits, U32> mHTTPTextureBits; // Mfnq // XXX possible delete //debug use diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 16c42dbd43..7a6351c880 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,6 +49,8 @@ #include "llviewertexturelist.h" #include "llvovolume.h" #include "llviewerstats.h" +#include "llworld.h" +#include "llviewerobjectlist.h" // For avatar texture view #include "llvoavatarself.h" @@ -505,23 +507,26 @@ private: void LLGLTexMemBar::draw() { - S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes); - S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes); - S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes; + LLUnit<LLUnits::Megabytes, S32> bound_mem = LLViewerTexture::sBoundTextureMemory; + LLUnit<LLUnits::Megabytes, S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem; + LLUnit<LLUnits::Megabytes, S32> total_mem = LLViewerTexture::sTotalTextureMemory; + LLUnit<LLUnits::Megabytes, S32> max_total_mem = LLViewerTexture::sMaxTotalTextureMem; F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; - F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ; - F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ; + F32 cache_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getUsage()).value() ; + F32 cache_max_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ; S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); - F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); - F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); - U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests(); + LLUnit<LLUnits::Bytes, F32> total_texture_downloaded = gTotalTextureData; + LLUnit<LLUnits::Bytes, F32> total_object_downloaded = gTotalObjectData; + U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; + U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects(); + U32 total_objects = gObjectList.getNumObjects(); + //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); LLColor4 color; - + // Gray background using completely magic numbers gGL.color4f(0.f, 0.f, 0.f, 0.25f); // const LLRect & rect(getRect()); @@ -532,10 +537,10 @@ void LLGLTexMemBar::draw() text_color, LLFontGL::LEFT, LLFontGL::TOP); text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", - total_mem, - max_total_mem, - bound_mem, - max_bound_mem, + total_mem.value(), + max_total_mem.value(), + bound_mem.value(), + max_bound_mem.value(), LLRenderTarget::sBytesAllocated/(1024*1024), LLImageRaw::sGlobalRawMemory >> 20, discard_bias, @@ -549,9 +554,11 @@ void LLGLTexMemBar::draw() U32 cache_read(0U), cache_write(0U), res_wait(0U); LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait); - text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u", - total_texture_downloaded, - total_object_downloaded, + text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB #Objs/#Cached: %d/%d Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u", + total_texture_downloaded.value(), + total_object_downloaded.value(), + total_objects, + total_active_cached_objects, total_http_requests, cache_read, cache_write, @@ -679,7 +686,7 @@ void LLGLTexSizeBar::draw() if(LLImageGL::sCurTexSizeBar == mIndex) { - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; + LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); std::string text; text = llformat("%d", mTopLoaded) ; @@ -691,8 +698,8 @@ void LLGLTexSizeBar::draw() text_color, LLFontGL::LEFT, LLFontGL::TOP); } - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; + LLColor4 loaded_color(1.0f, 0.0f, 0.0f, 0.75f); + LLColor4 bound_color(1.0f, 1.0f, 0.0f, 0.75f); gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ; gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ; } diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index a29f58b319..548cb7da7b 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -519,7 +519,7 @@ void LLToolBarView::draw() { if (mToolbars[i]) { - LLLayoutStack::ELayoutOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType()); + LLView::EOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType()); if (orientation == LLLayoutStack::HORIZONTAL) { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index c69999981c..90ae0b428b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1062,7 +1062,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, return; } LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); + add(LLStatViewer::EDIT_TEXTURE, 1); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) { @@ -1130,7 +1130,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, } // update viewer side image in anticipation of update from simulator LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); + add(LLStatViewer::EDIT_TEXTURE, 1); hit_obj->setTEImage(hit_face, image); dialog_refresh_all(); @@ -1354,7 +1354,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT); + add(LLStatViewer::OBJECT_REZ, 1); } void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 93ba3b2558..c026ddd42e 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -433,7 +433,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT); + add(LLStatViewer::OBJECT_CREATE, 1); return TRUE; } diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 4c59fd0371..8623af52ff 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -31,6 +31,8 @@ #include "stdtypes.h" #include "llvoavatar.h" +#include "llsdparam.h" +#include "llsdutil.h" /* * Classes and utility functions for per-thread and per-region @@ -78,128 +80,261 @@ * */ +namespace LLViewerAssetStatsFF +{ + static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) + { + // For statistical purposes, we divide GETs into several + // populations of asset fetches: + // - textures which are de-prioritized in the asset system + // - wearables (clothing, bodyparts) which directly affect + // user experiences when they log in + // - sounds + // - gestures + // - everything else. + // + llassert_always(50 == LLViewerAssetType::AT_COUNT); + + // Multiple asset definitions are floating around so this requires some + // maintenance and attention. + static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = + { + EVACTextureTempHTTPGet, // (0) AT_TEXTURE + EVACSoundUDPGet, // AT_SOUND + EVACOtherGet, // AT_CALLINGCARD + EVACOtherGet, // AT_LANDMARK + EVACOtherGet, // AT_SCRIPT + EVACWearableUDPGet, // AT_CLOTHING + EVACOtherGet, // AT_OBJECT + EVACOtherGet, // AT_NOTECARD + EVACOtherGet, // AT_CATEGORY + EVACOtherGet, // AT_ROOT_CATEGORY + EVACOtherGet, // (10) AT_LSL_TEXT + EVACOtherGet, // AT_LSL_BYTECODE + EVACOtherGet, // AT_TEXTURE_TGA + EVACWearableUDPGet, // AT_BODYPART + EVACOtherGet, // AT_TRASH + EVACOtherGet, // AT_SNAPSHOT_CATEGORY + EVACOtherGet, // AT_LOST_AND_FOUND + EVACSoundUDPGet, // AT_SOUND_WAV + EVACOtherGet, // AT_IMAGE_TGA + EVACOtherGet, // AT_IMAGE_JPEG + EVACGestureUDPGet, // (20) AT_ANIMATION + EVACGestureUDPGet, // AT_GESTURE + EVACOtherGet, // AT_SIMSTATE + EVACOtherGet, // AT_FAVORITE + EVACOtherGet, // AT_LINK + EVACOtherGet, // AT_LINK_FOLDER + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // (30) + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // (40) + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // + EVACOtherGet, // AT_MESH + // (50) + }; -// ------------------------------------------------------ -// Global data definitions -// ------------------------------------------------------ -LLViewerAssetStats * gViewerAssetStatsMain(0); -LLViewerAssetStats * gViewerAssetStatsThread1(0); + if (at < 0 || at >= LLViewerAssetType::AT_COUNT) + { + return EVACOtherGet; + } + EViewerAssetCategories ret(asset_to_bin_map[at]); + if (EVACTextureTempHTTPGet == ret) + { + // Indexed with [is_temp][with_http] + static const EViewerAssetCategories texture_bin_map[2][2] = + { + { + EVACTextureNonTempUDPGet, + EVACTextureNonTempHTTPGet, + }, + { + EVACTextureTempUDPGet, + EVACTextureTempHTTPGet, + } + }; + ret = texture_bin_map[is_temp][with_http]; + } + return ret; + } + + static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP ("enqueuedassetrequeststemptexturehttp", + "Number of temporary texture asset http requests enqueued"), + sEnqueueAssetRequestsTempTextureUDP ("enqueuedassetrequeststemptextureudp", + "Number of temporary texture asset udp requests enqueued"), + sEnqueueAssetRequestsNonTempTextureHTTP("enqueuedassetrequestsnontemptexturehttp", + "Number of texture asset http requests enqueued"), + sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp", + "Number of texture asset udp requests enqueued"), + sEnqueuedAssetRequestsWearableUdp ("enqueuedassetrequestswearableudp", + "Number of wearable asset requests enqueued"), + sEnqueuedAssetRequestsSoundUdp ("enqueuedassetrequestssoundudp", + "Number of sound asset requests enqueued"), + sEnqueuedAssetRequestsGestureUdp ("enqueuedassetrequestsgestureudp", + "Number of gesture asset requests enqueued"), + sEnqueuedAssetRequestsOther ("enqueuedassetrequestsother", + "Number of other asset requests enqueued"); + + static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = { + &sEnqueueAssetRequestsTempTextureHTTP, + &sEnqueueAssetRequestsTempTextureUDP, + &sEnqueueAssetRequestsNonTempTextureHTTP, + &sEnqueueAssetRequestsNonTempTextureUDP, + &sEnqueuedAssetRequestsWearableUdp, + &sEnqueuedAssetRequestsSoundUdp, + &sEnqueuedAssetRequestsGestureUdp, + &sEnqueuedAssetRequestsOther + }; + + static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP ("dequeuedassetrequeststemptexturehttp", + "Number of temporary texture asset http requests dequeued"), + sDequeueAssetRequestsTempTextureUDP ("dequeuedassetrequeststemptextureudp", + "Number of temporary texture asset udp requests dequeued"), + sDequeueAssetRequestsNonTempTextureHTTP("dequeuedassetrequestsnontemptexturehttp", + "Number of texture asset http requests dequeued"), + sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp", + "Number of texture asset udp requests dequeued"), + sDequeuedAssetRequestsWearableUdp ("dequeuedassetrequestswearableudp", + "Number of wearable asset requests dequeued"), + sDequeuedAssetRequestsSoundUdp ("dequeuedassetrequestssoundudp", + "Number of sound asset requests dequeued"), + sDequeuedAssetRequestsGestureUdp ("dequeuedassetrequestsgestureudp", + "Number of gesture asset requests dequeued"), + sDequeuedAssetRequestsOther ("dequeuedassetrequestsother", + "Number of other asset requests dequeued"); + + static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = { + &sDequeueAssetRequestsTempTextureHTTP, + &sDequeueAssetRequestsTempTextureUDP, + &sDequeueAssetRequestsNonTempTextureHTTP, + &sDequeueAssetRequestsNonTempTextureUDP, + &sDequeuedAssetRequestsWearableUdp, + &sDequeuedAssetRequestsSoundUdp, + &sDequeuedAssetRequestsGestureUdp, + &sDequeuedAssetRequestsOther + }; + + static LLTrace::MeasurementStatHandle<LLTrace::Seconds> sResponseAssetRequestsTempTextureHTTP ("assetresponsetimestemptexturehttp", + "Time spent responding to temporary texture asset http requests"), + sResponseAssetRequestsTempTextureUDP ("assetresponsetimestemptextureudp", + "Time spent responding to temporary texture asset udp requests"), + sResponseAssetRequestsNonTempTextureHTTP("assetresponsetimesnontemptexturehttp", + "Time spent responding to texture asset http requests"), + sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp", + "Time spent responding to texture asset udp requests"), + sResponsedAssetRequestsWearableUdp ("assetresponsetimeswearableudp", + "Time spent responding to wearable asset requests"), + sResponsedAssetRequestsSoundUdp ("assetresponsetimessoundudp", + "Time spent responding to sound asset requests"), + sResponsedAssetRequestsGestureUdp ("assetresponsetimesgestureudp", + "Time spent responding to gesture asset requests"), + sResponsedAssetRequestsOther ("assetresponsetimesother", + "Time spent responding to other asset requests"); + + static LLTrace::MeasurementStatHandle<LLTrace::Seconds>* sResponse[EVACCount] = { + &sResponseAssetRequestsTempTextureHTTP, + &sResponseAssetRequestsTempTextureUDP, + &sResponseAssetRequestsNonTempTextureHTTP, + &sResponseAssetRequestsNonTempTextureUDP, + &sResponsedAssetRequestsWearableUdp, + &sResponsedAssetRequestsSoundUdp, + &sResponsedAssetRequestsGestureUdp, + &sResponsedAssetRequestsOther + }; +} // ------------------------------------------------------ -// Local declarations +// Global data definitions // ------------------------------------------------------ -namespace -{ - -static LLViewerAssetStats::EViewerAssetCategories -asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp); - -} +LLViewerAssetStats * gViewerAssetStats(0); // ------------------------------------------------------ -// LLViewerAssetStats::PerRegionStats struct definition +// LLViewerAssetStats class definition // ------------------------------------------------------ -void -LLViewerAssetStats::PerRegionStats::reset() +LLViewerAssetStats::LLViewerAssetStats() +: mRegionHandle(U64(0)), + mCurRecording(NULL) { - for (int i(0); i < LL_ARRAY_SIZE(mRequests); ++i) - { - mRequests[i].mEnqueued.reset(); - mRequests[i].mDequeued.reset(); - mRequests[i].mResponse.reset(); - } - mFPS.reset(); - - mTotalTime = 0; - mStartTimestamp = LLViewerAssetStatsFF::get_timestamp(); + start(); } -void -LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionStats & src) +LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) +: mRegionHandle(src.mRegionHandle), + mPhaseStats(src.mPhaseStats), + mAvatarRezStates(src.mAvatarRezStates) { - // mRegionHandle, mTotalTime, mStartTimestamp are left alone. - - // mFPS - if (src.mFPS.getCount() && mFPS.getCount()) - { - mFPS.merge(src.mFPS); - } + src.mCurRecording->update(); + mRegionRecordings = src.mRegionRecordings; - // Avatar stats - data all comes from main thread, so leave alone. + mCurRecording = &mRegionRecordings[mRegionHandle]; + mCurRecording->stop(); - // Requests - for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) + // assume this is being passed to another thread, so make sure we have unique copies of recording data + for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end(); + it != end_it; + ++it) { - mRequests[i].mEnqueued.merge(src.mRequests[i].mEnqueued); - mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued); - mRequests[i].mResponse.merge(src.mRequests[i].mResponse); + it->second.makeUnique(); } + LLStopWatchControlsMixin<LLViewerAssetStats>::setPlayState(src.getPlayState()); } - -void -LLViewerAssetStats::PerRegionStats::accumulateTime(duration_t now) +void LLViewerAssetStats::handleStart() { - mTotalTime += (now - mStartTimestamp); - mStartTimestamp = now; + if (mCurRecording) + { + mCurRecording->start(); + } } - -// ------------------------------------------------------ -// LLViewerAssetStats class definition -// ------------------------------------------------------ -LLViewerAssetStats::LLViewerAssetStats() - : mRegionHandle(U64(0)) +void LLViewerAssetStats::handleStop() { - reset(); + if (mCurRecording) + { + mCurRecording->stop(); + } } - -LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) - : mRegionHandle(src.mRegionHandle), - mResetTimestamp(src.mResetTimestamp), - mPhaseStats(src.mPhaseStats), - mAvatarRezStates(src.mAvatarRezStates) +void LLViewerAssetStats::handleReset() { - const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); - for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) - { - mRegionStats[it->first] = new PerRegionStats(*it->second); - } - mCurRegionStats = mRegionStats[mRegionHandle]; + reset(); } -void -LLViewerAssetStats::reset() +void LLViewerAssetStats::reset() { // Empty the map of all region stats - mRegionStats.clear(); + mRegionRecordings.clear(); - // If we have a current stats, reset it, otherwise, as at construction, - // create a new one as we must always have a current stats block. - if (mCurRegionStats) - { - mCurRegionStats->reset(); - } - else + // initialize new recording for current region + if (mRegionHandle) { - mCurRegionStats = new PerRegionStats(mRegionHandle); + mCurRecording = &mRegionRecordings[mRegionHandle]; } - - // And add reference to map - mRegionStats[mRegionHandle] = mCurRegionStats; - - // Start timestamp consistent with per-region collector - mResetTimestamp = mCurRegionStats->mStartTimestamp; } - -void -LLViewerAssetStats::setRegion(region_handle_t region_handle) +void LLViewerAssetStats::setRegion(region_handle_t region_handle) { if (region_handle == mRegionHandle) { @@ -207,445 +342,308 @@ LLViewerAssetStats::setRegion(region_handle_t region_handle) return; } - // Get duration for current set - const duration_t now = LLViewerAssetStatsFF::get_timestamp(); - mCurRegionStats->accumulateTime(now); - - // Prepare new set - PerRegionContainer::iterator new_stats = mRegionStats.find(region_handle); - if (mRegionStats.end() == new_stats) + if (mCurRecording) { - // Haven't seen this region_id before, create a new block and make it current. - mCurRegionStats = new PerRegionStats(region_handle); - mRegionStats[region_handle] = mCurRegionStats; + mCurRecording->pause(); } - else + if (region_handle) { - mCurRegionStats = new_stats->second; + mCurRecording = &mRegionRecordings[region_handle]; + mCurRecording->start(); } - mCurRegionStats->mStartTimestamp = now; + mRegionHandle = region_handle; } - -void -LLViewerAssetStats::recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void LLViewerAssetStats::recordAvatarStats() { - const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - - ++(mCurRegionStats->mRequests[int(eac)].mEnqueued); -} - -void -LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp) -{ - const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - - ++(mCurRegionStats->mRequests[int(eac)].mDequeued); + LLVOAvatar::getNearbyRezzedStats(mAvatarRezStates); + mPhaseStats.clear(); + mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); + mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); } -void -LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration) +void LLViewerAssetStats::updateStats() { - const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - - mCurRegionStats->mRequests[int(eac)].mResponse.record(duration); + if (mCurRecording && mCurRecording->isStarted()) + { + mCurRecording->update(); + } } -void -LLViewerAssetStats::recordFPS(F32 fps) +void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output) { - mCurRegionStats->mFPS.record(fps); -} + using namespace LLViewerAssetStatsFF; + + stats.regions.setProvided(); + + for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end(); + it != end_it; + ++it) + { + RegionStats& r = stats.regions.add(); + LLTrace::Recording& rec = it->second; + if (!compact_output + || rec.getSum(*sEnqueued[EVACTextureTempHTTPGet]) + || rec.getSum(*sDequeued[EVACTextureTempHTTPGet]) + || rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value()) + { + r.get_texture_temp_http .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempHTTPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACTextureTempHTTPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACTextureTempHTTPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACTextureTempHTTPGet]).value()); + } + if (!compact_output + || rec.getSum(*sEnqueued[EVACTextureTempUDPGet]) + || rec.getSum(*sDequeued[EVACTextureTempUDPGet]) + || rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) + { + r.get_texture_temp_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACTextureTempUDPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACTextureTempUDPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACTextureTempUDPGet]).value()); + } + if (!compact_output + || rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet]) + || rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet]) + || rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) + { + r.get_texture_non_temp_http .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACTextureNonTempHTTPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACTextureNonTempHTTPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACTextureNonTempHTTPGet]).value()); + } -void -LLViewerAssetStats::recordAvatarStats() -{ - std::vector<S32> rez_counts; - LLVOAvatar::getNearbyRezzedStats(rez_counts); - mAvatarRezStates = rez_counts; - mPhaseStats.clear(); - mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); - mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); -} + if (!compact_output + || rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet]) + || rec.getSum(*sDequeued[EVACTextureNonTempUDPGet]) + || rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) + { + r.get_texture_non_temp_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACTextureNonTempUDPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACTextureNonTempUDPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACTextureNonTempUDPGet]).value()); + } -LLSD -LLViewerAssetStats::asLLSD(bool compact_output) -{ - // Top-level tags - static const LLSD::String tags[EVACCount] = + if (!compact_output + || rec.getSum(*sEnqueued[EVACWearableUDPGet]) + || rec.getSum(*sDequeued[EVACWearableUDPGet]) + || rec.getSum(*sResponse[EVACWearableUDPGet]).value()) { - LLSD::String("get_texture_temp_http"), - LLSD::String("get_texture_temp_udp"), - LLSD::String("get_texture_non_temp_http"), - LLSD::String("get_texture_non_temp_udp"), - LLSD::String("get_wearable_udp"), - LLSD::String("get_sound_udp"), - LLSD::String("get_gesture_udp"), - LLSD::String("get_other") - }; + r.get_wearable_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACWearableUDPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACWearableUDPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACWearableUDPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACWearableUDPGet]).value()); + } - // Stats Group Sub-tags. - static const LLSD::String enq_tag("enqueued"); - static const LLSD::String deq_tag("dequeued"); - static const LLSD::String rcnt_tag("resp_count"); - static const LLSD::String rmin_tag("resp_min"); - static const LLSD::String rmax_tag("resp_max"); - static const LLSD::String rmean_tag("resp_mean"); - - // MMM Group Sub-tags. - static const LLSD::String cnt_tag("count"); - static const LLSD::String min_tag("min"); - static const LLSD::String max_tag("max"); - static const LLSD::String mean_tag("mean"); - - // Avatar sub-tags - static const LLSD::String avatar_tag("avatar"); - static const LLSD::String avatar_nearby_tag("nearby"); - static const LLSD::String avatar_phase_stats_tag("phase_stats"); - - const duration_t now = LLViewerAssetStatsFF::get_timestamp(); - mCurRegionStats->accumulateTime(now); + if (!compact_output + || rec.getSum(*sEnqueued[EVACSoundUDPGet]) + || rec.getSum(*sDequeued[EVACSoundUDPGet]) + || rec.getSum(*sResponse[EVACSoundUDPGet]).value()) + { + r.get_sound_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACSoundUDPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACSoundUDPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACSoundUDPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACSoundUDPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACSoundUDPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACSoundUDPGet]).value()); + } - LLSD regions = LLSD::emptyArray(); - for (PerRegionContainer::iterator it = mRegionStats.begin(); - mRegionStats.end() != it; - ++it) - { - if (0 == it->first) + if (!compact_output + || rec.getSum(*sEnqueued[EVACGestureUDPGet]) + || rec.getSum(*sDequeued[EVACGestureUDPGet]) + || rec.getSum(*sResponse[EVACGestureUDPGet]).value()) { - // Never emit NULL UUID/handle in results. - continue; + r.get_gesture_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACGestureUDPGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACGestureUDPGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACGestureUDPGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACGestureUDPGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACGestureUDPGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACGestureUDPGet]).value()); } - PerRegionStats & stats = *it->second; - - LLSD reg_stat = LLSD::emptyMap(); - - for (int i = 0; i < LL_ARRAY_SIZE(tags); ++i) + if (!compact_output + || rec.getSum(*sEnqueued[EVACOtherGet]) + || rec.getSum(*sDequeued[EVACOtherGet]) + || rec.getSum(*sResponse[EVACOtherGet]).value()) { - PerRegionStats::prs_group & group(stats.mRequests[i]); - - if ((! compact_output) || - group.mEnqueued.getCount() || - group.mDequeued.getCount() || - group.mResponse.getCount()) - { - LLSD & slot = reg_stat[tags[i]]; - slot = LLSD::emptyMap(); - slot[enq_tag] = LLSD(S32(stats.mRequests[i].mEnqueued.getCount())); - slot[deq_tag] = LLSD(S32(stats.mRequests[i].mDequeued.getCount())); - slot[rcnt_tag] = LLSD(S32(stats.mRequests[i].mResponse.getCount())); - slot[rmin_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMin() * 1.0e-6)); - slot[rmax_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMax() * 1.0e-6)); - slot[rmean_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMean() * 1.0e-6)); - } + r.get_other .enqueued((S32)rec.getSum(*sEnqueued[EVACOtherGet])) + .dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet])) + .resp_count((S32)rec.getSum(*sResponse[EVACOtherGet]).value()) + .resp_min(rec.getMin(*sResponse[EVACOtherGet]).value()) + .resp_max(rec.getMax(*sResponse[EVACOtherGet]).value()) + .resp_mean(rec.getMean(*sResponse[EVACOtherGet]).value()); } - if ((! compact_output) || stats.mFPS.getCount()) + S32 fps = (S32)rec.getSum(LLStatViewer::FPS_SAMPLE); + if (!compact_output || fps != 0) { - LLSD & slot = reg_stat["fps"]; - slot = LLSD::emptyMap(); - slot[cnt_tag] = LLSD(S32(stats.mFPS.getCount())); - slot[min_tag] = LLSD(F64(stats.mFPS.getMin())); - slot[max_tag] = LLSD(F64(stats.mFPS.getMax())); - slot[mean_tag] = LLSD(F64(stats.mFPS.getMean())); + r.fps.count(fps); + r.fps.min(rec.getMin(LLStatViewer::FPS_SAMPLE)); + r.fps.max(rec.getMax(LLStatViewer::FPS_SAMPLE)); + r.fps.mean(rec.getMean(LLStatViewer::FPS_SAMPLE)); } U32 grid_x(0), grid_y(0); grid_from_region_handle(it->first, &grid_x, &grid_y); - reg_stat["grid_x"] = LLSD::Integer(grid_x); - reg_stat["grid_y"] = LLSD::Integer(grid_y); - reg_stat["duration"] = LLSD::Real(stats.mTotalTime * 1.0e-6); - regions.append(reg_stat); + r.grid_x(grid_x); + r.grid_y(grid_y); + r.duration(LLUnit<LLUnits::Microseconds, F64>(rec.getDuration()).value()); } - LLSD ret = LLSD::emptyMap(); - ret["regions"] = regions; - ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); - LLSD avatar_info; - avatar_info[avatar_nearby_tag] = LLSD::emptyArray(); + stats.duration(mCurRecording ? LLUnit<LLUnits::Microseconds, F64>(mCurRecording->getDuration()).value() : 0.0); + stats.avatar.setProvided(true); + for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) { - std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); - avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat]; + stats.avatar.nearby .cloud(mAvatarRezStates[0]) + .gray(mAvatarRezStates[1]) + .textured(mAvatarRezStates[2]); } - avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData(); - avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData(); - ret[avatar_tag] = avatar_info; - - return ret; + + stats.avatar.phase_stats .cloud(mPhaseStats["cloud"].asLLSD()) + .cloud_or_gray(mPhaseStats["cloud-or-gray"].asLLSD()); } -void -LLViewerAssetStats::merge(const LLViewerAssetStats & src) +LLSD LLViewerAssetStats::asLLSD(bool compact_output) { - // mRegionHandle, mCurRegionStats and mResetTimestamp are left untouched. - // Just merge the stats bodies - - const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); - for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) + LLParamSDParser parser; + LLSD sd; + AssetStats stats; + getStats(stats, compact_output); + LLInitParam::predicate_rule_t rule = LLInitParam::default_parse_rules(); + if (!compact_output) { - PerRegionContainer::iterator dst(mRegionStats.find(it->first)); - if (mRegionStats.end() == dst) - { - // Destination is missing data, just make a private copy - mRegionStats[it->first] = new PerRegionStats(*it->second); - } - else - { - dst->second->merge(*it->second); - } + rule.allow(LLInitParam::EMPTY); } + parser.writeSD(sd, stats, rule); + return sd; } - // ------------------------------------------------------ // Global free-function definitions (LLViewerAssetStatsFF namespace) // ------------------------------------------------------ namespace LLViewerAssetStatsFF { - -// -// Target thread is elaborated in the function name. This could -// have been something 'templatey' like specializations iterated -// over a set of constants but with so few, this is clearer I think. -// -// As for the threads themselves... rather than do fine-grained -// locking as we gather statistics, this code creates a collector -// for each thread, allocated and run independently. Logging -// happens at relatively infrequent intervals and at that time -// the data is sent to a single thread to be aggregated into -// a single entity with locks, thread safety and other niceties. -// -// A particularly fussy implementation would distribute the -// per-thread pointers across separate cache lines. But that should -// be beyond current requirements. -// - -// 'main' thread - initial program thread - -void -set_region_main(LLViewerAssetStats::region_handle_t region_handle) +void set_region(LLViewerAssetStats::region_handle_t region_handle) { - if (! gViewerAssetStatsMain) + if (! gViewerAssetStats) return; - gViewerAssetStatsMain->setRegion(region_handle); + gViewerAssetStats->setRegion(region_handle); } -void -record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp) { - if (! gViewerAssetStatsMain) - return; - - gViewerAssetStatsMain->recordGetEnqueued(at, with_http, is_temp); -} - -void -record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp) -{ - if (! gViewerAssetStatsMain) - return; - - gViewerAssetStatsMain->recordGetDequeued(at, with_http, is_temp); -} - -void -record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) -{ - if (! gViewerAssetStatsMain) - return; - - gViewerAssetStatsMain->recordGetServiced(at, with_http, is_temp, duration); -} - -void -record_fps_main(F32 fps) -{ - if (! gViewerAssetStatsMain) - return; - - gViewerAssetStatsMain->recordFPS(fps); -} - -void -record_avatar_stats() -{ - if (! gViewerAssetStatsMain) - return; + const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - gViewerAssetStatsMain->recordAvatarStats(); + add(*sEnqueued[int(eac)], 1); } -// 'thread1' - should be for TextureFetch thread - -void -set_region_thread1(LLViewerAssetStats::region_handle_t region_handle) +void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp) { - if (! gViewerAssetStatsThread1) - return; + const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - gViewerAssetStatsThread1->setRegion(region_handle); + add(*sDequeued[int(eac)], 1); } -void -record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) { - if (! gViewerAssetStatsThread1) - return; + const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - gViewerAssetStatsThread1->recordGetEnqueued(at, with_http, is_temp); + sample(*sResponse[int(eac)], LLTrace::Microseconds(duration)); } -void -record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void record_avatar_stats() { - if (! gViewerAssetStatsThread1) + if (! gViewerAssetStats) return; - gViewerAssetStatsThread1->recordGetDequeued(at, with_http, is_temp); + gViewerAssetStats->recordAvatarStats(); } -void -record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) +void init() { - if (! gViewerAssetStatsThread1) - return; - - gViewerAssetStatsThread1->recordGetServiced(at, with_http, is_temp, duration); -} - - -void -init() -{ - if (! gViewerAssetStatsMain) + if (! gViewerAssetStats) { - gViewerAssetStatsMain = new LLViewerAssetStats(); - } - if (! gViewerAssetStatsThread1) - { - gViewerAssetStatsThread1 = new LLViewerAssetStats(); + gViewerAssetStats = new LLViewerAssetStats(); } } void cleanup() { - delete gViewerAssetStatsMain; - gViewerAssetStatsMain = 0; - - delete gViewerAssetStatsThread1; - gViewerAssetStatsThread1 = 0; + delete gViewerAssetStats; + gViewerAssetStats = 0; } } // namespace LLViewerAssetStatsFF -// ------------------------------------------------------ -// Local function definitions -// ------------------------------------------------------ -namespace +LLViewerAssetStats::AssetRequestType::AssetRequestType() +: enqueued("enqueued"), + dequeued("dequeued"), + resp_count("resp_count"), + resp_min("resp_min"), + resp_max("resp_max"), + resp_mean("resp_mean") +{} + +LLViewerAssetStats::FPSStats::FPSStats() +: count("count"), + min("min"), + max("max"), + mean("mean") +{} + +LLViewerAssetStats::RegionStats::RegionStats() +: get_texture_temp_http("get_texture_temp_http"), + get_texture_temp_udp("get_texture_temp_udp"), + get_texture_non_temp_http("get_texture_non_temp_http"), + get_texture_non_temp_udp("get_texture_non_temp_udp"), + get_wearable_udp("get_wearable_udp"), + get_sound_udp("get_sound_udp"), + get_gesture_udp("get_gesture_udp"), + get_other("get_other"), + fps("fps"), + grid_x("grid_x"), + grid_y("grid_y"), + duration("duration") +{} + +LLViewerAssetStats::AvatarRezState::AvatarRezState() +: cloud("cloud"), + gray("gray"), + textured("textured") +{} + +LLViewerAssetStats::AvatarInfo::AvatarInfo() +: nearby("nearby"), + phase_stats("phase_stats") { -LLViewerAssetStats::EViewerAssetCategories -asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) -{ - // For statistical purposes, we divide GETs into several - // populations of asset fetches: - // - textures which are de-prioritized in the asset system - // - wearables (clothing, bodyparts) which directly affect - // user experiences when they log in - // - sounds - // - gestures - // - everything else. - // - llassert_always(50 == LLViewerAssetType::AT_COUNT); - - // Multiple asset definitions are floating around so this requires some - // maintenance and attention. - static const LLViewerAssetStats::EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = - { - LLViewerAssetStats::EVACTextureTempHTTPGet, // (0) AT_TEXTURE - LLViewerAssetStats::EVACSoundUDPGet, // AT_SOUND - LLViewerAssetStats::EVACOtherGet, // AT_CALLINGCARD - LLViewerAssetStats::EVACOtherGet, // AT_LANDMARK - LLViewerAssetStats::EVACOtherGet, // AT_SCRIPT - LLViewerAssetStats::EVACWearableUDPGet, // AT_CLOTHING - LLViewerAssetStats::EVACOtherGet, // AT_OBJECT - LLViewerAssetStats::EVACOtherGet, // AT_NOTECARD - LLViewerAssetStats::EVACOtherGet, // AT_CATEGORY - LLViewerAssetStats::EVACOtherGet, // AT_ROOT_CATEGORY - LLViewerAssetStats::EVACOtherGet, // (10) AT_LSL_TEXT - LLViewerAssetStats::EVACOtherGet, // AT_LSL_BYTECODE - LLViewerAssetStats::EVACOtherGet, // AT_TEXTURE_TGA - LLViewerAssetStats::EVACWearableUDPGet, // AT_BODYPART - LLViewerAssetStats::EVACOtherGet, // AT_TRASH - LLViewerAssetStats::EVACOtherGet, // AT_SNAPSHOT_CATEGORY - LLViewerAssetStats::EVACOtherGet, // AT_LOST_AND_FOUND - LLViewerAssetStats::EVACSoundUDPGet, // AT_SOUND_WAV - LLViewerAssetStats::EVACOtherGet, // AT_IMAGE_TGA - LLViewerAssetStats::EVACOtherGet, // AT_IMAGE_JPEG - LLViewerAssetStats::EVACGestureUDPGet, // (20) AT_ANIMATION - LLViewerAssetStats::EVACGestureUDPGet, // AT_GESTURE - LLViewerAssetStats::EVACOtherGet, // AT_SIMSTATE - LLViewerAssetStats::EVACOtherGet, // AT_FAVORITE - LLViewerAssetStats::EVACOtherGet, // AT_LINK - LLViewerAssetStats::EVACOtherGet, // AT_LINK_FOLDER - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // (30) - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // (40) - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // AT_MESH - // (50) - }; - - if (at < 0 || at >= LLViewerAssetType::AT_COUNT) - { - return LLViewerAssetStats::EVACOtherGet; - } - LLViewerAssetStats::EViewerAssetCategories ret(asset_to_bin_map[at]); - if (LLViewerAssetStats::EVACTextureTempHTTPGet == ret) - { - // Indexed with [is_temp][with_http] - static const LLViewerAssetStats::EViewerAssetCategories texture_bin_map[2][2] = - { - { - LLViewerAssetStats::EVACTextureNonTempUDPGet, - LLViewerAssetStats::EVACTextureNonTempHTTPGet, - }, - { - LLViewerAssetStats::EVACTextureTempUDPGet, - LLViewerAssetStats::EVACTextureTempHTTPGet, - } - }; - - ret = texture_bin_map[is_temp][with_http]; - } - return ret; } -} // anonymous namespace +LLViewerAssetStats::AssetStats::AssetStats() +: regions("regions"), + duration("duration"), + avatar("avatar"), + session_id("session_id"), + agent_id("agent_id"), + message("message"), + sequence("sequence"), + initial("initial"), + break_("break") +{} diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 8319752230..5b25d791a9 100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -37,6 +37,7 @@ #include "llsimplestat.h" #include "llsd.h" #include "llvoavatar.h" +#include "lltrace.h" /** * @class LLViewerAssetStats @@ -73,23 +74,9 @@ * LLViewerAssetStatsFF is provided for conditional test-and-call * operations. */ -class LLViewerAssetStats +class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats> { public: - enum EViewerAssetCategories - { - EVACTextureTempHTTPGet, //< Texture GETs - temp/baked, HTTP - EVACTextureTempUDPGet, //< Texture GETs - temp/baked, UDP - EVACTextureNonTempHTTPGet, //< Texture GETs - perm, HTTP - EVACTextureNonTempUDPGet, //< Texture GETs - perm, UDP - EVACWearableUDPGet, //< Wearable GETs - EVACSoundUDPGet, //< Sound GETs - EVACGestureUDPGet, //< Gesture GETs - EVACOtherGet, //< Other GETs - - EVACCount // Must be last - }; - /** * Type for duration and other time values in the metrics. Selected * for compatibility with the pre-existing timestamp on the texture @@ -104,64 +91,93 @@ public: */ typedef U64 region_handle_t; - /** - * @brief Collected data for a single region visited by the avatar. - * - * Fairly simple, for each asset bin enumerated above a count - * of enqueue and dequeue operations and simple stats on response - * times for completed requests. - */ - class PerRegionStats : public LLRefCount + struct AssetRequestType : public LLInitParam::Block<AssetRequestType> { - public: - PerRegionStats(const region_handle_t region_handle) - : LLRefCount(), - mRegionHandle(region_handle) - { - reset(); - } - - PerRegionStats(const PerRegionStats & src) - : LLRefCount(), - mRegionHandle(src.mRegionHandle), - mTotalTime(src.mTotalTime), - mStartTimestamp(src.mStartTimestamp), - mFPS(src.mFPS) - { - for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) - { - mRequests[i] = src.mRequests[i]; - } - } - - // Default assignment and destructor are correct. - - void reset(); - - void merge(const PerRegionStats & src); - - // Apply current running time to total and reset start point. - // Return current timestamp as a convenience. - void accumulateTime(duration_t now); - - public: - region_handle_t mRegionHandle; - duration_t mTotalTime; - duration_t mStartTimestamp; - LLSimpleStatMMM<> mFPS; - - struct prs_group - { - LLSimpleStatCounter mEnqueued; - LLSimpleStatCounter mDequeued; - LLSimpleStatMMM<duration_t> mResponse; - } - mRequests [EVACCount]; + Mandatory<S32> enqueued, + dequeued, + resp_count; + Mandatory<F64> resp_min, + resp_max, + resp_mean; + + AssetRequestType(); + }; + + struct FPSStats : public LLInitParam::Block<FPSStats> + { + Mandatory<S32> count; + Mandatory<F64> min, + max, + mean; + FPSStats(); + }; + + struct RegionStats : public LLInitParam::Block<RegionStats> + { + Optional<AssetRequestType> get_texture_temp_http, + get_texture_temp_udp, + get_texture_non_temp_http, + get_texture_non_temp_udp, + get_wearable_udp, + get_sound_udp, + get_gesture_udp, + get_other; + Optional<FPSStats> fps; + Optional<S32> grid_x, + grid_y; + Optional<F64> duration; + + RegionStats(); + }; + + struct AvatarRezState : public LLInitParam::Block<AvatarRezState> + { + Mandatory<S32> cloud, + gray, + textured; + AvatarRezState(); + }; + + struct AvatarPhaseStats : public LLInitParam::Block<AvatarPhaseStats> + { + Mandatory<LLSD> cloud, + cloud_or_gray; + + AvatarPhaseStats() + : cloud("cloud"), + cloud_or_gray("cloud-or-gray") + {} + }; + + struct AvatarInfo : public LLInitParam::Block<AvatarInfo> + { + Optional<AvatarRezState> nearby; + Optional<AvatarPhaseStats> phase_stats; + + AvatarInfo(); + }; + + struct AssetStats : public LLInitParam::Block<AssetStats> + { + Multiple<RegionStats> regions; + Mandatory<F64> duration; + Mandatory<AvatarInfo> avatar; + + Mandatory<LLUUID> session_id, + agent_id; + + Mandatory<std::string> message; + Mandatory<S32> sequence; + Mandatory<bool> initial, + break_; + + AssetStats(); }; public: LLViewerAssetStats(); LLViewerAssetStats(const LLViewerAssetStats &); + // Default destructor is correct. LLViewerAssetStats & operator=(const LLViewerAssetStats &); // Not defined @@ -174,88 +190,35 @@ public: // collection calls. void setRegion(region_handle_t region_handle); - // Asset GET Requests - void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp); - void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp); - void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration); - - // Frames-Per-Second Samples - void recordFPS(F32 fps); - // Avatar-related statistics void recordAvatarStats(); - // Merge a source instance into a destination instance. This is - // conceptually an 'operator+=()' method: - // - counts are added - // - minimums are min'd - // - maximums are max'd - // - other scalars are ignored ('this' wins) - // - void merge(const LLViewerAssetStats & src); - + // gather latest metrics data + // call from main thread + void updateStats(); + // Retrieve current metrics for all visited regions (NULL region UUID/handle excluded) - // Returned LLSD is structured as follows: - // - // &stats_group = { - // enqueued : int, - // dequeued : int, - // resp_count : int, - // resp_min : float, - // resp_max : float, - // resp_mean : float - // } - // - // &mmm_group = { - // count : int, - // min : float, - // max : float, - // mean : float - // } - // - // { - // duration: int - // regions: { - // $: { // Keys are strings of the region's handle in hex - // duration: : int, - // fps: : &mmm_group, - // get_texture_temp_http : &stats_group, - // get_texture_temp_udp : &stats_group, - // get_texture_non_temp_http : &stats_group, - // get_texture_non_temp_udp : &stats_group, - // get_wearable_udp : &stats_group, - // get_sound_udp : &stats_group, - // get_gesture_udp : &stats_group, - // get_other : &stats_group - // } - // } - // } - // - // @param compact_output If true, omits from conversion any mmm_block - // or stats_block that would contain all zero data. - // Useful for transmission when the receiver knows - // what is expected and will assume zero for missing - // blocks. + // Uses AssetStats structure seen above + void getStats(AssetStats& stats, bool compact_output); LLSD asLLSD(bool compact_output); protected: - typedef std::map<region_handle_t, LLPointer<PerRegionStats> > PerRegionContainer; + void handleStart(); + void handleStop(); + void handleReset(); + + typedef std::map<region_handle_t, LLTrace::Recording > PerRegionRecordingContainer; // Region of the currently-active region. Always valid but may // be zero after construction or when explicitly set. Unchanged // by a reset() call. region_handle_t mRegionHandle; - // Pointer to metrics collection for currently-active region. Always - // valid and unchanged after reset() though contents will be changed. - // Always points to a collection contained in mRegionStats. - LLPointer<PerRegionStats> mCurRegionStats; + // Pointer to metrics collection for currently-active region. + LLTrace::Recording* mCurRecording; // Metrics data for all regions during one collection cycle - PerRegionContainer mRegionStats; - - // Time of last reset - duration_t mResetTimestamp; + PerRegionRecordingContainer mRegionRecordings; // Nearby avatar stats std::vector<S32> mAvatarRezStates; @@ -277,12 +240,24 @@ protected: * - Main: main() program execution thread * - Thread1: TextureFetch worker thread */ -extern LLViewerAssetStats * gViewerAssetStatsMain; - -extern LLViewerAssetStats * gViewerAssetStatsThread1; +extern LLViewerAssetStats * gViewerAssetStats; namespace LLViewerAssetStatsFF { + enum EViewerAssetCategories + { + EVACTextureTempHTTPGet, //< Texture GETs - temp/baked, HTTP + EVACTextureTempUDPGet, //< Texture GETs - temp/baked, UDP + EVACTextureNonTempHTTPGet, //< Texture GETs - perm, HTTP + EVACTextureNonTempUDPGet, //< Texture GETs - perm, UDP + EVACWearableUDPGet, //< Wearable GETs + EVACSoundUDPGet, //< Sound GETs + EVACGestureUDPGet, //< Gesture GETs + EVACOtherGet, //< Other GETs + + EVACCount // Must be last + }; + /** * @brief Allocation and deallocation of globals. * @@ -307,31 +282,17 @@ inline LLViewerAssetStats::duration_t get_timestamp() /** * Region context, event and duration loggers for the Main thread. */ -void set_region_main(LLViewerAssetStats::region_handle_t region_handle); +void set_region(LLViewerAssetStats::region_handle_t region_handle); -void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp); +void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp); -void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp); +void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp); -void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, +void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration); -void record_fps_main(F32 fps); - void record_avatar_stats(); -/** - * Region context, event and duration loggers for Thread 1. - */ -void set_region_thread1(LLViewerAssetStats::region_handle_t region_handle); - -void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp); - -void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp); - -void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, - LLViewerAssetStats::duration_t duration); - } // namespace LLViewerAssetStatsFF #endif // LL_LLVIEWERASSETSTATUS_H diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index d042f62830..6f41abbd8a 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -73,8 +73,8 @@ protected: { // Okay, it appears this request was used for useful things. Record // the expected dequeue and duration of request processing. - LLViewerAssetStatsFF::record_dequeue_main(mType, false, false); - LLViewerAssetStatsFF::record_response_main(mType, false, false, + LLViewerAssetStatsFF::record_dequeue(mType, false, false); + LLViewerAssetStatsFF::record_response(mType, false, false, (LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime)); mMetricsStartTime = 0; @@ -373,7 +373,7 @@ void LLViewerAssetStorage::_queueDataRequest( LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f)); - LLViewerAssetStatsFF::record_enqueue_main(atype, false, false); + LLViewerAssetStatsFF::record_enqueue(atype, false, false); } } else diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index a437a8b3b5..9ca5f07f35 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -49,10 +49,14 @@ #include "llglheaders.h" #include "llquaternion.h" #include "llwindow.h" // getPixelAspectRatio() +#include "lltracerecording.h" // System includes #include <iomanip> // for setprecision +LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity"); +LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); + U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; //glu pick matrix implementation borrowed from Mesa3D @@ -163,11 +167,11 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, F32 drot; rotation.getAngleAxis(&drot, &x, &y, &z); - mVelocityStat.addValue(dpos); - mAngularVelocityStat.addValue(drot); + add(sVelocityStat, dpos); + add(sAngularVelocityStat, drot); - mAverageSpeed = mVelocityStat.getMeanPerSec() ; - mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ; + mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat); + mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat); mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); // update pixel meter ratio using default fov, not modified one diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index b857c7fe89..ffec284f72 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -29,10 +29,10 @@ #include "llcamera.h" #include "llsingleton.h" -#include "llstat.h" #include "lltimer.h" #include "m4math.h" #include "llcoord.h" +#include "lltrace.h" class LLViewerObject; @@ -101,8 +101,8 @@ public: BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const; const LLVector3* getVelocityDir() const {return &mVelocityDir;} - LLStat *getVelocityStat() { return &mVelocityStat; } - LLStat *getAngularVelocityStat() { return &mAngularVelocityStat; } + static LLTrace::CountStatHandle<>* getVelocityStat() {return &sVelocityStat; } + static LLTrace::CountStatHandle<>* getAngularVelocityStat() {return &sAngularVelocityStat; } F32 getCosHalfFov() {return mCosHalfCameraFOV;} F32 getAverageSpeed() {return mAverageSpeed ;} F32 getAverageAngularSpeed() {return mAverageAngularSpeed;} @@ -117,9 +117,9 @@ public: F32 getDefaultFOV() { return mCameraFOVDefault; } BOOL cameraUnderWater() const; + BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts); const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; } - BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts); F32 getPixelMeterRatio() const { return mPixelMeterRatio; } S32 getScreenPixelArea() const { return mScreenPixelArea; } @@ -130,12 +130,12 @@ public: protected: void calcProjection(const F32 far_distance) const; - LLStat mVelocityStat; - LLStat mAngularVelocityStat; + static LLTrace::CountStatHandle<> sVelocityStat; + static LLTrace::CountStatHandle<> sAngularVelocityStat; + LLVector3 mVelocityDir ; F32 mAverageSpeed ; F32 mAverageAngularSpeed ; - mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix mutable LLMatrix4 mModelviewMatrix; F32 mCameraFOVDefault; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ffeea2f4df..0889c3ec6c 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -77,6 +77,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" +#include "llscenemonitor.h" extern LLPointer<LLViewerTexture> gStartTexture; extern bool gShiftFrame; @@ -607,7 +608,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM); - const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time + const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.processPartitionQ(); gPipeline.updateGeom(max_geom_update_time); @@ -748,8 +749,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_IMAGE_UPDATE_CLASS); - LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), - LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); + LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); + LLTrace::CountStatHandle<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat(); + LLViewerTexture::updateClass(LLTrace::get_frame_recording().getPeriodMeanPerSec(*velocity_stat), + LLTrace::get_frame_recording().getPeriodMeanPerSec(*angular_velocity_stat)); } @@ -760,7 +763,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_IMAGE_UPDATE_LIST); - F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time + F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame) gTextureList.updateImages(max_image_decode_time); } @@ -989,6 +992,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLPipeline::sUnderWaterRender = FALSE; + { + //capture the frame buffer. + LLSceneMonitor::getInstance()->capture(); + } + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); if (!for_snapshot) { @@ -1033,7 +1041,7 @@ void render_hud_attachments() // clamp target zoom level to reasonable values gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f); // smoothly interpolate current zoom level - gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); + gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLSmoothInterpolation::getInterpolant(0.03f)); if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices()) { @@ -1222,6 +1230,15 @@ void render_ui(F32 zoom_factor, int subfield) glh_set_current_modelview(glh_copy_matrix(gGLLastModelView)); } + if(LLSceneMonitor::getInstance()->needsUpdate()) + { + gGL.pushMatrix(); + gViewerWindow->setup2DRender(); + LLSceneMonitor::getInstance()->compare(); + gViewerWindow->setup3DRender(); + gGL.popMatrix(); + } + { BOOL to_texture = gPipeline.canUseVertexShaders() && LLPipeline::sRenderGlow; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 1f7cf0cdd4..792c55441d 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -28,64 +28,62 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterreg.h" - #include "llviewerfloaterreg.h" -#include "llfloaterautoreplacesettings.h" -#include "llcompilequeue.h" + #include "llcallfloater.h" +#include "llcommandhandler.h" +#include "llcompilequeue.h" #include "llfasttimerview.h" #include "llfloaterabout.h" #include "llfloaterauction.h" +#include "llfloaterautoreplacesettings.h" #include "llfloateravatar.h" #include "llfloateravatarpicker.h" #include "llfloateravatartextures.h" #include "llfloaterbeacons.h" #include "llfloaterbuildoptions.h" +#include "llfloaterbulkpermission.h" +#include "llfloaterbump.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" #include "llfloaterbuycurrencyhtml.h" #include "llfloaterbuyland.h" -#include "llfloaterbulkpermission.h" -#include "llfloaterbump.h" #include "llfloaterbvhpreview.h" #include "llfloatercamera.h" #include "llfloaterdeleteenvpreset.h" +#include "llfloaterdestinations.h" #include "llfloaterdisplayname.h" #include "llfloatereditdaycycle.h" #include "llfloatereditsky.h" #include "llfloatereditwater.h" #include "llfloaterenvironmentsettings.h" #include "llfloaterevent.h" -#include "llfloaterdestinations.h" #include "llfloaterfonttest.h" #include "llfloatergesture.h" #include "llfloatergodtools.h" #include "llfloatergroups.h" #include "llfloaterhardwaresettings.h" #include "llfloaterhelpbrowser.h" -#include "llfloaterwebcontent.h" -#include "llfloaterwebprofile.h" -#include "llfloatermediasettings.h" #include "llfloaterhud.h" #include "llfloaterimagepreview.h" -#include "llimfloater.h" #include "llfloaterinspect.h" #include "llfloaterinventory.h" #include "llfloaterjoystick.h" -#include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterlandholdings.h" #include "llfloatermap.h" +#include "llfloatermediasettings.h" #include "llfloatermemleak.h" +#include "llfloatermodelpreview.h" #include "llfloaternamedesc.h" #include "llfloaternotificationsconsole.h" #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" #include "llfloateroutbox.h" #include "llfloaterpathfindingcharacters.h" -#include "llfloaterpathfindinglinksets.h" #include "llfloaterpathfindingconsole.h" +#include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" #include "llfloaterperms.h" #include "llfloaterpostprocess.h" @@ -94,6 +92,7 @@ #include "llfloaterregiondebugconsole.h" #include "llfloaterregioninfo.h" #include "llfloaterreporter.h" +#include "llfloatersceneloadstats.h" #include "llfloaterscriptdebug.h" #include "llfloaterscriptlimits.h" #include "llfloatersearch.h" @@ -108,15 +107,18 @@ #include "llfloatertestlistview.h" #include "llfloatertexturefetchdebugger.h" #include "llfloatertools.h" -#include "llfloatertos.h" #include "llfloatertopobjects.h" +#include "llfloatertos.h" #include "llfloatertoybox.h" #include "llfloatertranslationsettings.h" #include "llfloateruipreview.h" #include "llfloatervoiceeffect.h" +#include "llfloaterwebcontent.h" +#include "llfloaterwebprofile.h" #include "llfloaterwhitelistentry.h" #include "llfloaterwindowsize.h" #include "llfloaterworldmap.h" +#include "llimfloater.h" #include "llimfloatercontainer.h" #include "llinspectavatar.h" #include "llinspectgroup.h" @@ -125,6 +127,7 @@ #include "llinspecttoast.h" #include "llmoveview.h" #include "llnearbychat.h" +#include "llnearbychatbar.h" #include "llpanelblockedlist.h" #include "llpanelclassified.h" #include "llpreviewanim.h" @@ -133,11 +136,8 @@ #include "llpreviewscript.h" #include "llpreviewsound.h" #include "llpreviewtexture.h" -#include "llsyswellwindow.h" #include "llscriptfloater.h" -#include "llfloatermodelpreview.h" -#include "llcommandhandler.h" -#include "llnearbychatbar.h" +#include "llsyswellwindow.h" // *NOTE: Please add files in alphabetical order to keep merges easy. @@ -227,7 +227,6 @@ void LLViewerFloaterReg::registerFloaters() LLNotificationsUI::registerFloater(); LLFloaterDisplayNameUtil::registerFloater(); - LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>); LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>); LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); @@ -300,6 +299,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>); LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>); + LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>); LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index f6e840adcd..f4155df4d1 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -501,7 +501,7 @@ void LLViewerJoystick::moveObjects(bool reset) }; F32 cur_delta[6]; - F32 time = gFrameIntervalSeconds; + F32 time = gFrameIntervalSeconds.value(); // avoid making ridicously big movements if there's a big drop in fps if (time > .2f) @@ -665,7 +665,7 @@ void LLViewerJoystick::moveAvatar(bool reset) }; // time interval in seconds between this frame and the previous - F32 time = gFrameIntervalSeconds; + F32 time = gFrameIntervalSeconds.value(); // avoid making ridicously big movements if there's a big drop in fps if (time > .2f) @@ -878,7 +878,7 @@ void LLViewerJoystick::moveFlycam(bool reset) gSavedSettings.getF32("FlycamAxisDeadZone6") }; - F32 time = gFrameIntervalSeconds; + F32 time = gFrameIntervalSeconds.value(); // avoid making ridiculously big movements if there's a big drop in fps if (time > .2f) diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 1aa9fd8a45..f5d3341c66 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -160,6 +160,11 @@ void agent_push_backward( EKeystate s ) camera_move_backward(s); return; } + else if (gAgentAvatarp->isSitting()) + { + gAgentCamera.changeCameraToThirdPerson(); + return; + } agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 93e4f4428a..25907dcb52 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -122,6 +122,7 @@ #include "llwindow.h" #include "llpathfindingmanager.h" #include "boost/unordered_map.hpp" +#include "llscenemonitor.h" using namespace LLVOAvatarDefines; @@ -527,7 +528,10 @@ class LLAdvancedToggleConsole : public view_listener_t { toggle_visibility( (void*)gSceneView); } - + else if ("scene monitor" == console_type) + { + toggle_visibility( (void*)gSceneMonitorView); + } #if MEM_TRACK_MEM else if ("memory view" == console_type) { @@ -555,9 +559,9 @@ class LLAdvancedCheckConsole : public view_listener_t { new_value = LLFloaterReg::instanceVisible("fast_timers"); } - else if ("scene view" == console_type) + else if ("scene monitor" == console_type) { - new_value = get_visibility( (void*) gSceneView); + new_value = get_visibility( (void*) gSceneMonitorView); } #if MEM_TRACK_MEM else if ("memory view" == console_type) @@ -3959,24 +3963,24 @@ class LLViewToggleUI : public view_listener_t { if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) { - LLNotification::Params params("ConfirmHideUI"); - params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); - LLSD substitutions; + LLNotification::Params params("ConfirmHideUI"); + params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); + LLSD substitutions; #if LL_DARWIN - substitutions["SHORTCUT"] = "Cmd+Shift+U"; + substitutions["SHORTCUT"] = "Cmd+Shift+U"; #else - substitutions["SHORTCUT"] = "Ctrl+Shift+U"; + substitutions["SHORTCUT"] = "Ctrl+Shift+U"; #endif - params.substitutions = substitutions; + params.substitutions = substitutions; if (!gSavedSettings.getBOOL("HideUIControls")) - { - // hiding, so show notification - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } + { + // hiding, so show notification + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } } return true; } @@ -4023,72 +4027,6 @@ void handle_duplicate_in_place(void*) LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE); } -/* dead code 30-apr-2008 -void handle_deed_object_to_group(void*) -{ - LLUUID group_id; - - LLSelectMgr::getInstance()->selectGetGroup(group_id); - LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); -} - -BOOL enable_deed_object_to_group(void*) -{ - if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) return FALSE; - LLPermissions perm; - LLUUID group_id; - - if (LLSelectMgr::getInstance()->selectGetGroup(group_id) && - gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && - LLSelectMgr::getInstance()->selectGetPermissions(perm) && - perm.deedToGroup(gAgent.getID(), group_id)) - { - return TRUE; - } - return FALSE; -} - -*/ - - -/* - * No longer able to support viewer side manipulations in this way - * -void god_force_inv_owner_permissive(LLViewerObject* object, - LLInventoryObject::object_list_t* inventory, - S32 serial_num, - void*) -{ - typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t; - item_array_t items; - - LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin(); - LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end(); - for ( ; inv_it != inv_end; ++inv_it) - { - if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)) - { - LLInventoryObject* obj = *inv_it; - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj); - LLPermissions perm(new_item->getPermissions()); - perm.setMaskBase(PERM_ALL); - perm.setMaskOwner(PERM_ALL); - new_item->setPermissions(perm); - items.push_back(new_item); - } - } - item_array_t::iterator end = items.end(); - item_array_t::iterator it; - for(it = items.begin(); it != end; ++it) - { - // since we have the inventory item in the callback, it should not - // invalidate iteration through the selection manager. - object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false); - } -} -*/ - void handle_object_owner_permissive(void*) { // only send this if they're a god. @@ -7387,7 +7325,7 @@ void handle_dump_avatar_local_textures(void*) void handle_dump_timers() { - LLFastTimer::dumpCurTimes(); + LLTrace::TimeBlock::dumpCurTimes(); } void handle_debug_avatar_textures(void*) diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index be78603e2d..b7282a8493 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1096,17 +1096,17 @@ void upload_new_resource( if( LLAssetType::AT_SOUND == asset_type ) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT ); + add(LLStatViewer::UPLOAD_SOUND, 1); } else if( LLAssetType::AT_TEXTURE == asset_type ) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); + add(LLStatViewer::UPLOAD_TEXTURE, 1); } else if( LLAssetType::AT_ANIMATION == asset_type) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT ); + add(LLStatViewer::ANIMATION_UPLOADS, 1); } if(LLInventoryType::IT_NONE == inv_type) @@ -1231,18 +1231,15 @@ void increase_new_upload_stats(LLAssetType::EType asset_type) { if ( LLAssetType::AT_SOUND == asset_type ) { - LLViewerStats::getInstance()->incStat( - LLViewerStats::ST_UPLOAD_SOUND_COUNT ); + add(LLStatViewer::UPLOAD_SOUND, 1); } else if ( LLAssetType::AT_TEXTURE == asset_type ) { - LLViewerStats::getInstance()->incStat( - LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); + add(LLStatViewer::UPLOAD_TEXTURE, 1); } else if ( LLAssetType::AT_ANIMATION == asset_type ) { - LLViewerStats::getInstance()->incStat( - LLViewerStats::ST_UPLOAD_ANIM_COUNT ); + add(LLStatViewer::ANIMATION_UPLOADS, 1); } } diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 3136358b83..6bba375f50 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -31,6 +31,7 @@ #include "llassetstorage.h" #include "llinventorytype.h" #include "llfilepicker.h" +#include <queue> class LLTransactionID; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a897eec551..4b1c9c5574 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2587,7 +2587,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLSD args; args["SUBJECT"] = subj; args["MESSAGE"] = mes; - LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp)); + LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(LLDate(timestamp))); } // Also send down the old path for now. @@ -3007,11 +3007,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - LLNotification::Params params("TeleportOffered"); - params.substitutions = args; - params.payload = payload; - LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); - } + LLNotification::Params params("TeleportOffered"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } } } @@ -3102,10 +3102,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - // do not show a message box, because you're about to be - // teleported. - LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); - } + // do not show a message box, because you're about to be + // teleported. + LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); + } } break; @@ -4065,7 +4065,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) { LLTracker::stopTracking(NULL); } - else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() ) + else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() && look_at.isExactlyZero()) { //look at the beacon LLVector3 global_agent_pos = agent_pos; @@ -4276,7 +4276,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) msg_number += 1; if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) { - //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; + //LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL; LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL; } if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) @@ -4295,7 +4295,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) { LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL; } -*/ + */ duplicate_count = 0; } @@ -4416,18 +4416,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) // *TODO: Remove this dependency, or figure out a better way to handle // this hack. -extern U32 gObjectBits; +extern LLUnit<LLUnits::Bits, U32> gObjectData; void process_object_update(LLMessageSystem *mesgsys, void **user_data) { // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize(); } // Update the object... @@ -4439,11 +4439,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize(); } // Update the object... @@ -4455,11 +4455,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize(); } // Update the object... @@ -4471,11 +4471,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ { if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize(); } gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); @@ -4483,30 +4483,42 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects"); +const U32 KILLOBJECT_DELETE_OPCODE = 0; + void process_kill_object(LLMessageSystem *mesgsys, void **user_data) { LLFastTimer t(FTM_PROCESS_OBJECTS); LLUUID id; - U32 local_id; - S32 i; - S32 num_objects; - num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); + U32 ip = mesgsys->getSenderIP(); + U32 port = mesgsys->getSenderPort(); + LLViewerRegion* regionp = NULL; + { + LLHost host(ip, port); + regionp = LLWorld::getInstance()->getRegion(host); + } - for (i = 0; i < num_objects; i++) + bool delete_object = false; + S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); + for (S32 i = 0; i < num_objects; ++i) { + U32 local_id; mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); + if (local_id == KILLOBJECT_DELETE_OPCODE) + { + // This local_id is invalid, but was sent by the server to flag + // all subsequent local_id's as objects that were actually deleted + // rather than unsubscribed from interestlist. + delete_object = true; + continue; + } - LLViewerObjectList::getUUIDFromLocal(id, - local_id, - gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); + LLViewerObjectList::getUUIDFromLocal(id, local_id, ip, port); if (id == LLUUID::null) { LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL; - gObjectList.mNumUnknownKills++; continue; } else @@ -4514,9 +4526,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL; } - // ...don't kill the avatar - if (!(id == gAgentID)) + if (id == gAgentID) { + // never kill our avatar + continue; + } + LLViewerObject *objectp = gObjectList.findObject(id); if (objectp) { @@ -4530,18 +4545,16 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) // Do the kill gObjectList.killObject(objectp); } - else + + if(delete_object) { - LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL; - gObjectList.mNumUnknownKills++; - } + regionp->killCacheEntry(local_id); } // We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab, // which is using the object, release the mouse capture correctly when the object dies. // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical(). LLSelectMgr::getInstance()->removeObjectFromSelections(id); - } } @@ -4753,145 +4766,18 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) F32 stat_value; msg->getU32("Stat", "StatID", stat_id, i); msg->getF32("Stat", "StatValue", stat_value, i); - switch (stat_id) + LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id); + + if (measurementp ) { - case LL_SIM_STAT_TIME_DILATION: - LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value); - break; - case LL_SIM_STAT_FPS: - LLViewerStats::getInstance()->mSimFPS.addValue(stat_value); - break; - case LL_SIM_STAT_PHYSFPS: - LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value); - break; - case LL_SIM_STAT_AGENTUPS: - LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value); - break; - case LL_SIM_STAT_FRAMEMS: - LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value); - break; - case LL_SIM_STAT_NETMS: - LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SIMOTHERMS: - LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SIMPHYSICSMS: - LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value); - break; - case LL_SIM_STAT_AGENTMS: - LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value); - break; - case LL_SIM_STAT_IMAGESMS: - LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SCRIPTMS: - LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value); - break; - case LL_SIM_STAT_NUMTASKS: - LLViewerStats::getInstance()->mSimObjects.addValue(stat_value); - break; - case LL_SIM_STAT_NUMTASKSACTIVE: - LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value); - break; - case LL_SIM_STAT_NUMAGENTMAIN: - LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value); - break; - case LL_SIM_STAT_NUMAGENTCHILD: - LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value); - break; - case LL_SIM_STAT_NUMSCRIPTSACTIVE: - LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value); - break; - case LL_SIM_STAT_SCRIPT_EPS: - LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value); - break; - case LL_SIM_STAT_INPPS: - LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value); - break; - case LL_SIM_STAT_OUTPPS: - LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value); - break; - case LL_SIM_STAT_PENDING_DOWNLOADS: - LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value); - break; - case LL_SIM_STAT_PENDING_UPLOADS: - LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value); - break; - case LL_SIM_STAT_PENDING_LOCAL_UPLOADS: - LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value); - break; - case LL_SIM_STAT_TOTAL_UNACKED_BYTES: - LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f); - break; - case LL_SIM_STAT_PHYSICS_PINNED_TASKS: - LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value); - break; - case LL_SIM_STAT_PHYSICS_LOD_TASKS: - LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value); - break; - case LL_SIM_STAT_SIMPHYSICSSTEPMS: - LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SIMPHYSICSSHAPEMS: - LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SIMPHYSICSOTHERMS: - LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SIMPHYSICSMEMORY: - LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value); - break; - case LL_SIM_STAT_SIMSPARETIME: - LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SIMSLEEPTIME: - LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value); - break; - case LL_SIM_STAT_IOPUMPTIME: - LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value); - break; - case LL_SIM_STAT_PCTSCRIPTSRUN: - LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value); - break; - case LL_SIM_STAT_SIMAISTEPTIMEMS: - LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value); - break; - case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS: - LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value); - break; - case LL_SIM_STAT_PCTSTEPPEDCHARACTERS: - LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value); - break; - default: - // Used to be a commented out warning. - LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL; - break; + measurementp->sample(stat_value); + } + else + { + llwarns << "Unknown sim stat identifier: " << stat_id << llendl; } } - /* - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation); - LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation); - - // Process information - // { CpuUsage F32 } - // { SimMemTotal F32 } - // { SimMemRSS F32 } - // { ProcessUptime F32 } - F32 cpu_usage; - F32 sim_mem_total; - F32 sim_mem_rss; - F32 process_uptime; - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage); - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total); - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss); - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime); - LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage); - LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total); - LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss); - */ - // // Various hacks that aren't statistics, but are being handled here. // @@ -5625,14 +5511,14 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - + if (0 == option) { // set the preference to the maturity of the region we're calling U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger()); gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity)); } - + return false; } @@ -5695,7 +5581,7 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) gAgent.clearTeleportRequest(); maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); returnValue = true; - + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG() || gAgent.prefersMature()) @@ -5792,7 +5678,7 @@ bool handle_teleport_access_blocked(LLSD& llsdBlock) maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); returnValue = true; } - } + } if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) { @@ -5938,7 +5824,7 @@ void process_alert_core(const std::string& message, BOOL modal) // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml if ( message == "You died and have been teleported to your home location") { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT); + add(LLStatViewer::KILLED, 1); } else if( message == "Home position set." ) { @@ -5958,8 +5844,8 @@ void process_alert_core(const std::string& message, BOOL modal) std::string alert_name(message.substr(ALERT_PREFIX.length())); if (!handle_special_alerts(alert_name)) { - LLNotificationsUtil::add(alert_name); - } + LLNotificationsUtil::add(alert_name); + } } else if (message.find(NOTIFY_PREFIX) == 0) { @@ -7365,8 +7251,6 @@ void onCovenantLoadComplete(LLVFS *vfs, } else { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b1a60197a2..61c5a52f98 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -100,6 +100,7 @@ #include "lltrans.h" #include "llsdutil.h" #include "llmediaentry.h" +#include "llvocache.h" //#define DEBUG_UPDATE_TYPE @@ -112,6 +113,9 @@ BOOL LLViewerObject::sMapDebug = TRUE; LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit S32 LLViewerObject::sAxisArrowLength(50); +LLTrace::MemStatHandle LLViewerObject::sMemStat("LLViewerObject"); + + BOOL LLViewerObject::sPulseEnabled(FALSE); BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE @@ -323,6 +327,22 @@ void LLViewerObject::deleteTEImages() mTEImages = NULL; } +//if enabled, add this object to vo cache tree when removed from rendering. +void LLViewerObject::EnableToCacheTree(bool enabled) +{ + if(mDrawable.notNull() && mDrawable->getEntry() && mDrawable->getEntry()->hasVOCacheEntry()) + { + if(enabled) + { + ((LLVOCacheEntry*)mDrawable->getEntry()->getVOCacheEntry())->addState(LLVOCacheEntry::ADD_TO_CACHE_TREE); + } + else + { + ((LLVOCacheEntry*)mDrawable->getEntry()->getVOCacheEntry())->clearState(LLVOCacheEntry::ADD_TO_CACHE_TREE); + } + } +} + void LLViewerObject::markDead() { if (!mDead) @@ -886,10 +906,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } // Coordinates of objects on simulators are region-local. - U64 region_handle; - mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + U64 region_handle = 0; + if(mesgsys != NULL) { + mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if(regionp != mRegionp && regionp && mRegionp)//region cross { @@ -915,11 +936,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } + if(mesgsys != NULL) + { U16 time_dilation16; mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16); F32 time_dilation = ((F32) time_dilation16) / 65535.f; mTimeDilation = time_dilation; mRegionp->setTimeDilation(time_dilation); + } // this will be used to determine if we've really changed position // Use getPosition, not getPositionRegion, since this is what we're comparing directly against. @@ -1692,6 +1716,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // Preload these five flags for every object. // Finer shades require the object to be selected, and the selection manager // stores the extended permission info. + if(mesgsys != NULL) + { U32 flags; mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); // keep local flags and overwrite remote-controlled flags @@ -1700,6 +1726,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // ...new objects that should come in selected need to be added to the selected list mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); } + } break; default: @@ -1726,10 +1753,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, { // No parent now, new parent in message -> attach to that parent if possible LLUUID parent_uuid; + + if(mesgsys != NULL) + { LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort()); + } + else + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mRegionp->getHost().getAddress(), + mRegionp->getHost().getPort()); + } LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid); @@ -1805,9 +1843,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // //parent_id - U32 ip = mesgsys->getSenderIP(); - U32 port = mesgsys->getSenderPort(); + U32 ip, port; + if(mesgsys != NULL) + { + ip = mesgsys->getSenderIP(); + port = mesgsys->getSenderPort(); + } + else + { + ip = mRegionp->getHost().getAddress(); + port = mRegionp->getHost().getPort(); + } gObjectList.orphanize(this, parent_id, ip, port); // Hide particles, icon and HUD @@ -1845,10 +1892,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, else { LLUUID parent_uuid; + + if(mesgsys != NULL) + { LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, gMessageSystem->getSenderIP(), gMessageSystem->getSenderPort()); + } + else + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mRegionp->getHost().getAddress(), + mRegionp->getHost().getPort()); + } sent_parentp = gObjectList.findObject(parent_uuid); if (isAvatar()) @@ -1869,8 +1927,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // // Switching parents, but we don't know the new parent. // - U32 ip = mesgsys->getSenderIP(); - U32 port = mesgsys->getSenderPort(); + U32 ip, port; + + if(mesgsys != NULL) + { + ip = mesgsys->getSenderIP(); + port = mesgsys->getSenderPort(); + } + else + { + ip = mRegionp->getHost().getAddress(); + port = mRegionp->getHost().getPort(); + } // We're an orphan, flag things appropriately. gObjectList.orphanize(this, parent_id, ip, port); @@ -1954,7 +2022,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, new_rot.normQuat(); - if (sPingInterpolate) + if (sPingInterpolate && mesgsys != NULL) { LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender()); if (cdp) @@ -1977,6 +2045,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // If we're going to skip this message, why are we // doing all the parenting, etc above? + if(mesgsys != NULL) + { U32 packet_id = mesgsys->getCurrentRecvPacketID(); if (packet_id < mLatestRecvPacketID && mLatestRecvPacketID - packet_id < 65536) @@ -1984,8 +2054,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, //skip application of this message, it's old return retval; } - mLatestRecvPacketID = packet_id; + } // Set the change flags for scale if (new_scale != getScale()) @@ -2033,7 +2103,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) ) { - LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() ); + sample(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length())); } } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 97cf0a4850..933b017aa6 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -107,7 +107,11 @@ struct PotentialReturnableObject //============================================================================ -class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate +class LLViewerObject +: public LLPrimitive, + public LLRefCount, + public LLGLUpdate, + public LLTrace::MemTrackable<LLViewerObject> { protected: ~LLViewerObject(); // use unref() @@ -132,6 +136,7 @@ public: BOOL isDead() const {return mDead;} BOOL isOrphaned() const { return mOrphaned; } BOOL isParticleSource() const; + void EnableToCacheTree(bool enabled); virtual LLVOAvatar* asAvatar(); @@ -631,6 +636,7 @@ public: LLPointer<LLHUDIcon> mIcon; static BOOL sUseSharedDrawables; + static LLTrace::MemStatHandle sMemStat; protected: // delete an item in the inventory, but don't tell the @@ -666,8 +672,6 @@ protected: void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); -public: - private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string void deleteTEImages(); // correctly deletes list of images @@ -746,6 +750,7 @@ protected: static S32 sAxisArrowLength; + // These two caches are only correct for non-parented objects right now! mutable LLVector3 mPositionRegion; mutable LLVector3 mPositionAgent; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 6b9d6bbc68..b26be5bc63 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -76,6 +76,7 @@ #include "object_flags.h" #include "llappviewer.h" +#include "llvocache.h" extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; @@ -93,7 +94,7 @@ extern LLPipeline gPipeline; U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex; std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID; -LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128); +LLTrace::MeasurementStatHandle<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); LLViewerObjectList::LLViewerObjectList() { @@ -106,7 +107,6 @@ LLViewerObjectList::LLViewerObjectList() mNumNewObjects = 0; mWasPaused = FALSE; mNumDeadObjectUpdates = 0; - mNumUnknownKills = 0; mNumUnknownUpdates = 0; } @@ -228,9 +228,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, U32 i, const EObjectUpdateType update_type, LLDataPacker* dpp, - BOOL just_created) + bool just_created, + bool from_cache) { - LLMessageSystem* msg = gMessageSystem; + LLMessageSystem* msg = NULL; + + if(!from_cache) + { + msg = gMessageSystem; + } // ignore returned flags objectp->processUpdateMessage(msg, user_data, i, update_type, dpp); @@ -254,7 +260,18 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, // RN: this must be called after we have a drawable // (from gPipeline.addObject) // so that the drawable parent is set properly + if(msg != NULL) + { findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); + } + else + { + LLViewerRegion* regionp = objectp->getRegion(); + if(regionp != NULL) + { + findOrphans(objectp, regionp->getHost().getAddress(), regionp->getHost().getPort()); + } + } // If we're just wandering around, don't create new objects selected. if (just_created @@ -277,10 +294,88 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); +LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) +{ + LLDataPacker *cached_dpp = entry->getDP(); + + if (!cached_dpp) + { + return NULL; //nothing cached. + } + + LLViewerObject *objectp; + U32 local_id; + LLPCode pcode = 0; + LLUUID fullid; + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + + // Cache Hit. + cached_dpp->reset(); + cached_dpp->unpackUUID(fullid, "ID"); + cached_dpp->unpackU32(local_id, "LocalID"); + cached_dpp->unpackU8(pcode, "PCode"); + + objectp = findObject(fullid); + + if (objectp) + { + if(!objectp->isDead() && (objectp->mLocalID != entry->getLocalID() || + objectp->getRegion() != regionp)) + { + removeFromLocalIDTable(objectp); + setUUIDAndLocal(fullid, entry->getLocalID(), + regionp->getHost().getAddress(), + regionp->getHost().getPort()); + + if (objectp->mLocalID != entry->getLocalID()) + { // Update local ID in object with the one sent from the region + objectp->mLocalID = entry->getLocalID(); + } + + if (objectp->getRegion() != regionp) + { // Object changed region, so update it + objectp->updateRegion(regionp); // for LLVOAvatar + } + } + else + { + return objectp; //already loaded. + } + } + + bool justCreated = false; + if (!objectp) + { + objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID()); + + if (!objectp) + { + llinfos << "createObject failure for object: " << fullid << llendl; + recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0); + return NULL; + } + justCreated = true; + mNumNewObjects++; + sample(sCacheHitRate, 100.f); + } + + if (objectp->isDead()) + { + llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl; + } + + processUpdateCore(objectp, NULL, 0, OUT_FULL_CACHED, cached_dpp, justCreated, true); + + recorder.log(0.2f); + LLVOAvatar::cullAvatarsByPixelArea(); + + return objectp; +} + void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type, - bool cached, bool compressed) + bool compressed) { LLFastTimer t(FTM_PROCESS_OBJECTS); @@ -299,7 +394,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); // I don't think this case is ever hit. TODO* Test this. - if (!cached && !compressed && update_type != OUT_FULL) + if (!compressed && update_type != OUT_FULL) { //llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl; gTerseObjectUpdates += num_objects; @@ -343,7 +438,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U8 compressed_dpbuffer[2048]; LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048); - LLDataPacker *cached_dpp = NULL; LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); for (i = 0; i < num_objects; i++) @@ -353,44 +447,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, BOOL justCreated = FALSE; S32 msg_size = 0; - if (cached) - { - U32 id; - U32 crc; - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); - msg_size += sizeof(U32) * 2; - - // Lookup data packer and add this id to cache miss lists if necessary. - U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; - cached_dpp = regionp->getDP(id, crc, cache_miss_type); - if (cached_dpp) - { - // Cache Hit. - cached_dpp->reset(); - cached_dpp->unpackUUID(fullid, "ID"); - cached_dpp->unpackU32(local_id, "LocalID"); - cached_dpp->unpackU8(pcode, "PCode"); - } - else - { - // Cache Miss. - recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); - - continue; // no data packer, skip this object - } - } - else if (compressed) + if (compressed) { S32 uncompressed_length = 2048; compressed_dp.reset(); - U32 flags = 0; - if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? - { - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); - } - uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data); mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i); compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length); @@ -485,9 +546,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, continue; } } - else if (cached) // Cache hit only? - { - } else { if (update_type != OUT_FULL) @@ -520,8 +578,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } justCreated = TRUE; mNumNewObjects++; - sCacheHitRate.addValue(cached ? 100.f : 0.f); - } @@ -540,15 +596,16 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { + U32 flags = 0; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); + + if(!(flags & FLAGS_TEMPORARY_ON_REZ)) + { bCached = true; LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); + recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); } } - else if (cached) // Cache hit only? - { - objectp->mLocalID = local_id; - processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated); } else { @@ -572,14 +629,51 @@ void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type) { - processObjectUpdate(mesgsys, user_data, update_type, false, true); + processObjectUpdate(mesgsys, user_data, update_type, true); } void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type) { - processObjectUpdate(mesgsys, user_data, update_type, true, false); + //processObjectUpdate(mesgsys, user_data, update_type, true, false); + + S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); + gFullObjectUpdates += num_objects; + + U64 region_handle; + mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); + if (!regionp) + { + llwarns << "Object update from unknown region! " << region_handle << llendl; + return; + } + + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + + for (S32 i = 0; i < num_objects; i++) + { + S32 msg_size = 0; + U32 id; + U32 crc; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); + msg_size += sizeof(U32) * 2; + + // Lookup data packer and add this id to cache miss lists if necessary. + U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; + if(!regionp->probeCache(id, crc, cache_miss_type)) + { + // Cache Miss. + recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); + + continue; // no data packer, skip this object + } + sample(sCacheHitRate, 100.f); + } + + return; } void LLViewerObjectList::dirtyAllObjectInventory() @@ -850,6 +944,8 @@ private: LLSD mObjectIDs; }; +static LLFastTimer::DeclareTimer FTM_IDLE_COPY("Idle Copy"); + void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { // Update globals @@ -899,12 +995,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) static std::vector<LLViewerObject*> idle_list; U32 idle_count = 0; - - static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); - + { - LLFastTimer t(idle_copy); - + LLFastTimer t(FTM_IDLE_COPY); + for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { @@ -913,9 +1007,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { if (idle_count >= idle_list.size()) { - idle_list.push_back( objectp ); - } - else + idle_list.push_back( objectp ); + } + else { idle_list[idle_count] = objectp; } @@ -932,7 +1026,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count; if (gSavedSettings.getBOOL("FreezeTime")) - { + { for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin(); iter != idle_end; iter++) @@ -1029,10 +1123,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } */ - LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size()); - LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); - LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); - LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); + sample(LLStatViewer::NUM_OBJECTS, mObjects.size()); + sample(LLStatViewer::NUM_ACTIVE_OBJECTS, idle_count); + sample(LLStatViewer::NUM_SIZE_CULLED, mNumSizeCulled); + sample(LLStatViewer::NUM_VIS_CULLED, mNumVisCulled); } void LLViewerObjectList::fetchObjectCosts() @@ -1230,7 +1324,7 @@ void LLViewerObjectList::removeDrawable(LLDrawable* drawablep) } } -BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) +BOOL LLViewerObjectList::killObject(LLViewerObject *objectp, bool cache_enabled) { // Don't ever kill gAgentAvatarp, just force it to the agent's region // unless region is NULL which is assumed to mean you are logging out. @@ -1245,16 +1339,8 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) if (objectp) { - if (objectp->isDead()) - { - // This object is already dead. Don't need to do more. - return TRUE; - } - else - { - objectp->markDead(); - } - + objectp->EnableToCacheTree(cache_enabled); //enable to add to VO cache tree if set. + objectp->markDead(); // does the right thing if object already dead return TRUE; } @@ -1406,10 +1492,10 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) { mActiveObjects.push_back(objectp); objectp->setListIndex(mActiveObjects.size()-1); - objectp->setOnActiveList(TRUE); - } - else - { + objectp->setOnActiveList(TRUE); + } + else + { llassert(idx < mActiveObjects.size()); llassert(mActiveObjects[idx] == objectp); @@ -1538,13 +1624,13 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { LLFastTimer t(FTM_PIPELINE_SHIFT); - gPipeline.shiftObjects(offset); + gPipeline.shiftObjects(offset); } { LLFastTimer t(FTM_REGION_SHIFT); - LLWorld::getInstance()->shiftRegions(offset); -} + LLWorld::getInstance()->shiftRegions(offset); + } } void LLViewerObjectList::repartitionObjects() @@ -1890,6 +1976,29 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi return objectp; } +LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id) +{ + llassert_always(uuid.notNull()); + + LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp); + if (!objectp) + { +// llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl; + return NULL; + } + + objectp->mLocalID = local_id; + mUUIDObjectMap[uuid] = objectp; + setUUIDAndLocal(uuid, + local_id, + regionp->getHost().getAddress(), + regionp->getHost().getPort()); + mObjects.push_back(objectp); + + updateActive(objectp); + + return objectp; +} LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 449a4633ff..cb11ef1f5e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -31,8 +31,8 @@ #include <set> // common includes -#include "llstat.h" #include "llstring.h" +#include "lltrace.h" // project includes #include "llviewerobject.h" @@ -40,6 +40,7 @@ class LLCamera; class LLNetMap; class LLDebugBeacon; +class LLVOCacheEntry; const U32 CLOSE_BIN_SIZE = 10; const U32 NUM_BINS = 128; @@ -65,12 +66,13 @@ public: inline LLViewerObject *findObject(const LLUUID &id); LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object + LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id); LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender); LLViewerObject *replaceObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); // TomY: hack to switch VO instances on the fly - BOOL killObject(LLViewerObject *objectp); + BOOL killObject(LLViewerObject *objectp, bool cache_enabled = false); void killObjects(LLViewerRegion *regionp); // Kill all objects owned by a particular region. void killAllObjects(); void removeDrawable(LLDrawable* drawablep); @@ -78,8 +80,10 @@ public: void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list. // Simulator and viewer side object updates... - void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, LLDataPacker* dpp, BOOL justCreated); - void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool cached=false, bool compressed=false); + void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, + LLDataPacker* dpp, bool justCreated, bool from_cache = false); + LLViewerObject* processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp); + void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool compressed=false); void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type); void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type); void updateApparentAngles(LLAgent &agent); @@ -188,14 +192,13 @@ public: S32 mNumUnknownUpdates; S32 mNumDeadObjectUpdates; - S32 mNumUnknownKills; S32 mNumDeadObjects; protected: std::vector<U64> mOrphanParents; // LocalID/ip,port of orphaned objects std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; - static LLStat sCacheHitRate; + static LLTrace::MeasurementStatHandle<> sCacheHitRate; typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t; diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp new file mode 100644 index 0000000000..cfa24c32ed --- /dev/null +++ b/indra/newview/llvieweroctree.cpp @@ -0,0 +1,800 @@ +/** + * @file llvieweroctree.cpp + * @brief LLViewerOctreeGroup class implementation and supporting functions + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llvieweroctree.h" +#include "llviewerregion.h" + +//----------------------------------------------------------------------------------- +//static variables definitions +//----------------------------------------------------------------------------------- +U32 LLViewerOctreeEntryData::sCurVisible = 0; + +//----------------------------------------------------------------------------------- +//some global functions definitions +//----------------------------------------------------------------------------------- +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) +{ + return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) +{ + F32 d = 0.f; + F32 t; + + if ((min-origin).magVecSquared() < r && + (max-origin).magVecSquared() < r) + { + return 2; + } + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min.mV[i]) + { + t = min.mV[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max.mV[i]) + { + t = origin.mV[i] - max.mV[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + + +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) +{ + return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) +{ + F32 d = 0.f; + F32 t; + + LLVector4a origina; + origina.load3(origin.mV); + + LLVector4a v; + v.setSub(min, origina); + + if (v.dot3(v) < r) + { + v.setSub(max, origina); + if (v.dot3(v) < r) + { + return 2; + } + } + + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min[i]) + { + t = min[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max[i]) + { + t = origin.mV[i] - max[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeEntry definitions +//----------------------------------------------------------------------------------- +LLViewerOctreeEntry::LLViewerOctreeEntry() + : mGroup(NULL), + mBinRadius(0.f), + mBinIndex(-1) +{ + mPositionGroup.clear(); + mExtents[0].clear(); + mExtents[1].clear(); + + for(S32 i = 0; i < NUM_DATA_TYPE; i++) + { + mData[i] = NULL; + } +} + +LLViewerOctreeEntry::~LLViewerOctreeEntry() +{ + llassert(!mGroup); +} + +void LLViewerOctreeEntry::addData(LLViewerOctreeEntryData* data) +{ + //llassert(mData[data->getDataType()] == NULL); + llassert(data != NULL); + + mData[data->getDataType()] = data; +} + +void LLViewerOctreeEntry::removeData(LLViewerOctreeEntryData* data) +{ + //llassert(data->getDataType() != LLVOCACHEENTRY); //can not remove VOCache entry + + if(!mData[data->getDataType()]) + { + return; + } + + mData[data->getDataType()] = NULL; + + if(mGroup != NULL && !mData[LLDRAWABLE]) + { + LLviewerOctreeGroup* group = mGroup; + mGroup = NULL; + group->removeFromGroup(data); + + llassert(mBinIndex == -1); + } +} + +//called by group handleDestruction() ONLY when group is destroyed by octree. +void LLViewerOctreeEntry::nullGroup() +{ + mGroup = NULL; +} + +void LLViewerOctreeEntry::setGroup(LLviewerOctreeGroup* group) +{ + if(mGroup == group) + { + return; + } + + if(mGroup) + { + LLviewerOctreeGroup* group = mGroup; + mGroup = NULL; + group->removeFromGroup(this); + + llassert(mBinIndex == -1); + } + + mGroup = group; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeEntryData definitions +//----------------------------------------------------------------------------------- +LLViewerOctreeEntryData::~LLViewerOctreeEntryData() +{ + if(mEntry) + { + mEntry->removeData(this); + } +} + +LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type) + : mDataType(data_type), + mEntry(NULL) +{ +} + +//virtual +void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry) +{ + if(mEntry.notNull()) + { + return; + } + + if(!entry) + { + mEntry = new LLViewerOctreeEntry(); + } + else + { + mEntry = entry; + } + mEntry->addData(this); +} + +void LLViewerOctreeEntryData::setSpatialExtents(const LLVector3& min, const LLVector3& max) +{ + mEntry->mExtents[0].load3(min.mV); + mEntry->mExtents[1].load3(max.mV); +} + +void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) +{ + mEntry->mExtents[0] = min; + mEntry->mExtents[1] = max; +} + +void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos) +{ + mEntry->mPositionGroup = pos; +} + +const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const +{ + return mEntry->getSpatialExtents(); +} + +//virtual +void LLViewerOctreeEntryData::setGroup(LLviewerOctreeGroup* group) +{ + mEntry->setGroup(group); +} + +void LLViewerOctreeEntryData::shift(const LLVector4a &shift_vector) +{ + mEntry->mExtents[0].add(shift_vector); + mEntry->mExtents[1].add(shift_vector); + mEntry->mPositionGroup.add(shift_vector); +} + +LLviewerOctreeGroup* LLViewerOctreeEntryData::getGroup()const +{ + return mEntry.notNull() ? mEntry->mGroup : NULL; +} + +const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const +{ + return mEntry->getPositionGroup(); +} + +//virtual +bool LLViewerOctreeEntryData::isVisible() const +{ + if(mEntry) + { + return mEntry->mVisible == sCurVisible; + } + return false; +} + +//virtual +bool LLViewerOctreeEntryData::isRecentlyVisible() const +{ + if(!mEntry) + { + return false; + } + + if(isVisible()) + { + return true; + } + if(getGroup() && getGroup()->isRecentlyVisible()) + { + setVisible(); + return true; + } + + return (sCurVisible - mEntry->mVisible < getMinVisFrameRange()); +} + +void LLViewerOctreeEntryData::setVisible() const +{ + if(mEntry) + { + mEntry->mVisible = sCurVisible; + } +} + +//----------------------------------------------------------------------------------- +//class LLviewerOctreeGroup definitions +//----------------------------------------------------------------------------------- + +LLviewerOctreeGroup::~LLviewerOctreeGroup() +{ + if(LLViewerRegion::sCurRegionp && isVisible()) + { + LLViewerRegion::sCurRegionp->clearVisibleGroup(this); + } +} + +LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) : + mOctreeNode(node), + mState(CLEAN) +{ + LLVector4a tmp; + tmp.splat(0.f); + mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = + mObjectExtents[0] = mObjectExtents[1] = tmp; + + mBounds[0] = node->getCenter(); + mBounds[1] = node->getSize(); + + mOctreeNode->addListener(this); +} + +bool LLviewerOctreeGroup::hasElement(LLViewerOctreeEntryData* data) +{ + if(!data->getEntry()) + { + return false; + } + return std::find(getDataBegin(), getDataEnd(), data->getEntry()) != getDataEnd(); +} + +bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntryData* data) +{ + return removeFromGroup(data->getEntry()); +} + +bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry) +{ + llassert(entry != NULL); + llassert(!entry->getGroup()); + + unbound(); + if (mOctreeNode) + { + if (!mOctreeNode->remove(entry)) + { + OCT_ERRS << "Could not remove LLVOCacheEntry from LLVOCacheOctreeGroup" << llendl; + return false; + } + } + setState(OBJECT_DIRTY); + + return true; +} + +//virtual +void LLviewerOctreeGroup::unbound() +{ + if (isDirty()) + { + return; + } + + setState(DIRTY); + + //all the parent nodes need to rebound this child + if (mOctreeNode) + { + OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); + while (parent != NULL) + { + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) parent->getListener(0); + if (!group || group->isDirty()) + { + return; + } + + group->setState(DIRTY); + parent = (OctreeNode*) parent->getParent(); + } + } +} + +//virtual +void LLviewerOctreeGroup::rebound() +{ + if (!isDirty()) + { + return; + } + + if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) + { + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0); + group->rebound(); + + //copy single child's bounding box + mBounds[0] = group->mBounds[0]; + mBounds[1] = group->mBounds[1]; + mExtents[0] = group->mExtents[0]; + mExtents[1] = group->mExtents[1]; + + group->setState(SKIP_FRUSTUM_CHECK); + } + else if (mOctreeNode->isLeaf()) + { //copy object bounding box if this is a leaf + boundObjects(TRUE, mExtents[0], mExtents[1]); + mBounds[0] = mObjectBounds[0]; + mBounds[1] = mObjectBounds[1]; + } + else + { + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0); + group->clearState(SKIP_FRUSTUM_CHECK); + group->rebound(); + //initialize to first child + newMin = group->mExtents[0]; + newMax = group->mExtents[1]; + + //first, rebound children + for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) + { + group = (LLviewerOctreeGroup*) mOctreeNode->getChild(i)->getListener(0); + group->clearState(SKIP_FRUSTUM_CHECK); + group->rebound(); + const LLVector4a& max = group->mExtents[1]; + const LLVector4a& min = group->mExtents[0]; + + newMax.setMax(newMax, max); + newMin.setMin(newMin, min); + } + + boundObjects(FALSE, newMin, newMax); + + mBounds[0].setAdd(newMin, newMax); + mBounds[0].mul(0.5f); + mBounds[1].setSub(newMax, newMin); + mBounds[1].mul(0.5f); + } + + clearState(DIRTY); + + return; +} + +//virtual +void LLviewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) +{ + obj->setGroup(this); + unbound(); + setState(OBJECT_DIRTY); +} + +//virtual +void LLviewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj) +{ + obj->setGroup(NULL); + unbound(); + setState(OBJECT_DIRTY); +} + +//virtual +void LLviewerOctreeGroup::handleDestruction(const TreeNode* node) +{ + for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(); i != mOctreeNode->getDataEnd(); ++i) + { + LLViewerOctreeEntry* obj = *i; + if (obj && obj->getGroup() == this) + { + obj->nullGroup(); + //obj->setGroup(NULL); + } + } + mOctreeNode = NULL; +} + +//virtual +void LLviewerOctreeGroup::handleStateChange(const TreeNode* node) +{ + //drop bounding box upon state change + if (mOctreeNode != node) + { + mOctreeNode = (OctreeNode*) node; + } + unbound(); +} + +//virtual +void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +{ + if (child->getListenerCount() == 0) + { + new LLviewerOctreeGroup(child); + } + else + { + OCT_ERRS << "LLSpatialGroup redundancy detected." << llendl; + } + + unbound(); + + //((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} + +//virtual +void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) +{ + unbound(); +} + +LLviewerOctreeGroup* LLviewerOctreeGroup::getParent() +{ + if(!mOctreeNode) + { + return NULL; + } + + OctreeNode* parent = mOctreeNode->getOctParent(); + + if (parent) + { + return (LLviewerOctreeGroup*) parent->getListener(0); + } + + return NULL; +} + +//virtual +bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) +{ + const OctreeNode* node = mOctreeNode; + + if (node->isEmpty()) + { //don't do anything if there are no objects + if (empty && mOctreeNode->getParent()) + { //only root is allowed to be empty + OCT_ERRS << "Empty leaf found in octree." << llendl; + } + return false; + } + + LLVector4a& newMin = mObjectExtents[0]; + LLVector4a& newMax = mObjectExtents[1]; + + if (hasState(OBJECT_DIRTY)) + { //calculate new bounding box + clearState(OBJECT_DIRTY); + + //initialize bounding box to first element + OctreeNode::const_element_iter i = node->getDataBegin(); + LLViewerOctreeEntry* entry = *i; + const LLVector4a* minMax = entry->getSpatialExtents(); + + newMin = minMax[0]; + newMax = minMax[1]; + + for (++i; i != node->getDataEnd(); ++i) + { + entry = *i; + minMax = entry->getSpatialExtents(); + + update_min_max(newMin, newMax, minMax[0]); + update_min_max(newMin, newMax, minMax[1]); + } + + mObjectBounds[0].setAdd(newMin, newMax); + mObjectBounds[0].mul(0.5f); + mObjectBounds[1].setSub(newMax, newMin); + mObjectBounds[1].mul(0.5f); + } + + if (empty) + { + minOut = newMin; + maxOut = newMax; + } + else + { + minOut.setMin(minOut, newMin); + maxOut.setMax(maxOut, newMax); + } + + return TRUE; +} + +//virtual +BOOL LLviewerOctreeGroup::isVisible() const +{ + return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE; +} + +//virtual +BOOL LLviewerOctreeGroup::isRecentlyVisible() const +{ + return FALSE; +} + +void LLviewerOctreeGroup::setVisible() +{ + mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); +} +//----------------------------------------------------------------------------------- +//class LLViewerOctreePartition definitions +//----------------------------------------------------------------------------------- +LLViewerOctreePartition::LLViewerOctreePartition() : mRegionp(NULL) +{ + LLVector4a center, size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new OctreeRoot(center,size, NULL); +} + +LLViewerOctreePartition::~LLViewerOctreePartition() +{ + delete mOctree; + mOctree = NULL; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeCull definitions +//----------------------------------------------------------------------------------- + +//virtual +bool LLViewerOctreeCull::earlyFail(LLviewerOctreeGroup* group) +{ + return false; +} + +//virtual +void LLViewerOctreeCull::traverse(const OctreeNode* n) +{ + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) n->getListener(0); + + if (earlyFail(group)) + { + return; + } + + if (mRes == 2 || + (mRes && group->hasState(LLviewerOctreeGroup::SKIP_FRUSTUM_CHECK))) + { //fully in, just add everything + OctreeTraveler::traverse(n); + } + else + { + mRes = frustumCheck(group); + + if (mRes) + { //at least partially in, run on down + OctreeTraveler::traverse(n); + } + + mRes = 0; + } +} + +//------------------------------------------ +//agent space group culling +S32 LLViewerOctreeCull::AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group) +{ + return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist); +} + +S32 LLViewerOctreeCull::AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); +} +//------------------------------------------ + +//------------------------------------------ +//agent space object set culling +S32 LLViewerOctreeCull::AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group) +{ + return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist); +} + +S32 LLViewerOctreeCull::AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); +} +//------------------------------------------ + +//------------------------------------------ +//local regional space group culling +S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInRegionFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInRegionFrustum(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift) +{ + return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist); +} +//------------------------------------------ + +//------------------------------------------ +//local regional space object culling +S32 LLViewerOctreeCull::AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInRegionFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInRegionFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift) +{ + return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist); +} +//------------------------------------------ + +//virtual +bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group) +{ + if (branch->getElementCount() == 0) //no elements + { + return false; + } + else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box + { + return true; + } + else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum + { + return false; + } + + return true; +} + +//virtual +void LLViewerOctreeCull::preprocess(LLviewerOctreeGroup* group) +{ +} + +//virtual +void LLViewerOctreeCull::processGroup(LLviewerOctreeGroup* group) +{ +} + +//virtual +void LLViewerOctreeCull::visit(const OctreeNode* branch) +{ + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0); + + preprocess(group); + + if (checkObjects(branch, group)) + { + processGroup(group); + } +} + diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h new file mode 100644 index 0000000000..a35c551949 --- /dev/null +++ b/indra/newview/llvieweroctree.h @@ -0,0 +1,327 @@ +/** + * @file llvieweroctree.h + * @brief LLViewerObjectOctree.cpp header file, defining all supporting classes. + * + * $LicenseInfo:firstyear=2002&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_VIEWEROCTREE_H +#define LL_VIEWEROCTREE_H + +#include <vector> +#include <map> + +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "m4math.h" +#include "llvector4a.h" +#include "llquaternion.h" +#include "lloctree.h" +#include "llviewercamera.h" + +class LLViewerRegion; +class LLViewerOctreeEntryData; +class LLviewerOctreeGroup; +class LLViewerOctreeEntry; + +typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener; +typedef LLTreeNode<LLViewerOctreeEntry> TreeNode; +typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode; +typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot; +typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler; + +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); + +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); + +//defines data needed for octree of an entry +LL_ALIGN_PREFIX(16) +class LLViewerOctreeEntry : public LLRefCount +{ + friend class LLViewerOctreeEntryData; + +public: + typedef enum + { + LLDRAWABLE = 0, + LLVOCACHEENTRY, + NUM_DATA_TYPE + }eEntryDataType_t; + + ~LLViewerOctreeEntry(); +public: + LLViewerOctreeEntry(); + + void nullGroup(); //called by group handleDestruction() only + void setGroup(LLviewerOctreeGroup* group); + void removeData(LLViewerOctreeEntryData* data); + + LLViewerOctreeEntryData* getData(U32 data_type)const {return mData[data_type];} + bool hasData(U32 data_type)const {return mData[data_type] != NULL;} + + LLViewerOctreeEntryData* getDrawable() const {return mData[LLDRAWABLE];} + bool hasDrawable() const {return mData[LLDRAWABLE] != NULL;} + LLViewerOctreeEntryData* getVOCacheEntry() const {return mData[LLVOCACHEENTRY];} + bool hasVOCacheEntry() const {return mData[LLVOCACHEENTRY] != NULL;} + + const LLVector4a* getSpatialExtents() const {return mExtents;} + const LLVector4a& getPositionGroup() const {return mPositionGroup;} + LLviewerOctreeGroup* getGroup()const {return mGroup;} + + F32 getBinRadius() const {return mBinRadius;} + S32 getBinIndex() const {return mBinIndex; } + void setBinIndex(S32 index) const {mBinIndex = index; } + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + +private: + void addData(LLViewerOctreeEntryData* data); + +private: + LLViewerOctreeEntryData* mData[NUM_DATA_TYPE]; //do not use LLPointer here. + LLviewerOctreeGroup* mGroup; + + //aligned members + LL_ALIGN_16(LLVector4a mExtents[2]); + LL_ALIGN_16(LLVector4a mPositionGroup); + F32 mBinRadius; + mutable S32 mBinIndex; + mutable U32 mVisible; + +} LL_ALIGN_POSTFIX(16); + +//defines an abstract class for entry data +LL_ALIGN_PREFIX(16) +class LLViewerOctreeEntryData : public LLRefCount +{ +protected: + ~LLViewerOctreeEntryData(); + +public: + LLViewerOctreeEntryData(const LLViewerOctreeEntryData& rhs) + { + *this = rhs; + } + LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type); + + LLViewerOctreeEntry::eEntryDataType_t getDataType() const {return mDataType;} + LLViewerOctreeEntry* getEntry() {return mEntry;} + + virtual void setOctreeEntry(LLViewerOctreeEntry* entry); + + virtual S32 getMinVisFrameRange()const = 0; + + F32 getBinRadius() const {return mEntry->getBinRadius();} + const LLVector4a* getSpatialExtents() const; + LLviewerOctreeGroup* getGroup()const; + const LLVector4a& getPositionGroup() const; + + void setBinRadius(F32 rad) {mEntry->mBinRadius = rad;} + void setSpatialExtents(const LLVector3& min, const LLVector3& max); + void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); + void setPositionGroup(const LLVector4a& pos); + + virtual void setGroup(LLviewerOctreeGroup* group); + void shift(const LLVector4a &shift_vector); + + U32 getVisible() const {return mEntry ? mEntry->mVisible : 0;} + void setVisible() const; + virtual bool isVisible() const; + virtual bool isRecentlyVisible() const; + + static S32 getCurrentFrame() { return sCurVisible; } + +protected: + LLVector4a& getGroupPosition() {return mEntry->mPositionGroup;} + void initVisible(U32 visible) {mEntry->mVisible = visible;} + + static void incrementVisible() {sCurVisible++;} +protected: + LLPointer<LLViewerOctreeEntry> mEntry; + LLViewerOctreeEntry::eEntryDataType_t mDataType; + static U32 sCurVisible; // Counter for what value of mVisible means currently visible +}LL_ALIGN_POSTFIX(16); + + +//defines an octree group for an octree node, which contains multiple entries. +LL_ALIGN_PREFIX(16) +class LLviewerOctreeGroup : public LLOctreeListener<LLViewerOctreeEntry> +{ + friend class LLViewerOctreeCull; +protected: + ~LLviewerOctreeGroup(); + +public: + enum + { + CLEAN = 0x00000000, + DIRTY = 0x00000001, + OBJECT_DIRTY = 0x00000002, + SKIP_FRUSTUM_CHECK = 0x00000004, + INVALID_STATE = 0x00000008, + }; + +public: + typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter; + typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list; + + LLviewerOctreeGroup(OctreeNode* node); + LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs) + { + *this = rhs; + } + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + bool removeFromGroup(LLViewerOctreeEntryData* data); + bool removeFromGroup(LLViewerOctreeEntry* entry); + + virtual void unbound(); + virtual void rebound(); + + void setVisible(); + BOOL isVisible() const; + virtual BOOL isRecentlyVisible() const; + bool isEmpty() const { return mOctreeNode->isEmpty(); } + + U32 getState() {return mState; } + bool isDirty() const {return mState & DIRTY;} + bool hasState(U32 state) const {return mState & state;} + void setState(U32 state) {mState |= state;} + void clearState(U32 state) {mState &= ~state;} + + //LISTENER FUNCTIONS + virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj); + virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj); + virtual void handleDestruction(const TreeNode* node); + virtual void handleStateChange(const TreeNode* node); + virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); + virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); + + OctreeNode* getOctreeNode() {return mOctreeNode;} + LLviewerOctreeGroup* getParent(); + + const LLVector4a* getBounds() const {return mBounds;} + const LLVector4a* getExtents() const {return mExtents;} + const LLVector4a* getObjectBounds() const {return mObjectBounds;} + const LLVector4a* getObjectExtents() const {return mObjectExtents;} + + //octree wrappers to make code more readable + element_list& getData() { return mOctreeNode->getData(); } + element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } + element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } + U32 getElementCount() const { return mOctreeNode->getElementCount(); } + bool hasElement(LLViewerOctreeEntryData* data); + +private: + virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut); + +protected: + U32 mState; + OctreeNode* mOctreeNode; + + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + +public: + S32 mVisible[LLViewerCamera::NUM_CAMERAS]; +}LL_ALIGN_POSTFIX(16); + +class LLViewerOctreePartition +{ +public: + LLViewerOctreePartition(); + virtual ~LLViewerOctreePartition(); + + // Cull on arbitrary frustum + virtual S32 cull(LLCamera &camera) = 0; + +public: + U32 mPartitionType; + OctreeNode* mOctree; + LLViewerRegion* mRegionp; // the region this partition belongs to. +}; + +class LLViewerOctreeCull : public OctreeTraveler +{ +public: + LLViewerOctreeCull(LLCamera* camera) + : mCamera(camera), mRes(0) { } + + virtual bool earlyFail(LLviewerOctreeGroup* group); + virtual void traverse(const OctreeNode* n); + + //agent space group cull + S32 AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group); + S32 AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group); + S32 AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group); + + //agent space object set cull + S32 AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group); + S32 AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group); + S32 AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group); + + //local region space group cull + S32 AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group); + S32 AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group); + S32 AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift); + + //local region space object set cull + S32 AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group); + S32 AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group); + S32 AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift); + + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) = 0; + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) = 0; + + virtual bool checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group); + virtual void preprocess(LLviewerOctreeGroup* group); + virtual void processGroup(LLviewerOctreeGroup* group); + virtual void visit(const OctreeNode* branch); + +protected: + LLCamera *mCamera; + S32 mRes; +}; + +#endif diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6bd9f66b9c..8acdc08b00 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -151,8 +151,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo if (group != NULL) { - LLVector3 center(group->mOctreeNode->getCenter().getF32ptr()); - LLVector3 size(group->mOctreeNode->getSize().getF32ptr()); + LLVector3 center(group->getOctreeNode()->getCenter().getF32ptr()); + LLVector3 size(group->getOctreeNode()->getSize().getF32ptr()); size += LLVector3(0.01f, 0.01f, 0.01f); mMinObjPos = center - size; mMaxObjPos = center + size; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e4234a538d..914a201ffe 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -70,6 +70,7 @@ #include "stringize.h" #include "llviewercontrol.h" #include "llsdserialize.h" +#include "llvieweroctree.h" #ifdef LL_WINDOWS #pragma warning(disable:4355) @@ -85,6 +86,9 @@ const F32 CAP_REQUEST_TIMEOUT = 18; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; +LLViewerRegion* LLViewerRegion::sCurRegionp = NULL; +BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE; + typedef std::map<std::string, std::string> CapabilityMap; class LLViewerRegionImpl { @@ -97,6 +101,8 @@ public: mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), mSeedCapAttempts(0), mHttpResponderID(0), + mLastCameraUpdate(0), + mLastCameraOrigin(), // I'd prefer to set the LLCapabilityListener name to match the region // name -- it's disappointing that's not available at construction time. // We could instead store an LLCapabilityListener*, making @@ -133,7 +139,14 @@ public: // Misc LLVLComposition *mCompositionp; // Composition layer for the surface - LLVOCacheEntry::vocache_entry_map_t mCacheMap; + LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries + LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; + LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. + std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible groupa + LLVOCachePartition* mVOCachePartition; + LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. + LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. + // time? // LRU info? @@ -157,7 +170,10 @@ public: LLCapabilityListener mCapabilityListener; //spatial partitions for objects in this region - std::vector<LLSpatialPartition*> mObjectPartition; + std::vector<LLViewerOctreePartition*> mObjectPartition; + + LLVector3 mLastCameraOrigin; + U32 mLastCameraUpdate; }; // support for secondlife:///app/region/{REGION} SLapps @@ -290,7 +306,10 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mBitsReceived(0.f), + mPacketsReceived(0.f), + mDead(FALSE) { mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); @@ -322,17 +341,20 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, //create object partitions //MUST MATCH declaration of eObjectPartitions - mImpl->mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD - mImpl->mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN - mImpl->mObjectPartition.push_back(new LLVoidWaterPartition()); //PARTITION_VOIDWATER - mImpl->mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER - mImpl->mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE - mImpl->mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE - mImpl->mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS - mImpl->mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME - mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE - mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD + mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN + mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER + mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER + mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE + mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE + mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS + mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME + mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE + mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE + + mImpl->mVOCachePartition = getVOCachePartition(); } @@ -353,6 +375,12 @@ void LLViewerRegion::initStats() LLViewerRegion::~LLViewerRegion() { + mDead = TRUE; + mImpl->mActiveSet.clear(); + mImpl->mVisibleEntries.clear(); + mImpl->mVisibleGroups.clear(); + mImpl->mWaitingSet.clear(); + gVLManager.cleanupData(this); // Can't do this on destruction, because the neighbor pointers might be invalid. // This should be reference counted... @@ -367,10 +395,10 @@ LLViewerRegion::~LLViewerRegion() delete mImpl->mEventPoll; LLHTTPSender::clearSender(mImpl->mHost); - saveObjectCache(); - std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); + saveObjectCache(); + delete mImpl; mImpl = NULL; } @@ -436,10 +464,6 @@ void LLViewerRegion::saveObjectCache() mCacheDirty = FALSE; } - for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) - { - delete iter->second; - } mImpl->mCacheMap.clear(); } @@ -717,8 +741,357 @@ void LLViewerRegion::dirtyHeights() } } +void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) +{ + U32 state = LLVOCacheEntry::INACTIVE; + + if(old_entry) + { + old_entry->copyTo(new_entry); + state = old_entry->getState(); + killCacheEntry(old_entry); + } + + mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; + + if(state == LLVOCacheEntry::ACTIVE) + { + llassert(new_entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(new_entry); + } + else if(state == LLVOCacheEntry::WAITING) + { + mImpl->mWaitingSet.insert(new_entry); + } + else if(old_entry && new_entry->getEntry()) + { + addToVOCacheTree(new_entry); + } + new_entry->setState(state); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry) +{ + if(!entry) + { + return; + } + + //remove from active list and waiting list + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mActiveSet.erase(entry); + } + else + { + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + //remove from mVOCachePartition + removeFromVOCacheTree(entry); + } + + //remove from the forced visible list + mImpl->mVisibleEntries.erase(entry); + + //kill LLViewerObject if exists + //this should be done by the rendering pipeline automatically. + + entry->setState(LLVOCacheEntry::INACTIVE); + + //remove from mCacheMap, real deletion + mImpl->mCacheMap.erase(entry->getLocalID()); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(U32 local_id) +{ + killCacheEntry(getCacheEntry(local_id)); +} + +U32 LLViewerRegion::getNumOfActiveCachedObjects() const +{ + return mImpl->mActiveSet.size(); +} + +void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry) +{ + if(!entry || mDead) + { + return; + } + + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + entry->setState(LLVOCacheEntry::ACTIVE); + entry->setVisible(); + + llassert(entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(entry); +} + +void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep) +{ + if(mDead) + { + return; + } + + if(drawablep->getParent()) //child object + { + LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry(); + if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry()) + { + LLVOCacheEntry* parent = (LLVOCacheEntry*)parent_oct_entry->getVOCacheEntry(); + parent->addChild(entry); + } + } + else //insert to vo cache tree. + { + //shift to the local regional space from agent space + const LLVector3 pos = drawablep->getVObj()->getPositionRegion(); + LLVector4a vec(pos[0], pos[1], pos[2]); + LLVector4a shift; + shift.setSub(vec, entry->getPositionGroup()); + entry->shift(shift); + + addToVOCacheTree(entry); + } + + mImpl->mVisibleEntries.erase(entry); + mImpl->mActiveSet.erase(entry); + mImpl->mWaitingSet.erase(entry); + entry->setState(LLVOCacheEntry::INACTIVE); +} + +void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) +{ + if(mDead || group->isEmpty()) + { + return; + } + group->setVisible(); + mImpl->mVisibleGroups.insert(group); +} + +void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) +{ + if(!sVOCacheCullingEnabled) + { + return; + } + + if(mDead || !entry || !entry->getEntry()) + { + return; + } + if(entry->getGroup()) //already in octree. + { + return; + } + if(!entry->hasState(LLVOCacheEntry::ADD_TO_CACHE_TREE)) + { + return; //can not add to vo cache tree. + } + + mImpl->mVOCachePartition->addEntry(entry->getEntry()); +} + +void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) +{ + if(mDead || !entry || !entry->getEntry()) + { + return; + } + if(!entry->getGroup()) + { + return; + } + + mImpl->mVOCachePartition->removeEntry(entry->getEntry()); +} + +//add the visible entries +void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) +{ + if(mDead || !entry) + { + return; + } + + if(entry->isState(LLVOCacheEntry::IN_QUEUE)) + { + return; + } + + if(entry->isState(LLVOCacheEntry::INACTIVE)) + { + entry->setState(LLVOCacheEntry::IN_QUEUE); + } + mImpl->mVisibleEntries.insert(entry); +} + +void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) +{ + if(mDead) + { + return; + } + + llassert(!group->getOctreeNode() || group->isEmpty()); + + mImpl->mVisibleGroups.erase(group); +} + +F32 LLViewerRegion::updateVisibleEntries(F32 max_time) +{ + if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) + { + return max_time; + } + + LLTimer update_timer; + + const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); + const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); + bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f); + + //process visible entries + max_time *= 0.5f; //only use up to half available time to update entries. + +#if 1 + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) + { + LLVOCacheEntry* vo_entry = *iter; + vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); + + if(vo_entry->getState() < LLVOCacheEntry::WAITING) + { + mImpl->mWaitingList.insert(vo_entry); + } + + LLVOCacheEntry* child; + S32 num_child = vo_entry->getNumOfChildren(); + S32 num_done = 0; + for(S32 i = 0; i < num_child; i++) + { + child = vo_entry->getChild(i); + if(child->getState() < LLVOCacheEntry::WAITING) + { + child->setSceneContribution(vo_entry->getSceneContribution()); + mImpl->mWaitingList.insert(child); + } + else + { + num_done++; + } + } + if(num_done == num_child) + { + vo_entry->clearChildrenList(); + } + + if(!vo_entry->getNumOfChildren()) + { + if(vo_entry->getState() >= LLVOCacheEntry::WAITING) + { + LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; + ++next_iter; + mImpl->mVisibleEntries.erase(iter); + iter = next_iter; + } + else + { + ++iter; + } + } + else + { + ++iter; + } + + //if(update_timer.getElapsedTimeF32() > max_time) + //{ + // break; + //} + } +#endif + + //process visible groups + std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); + for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) + { + LLviewerOctreeGroup* group = *group_iter; + if(!group->getOctreeNode() || group->isEmpty()) + { + continue; + } + + for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + if((*i)->hasVOCacheEntry()) + { + LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); + + vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); + mImpl->mWaitingList.insert(vo_entry); + } + } + + //if(update_timer.getElapsedTimeF32() > max_time) + //{ + // break; + //} + } + mImpl->mVisibleGroups.clear(); + + if(needs_update) + { + mImpl->mLastCameraOrigin = camera_origin; + mImpl->mLastCameraUpdate = cur_frame; + } + + return 2.0f * max_time - update_timer.getElapsedTimeF32(); +} + +F32 LLViewerRegion::createVisibleObjects(F32 max_time) +{ + if(mImpl->mWaitingList.empty()) + { + return max_time; + } + + LLTimer update_timer; + S32 max_num_objects = 64; //minimum number of new objects to be added + for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin(); + iter != mImpl->mWaitingList.end(); ++iter) + { + LLVOCacheEntry* vo_entry = *iter; + + if(vo_entry->getState() < LLVOCacheEntry::WAITING) + { + addNewObject(vo_entry); + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) + { + break; + } + } + } + mImpl->mWaitingList.clear(); + + return max_time - update_timer.getElapsedTimeF32(); +} + BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { + LLTimer update_timer; + // did_update returns TRUE if we did at least one significant update BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); @@ -728,9 +1101,98 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) mParcelOverlay->idleUpdate(); } + max_update_time -= update_timer.getElapsedTimeF32(); + if(max_update_time < 0.f || mImpl->mCacheMap.empty()) + { + return did_update; +} + + sCurRegionp = this; + + //kill invisible objects + max_update_time = killInvisibleObjects(max_update_time); + + max_update_time = updateVisibleEntries(max_update_time); + createVisibleObjects(max_update_time); + + mImpl->mVisibleGroups.clear(); + mImpl->mWaitingList.clear(); + + sCurRegionp = NULL; return did_update; } +F32 LLViewerRegion::killInvisibleObjects(F32 max_time) +{ + if(!sVOCacheCullingEnabled) + { + return max_time; + } + + std::vector<LLDrawable*> delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj(), true); + } + delete_list.clear(); + + return max_time; +} + +void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list) +{ + //kill the object. + LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable(); + llassert(drawablep); + + if(!drawablep->getParent()) + { + LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + if(child->mDrawable->isRecentlyVisible()) + { + //set the parent group visible if any of its children visible. + ((LLViewerOctreeEntryData*)drawablep)->setVisible(); + return; + } + } + delete_list.push_back(drawablep); + } +} + +LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) +{ + LLViewerObject* obj = NULL; + if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet + { + //add the object + obj = gObjectList.processObjectUpdateFromCache(entry, this); + if(obj) + { + if(!entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mWaitingSet.insert(entry); + entry->setState(LLVOCacheEntry::WAITING); + } + } + } + else + { + llerrs << "Object is already created." << llendl; + } + return obj; +} // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() @@ -908,9 +1370,8 @@ void LLViewerRegion::updateNetStats() mPacketsLost = cdp->getPacketsLost(); mPingDelay = cdp->getPingDelay(); - mBitStat.addValue(mBitsIn - mLastBitsIn); - mPacketsStat.addValue(mPacketsIn - mLastPacketsIn); - mPacketsLostStat.addValue(mPacketsLost); + mBitsReceived += mBitsIn - mLastBitsIn; + mPacketsReceived += mPacketsIn - mLastPacketsIn; } @@ -1190,8 +1651,9 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { U32 local_id = objectp->getLocalID(); U32 crc = objectp->getCRC(); + eCacheUpdateResult result; - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1200,41 +1662,72 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { // Record a hit entry->recordDupe(); - return CACHE_UPDATE_DUPE; + result = CACHE_UPDATE_DUPE; } + else + { + // Update the cache entry + LLPointer<LLVOCacheEntry> new_entry = new LLVOCacheEntry(local_id, crc, dp); + replaceCacheEntry(entry, new_entry); + entry = new_entry; - // Update the cache entry - mImpl->mCacheMap.erase(local_id); - delete entry; + result = CACHE_UPDATE_CHANGED; + } + } + else + { + // we haven't seen this object before + // Create new entry and add to map + result = CACHE_UPDATE_ADDED; + //if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) + //{ + // delete mImpl->mCacheMap.begin()->second ; + // mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); + // result = CACHE_UPDATE_REPLACED; + // + //} entry = new LLVOCacheEntry(local_id, crc, dp); + mImpl->mCacheMap[local_id] = entry; - return CACHE_UPDATE_CHANGED; } - // we haven't seen this object before + if(objectp->mDrawable.notNull() && !entry->getEntry()) + { + entry->setOctreeEntry(objectp->mDrawable->getEntry()); + } + if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addActiveCacheEntry(entry); + } + + return result; +} - // Create new entry and add to map - eCacheUpdateResult result = CACHE_UPDATE_ADDED; - if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) +LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) { - delete mImpl->mCacheMap.begin()->second ; - mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); - result = CACHE_UPDATE_REPLACED; + LLVOCacheEntry* entry = getCacheEntry(local_id); + removeFromVOCacheTree(entry); + return entry; } - entry = new LLVOCacheEntry(local_id, crc, dp); - mImpl->mCacheMap[local_id] = entry; - return result; +LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) +{ + LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id); + if(iter != mImpl->mCacheMap.end()) + { + return iter->second; + } + return NULL; } // Get data packer for this object, if we have cached data // AND the CRC matches. JC -LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) +bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type) { //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1244,7 +1737,14 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) // Record a hit entry->recordHit(); cache_miss_type = CACHE_MISS_TYPE_NONE; - return entry->getDP(crc); + + if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) + { + return true; + } + + addVisibleCacheEntry(entry); + return true; } else { @@ -1260,7 +1760,7 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) mCacheMissFull.put(local_id); } - return NULL; + return false; } void LLViewerRegion::addCacheMissFull(const U32 local_id) @@ -1542,7 +2042,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("LandResources"); capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); - capabilityNames.append("MeshUploadFlag"); + capabilityNames.append("MeshUploadFlag"); capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ObjectMedia"); @@ -1581,7 +2081,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ViewerMetrics"); capabilityNames.append("ViewerStartAuction"); capabilityNames.append("ViewerStats"); - + // Please add new capabilities alphabetically to reduce // merge conflicts. } @@ -1783,9 +2283,18 @@ void LLViewerRegion::logActiveCapabilities() const LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type) { - if (type < mImpl->mObjectPartition.size()) + if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) + { + return (LLSpatialPartition*)mImpl->mObjectPartition[type]; + } + return NULL; +} + +LLVOCachePartition* LLViewerRegion::getVOCachePartition() +{ + if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size()) { - return mImpl->mObjectPartition[type]; + return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE]; } return NULL; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c9fffaf30e..9252923aa3 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -34,7 +34,6 @@ #include "lldarray.h" #include "llwind.h" -#include "llstat.h" #include "v3dmath.h" #include "llstring.h" #include "llregionflags.h" @@ -66,8 +65,11 @@ class LLDataPacker; class LLDataPackerBinaryBuffer; class LLHost; class LLBBox; - +class LLSpatialGroup; +class LLDrawable; class LLViewerRegionImpl; +class LLviewerOctreeGroup; +class LLVOCachePartition; class LLViewerRegion: public LLCapabilityProvider // implements this interface { @@ -84,7 +86,8 @@ public: PARTITION_GRASS, PARTITION_VOLUME, PARTITION_BRIDGE, - PARTITION_HUD_PARTICLE, + PARTITION_HUD_PARTICLE, + PARTITION_VO_CACHE, PARTITION_NONE, NUM_PARTITIONS } eObjectPartitions; @@ -216,6 +219,12 @@ public: F32 getWidth() const { return mWidth; } BOOL idleUpdate(F32 max_update_time); + void addVisibleGroup(LLviewerOctreeGroup* group); + void addVisibleCacheEntry(LLVOCacheEntry* entry); + void addActiveCacheEntry(LLVOCacheEntry* entry); + void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); + void killCacheEntry(U32 local_id); //physically delete the cache entry + void clearVisibleGroup(LLviewerOctreeGroup* group); // Like idleUpdate, but forces everything to complete regardless of // how long it takes. @@ -305,8 +314,9 @@ public: } eCacheUpdateResult; // handle a full update message - eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); - LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type); + eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); + LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); + bool probeCache(U32 local_id, U32 crc, U8 &cache_miss_type); void requestCacheMisses(); void addCacheMissFull(const U32 local_id); @@ -322,7 +332,9 @@ public: virtual std::string getDescription() const; std::string getHttpUrl() const { return mHttpUrl ;} + U32 getNumOfActiveCachedObjects() const; LLSpatialPartition* getSpatialPartition(U32 type); + LLVOCachePartition* getVOCachePartition(); bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; @@ -331,6 +343,19 @@ public: void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); void getNeighboringRegionsStatus( std::vector<S32>& regions ); +private: + void addToVOCacheTree(LLVOCacheEntry* entry); + LLViewerObject* addNewObject(LLVOCacheEntry* entry); + void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list); + LLVOCacheEntry* getCacheEntry(U32 local_id); + void removeFromVOCacheTree(LLVOCacheEntry* entry); + void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); + void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry + + F32 killInvisibleObjects(F32 max_time); + F32 createVisibleObjects(F32 max_time); + F32 updateVisibleEntries(F32 max_time); //update visible entries + public: struct CompareDistance { @@ -351,9 +376,8 @@ public: LLWind mWind; LLViewerParcelOverlay *mParcelOverlay; - LLStat mBitStat; - LLStat mPacketsStat; - LLStat mPacketsLostStat; + F32 mBitsReceived; + F32 mPacketsReceived; LLMatrix4 mRenderMatrix; @@ -365,6 +389,8 @@ public: LLDynamicArray<U32> mMapAvatars; LLDynamicArray<LLUUID> mMapAvatarIDs; + static LLViewerRegion* sCurRegionp; + static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not. private: LLViewerRegionImpl * mImpl; @@ -408,18 +434,17 @@ private: // Maps local ids to cache entries. // Regions can have order 10,000 objects, so assume // a structure of size 2^14 = 16,000 - BOOL mCacheLoaded; - BOOL mCacheDirty; + BOOL mCacheLoaded; + BOOL mCacheDirty; + BOOL mAlive; // can become false if circuit disconnects + BOOL mCapabilitiesReceived; + BOOL mReleaseNotesRequested; + BOOL mDead; //if true, this region is in the process of deleting. LLDynamicArray<U32> mCacheMissFull; LLDynamicArray<U32> mCacheMissCRC; - - bool mAlive; // can become false if circuit disconnects - bool mCapabilitiesReceived; - caps_received_signal_t mCapabilitiesReceivedSignal; - - BOOL mReleaseNotesRequested; + caps_received_signal_t mCapabilitiesReceivedSignal; LLSD mSimulatorFeatures; }; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ba9818946c..28bd02c606 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -78,6 +78,8 @@ LLGLSLShader gGlowCombineProgram; LLGLSLShader gSplatTextureRectProgram; LLGLSLShader gGlowCombineFXAAProgram; LLGLSLShader gTwoTextureAddProgram; +LLGLSLShader gTwoTextureCompareProgram; +LLGLSLShader gOneTextureFilterProgram; LLGLSLShader gOneTextureNoColorProgram; LLGLSLShader gDebugProgram; LLGLSLShader gClipProgram; @@ -672,6 +674,8 @@ void LLViewerShaderMgr::unloadShaders() gSplatTextureRectProgram.unload(); gGlowCombineFXAAProgram.unload(); gTwoTextureAddProgram.unload(); + gTwoTextureCompareProgram.unload(); + gOneTextureFilterProgram.unload(); gOneTextureNoColorProgram.unload(); gSolidColorProgram.unload(); @@ -2709,6 +2713,37 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { + gTwoTextureCompareProgram.mName = "Two Texture Compare Shader"; + gTwoTextureCompareProgram.mShaderFiles.clear(); + gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB)); + gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTwoTextureCompareProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gTwoTextureCompareProgram.createShader(NULL, NULL); + if (success) + { + gTwoTextureCompareProgram.bind(); + gTwoTextureCompareProgram.uniform1i("tex0", 0); + gTwoTextureCompareProgram.uniform1i("tex1", 1); + } + } + + if (success) + { + gOneTextureFilterProgram.mName = "One Texture Filter Shader"; + gOneTextureFilterProgram.mShaderFiles.clear(); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB)); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOneTextureFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gOneTextureFilterProgram.createShader(NULL, NULL); + if (success) + { + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1i("tex0", 0); + } + } + + if (success) + { gOneTextureNoColorProgram.mName = "One Texture No Color Shader"; gOneTextureNoColorProgram.mShaderFiles.clear(); gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index d6dd645e8c..3e7c615f23 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -233,7 +233,11 @@ extern LLGLSLShader gAlphaMaskProgram; //output tex0[tc0] + tex1[tc1] extern LLGLSLShader gTwoTextureAddProgram; - +//output tex0[tc0] - tex1[tc1] +extern LLGLSLShader gTwoTextureCompareProgram; +//discard some fragments based on user-set color tolerance +extern LLGLSLShader gOneTextureFilterProgram; + extern LLGLSLShader gOneTextureNoColorProgram; //object shaders diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 35839ae459..fa4eb73180 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -61,363 +61,240 @@ #include "llviewernetwork.h" #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived - -class StatAttributes +namespace LLStatViewer { -public: - StatAttributes(const char* name, - const BOOL enabled, - const BOOL is_timer) - : mName(name), - mEnabled(enabled), - mIsTimer(is_timer) - { - } + +LLTrace::CountStatHandle<> FPS("fpsstat"), + PACKETS_IN("packetsinstat"), + PACKETS_LOST("packetsloststat"), + PACKETS_OUT("packetsoutstat"), + TEXTURE_PACKETS("texturepacketsstat"), + TRIANGLES_DRAWN("trianglesdrawnstat"), + CHAT_COUNT("chatcount", "Chat messages sent"), + IM_COUNT("imcount", "IMs sent"), + OBJECT_CREATE("objectcreate"), + OBJECT_REZ("objectrez", "Object rez count"), + LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"), + LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"), + LSL_SAVES("lslsaves", "Number of times user has saved a script"), + ANIMATION_UPLOADS("animationuploads", "Animations uploaded"), + FLY("fly", "Fly count"), + TELEPORT("teleport", "Teleport count"), + DELETE_OBJECT("deleteobject", "Objects deleted"), + SNAPSHOT("snapshot", "Snapshots taken"), + UPLOAD_SOUND("uploadsound", "Sounds uploaded"), + UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"), + EDIT_TEXTURE("edittexture", "Changes to textures on objects"), + KILLED("killed", "Number of times killed"), + FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"), + TEX_BAKES("texbakes"), + TEX_REBAKES("texrebakes"), + NUM_NEW_OBJECTS("numnewobjectsstat"); +LLTrace::CountStatHandle<LLTrace::Kilobits> KBIT("kbitstat"), + LAYERS_KBIT("layerskbitstat"), + OBJECT_KBIT("objectkbitstat"), + ASSET_KBIT("assetkbitstat"), + TEXTURE_KBIT("texturekbitstat"), + ACTUAL_IN_KBIT("actualinkbitstat"), + ACTUAL_OUT_KBIT("actualoutkbitstat"); + +LLTrace::CountStatHandle<LLTrace::Seconds> AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"), + TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), + MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), + FPS_10_TIME("fps10time", "Seconds below 10 FPS"), + FPS_8_TIME("fps8time", "Seconds below 8 FPS"), + FPS_2_TIME("fps2time", "Seconds below 2 FPS"), + SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), + SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), + LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); + +SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DILATION), + SIM_FPS("simfps", "", LL_SIM_STAT_FPS), + SIM_PHYSICS_FPS("simphysicsfps", "", LL_SIM_STAT_PHYSFPS), + SIM_AGENT_UPS("simagentups", "", LL_SIM_STAT_AGENTUPS), + SIM_SCRIPT_EPS("simscripteps", "", LL_SIM_STAT_SCRIPT_EPS), + SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps", "", LL_SIM_STAT_SKIPPEDAISILSTEPS_PS), + SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters", "", LL_SIM_STAT_PCTSTEPPEDCHARACTERS), + SIM_MAIN_AGENTS("simmainagents", "", LL_SIM_STAT_NUMAGENTMAIN), + SIM_CHILD_AGENTS("simchildagents", "", LL_SIM_STAT_NUMAGENTCHILD), + SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS), + SIM_ACTIVE_OBJECTS("simactiveobjects", "", LL_SIM_STAT_NUMTASKSACTIVE), + SIM_ACTIVE_SCRIPTS("simactivescripts", "", LL_SIM_STAT_NUMSCRIPTSACTIVE), + SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun", "", LL_SIM_STAT_PCTSCRIPTSRUN), + SIM_IN_PACKETS_PER_SEC("siminpps", "", LL_SIM_STAT_INPPS), + SIM_OUT_PACKETS_PER_SEC("simoutpps", "", LL_SIM_STAT_OUTPPS), + SIM_PENDING_DOWNLOADS("simpendingdownloads", "", LL_SIM_STAT_PENDING_DOWNLOADS), + SIM_PENDING_UPLOADS("simpendinguploads", "", LL_SIM_STAT_PENDING_UPLOADS), + SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads", "", LL_SIM_STAT_PENDING_LOCAL_UPLOADS), + SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS), + SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS); + +LLTrace::MeasurementStatHandle<> FPS_SAMPLE("fpssample"), + NUM_IMAGES("numimagesstat"), + NUM_RAW_IMAGES("numrawimagesstat"), + NUM_OBJECTS("numobjectsstat"), + NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), + NUM_SIZE_CULLED("numsizeculledstat"), + NUM_VIS_CULLED("numvisculledstat"), + ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), + LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), + VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), + SHADER_OBJECTS("shaderobjects", "Object Shaders"), + DRAW_DISTANCE("drawdistance", "Draw Distance"), + CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"), + PENDING_VFS_OPERATIONS("vfspendingoperations"), + PACKETS_LOST_PERCENT("packetslostpercentstat"), + WINDOW_WIDTH("windowwidth", "Window width"), + WINDOW_HEIGHT("windowheight", "Window height"); - std::string mName; - BOOL mEnabled; - BOOL mIsTimer; -}; +LLTrace::MeasurementStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); -const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] = -{ - // ST_VERSION - StatAttributes("Version", TRUE, FALSE), - // ST_AVATAR_EDIT_SECONDS - StatAttributes("Seconds in Edit Appearence", FALSE, TRUE), - // ST_TOOLBOX_SECONDS - StatAttributes("Seconds using Toolbox", FALSE, TRUE), - // ST_CHAT_COUNT - StatAttributes("Chat messages sent", FALSE, FALSE), - // ST_IM_COUNT - StatAttributes("IMs sent", FALSE, FALSE), - // ST_FULLSCREEN_BOOL - StatAttributes("Fullscreen mode", FALSE, FALSE), - // ST_RELEASE_COUNT - StatAttributes("Object release count", FALSE, FALSE), - // ST_CREATE_COUNT - StatAttributes("Object create count", FALSE, FALSE), - // ST_REZ_COUNT - StatAttributes("Object rez count", FALSE, FALSE), - // ST_FPS_10_SECONDS - StatAttributes("Seconds below 10 FPS", FALSE, TRUE), - // ST_FPS_2_SECONDS - StatAttributes("Seconds below 2 FPS", FALSE, TRUE), - // ST_MOUSELOOK_SECONDS - StatAttributes("Seconds in Mouselook", FALSE, TRUE), - // ST_FLY_COUNT - StatAttributes("Fly count", FALSE, FALSE), - // ST_TELEPORT_COUNT - StatAttributes("Teleport count", FALSE, FALSE), - // ST_OBJECT_DELETE_COUNT - StatAttributes("Objects deleted", FALSE, FALSE), - // ST_SNAPSHOT_COUNT - StatAttributes("Snapshots taken", FALSE, FALSE), - // ST_UPLOAD_SOUND_COUNT - StatAttributes("Sounds uploaded", FALSE, FALSE), - // ST_UPLOAD_TEXTURE_COUNT - StatAttributes("Textures uploaded", FALSE, FALSE), - // ST_EDIT_TEXTURE_COUNT - StatAttributes("Changes to textures on objects", FALSE, FALSE), - // ST_KILLED_COUNT - StatAttributes("Number of times killed", FALSE, FALSE), - // ST_FRAMETIME_JITTER - StatAttributes("Average delta between sucessive frame times", FALSE, FALSE), - // ST_FRAMETIME_SLEW - StatAttributes("Average delta between frame time and mean", FALSE, FALSE), - // ST_INVENTORY_TOO_LONG - StatAttributes("Inventory took too long to load", FALSE, FALSE), - // ST_WEARABLES_TOO_LONG - StatAttributes("Wearables took too long to load", FALSE, FALSE), - // ST_LOGIN_SECONDS - StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE), - // ST_LOGIN_TIMEOUT_COUNT - StatAttributes("Number of login attempts that timed out", FALSE, FALSE), - // ST_HAS_BAD_TIMER - StatAttributes("Known bad timer if != 0.0", FALSE, FALSE), - // ST_DOWNLOAD_FAILED - StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE), - // ST_LSL_SAVE_COUNT - StatAttributes("Number of times user has saved a script", FALSE, FALSE), - // ST_UPLOAD_ANIM_COUNT - StatAttributes("Animations uploaded", FALSE, FALSE), - // ST_FPS_8_SECONDS - StatAttributes("Seconds below 8 FPS", FALSE, TRUE), - // ST_SIM_FPS_20_SECONDS - StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE), - // ST_PHYS_FPS_20_SECONDS - StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE), - // ST_LOSS_05_SECONDS - StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE), - // ST_FPS_DROP_50_RATIO - StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE), - // ST_ENABLE_VBO - StatAttributes("Vertex Buffers Enabled", TRUE, FALSE), - // ST_DELTA_BANDWIDTH - StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE), - // ST_MAX_BANDWIDTH - StatAttributes("Max bandwidth setting", FALSE, FALSE), - // ST_LIGHTING_DETAIL - StatAttributes("Lighting Detail", FALSE, FALSE), - // ST_VISIBLE_AVATARS - StatAttributes("Visible Avatars", FALSE, FALSE), - // ST_SHADER_OJECTS - StatAttributes("Object Shaders", FALSE, FALSE), - // ST_SHADER_ENVIRONMENT - StatAttributes("Environment Shaders", FALSE, FALSE), - // ST_VISIBLE_DRAW_DIST - StatAttributes("Draw Distance", FALSE, FALSE), - // ST_VISIBLE_CHAT_BUBBLES - StatAttributes("Chat Bubbles Enabled", FALSE, FALSE), - // ST_SHADER_AVATAR - StatAttributes("Avatar Shaders", FALSE, FALSE), - // ST_FRAME_SECS - StatAttributes("FRAME_SECS", FALSE, FALSE), - // ST_UPDATE_SECS - StatAttributes("UPDATE_SECS", FALSE, FALSE), - // ST_NETWORK_SECS - StatAttributes("NETWORK_SECS", FALSE, FALSE), - // ST_IMAGE_SECS - StatAttributes("IMAGE_SECS", FALSE, FALSE), - // ST_REBUILD_SECS - StatAttributes("REBUILD_SECS", FALSE, FALSE), - // ST_RENDER_SECS - StatAttributes("RENDER_SECS", FALSE, FALSE), - // ST_CROSSING_AVG - StatAttributes("CROSSING_AVG", FALSE, FALSE), - // ST_CROSSING_MAX - StatAttributes("CROSSING_MAX", FALSE, FALSE), - // ST_LIBXUL_WIDGET_USED - StatAttributes("LibXUL Widget used", FALSE, FALSE), // Unused - // ST_WINDOW_WIDTH - StatAttributes("Window width", FALSE, FALSE), - // ST_WINDOW_HEIGHT - StatAttributes("Window height", FALSE, FALSE), - // ST_TEX_BAKES - StatAttributes("Texture Bakes", FALSE, FALSE), - // ST_TEX_REBAKES - StatAttributes("Texture Rebakes", FALSE, FALSE) -}; +LLTrace::MeasurementStatHandle<LLTrace::Bytes> GL_TEX_MEM("gltexmemstat"), + GL_BOUND_MEM("glboundmemstat"), + RAW_MEM("rawmemstat"), + FORMATTED_MEM("formattedmemstat"), + DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), + MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); -LLViewerStats::LLViewerStats() : - mKBitStat("kbitstat"), - mLayersKBitStat("layerskbitstat"), - mObjectKBitStat("objectkbitstat"), - mAssetKBitStat("assetkbitstat"), - mTextureKBitStat("texturekbitstat"), - mVFSPendingOperations("vfspendingoperations"), - mObjectsDrawnStat("objectsdrawnstat"), - mObjectsCulledStat("objectsculledstat"), - mObjectsTestedStat("objectstestedstat"), - mObjectsComparedStat("objectscomparedstat"), - mObjectsOccludedStat("objectsoccludedstat"), - mFPSStat("fpsstat"), - mPacketsInStat("packetsinstat"), - mPacketsLostStat("packetsloststat"), - mPacketsOutStat("packetsoutstat"), - mPacketsLostPercentStat("packetslostpercentstat", 64), - mTexturePacketsStat("texturepacketsstat"), - mActualInKBitStat("actualinkbitstat"), - mActualOutKBitStat("actualoutkbitstat"), - mTrianglesDrawnStat("trianglesdrawnstat"), - mSimTimeDilation("simtimedilation"), - mSimFPS("simfps"), - mSimPhysicsFPS("simphysicsfps"), - mSimAgentUPS("simagentups"), - mSimScriptEPS("simscripteps"), - mSimFrameMsec("simframemsec"), - mSimNetMsec("simnetmsec"), - mSimSimOtherMsec("simsimothermsec"), - mSimSimPhysicsMsec("simsimphysicsmsec"), - mSimSimPhysicsStepMsec("simsimphysicsstepmsec"), - mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"), - mSimSimPhysicsOtherMsec("simsimphysicsothermsec"), - mSimSimAIStepMsec("simsimaistepmsec"), - mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"), - mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"), - mSimAgentMsec("simagentmsec"), - mSimImagesMsec("simimagesmsec"), - mSimScriptMsec("simscriptmsec"), - mSimSpareMsec("simsparemsec"), - mSimSleepMsec("simsleepmsec"), - mSimPumpIOMsec("simpumpiomsec"), - mSimMainAgents("simmainagents"), - mSimChildAgents("simchildagents"), - mSimObjects("simobjects"), - mSimActiveObjects("simactiveobjects"), - mSimActiveScripts("simactivescripts"), - mSimPctScriptsRun("simpctscriptsrun"), - mSimInPPS("siminpps"), - mSimOutPPS("simoutpps"), - mSimPendingDownloads("simpendingdownloads"), - mSimPendingUploads("simpendinguploads"), - mSimPendingLocalUploads("simpendinglocaluploads"), - mSimTotalUnackedBytes("simtotalunackedbytes"), - mPhysicsPinnedTasks("physicspinnedtasks"), - mPhysicsLODTasks("physicslodtasks"), - mPhysicsMemoryAllocated("physicsmemoryallocated"), - mSimPingStat("simpingstat"), - mNumImagesStat("numimagesstat", 32, TRUE), - mNumRawImagesStat("numrawimagesstat", 32, TRUE), - mGLTexMemStat("gltexmemstat", 32, TRUE), - mGLBoundMemStat("glboundmemstat", 32, TRUE), - mRawMemStat("rawmemstat", 32, TRUE), - mFormattedMemStat("formattedmemstat", 32, TRUE), - mNumObjectsStat("numobjectsstat"), - mNumActiveObjectsStat("numactiveobjectsstat"), - mNumNewObjectsStat("numnewobjectsstat"), - mNumSizeCulledStat("numsizeculledstat"), - mNumVisCulledStat("numvisculledstat"), - mLastTimeDiff(0.0) -{ - for (S32 i = 0; i < ST_COUNT; i++) - { - mStats[i] = 0.0; - } - if (LLTimer::knownBadTimer()) - { - mStats[ST_HAS_BAD_TIMER] = 1.0; - } +SimMeasurement<LLTrace::Milliseconds> SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS), + SIM_NET_TIME("simnetmsec", "", LL_SIM_STAT_NETMS), + SIM_OTHER_TIME("simsimothermsec", "", LL_SIM_STAT_SIMOTHERMS), + SIM_PHYSICS_TIME("simsimphysicsmsec", "", LL_SIM_STAT_SIMPHYSICSMS), + SIM_PHYSICS_STEP_TIME("simsimphysicsstepmsec", "", LL_SIM_STAT_SIMPHYSICSSTEPMS), + SIM_PHYSICS_SHAPE_UPDATE_TIME("simsimphysicsshapeupdatemsec", "", LL_SIM_STAT_SIMPHYSICSSHAPEMS), + SIM_PHYSICS_OTHER_TIME("simsimphysicsothermsec", "", LL_SIM_STAT_SIMPHYSICSOTHERMS), + SIM_AI_TIME("simsimaistepmsec", "", LL_SIM_STAT_SIMAISTEPTIMEMS), + SIM_AGENTS_TIME("simagentmsec", "", LL_SIM_STAT_AGENTMS), + SIM_IMAGES_TIME("simimagesmsec", "", LL_SIM_STAT_IMAGESMS), + SIM_SCRIPTS_TIME("simscriptmsec", "", LL_SIM_STAT_SCRIPTMS), + SIM_SPARE_TIME("simsparemsec", "", LL_SIM_STAT_SIMSPARETIME), + SIM_SLEEP_TIME("simsleepmsec", "", LL_SIM_STAT_SIMSLEEPTIME), + SIM_PUMP_IO_TIME("simpumpiomsec", "", LL_SIM_STAT_IOPUMPTIME); + +SimMeasurement<LLTrace::Bytes> SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES), + SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); + + +LLTrace::MeasurementStatHandle<LLTrace::Milliseconds> FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), + FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), + LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"), + REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), + FRAME_STACKTIME("framestacktime", "FRAME_SECS"), + UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), + NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), + IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), + REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), + RENDER_STACKTIME("renderstacktime", "RENDER_SECS"), + SIM_PING("simpingstat"); - mAgentPositionSnaps.reset(); -} - -LLViewerStats::~LLViewerStats() -{ -} - -void LLViewerStats::resetStats() -{ - LLViewerStats& stats = LLViewerStats::instance(); - stats.mKBitStat.reset(); - stats.mLayersKBitStat.reset(); - stats.mObjectKBitStat.reset(); - stats.mTextureKBitStat.reset(); - stats.mVFSPendingOperations.reset(); - stats.mAssetKBitStat.reset(); - stats.mPacketsInStat.reset(); - stats.mPacketsLostStat.reset(); - stats.mPacketsOutStat.reset(); - stats.mFPSStat.reset(); - stats.mTexturePacketsStat.reset(); - stats.mAgentPositionSnaps.reset(); } - -F64 LLViewerStats::getStat(EStatType type) const +LLViewerStats::LLViewerStats() +: mLastTimeDiff(0.0) { - return mStats[type]; + mRecording.start(); + LLTrace::get_frame_recording().start(); } -F64 LLViewerStats::setStat(EStatType type, F64 value) +LLViewerStats::~LLViewerStats() { - mStats[type] = value; - return mStats[type]; } -F64 LLViewerStats::incStat(EStatType type, F64 value) +void LLViewerStats::resetStats() { - mStats[type] += value; - return mStats[type]; + LLViewerStats::instance().mRecording.reset(); } void LLViewerStats::updateFrameStats(const F64 time_diff) { - if (mPacketsLostPercentStat.getCurrent() > 5.0) + LLTrace::Seconds time_diff_seconds(time_diff); + if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0) { - incStat(ST_LOSS_05_SECONDS, time_diff); + add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff_seconds); } - if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f) + F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS); + if (0.f < sim_fps && sim_fps < 20.f) { - incStat(ST_SIM_FPS_20_SECONDS, time_diff); + add(LLStatViewer::SIM_20_FPS_TIME, time_diff_seconds); } - if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f) + F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS); + + if (0.f < sim_physics_fps && sim_physics_fps < 20.f) { - incStat(ST_PHYS_FPS_20_SECONDS, time_diff); + add(LLStatViewer::SIM_PHYSICS_20_FPS_TIME, time_diff_seconds); } if (time_diff >= 0.5) { - incStat(ST_FPS_2_SECONDS, time_diff); + add(LLStatViewer::FPS_2_TIME, time_diff_seconds); } if (time_diff >= 0.125) { - incStat(ST_FPS_8_SECONDS, time_diff); + add(LLStatViewer::FPS_8_TIME, time_diff_seconds); } if (time_diff >= 0.1) { - incStat(ST_FPS_10_SECONDS, time_diff); + add(LLStatViewer::FPS_10_TIME, time_diff_seconds); } if (gFrameCount && mLastTimeDiff > 0.0) { // new "stutter" meter - setStat(ST_FPS_DROP_50_RATIO, - (getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + - (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount); - + add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0); // old stats that were never really used - setStat(ST_FRAMETIME_JITTER, - (getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) + - fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount); + sample(LLStatViewer::FRAMETIME_JITTER, LLTrace::Milliseconds(mLastTimeDiff - time_diff)); F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; - setStat(ST_FRAMETIME_SLEW, - (getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) + - fabs(average_frametime - time_diff) / average_frametime) / gFrameCount); + sample(LLStatViewer::FRAMETIME_SLEW, LLTrace::Milliseconds(average_frametime - time_diff)); F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; - setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); - - setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); - + sample(LLStatViewer::DELTA_BANDWIDTH, LLTrace::Bits(delta_bandwidth)); + sample(LLStatViewer::MAX_BANDWIDTH, LLTrace::Bits(max_bandwidth)); } mLastTimeDiff = time_diff; - } void LLViewerStats::addToMessage(LLSD &body) const { LLSD &misc = body["misc"]; - for (S32 i = 0; i < ST_COUNT; i++) - { - if (STAT_INFO[i].mEnabled) - { - // TODO: send timer value so dataserver can normalize - misc[STAT_INFO[i].mName] = mStats[i]; - llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i] - << llendl; - } - } + misc["Version"] = TRUE; + //TODO RN: get last value, not mean + misc["Vertex Buffers Enabled"] = getRecording().getMean(LLStatViewer::ENABLE_VBO); - body["AgentPositionSnaps"] = mAgentPositionSnaps.getData(); - llinfos << "STAT: AgentPositionSnaps: Mean = " << mAgentPositionSnaps.getMean() << "; StdDev = " << mAgentPositionSnaps.getStdDev() - << "; Count = " << mAgentPositionSnaps.getCount() << llendl; + body["AgentPositionSnaps"] = getRecording().getSum(LLStatViewer::AGENT_POSITION_SNAP).value(); //mAgentPositionSnaps.asLLSD(); + llinfos << "STAT: AgentPositionSnaps: Mean = " << getRecording().getMean(LLStatViewer::AGENT_POSITION_SNAP).value() << "; StdDev = " << getRecording().getStandardDeviation(LLStatViewer::AGENT_POSITION_SNAP).value() + << "; Count = " << getRecording().getSampleCount(LLStatViewer::AGENT_POSITION_SNAP) << llendl; } // *NOTE:Mani The following methods used to exist in viewer.cpp // Moving them here, but not merging them into LLViewerStats yet. -U32 gTotalLandIn = 0, gTotalLandOut = 0; -U32 gTotalWaterIn = 0, gTotalWaterOut = 0; - -F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f; -F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f; -F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; - - - -U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0; -U32 gObjectBits = 0; +U32 gTotalLandIn = 0, + gTotalLandOut = 0, + gTotalWaterIn = 0, + gTotalWaterOut = 0; + +F32 gAveLandCompression = 0.f, + gAveWaterCompression = 0.f, + gBestLandCompression = 1.f, + gBestWaterCompression = 1.f, + gWorstLandCompression = 0.f, + gWorstWaterCompression = 0.f; + +LLUnit<LLUnits::Bytes, U32> gTotalWorldData = 0, + gTotalObjectData = 0, + gTotalTextureData = 0; +U32 gSimPingCount = 0; +LLUnit<LLUnits::Bits, U32> gObjectData = 0; F32 gAvgSimPing = 0.f; -U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; +LLUnit<LLUnits::Bytes, U32> gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; extern U32 gVisCompared; extern U32 gVisTested; @@ -426,59 +303,61 @@ LLFrameTimer gTextureTimer; void update_statistics() { - gTotalWorldBytes += gVLManager.getTotalBytes(); - gTotalObjectBytes += gObjectBits / 8; - - LLViewerStats& stats = LLViewerStats::instance(); + gTotalWorldData += gVLManager.getTotalBytes(); + gTotalObjectData += gObjectData; // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) { if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds); + add(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds); } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); + add(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds); } else if (LLFloaterReg::instanceVisible("build")) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); + add(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds); } } - stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); - stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); - stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); - stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); + sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); + sample(LLStatViewer::LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); + sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip")); + sample(LLStatViewer::CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); - stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); + sample(LLStatViewer::FRAME_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Frame"))); F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); - stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); - stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); - stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); - stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); - stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); + sample(LLStatViewer::UPDATE_STACKTIME, LLTrace::Seconds(idle_secs - network_secs)); + sample(LLStatViewer::NETWORK_STACKTIME, LLTrace::Seconds(network_secs)); + sample(LLStatViewer::IMAGE_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Update Images"))); + sample(LLStatViewer::REBUILD_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Sort Draw State"))); + sample(LLStatViewer::RENDER_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Geometry"))); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { - stats.mSimPingStat.addValue(cdp->getPingDelay()); + sample(LLStatViewer::SIM_PING, LLTrace::Milliseconds(cdp->getPingDelay())); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { - stats.mSimPingStat.addValue(10000); + sample(LLStatViewer::SIM_PING, LLTrace::Seconds(10)); } - stats.mFPSStat.addValue(1); + add(LLStatViewer::FPS, 1); + if (LLTrace::get_frame_recording().getTotalRecording().getSampleCount(LLStatViewer::FPS)) + { + sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getTotalRecording().getPerSec(LLStatViewer::FPS)); + } F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - stats.mLayersKBitStat.addValue(layer_bits/1024.f); - stats.mObjectKBitStat.addValue(gObjectBits/1024.f); - stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); - stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + add(LLStatViewer::LAYERS_KBIT, LLTrace::Bits(layer_bits)); + add(LLStatViewer::OBJECT_KBIT, gObjectData); + sample(LLStatViewer::PENDING_VFS_OPERATIONS, LLVFile::getVFSThread()->getPending()); + add(LLStatViewer::ASSET_KBIT, LLTrace::Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET))); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -499,14 +378,14 @@ void update_statistics() visible_avatar_frames = 1.f; avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } - stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); + sample(LLStatViewer::VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); // Reset all of these values. gVLManager.resetBitCounts(); - gObjectBits = 0; + gObjectData = 0; // gDecodedBits = 0; // Only update texture stats periodically so that they are less noisy @@ -515,11 +394,7 @@ void update_statistics() static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); - stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); - gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; - LLViewerTextureList::sTextureBits = 0; - LLViewerTextureList::sTexturePackets = 0; + gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)); texture_stats_timer.reset(); } } @@ -668,9 +543,9 @@ void send_stats() LLSD &download = body["downloads"]; - download["world_kbytes"] = gTotalWorldBytes / 1024.0; - download["object_kbytes"] = gTotalObjectBytes / 1024.0; - download["texture_kbytes"] = gTotalTextureBytes / 1024.0; + download["world_kbytes"] = LLTrace::Kilobytes(gTotalWorldData).value(); + download["object_kbytes"] = LLTrace::Kilobytes(gTotalObjectData).value(); + download["texture_kbytes"] = LLTrace::Kilobytes(gTotalTextureData).value(); download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; LLSD &in = body["stats"]["net"]["in"]; @@ -794,7 +669,7 @@ void LLViewerStats::PhaseMap::clearPhases() mPhaseMap.clear(); } -LLSD LLViewerStats::PhaseMap::dumpPhases() +LLSD LLViewerStats::PhaseMap::asLLSD() { LLSD result; for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter) diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index e02a4ccdc7..e94ba23163 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -1,5 +1,5 @@ /** - * @file llviewerstats.h + * @file llviewerim_peningtats.h * @brief LLViewerStats class header file * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ @@ -27,168 +27,181 @@ #ifndef LL_LLVIEWERSTATS_H #define LL_LLVIEWERSTATS_H -#include "llstat.h" +#include "llstatenums.h" #include "lltextureinfo.h" +#include "lltracerecording.h" +#include "lltrace.h" + +namespace LLStatViewer +{ + +struct SimMeasurementSampler : public LLInstanceTracker<SimMeasurementSampler, ESimStatID> +{ + SimMeasurementSampler(ESimStatID id) + : LLInstanceTracker<SimMeasurementSampler, ESimStatID>(id) + {} + virtual ~SimMeasurementSampler() {} + + virtual void sample(F64 value) = 0; +}; + +template<typename T = F64> +struct SimMeasurement : public LLTrace::MeasurementStatHandle<T>, public SimMeasurementSampler +{ + SimMeasurement(const char* name, const char* description, ESimStatID stat_id) + : LLTrace::MeasurementStatHandle<T>(name, description), + SimMeasurementSampler(stat_id) + {} + + using SimMeasurementSampler::getInstance; + + /*virtual*/ void sample(F64 value) + { + LLTrace::sample(*this, value); + } +}; + +template<typename T, typename VALUE_T> +void sample(SimMeasurement<T>& measurement, VALUE_T value) +{ + LLTrace::sample(measurement, value); +} +extern LLTrace::CountStatHandle<> FPS, + PACKETS_IN, + PACKETS_LOST, + PACKETS_OUT, + TEXTURE_PACKETS, + TRIANGLES_DRAWN, + CHAT_COUNT, + IM_COUNT, + OBJECT_CREATE, + OBJECT_REZ, + LOADING_WEARABLES_LONG_DELAY, + LOGIN_TIMEOUTS, + LSL_SAVES, + ANIMATION_UPLOADS, + FLY, + TELEPORT, + DELETE_OBJECT, + SNAPSHOT, + UPLOAD_SOUND, + UPLOAD_TEXTURE, + EDIT_TEXTURE, + KILLED, + FRAMETIME_DOUBLED, + TEX_BAKES, + TEX_REBAKES, + NUM_NEW_OBJECTS; + + +extern LLTrace::CountStatHandle<LLTrace::Kilobits> KBIT, + LAYERS_KBIT, + OBJECT_KBIT, + ASSET_KBIT, + TEXTURE_KBIT, + ACTUAL_IN_KBIT, + ACTUAL_OUT_KBIT; + +extern LLTrace::CountStatHandle<LLTrace::Seconds> AVATAR_EDIT_TIME, + TOOLBOX_TIME, + MOUSELOOK_TIME, + FPS_10_TIME, + FPS_8_TIME, + FPS_2_TIME, + SIM_20_FPS_TIME, + SIM_PHYSICS_20_FPS_TIME, + LOSS_5_PERCENT_TIME; + +extern SimMeasurement<> SIM_TIME_DILATION, + SIM_FPS, + SIM_PHYSICS_FPS, + SIM_AGENT_UPS, + SIM_SCRIPT_EPS, + SIM_SKIPPED_SILHOUETTE, + SIM_SKIPPED_CHARACTERS_PERCENTAGE, + SIM_MAIN_AGENTS, + SIM_CHILD_AGENTS, + SIM_OBJECTS, + SIM_ACTIVE_OBJECTS, + SIM_ACTIVE_SCRIPTS, + SIM_PERCENTAGE_SCRIPTS_RUN, + SIM_IN_PACKETS_PER_SEC, + SIM_OUT_PACKETS_PER_SEC, + SIM_PENDING_DOWNLOADS, + SIM_PENDING_UPLOADS, + SIM_PENDING_LOCAL_UPLOADS, + SIM_PHYSICS_PINNED_TASKS, + SIM_PHYSICS_LOD_TASKS; + +extern LLTrace::MeasurementStatHandle<> FPS_SAMPLE, + NUM_IMAGES, + NUM_RAW_IMAGES, + NUM_OBJECTS, + NUM_ACTIVE_OBJECTS, + NUM_SIZE_CULLED, + NUM_VIS_CULLED, + ENABLE_VBO, + LIGHTING_DETAIL, + VISIBLE_AVATARS, + SHADER_OBJECTS, + DRAW_DISTANCE, + CHAT_BUBBLES, + PENDING_VFS_OPERATIONS, + PACKETS_LOST_PERCENT, + WINDOW_WIDTH, + WINDOW_HEIGHT; + +extern LLTrace::MeasurementStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP; + +extern LLTrace::MeasurementStatHandle<LLTrace::Bytes> DELTA_BANDWIDTH, + MAX_BANDWIDTH, + GL_TEX_MEM, + GL_BOUND_MEM, + RAW_MEM, + FORMATTED_MEM; + +extern SimMeasurement<LLTrace::Milliseconds> SIM_FRAME_TIME, + SIM_NET_TIME, + SIM_OTHER_TIME, + SIM_PHYSICS_TIME, + SIM_PHYSICS_STEP_TIME, + SIM_PHYSICS_SHAPE_UPDATE_TIME, + SIM_PHYSICS_OTHER_TIME, + SIM_AI_TIME, + SIM_AGENTS_TIME, + SIM_IMAGES_TIME, + SIM_SCRIPTS_TIME, + SIM_SPARE_TIME, + SIM_SLEEP_TIME, + SIM_PUMP_IO_TIME; + +extern SimMeasurement<LLTrace::Bytes> SIM_UNACKED_BYTES, + SIM_PHYSICS_MEM; + + +extern LLTrace::MeasurementStatHandle<LLTrace::Milliseconds> FRAMETIME_JITTER, + FRAMETIME_SLEW, + LOGIN_SECONDS, + REGION_CROSSING_TIME, + FRAME_STACKTIME, + UPDATE_STACKTIME, + NETWORK_STACKTIME, + IMAGE_STACKTIME, + REBUILD_STACKTIME, + RENDER_STACKTIME, + SIM_PING; +} class LLViewerStats : public LLSingleton<LLViewerStats> { public: - LLStat mKBitStat, - mLayersKBitStat, - mObjectKBitStat, - mAssetKBitStat, - mTextureKBitStat, - mVFSPendingOperations, - mObjectsDrawnStat, - mObjectsCulledStat, - mObjectsTestedStat, - mObjectsComparedStat, - mObjectsOccludedStat, - mFPSStat, - mPacketsInStat, - mPacketsLostStat, - mPacketsOutStat, - mPacketsLostPercentStat, - mTexturePacketsStat, - mActualInKBitStat, // From the packet ring (when faking a bad connection) - mActualOutKBitStat, // From the packet ring (when faking a bad connection) - mTrianglesDrawnStat; - - // Simulator stats - LLStat mSimTimeDilation, - - mSimFPS, - mSimPhysicsFPS, - mSimAgentUPS, - mSimScriptEPS, - - mSimFrameMsec, - mSimNetMsec, - mSimSimOtherMsec, - mSimSimPhysicsMsec, - - mSimSimPhysicsStepMsec, - mSimSimPhysicsShapeUpdateMsec, - mSimSimPhysicsOtherMsec, - mSimSimAIStepMsec, - mSimSimSkippedSilhouetteSteps, - mSimSimPctSteppedCharacters, - - mSimAgentMsec, - mSimImagesMsec, - mSimScriptMsec, - mSimSpareMsec, - mSimSleepMsec, - mSimPumpIOMsec, - - mSimMainAgents, - mSimChildAgents, - mSimObjects, - mSimActiveObjects, - mSimActiveScripts, - mSimPctScriptsRun, - - mSimInPPS, - mSimOutPPS, - mSimPendingDownloads, - mSimPendingUploads, - mSimPendingLocalUploads, - mSimTotalUnackedBytes, - - mPhysicsPinnedTasks, - mPhysicsLODTasks, - mPhysicsMemoryAllocated, - - mSimPingStat, - - mNumImagesStat, - mNumRawImagesStat, - mGLTexMemStat, - mGLBoundMemStat, - mRawMemStat, - mFormattedMemStat, - - mNumObjectsStat, - mNumActiveObjectsStat, - mNumNewObjectsStat, - mNumSizeCulledStat, - mNumVisCulledStat; - void resetStats(); + public: - // If you change this, please also add a corresponding text label in llviewerstats.cpp - enum EStatType - { - ST_VERSION = 0, - ST_AVATAR_EDIT_SECONDS = 1, - ST_TOOLBOX_SECONDS = 2, - ST_CHAT_COUNT = 3, - ST_IM_COUNT = 4, - ST_FULLSCREEN_BOOL = 5, - ST_RELEASE_COUNT= 6, - ST_CREATE_COUNT = 7, - ST_REZ_COUNT = 8, - ST_FPS_10_SECONDS = 9, - ST_FPS_2_SECONDS = 10, - ST_MOUSELOOK_SECONDS = 11, - ST_FLY_COUNT = 12, - ST_TELEPORT_COUNT = 13, - ST_OBJECT_DELETE_COUNT = 14, - ST_SNAPSHOT_COUNT = 15, - ST_UPLOAD_SOUND_COUNT = 16, - ST_UPLOAD_TEXTURE_COUNT = 17, - ST_EDIT_TEXTURE_COUNT = 18, - ST_KILLED_COUNT = 19, - ST_FRAMETIME_JITTER = 20, - ST_FRAMETIME_SLEW = 21, - ST_INVENTORY_TOO_LONG = 22, - ST_WEARABLES_TOO_LONG = 23, - ST_LOGIN_SECONDS = 24, - ST_LOGIN_TIMEOUT_COUNT = 25, - ST_HAS_BAD_TIMER = 26, - ST_DOWNLOAD_FAILED = 27, - ST_LSL_SAVE_COUNT = 28, - ST_UPLOAD_ANIM_COUNT = 29, - ST_FPS_8_SECONDS = 30, - ST_SIM_FPS_20_SECONDS = 31, - ST_PHYS_FPS_20_SECONDS = 32, - ST_LOSS_05_SECONDS = 33, - ST_FPS_DROP_50_RATIO = 34, - ST_ENABLE_VBO = 35, - ST_DELTA_BANDWIDTH = 36, - ST_MAX_BANDWIDTH = 37, - ST_LIGHTING_DETAIL = 38, - ST_VISIBLE_AVATARS = 39, - ST_SHADER_OBJECTS = 40, - ST_SHADER_ENVIRONMENT = 41, - ST_DRAW_DIST = 42, - ST_CHAT_BUBBLES = 43, - ST_SHADER_AVATAR = 44, - ST_FRAME_SECS = 45, - ST_UPDATE_SECS = 46, - ST_NETWORK_SECS = 47, - ST_IMAGE_SECS = 48, - ST_REBUILD_SECS = 49, - ST_RENDER_SECS = 50, - ST_CROSSING_AVG = 51, - ST_CROSSING_MAX = 52, - ST_LIBXUL_WIDGET_USED = 53, // Unused - ST_WINDOW_WIDTH = 54, - ST_WINDOW_HEIGHT = 55, - ST_TEX_BAKES = 56, - ST_TEX_REBAKES = 57, - - ST_COUNT = 58 - }; LLViewerStats(); ~LLViewerStats(); - // all return latest value of given stat - F64 getStat(EStatType type) const; - F64 setStat(EStatType type, F64 value); // set the stat to value - F64 incStat(EStatType type, F64 value = 1.f); // add value to the stat - void updateFrameStats(const F64 time_diff); void addToMessage(LLSD &body) const; @@ -263,7 +276,7 @@ public: mCountOfNextUpdatesToIgnore = 0; } - inline LLSD getData() const + inline LLSD asLLSD() const { LLSD data; data["mean"] = getMean(); @@ -275,8 +288,6 @@ public: } }; - StatsAccumulator mAgentPositionSnaps; - // Phase tracking (originally put in for avatar rezzing), tracking // progress of active/completed phases for activities like outfit changing. typedef std::map<std::string,LLFrameTimer> phase_map_t; @@ -293,13 +304,16 @@ public: void stopPhase(const std::string& phase_name); void stopAllPhases(); void clearPhases(); - LLSD dumpPhases(); + LLSD asLLSD(); static StatsAccumulator& getPhaseStats(const std::string& phase_name); static void recordPhaseStat(const std::string& phase_name, F32 value); }; + LLTrace::Recording& getRecording() { return mRecording; } + const LLTrace::Recording& getRecording() const { return mRecording; } + private: - F64 mStats[ST_COUNT]; + LLTrace::Recording mRecording; F64 mLastTimeDiff; // used for time stat updates }; @@ -311,7 +325,7 @@ void update_statistics(); void send_stats(); extern LLFrameTimer gTextureTimer; -extern U32 gTotalTextureBytes; -extern U32 gTotalObjectBytes; -extern U32 gTotalTextureBytesPerBoostLevel[] ; +extern LLUnit<LLUnits::Bytes, U32> gTotalTextureData; +extern LLUnit<LLUnits::Bytes, U32> gTotalObjectData; +extern LLUnit<LLUnits::Bytes, U32> gTotalTextureBytesPerBoostLevel[] ; #endif // LL_LLVIEWERSTATS_H diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index 91e485d01b..61d0f02fc1 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -216,18 +216,21 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) << "Texture Fetch bps\t" << "\n"; - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + if (fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ) != data_msg.str().size()) + { + llwarns << "Failed to write log file." << llendl; + } } else - { - llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; + { + //llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; return; } } - std::ostringstream data_msg; + std::ostringstream data_msg; - data_msg << getTimeSinceStart() + data_msg << getTimeSinceStart() << "\t " << mObjectCacheHitCount << "\t" << mObjectCacheMissFullCount << "\t" << mObjectCacheMissCrcCount @@ -247,9 +250,12 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) << "\t" << (mObjectTerseUpdatesSize * 8 / delta_time) << "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time) << "\t" << (mTextureFetchSize * 8 / delta_time) - << "\n"; + << "\n"; - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + if (fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ) != data_msg.str().size()) + { + llwarns << "Failed to write log file." << llendl; + } clearStats(); } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 08fcb60d03..7edfa6adfa 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -64,6 +64,11 @@ #include "lltexturecache.h" /////////////////////////////////////////////////////////////////////////////// +// extern +const LLUnit<LLUnits::Megabytes, S32> gMinVideoRam = 32; +const LLUnit<LLUnits::Megabytes, S32> gMaxVideoRam = 512; + + // statics LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL; LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL; @@ -82,11 +87,11 @@ S32 LLViewerTexture::sAuxCount = 0; LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0; -S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0; -S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; -S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; -S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; +LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sBoundTextureMemory = 0; +LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sTotalTextureMemory = 0; +LLUnit<LLUnits::Megabytes, S32> LLViewerTexture::sMaxBoundTextureMem = 0; +LLUnit<LLUnits::Megabytes, S32> LLViewerTexture::sMaxTotalTextureMem = 0; +LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sMaxDesiredTextureMem = 0 ; S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ; F32 LLViewerTexture::sCameraMovingBias = 0.0f ; S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size @@ -518,17 +523,17 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity LLViewerMediaTexture::updateClass() ; } - sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes - sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes - sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB - sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB - sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small. + sBoundTextureMemory = LLImageGL::sBoundTextureMemory;//in bytes + sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;//in bytes + sMaxBoundTextureMem = gTextureList.getMaxResidentTexMem();//in MB + sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem() ;//in MB + sMaxDesiredTextureMem = sMaxTotalTextureMem ; //in Bytes, by default and when total used texture memory is small. - if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes || - BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes) + if (sBoundTextureMemory >= sMaxBoundTextureMem || + sTotalTextureMemory >= sMaxTotalTextureMem) { - //when texture memory overflows, lower down the threashold to release the textures more aggressively. - sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB + //when texture memory overflows, lower down the threshold to release the textures more aggressively. + sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit<LLUnits::Bytes, S32>(gMaxVideoRam)); // If we are using more texture memory than we should, // scale up the desired discard level @@ -544,8 +549,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity sEvaluationTimer.reset(); } else if (sDesiredDiscardBias > 0.0f && - BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale && - BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale) + sBoundTextureMemory < sMaxBoundTextureMem * texmem_lower_bound_scale && + sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale) { // If we are using less texture memory than we should, // scale down the desired discard level @@ -563,8 +568,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); sCameraMovingDiscardBias = (S8)(sCameraMovingBias); - LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && - (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; + LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMem * texmem_middle_bound_scale) && + (sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale) ; } //end of static functions @@ -961,6 +966,12 @@ void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) //nothing here. } +BOOL LLViewerTexture::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->setSubImageFromFrameBuffer(fb_x, fb_y, x_pos, y_pos, width, height); +} + void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { llassert(mGLTexturep.notNull()) ; @@ -3330,13 +3341,13 @@ void LLViewerLODTexture::processTextureStats() scaleDown() ; } // Limit the amount of GL memory bound each frame - else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale && + else if ( sBoundTextureMemory > sMaxBoundTextureMem * texmem_middle_bound_scale && (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; } // Only allow GL to have 2x the video card memory - else if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale && + else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale && (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 2e7949e9a3..0a9778ce76 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -34,12 +34,13 @@ #include "llgltypes.h" #include "llrender.h" #include "llmetricperformancetester.h" +#include "llunit.h" #include <map> #include <list> -#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 -#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. +extern const LLUnit<LLUnits::Megabytes, S32> gMinVideoRam; +extern const LLUnit<LLUnits::Megabytes, S32> gMaxVideoRam; class LLFace; class LLImageGL ; @@ -211,6 +212,7 @@ public: BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER); virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; + BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); void setFilteringOption(LLTexUnit::eTextureFilterOptions option); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); void setAddressMode(LLTexUnit::eTextureAddressMode mode); @@ -323,11 +325,11 @@ public: static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; static F32 sDesiredDiscardScale; - static S32 sBoundTextureMemoryInBytes; - static S32 sTotalTextureMemoryInBytes; - static S32 sMaxBoundTextureMemInMegaBytes; - static S32 sMaxTotalTextureMemInMegaBytes; - static S32 sMaxDesiredTextureMemInBytes ; + static LLUnit<LLUnits::Bytes, S32> sBoundTextureMemory; + static LLUnit<LLUnits::Bytes, S32> sTotalTextureMemory; + static LLUnit<LLUnits::Megabytes, S32> sMaxBoundTextureMem; + static LLUnit<LLUnits::Megabytes, S32> sMaxTotalTextureMem; + static LLUnit<LLUnits::Bytes, S32> sMaxDesiredTextureMem ; static S8 sCameraMovingDiscardBias; static F32 sCameraMovingBias; static S32 sMaxSculptRez ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b9f5c432d0..0066c09720 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,21 +58,14 @@ #include "pipeline.h" #include "llappviewer.h" #include "llxuiparser.h" +#include "lltracerecording.h" #include "llviewerdisplay.h" //////////////////////////////////////////////////////////////////////////// void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; -U32 LLViewerTextureList::sTextureBits = 0; -U32 LLViewerTextureList::sTexturePackets = 0; S32 LLViewerTextureList::sNumImages = 0; -LLStat LLViewerTextureList::sNumImagesStat("Num Images", 32, TRUE); -LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", 32, TRUE); -LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", 32, TRUE); -LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", 32, TRUE); -LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", 32, TRUE); -LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", 32, TRUE); LLViewerTextureList gTextureList; static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images"); @@ -606,9 +599,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch"); static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch"); static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create"); static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats"); +static LLFastTimer::DeclareTimer FTM_UPDATE_IMAGES("Update Images"); void LLViewerTextureList::updateImages(F32 max_time) { + LLFastTimer _(FTM_UPDATE_IMAGES); static BOOL cleared = FALSE; if(gTeleportDisplay) { @@ -622,14 +617,19 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = FALSE; - LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); + LLTrace::Recording& recording = LLTrace::get_frame_recording().getTotalRecording(); - LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); - LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); - LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); - LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); - LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); - LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); + LLAppViewer::getTextureFetch()->setTextureBandwidth(recording.getPerSec(LLStatViewer::TEXTURE_KBIT).value()); + + { + using namespace LLStatViewer; + sample(NUM_IMAGES, sNumImages); + sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount); + sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory); + sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory); + sample(RAW_MEM, LLTrace::Bytes(LLImageRaw::sGlobalRawMemory)); + sample(FORMATTED_MEM, LLTrace::Bytes(LLImageFormatted::sGlobalFormattedMemory)); + } { //loading from fast cache @@ -711,7 +711,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() // Update the decode priority for N images each frame { static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 - const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); + const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES); S32 update_counter = llmin(max_update_count, mUUIDMap.size()); uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); while ((update_counter-- > 0) && !mUUIDMap.empty()) @@ -945,11 +945,11 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false - size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); + size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT); max_priority_count = llmin(max_priority_count, mImageList.size()); size_t total_update_count = mUUIDMap.size(); - size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); + size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT); max_update_count = llmin(max_update_count, total_update_count); // MAX_HIGH_PRIO_COUNT high priority entries @@ -1186,7 +1186,7 @@ S32 LLViewerTextureList::getMinVideoRamSetting() { S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); //min texture mem sets to 64M if total physical mem is more than 1.5GB - return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; + return (system_ram > 1500) ? 64 : gMinVideoRam.value() ; } //static @@ -1236,7 +1236,7 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) else max_texmem = llmin(max_texmem, (S32)(system_ram)); - max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam.value()); return max_texmem; } @@ -1324,8 +1324,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d { received_size = msg->getReceiveSize() ; } - gTextureList.sTextureBits += received_size * 8; - gTextureList.sTexturePackets++; + add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); + add(LLStatViewer::TEXTURE_PACKETS, 1); U8 codec; U16 packets; @@ -1397,8 +1397,9 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d { received_size = msg->getReceiveSize() ; } - gTextureList.sTextureBits += received_size * 8; - gTextureList.sTexturePackets++; + + add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); + add(LLStatViewer::TEXTURE_PACKETS, 1); //llprintline("Start decode, image header..."); msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 3dda973d3f..e3df71cca2 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -1,5 +1,5 @@ /** - * @file llviewertexturelist.h + * @file llviewertexturelinumimagest.h * @brief Object for managing the list of images within a region * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ @@ -30,7 +30,6 @@ #include "lluuid.h" //#include "message.h" #include "llgl.h" -#include "llstat.h" #include "llviewertexture.h" #include "llui.h" #include <list> @@ -200,17 +199,6 @@ private: S32 mMaxTotalTextureMemInMegaBytes; LLFrameTimer mForceDecodeTimer; -public: - static U32 sTextureBits; - static U32 sTexturePackets; - - static LLStat sNumImagesStat; - static LLStat sNumRawImagesStat; - static LLStat sGLTexMemStat; - static LLStat sGLBoundMemStat; - static LLStat sRawMemStat; - static LLStat sFormattedMemStat; - private: static S32 sNumImages; static void (*sUUIDCallback)(void**, const LLUUID &); diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp index 5147272122..34f2c8f6e6 100644 --- a/indra/newview/llviewerthrottle.cpp +++ b/indra/newview/llviewerthrottle.cpp @@ -304,7 +304,8 @@ void LLViewerThrottle::updateDynamicThrottle() } mUpdateTimer.reset(); - if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() > TIGHTEN_THROTTLE_THRESHOLD) + F32 mean_packets_lost = LLViewerStats::instance().getRecording().getMean(LLStatViewer::PACKETS_LOST_PERCENT); + if (mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD) { if (mThrottleFrac <= MIN_FRACTIONAL || mCurrentBandwidth / 1024.0f <= MIN_BANDWIDTH) { @@ -317,7 +318,7 @@ void LLViewerThrottle::updateDynamicThrottle() mCurrent.sendToSim(); llinfos << "Tightening network throttle to " << mCurrentBandwidth << llendl; } - else if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() <= EASE_THROTTLE_THRESHOLD) + else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD) { if (mThrottleFrac >= MAX_FRACTIONAL || mCurrentBandwidth / 1024.0f >= MAX_BANDWIDTH) { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 48a69129eb..fea44a38c6 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -77,7 +77,6 @@ #include "llmediaentry.h" #include "llurldispatcher.h" #include "raytrace.h" -#include "llstat.h" // newview includes #include "llagent.h" @@ -249,6 +248,9 @@ std::string LLViewerWindow::sSnapshotDir; std::string LLViewerWindow::sMovieBaseName; +LLTrace::MeasurementStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); + + class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole> { public: @@ -616,7 +618,7 @@ public: addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPRetryCount)); ypos += y_inc; - + addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing)); ypos += y_inc; @@ -734,7 +736,7 @@ public: { if(gTotalTextureBytesPerBoostLevel[i] > 0) { - addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, (F32)gTotalTextureBytesPerBoostLevel[i] / (1024 * 1024))); + addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, LLUnit<LLUnits::Megabytes, F32>(gTotalTextureBytesPerBoostLevel[i]).value())); ypos += y_inc; } } @@ -1405,10 +1407,11 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255))); std::string temp_str; + LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ - LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(), - LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0), - LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); + recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(), + recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS), + recording.getLastValue(LLStatViewer::SIM_TIME_DILATION)); S32 len = temp_str.length(); TextOutA(hdc, 0, 0, temp_str.c_str(), len); @@ -1543,8 +1546,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) mResDirty(false), mStatesDirty(false), mCurrResolutionIndex(0), - mProgressView(NULL), - mMouseVelocityStat(new LLStat("Mouse Velocity")) + mProgressView(NULL) { // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to // pass its value right now. Instead, pass it a nullary function that @@ -1933,7 +1935,7 @@ void LLViewerWindow::initWorldUI() panel_ssf_container->addChild(panel_stand_stop_flying); panel_ssf_container->setVisible(TRUE); - + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); // Load and make the toolbars visible @@ -1981,12 +1983,12 @@ void LLViewerWindow::shutdownViews() gMorphView->setVisible(FALSE); } llinfos << "Global views cleaned." << llendl ; - + // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open // will crump with LL_ERRS. LLModalDialog::shutdownModals(); llinfos << "LLModalDialog shut down." << llendl; - + // destroy the nav bar, not currently part of gViewerWindow // *TODO: Make LLNavigationBar part of gViewerWindow if (LLNavigationBar::instanceExists()) @@ -1994,17 +1996,17 @@ void LLViewerWindow::shutdownViews() delete LLNavigationBar::getInstance(); } llinfos << "LLNavigationBar destroyed." << llendl ; - + // destroy menus after instantiating navbar above, as it needs // access to gMenuHolder cleanup_menus(); llinfos << "menus destroyed." << llendl ; - + // Delete all child views. delete mRootView; mRootView = NULL; llinfos << "RootView deleted." << llendl ; - + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); // Automatically deleted as children of mRootView. Fix the globals. @@ -2074,8 +2076,6 @@ LLViewerWindow::~LLViewerWindow() delete mDebugText; mDebugText = NULL; - - delete mMouseVelocityStat; } @@ -2186,8 +2186,8 @@ void LLViewerWindow::reshape(S32 width, S32 height) } } - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height); + sample(LLStatViewer::WINDOW_WIDTH, width); + sample(LLStatViewer::WINDOW_HEIGHT, height); LLLayoutStack::updateClass(); } @@ -2763,11 +2763,12 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params) } } +static LLFastTimer::DeclareTimer ftm("Update UI"); + // Update UI based on stored mouse position from mouse-move // event processing. void LLViewerWindow::updateUI() { - static LLFastTimer::DeclareTimer ftm("Update UI"); LLFastTimer t(ftm); static std::string last_handle_msg; @@ -3237,8 +3238,8 @@ void LLViewerWindow::updateMouseDelta() static F32 fdy = 0.f; F32 amount = 16.f; - fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f); - fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f); + fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f); + fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f); mCurrentMouseDelta.set(llround(fdx), llround(fdy)); mouse_vel.setVec(fdx,fdy); @@ -3249,7 +3250,7 @@ void LLViewerWindow::updateMouseDelta() mouse_vel.setVec((F32) dx, (F32) dy); } - mMouseVelocityStat->addValue(mouse_vel.magVec()); + sample(sMouseVelocityStat, mouse_vel.magVec()); } void LLViewerWindow::updateKeyboardFocus() @@ -4740,7 +4741,7 @@ void LLViewerWindow::stopGL(BOOL save_state) gGLManager.mIsDisabled = TRUE; stop_glerror(); - llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemoryInBytes << " bytes" << llendl; + llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << llendl; } } @@ -4773,7 +4774,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) LLViewerDynamicTexture::restoreGL(); LLVOAvatar::restoreGL(); LLVOPartGroup::restoreGL(); - + gResizeScreenTexture = TRUE; gWindowResized = TRUE; @@ -5260,8 +5261,8 @@ void LLPickInfo::getSurfaceInfo() LLFace* facep = objectp->mDrawable->getFace(mObjectFace); if (facep) { - mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); - } + mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); + } } // and XY coords: diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 5f475fe145..004a59fda5 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -44,12 +44,12 @@ #include "llmousehandler.h" #include "llhandle.h" #include "llinitparam.h" +#include "lltrace.h" #include <boost/function.hpp> #include <boost/signals2.hpp> #include <boost/scoped_ptr.hpp> -class LLStat; class LLView; class LLViewerObject; class LLUUID; @@ -250,7 +250,7 @@ public: S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - LLStat* getMouseVelocityStat() { return mMouseVelocityStat; } + static LLTrace::MeasurementStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -427,7 +427,6 @@ private: LLCoordGL mCurrentMousePoint; // last mouse position in GL coords LLCoordGL mLastMousePoint; // Mouse point at last frame. LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame - LLStat* mMouseVelocityStat; BOOL mLeftMouseDown; BOOL mMiddleMouseDown; BOOL mRightMouseDown; @@ -482,6 +481,8 @@ private: // Object temporarily hovered over while dragging LLPointer<LLViewerObject> mDragHoveredObject; + + static LLTrace::MeasurementStatHandle<> sMouseVelocityStat; }; // diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 62e93b7a53..5a07cdf7c9 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -102,6 +102,7 @@ #include "lldebugmessagebox.h" #include "llsdutil.h" +#include "llscenemonitor.h" extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; @@ -771,6 +772,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastPelvisToFoot = 0.0f; mPelvisFixup = 0.0f; mLastPelvisFixup = 0.0f; + + if(LLSceneMonitor::getInstance()->isEnabled()) + { + LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); + } } std::string LLVOAvatar::avString() const @@ -2911,7 +2917,7 @@ void LLVOAvatar::idleUpdateWindEffect() LLVector3 velocity = getVelocity(); F32 speed = velocity.length(); //RN: velocity varies too much frame to frame for this to work - mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(0.02f)); + mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f)); mLastVel = velocity; LLVector4 wind; wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity); @@ -2934,11 +2940,11 @@ void LLVOAvatar::idleUpdateWindEffect() F32 interp; if (wind.mV[VW] > mWindVec.mV[VW]) { - interp = LLCriticalDamp::getInterpolant(0.2f); + interp = LLSmoothInterpolation::getInterpolant(0.2f); } else { - interp = LLCriticalDamp::getInterpolant(0.4f); + interp = LLSmoothInterpolation::getInterpolant(0.4f); } mWindVec = lerp(mWindVec, wind, interp); @@ -3788,7 +3794,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // Set the root rotation, but do so incrementally so that it // lags in time by some fixed amount. - //F32 u = LLCriticalDamp::getInterpolant(PELVIS_LAG); + //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG); F32 pelvis_lag_time = 0.f; if (self_in_mouselook) { @@ -4318,8 +4324,6 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) //-------------------------------------------------------------------- // render all geometry attached to the skeleton //-------------------------------------------------------------------- - static LLStat render_stat; - LLViewerJointMesh::sRenderPass = pass; if (pass == AVATAR_RENDER_PASS_SINGLE) @@ -4372,10 +4376,6 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; - //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; - - //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f); - return num_indices; } @@ -7828,14 +7828,14 @@ void LLVOAvatar::cullAvatarsByPixelArea() if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame { sUnbakedUpdateTime = gFrameTimeSeconds; - sUnbakedTime += gFrameIntervalSeconds; + sUnbakedTime += gFrameIntervalSeconds.value(); } if (grey_avatars > 0) { if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame { sGreyUpdateTime = gFrameTimeSeconds; - sGreyTime += gFrameIntervalSeconds; + sGreyTime += gFrameIntervalSeconds.value(); } } } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e32fd3c3c8..4275552117 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -808,8 +808,10 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, updateMeshTextures(); // unpack the texture UUIDs to the texture slots + if(mesgsys != NULL) + { retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); - + } // need to trigger a few operations to get the avatar to use the new bakes for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { @@ -910,17 +912,11 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) if (mLastRegionHandle != 0) { ++mRegionCrossingCount; - F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32(); - F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG); - F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount; - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg); - - F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX); - max = llmax(delta, max); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max); + LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32(); + sample(LLStatViewer::REGION_CROSSING_TIME, delta); // Diagnostics - llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl; + llinfos << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << llendl; } if (regionp) { @@ -2138,7 +2134,7 @@ LLSD LLVOAvatarSelf::metricsData() result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32(); result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); - result["startup"] = LLStartUp::getPhases().dumpPhases(); + result["startup"] = LLStartUp::getPhases().asLLSD(); return result; } @@ -2587,7 +2583,7 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) llinfos << "TAT: rebake - matched entry " << (S32)index << llendl; gAgentAvatarp->invalidateComposite(layer_set, TRUE); found = TRUE; - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); + add(LLStatViewer::TEX_REBAKES, 1); } } } @@ -2632,7 +2628,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) } invalidateComposite(layer_set, TRUE); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); + add(LLStatViewer::TEX_REBAKES, 1); } else { @@ -2787,7 +2783,7 @@ void LLVOAvatarSelf::deleteScratchTextures() sScratchTexNames.deleteAllData(); sScratchTexLastBindTime.deleteAllData(); - LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes; + LLImageGL::sGlobalTextureMemory -= sScratchTexBytes; sScratchTexBytes = 0; } } diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 7db19c5c1b..86cfbb1d74 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -29,6 +29,10 @@ #include "llerror.h" #include "llregionhandle.h" #include "llviewercontrol.h" +#include "llviewerobjectlist.h" +#include "lldrawable.h" +#include "llviewerregion.h" +#include "pipeline.h" BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { @@ -46,12 +50,16 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) //--------------------------------------------------------------------------- LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp) - : + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(local_id), mCRC(crc), mHitCount(0), mDupeCount(0), - mCRCChangeCount(0) + mCRCChangeCount(0), + mState(INACTIVE), + mRepeatedVisCounter(0), + mVisFrameRange(64), + mSceneContrib(0.f) { mBuffer = new U8[dp.getBufferSize()]; mDP.assignBuffer(mBuffer, dp.getBufferSize()); @@ -59,24 +67,35 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer & } LLVOCacheEntry::LLVOCacheEntry() - : + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(0), mCRC(0), mHitCount(0), mDupeCount(0), mCRCChangeCount(0), - mBuffer(NULL) + mBuffer(NULL), + mState(INACTIVE), + mRepeatedVisCounter(0), + mVisFrameRange(64), + mSceneContrib(0.f) { mDP.assignBuffer(mBuffer, 0); } LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) - : mBuffer(NULL) + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), + mBuffer(NULL), + mState(INACTIVE), + mRepeatedVisCounter(0), + mVisFrameRange(64), + mSceneContrib(0.f) { S32 size = -1; BOOL success; mDP.assignBuffer(mBuffer, 0); + setOctreeEntry(NULL); + success = check_read(apr_file, &mLocalID, sizeof(U32)); if(success) { @@ -96,6 +115,36 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) } if(success) { + success = check_read(apr_file, &mState, sizeof(U32)); + } + if(success) + { + F32 ext[8]; + success = check_read(apr_file, (void*)ext, sizeof(F32) * 8); + + LLVector4a exts[2]; + exts[0].load4a(ext); + exts[1].load4a(&ext[4]); + + setSpatialExtents(exts[0], exts[1]); + } + if(success) + { + LLVector4 pos; + success = check_read(apr_file, (void*)pos.mV, sizeof(LLVector4)); + + LLVector4a pos_; + pos_.load4a(pos.mV); + setPositionGroup(pos_); + } + if(success) + { + F32 rad; + success = check_read(apr_file, &rad, sizeof(F32)); + setBinRadius(rad); + } + if(success) + { success = check_read(apr_file, &size, sizeof(S32)); // Corruption in the cache entries @@ -132,32 +181,100 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) mDupeCount = 0; mCRCChangeCount = 0; mBuffer = NULL; + mEntry = NULL; + mState = 0; } } LLVOCacheEntry::~LLVOCacheEntry() { mDP.freeBuffer(); + //llassert(mState == INACTIVE); } +//virtual +void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry) +{ + if(!entry && mDP.getBufferSize() > 0) + { + LLUUID fullid; + mDP.reset(); + mDP.unpackUUID(fullid, "ID"); + mDP.reset(); -// New CRC means the object has changed. -void LLVOCacheEntry::assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp) + LLViewerObject* obj = gObjectList.findObject(fullid); + if(obj && obj->mDrawable) + { + entry = obj->mDrawable->getEntry(); + } + } + + LLViewerOctreeEntryData::setOctreeEntry(entry); +} + +void LLVOCacheEntry::copyTo(LLVOCacheEntry* new_entry) { - if ( (mCRC != crc) - ||(mDP.getBufferSize() == 0)) + //copy LLViewerOctreeEntry + if(mEntry.notNull()) { - mCRC = crc; - mHitCount = 0; - mCRCChangeCount++; + new_entry->setOctreeEntry(mEntry); + mEntry = NULL; + } + + //copy children + S32 num_children = getNumOfChildren(); + for(S32 i = 0; i < num_children; i++) + { + new_entry->addChild(getChild(i)); + } +} + +void LLVOCacheEntry::setState(U32 state) +{ + mState &= 0xffff0000; //clear the low 16 bits + state &= 0x0000ffff; //clear the high 16 bits; + mState |= state; - mDP.freeBuffer(); - mBuffer = new U8[dp.getBufferSize()]; - mDP.assignBuffer(mBuffer, dp.getBufferSize()); - mDP = dp; + if(getState() == ACTIVE) + { + const S32 MIN_REAVTIVE_INTERVAL = 20; + U32 last_visible = getVisible(); + + setVisible(); + + if(getVisible() - last_visible < MIN_REAVTIVE_INTERVAL + mVisFrameRange) + { + mRepeatedVisCounter++; + } + else + { + mRepeatedVisCounter = 0; + mVisFrameRange = 64; + } + + if(mRepeatedVisCounter > 2) + { + //if repeatedly becomes visible immediately after invisible, enlarge the visible frame range + + mRepeatedVisCounter = 0; + mVisFrameRange *= 2; + } } } +//virtual +S32 LLVOCacheEntry::getMinVisFrameRange()const +{ + return mVisFrameRange; +} + +void LLVOCacheEntry::addChild(LLVOCacheEntry* entry) +{ + llassert(entry != NULL); + + mChildrenList.push_back(entry); +} + LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc) { if ( (mCRC != crc) @@ -170,6 +287,16 @@ LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc) return &mDP; } +LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP() +{ + if (mDP.getBufferSize() == 0) + { + //llinfos << "Not getting cache entry, invalid!" << llendl; + return NULL; + } + + return &mDP; +} void LLVOCacheEntry::recordHit() { @@ -189,6 +316,11 @@ void LLVOCacheEntry::dump() const BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const { + if(!mEntry) + { + return FALSE; + } + BOOL success; success = check_write(apr_file, (void*)&mLocalID, sizeof(U32)); if(success) @@ -209,6 +341,33 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const } if(success) { + U32 state = mState & 0xffff0000; //only store the high 16 bits. + success = check_write(apr_file, (void*)&state, sizeof(U32)); + } + if(success) + { + const LLVector4a* exts = getSpatialExtents() ; + LLVector4 ext(exts[0][0], exts[0][1], exts[0][2], exts[0][3]); + success = check_write(apr_file, ext.mV, sizeof(LLVector4)); + if(success) + { + ext.set(exts[1][0], exts[1][1], exts[1][2], exts[1][3]); + success = check_write(apr_file, ext.mV, sizeof(LLVector4)); + } + } + if(success) + { + const LLVector4a pos_ = getPositionGroup() ; + LLVector4 pos(pos_[0], pos_[1], pos_[2], pos_[3]); + success = check_write(apr_file, pos.mV, sizeof(LLVector4)); + } + if(success) + { + F32 rad = getBinRadius(); + success = check_write(apr_file, (void*)&rad, sizeof(F32)); + } + if(success) + { S32 size = mDP.getBufferSize(); success = check_write(apr_file, (void*)&size, sizeof(S32)); @@ -221,6 +380,121 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const return success ; } +void LLVOCacheEntry::calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update) +{ + if(!needs_update && getVisible() >= last_update) + { + return; //no need to update + } + + const LLVector4a& center = getPositionGroup(); + + LLVector4a origin; + origin.load3(camera_origin.mV); + + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 squared_dist = lookAt.dot3(lookAt).getF32(); + + F32 rad = getBinRadius(); + mSceneContrib = rad * rad / squared_dist; + + setVisible(); +} + +//------------------------------------------------------------------- +//LLVOCachePartition +//------------------------------------------------------------------- +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) +{ + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + mVisitedTime = 0; + + new LLviewerOctreeGroup(mOctree); +} + +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ + llassert(entry->hasVOCacheEntry()); + + mOctree->insert(entry); +} + +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ + entry->getVOCacheEntry()->setGroup(NULL); + + llassert(!entry->getGroup()); +} + +class LLVOCacheOctreeCull : public LLViewerOctreeCull +{ +public: + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift) : LLViewerOctreeCull(camera), mRegionp(regionp) + { + mLocalShift = shift; + } + + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) + { + //S32 res = AABBInRegionFrustumGroupBounds(group); + + S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group); + if (res != 0) + { + res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift)); + } + return res; + } + + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) + { + //S32 res = AABBInRegionFrustumObjectBounds(group); + + S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group); + if (res != 0) + { + res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift)); + } + return res; + } + + virtual void processGroup(LLviewerOctreeGroup* base_group) + { + mRegionp->addVisibleGroup(base_group); + } + +private: + LLViewerRegion* mRegionp; + LLVector3 mLocalShift; //shift vector from agent space to local region space. +}; + +S32 LLVOCachePartition::cull(LLCamera &camera) +{ + if(!LLViewerRegion::sVOCacheCullingEnabled) + { + return 0; + } + + if(mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) + { + return 0; //already visited. + } + mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); + + ((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound(); + + //localize the camera + LLVector3 region_agent = mRegionp->getOriginAgent(); + camera.calcRegionFrustumPlanes(region_agent); + + LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent); + culler.traverse(mOctree); + + return 0; +} + //------------------------------------------------------------------- //LLVOCache //------------------------------------------------------------------- @@ -625,11 +899,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca { for (S32 i = 0; i < num_entries; i++) { - LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file); + LLPointer<LLVOCacheEntry> entry = new LLVOCacheEntry(&apr_file); if (!entry->getLocalID()) { llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; - delete entry ; success = false ; break ; } diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 14e3b4c793..c631e12739 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -31,34 +31,95 @@ #include "lldatapacker.h" #include "lldlinked.h" #include "lldir.h" - +#include "llvieweroctree.h" //--------------------------------------------------------------------------- // Cache entries class LLVOCacheEntry; +class LLCamera; -class LLVOCacheEntry +class LLVOCacheEntry : public LLViewerOctreeEntryData { public: + enum + { + INACTIVE = 0x00000000, //not visible + IN_QUEUE = 0x00000001, //in visible queue, object to be created + WAITING = 0x00000002, //object creation request sent + ACTIVE = 0x00000004 //object created, and in rendering pipeline. + }; + + enum + { + ADD_TO_CACHE_TREE = 0x00010000, //has parent + }; + + struct CompareVOCacheEntry + { + bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) + { + F32 lpa = lhs->getSceneContribution(); + F32 rpa = rhs->getSceneContribution(); + + //larger pixel area first + if(lpa > rpa) + { + return true; + } + else if(lpa < rpa) + { + return false; + } + else + { + return lhs < rhs; + } + } + }; +protected: + ~LLVOCacheEntry(); +public: LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp); LLVOCacheEntry(LLAPRFile* apr_file); - LLVOCacheEntry(); - ~LLVOCacheEntry(); - + LLVOCacheEntry(); + + void setState(U32 state); + void clearState(U32 state) {mState &= ~state;} + void addState(U32 state) {mState |= state;} + bool isState(U32 state) {return (mState & 0xffff) == state;} + bool hasState(U32 state) {return mState & state;} + U32 getState() const {return (mState & 0xffff);} + U32 getFullState() const {return mState;} + U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mCRC; } S32 getHitCount() const { return mHitCount; } S32 getCRCChangeCount() const { return mCRCChangeCount; } + S32 getMinVisFrameRange()const; + + void calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update); + void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;} + F32 getSceneContribution() const { return mSceneContrib;} void dump() const; BOOL writeToFile(LLAPRFile* apr_file) const; - void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp); LLDataPackerBinaryBuffer *getDP(U32 crc); + LLDataPackerBinaryBuffer *getDP(); void recordHit(); void recordDupe() { mDupeCount++; } + + void copyTo(LLVOCacheEntry* new_entry); //copy variables + /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry); + + void addChild(LLVOCacheEntry* entry); + LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];} + S32 getNumOfChildren() {return mChildrenList.size();} + void clearChildrenList() {mChildrenList.clear();} public: - typedef std::map<U32, LLVOCacheEntry*> vocache_entry_map_t; + typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t; + typedef std::set<LLVOCacheEntry*> vocache_entry_set_t; + typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t; protected: U32 mLocalID; @@ -68,6 +129,25 @@ protected: S32 mCRCChangeCount; LLDataPackerBinaryBuffer mDP; U8 *mBuffer; + + F32 mSceneContrib; //projected scene contributuion of this object. + S32 mVisFrameRange; + S32 mRepeatedVisCounter; //number of repeatedly visible within a short time. + U32 mState; //high 16 bits reserved for special use. + std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set. +}; + +class LLVOCachePartition : public LLViewerOctreePartition +{ +public: + LLVOCachePartition(LLViewerRegion* regionp); + + void addEntry(LLViewerOctreeEntry* entry); + void removeEntry(LLViewerOctreeEntry* entry); + /*virtual*/ S32 cull(LLCamera &camera); + +private: + U32 mVisitedTime; }; // diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 4dca87652d..d378ed2577 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -603,8 +603,8 @@ U32 LLVOGrass::getPartitionType() const return LLViewerRegion::PARTITION_GRASS; } -LLGrassPartition::LLGrassPartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) +LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_GRASS; mPartitionType = LLViewerRegion::PARTITION_GRASS; @@ -624,9 +624,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawablep = *i; + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - if (drawablep->isDead()) + if (!drawablep || drawablep->isDead()) { continue; } @@ -738,8 +738,10 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), //facep->getTexture(), buffer, fullbright); - info->mExtents[0] = group->mObjectExtents[0]; - info->mExtents[1] = group->mObjectExtents[1]; + + const LLVector4a* exts = group->getObjectExtents(); + info->mExtents[0] = exts[0]; + info->mExtents[1] = exts[1]; info->mVSize = vsize; draw_vec.push_back(info); //for alpha sorting diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index fa34a6f1f5..29c78f85f2 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -489,8 +489,8 @@ U32 LLVOPartGroup::getPartitionType() const return LLViewerRegion::PARTITION_PARTICLE; } -LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) +LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -499,8 +499,8 @@ LLParticlePartition::LLParticlePartition() mLODPeriod = 1; } -LLHUDParticlePartition::LLHUDParticlePartition() : - LLParticlePartition() +LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) : + LLParticlePartition(regionp) { mDrawableType = LLPipeline::RENDER_TYPE_HUD_PARTICLES; mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE; @@ -510,7 +510,7 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO"); void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) { - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -558,9 +558,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawablep = *i; + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - if (drawablep->isDead()) + if (!drawablep || drawablep->isDead()) { continue; } @@ -699,8 +699,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), //facep->getTexture(), buffer, fullbright); - info->mExtents[0] = group->mObjectExtents[0]; - info->mExtents[1] = group->mObjectExtents[1]; + + const LLVector4a* exts = group->getObjectExtents(); + info->mExtents[0] = exts[0]; + info->mExtents[1] = exts[1]; info->mVSize = vsize; draw_vec.push_back(info); //for alpha sorting diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 31358df85f..82de61cda2 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -2146,7 +2146,7 @@ void LLVOSky::updateFog(const F32 distance) // get the water param manager variables float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity(); - LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV; + LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV); // adjust the color based on depth. We're doing linear approximations float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale"); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index cb905d02da..d5b3f2fd14 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1058,8 +1058,8 @@ U32 LLVOSurfacePatch::getPartitionType() const return LLViewerRegion::PARTITION_TERRAIN; } -LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) +LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp) { mOcclusionEnabled = FALSE; mInfiniteFarClip = TRUE; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 6687ce432f..fe1ef10f7f 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1290,8 +1290,8 @@ U32 LLVOTree::getPartitionType() const return LLViewerRegion::PARTITION_TREE; } -LLTreePartition::LLTreePartition() -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) +LLTreePartition::LLTreePartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d94cd01a0b..12f268d324 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1143,7 +1143,7 @@ void LLVOVolume::sculpt() { // Log first time, then every 100 afterwards otherwise this can flood the logs llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() << " at " << current_discard - << " is less than -2." << llendl; + << " is less than -2." << llendl; low_sculpty_discard_warning_count = 0; } @@ -1157,10 +1157,10 @@ void LLVOVolume::sculpt() { // Log first time, then every 100 afterwards otherwise this can flood the logs llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() << " at " << current_discard - << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; + << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; high_sculpty_discard_warning_count = 0; } - + // corrupted volume... don't update the sculpty return; } @@ -3945,8 +3945,8 @@ U32 LLVOVolume::getPartitionType() const return LLViewerRegion::PARTITION_VOLUME; } -LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) +LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp) { mLODPeriod = 32; mDepthMask = FALSE; @@ -3956,8 +3956,8 @@ LLVolumePartition::LLVolumePartition() mBufferUsage = GL_DYNAMIC_DRAW_ARB; } -LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) +LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp) { mDepthMask = FALSE; mLODPeriod = 32; @@ -4175,9 +4175,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->mLastUpdateViewAngle = group->mViewAngle; - if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) { - if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) + if (group->hasState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) { rebuildMesh(group); } @@ -4215,7 +4215,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->mSurfaceArea = 0; //cache object box size since it might be used for determining visibility - group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32(); + const LLVector4a* bounds = group->getObjectBounds(); + group->mObjectBoxSize = bounds[1].getLength3().getF32(); group->clearDrawMap(); @@ -4242,9 +4243,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //get all the faces into a list for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) { continue; } @@ -4648,10 +4649,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //drawables have been rebuilt, clear rebuild status for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(drawablep) + { drawablep->clearState(LLDrawable::REBUILD_ALL); } } + } group->mLastUpdateTime = gFrameTimeSeconds; group->mBuilt = 1.f; @@ -4675,7 +4679,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { llassert(group); - if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers @@ -4688,9 +4692,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); @@ -4756,7 +4760,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(!drawablep) + { + continue; + } for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); @@ -5229,9 +5237,9 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep->isDead()) + if (!drawablep || drawablep->isDead()) { continue; } @@ -5269,7 +5277,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun group->mBufferUsage = usage; } -LLHUDPartition::LLHUDPartition() +LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp) { mPartitionType = LLViewerRegion::PARTITION_HUD; mDrawableType = LLPipeline::RENDER_TYPE_HUD; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index e8a1c3d1d6..50e7ed7bb5 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -298,15 +298,15 @@ U32 LLVOVoidWater::getPartitionType() const return LLViewerRegion::PARTITION_VOIDWATER; } -LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) +LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp) { mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; mPartitionType = LLViewerRegion::PARTITION_WATER; } -LLVoidWaterPartition::LLVoidWaterPartition() +LLVoidWaterPartition::LLVoidWaterPartition(LLViewerRegion* regionp) : LLWaterPartition(regionp) { mOcclusionEnabled = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER; diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 7f17fd3e56..717f215d3d 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -394,7 +394,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) segment->flush(); } - llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32()) << "seconds" << llendl; + llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << llendl; } #else mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 6f6411ce3c..0eb00f7191 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -136,7 +136,6 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID { LLFile::remove(std::string(filename)); } - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL; switch( status ) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 09d17b3701..12eea513da 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -55,7 +55,7 @@ #include "message.h" #include "pipeline.h" #include "llappviewer.h" // for do_disconnect() - +#include "llscenemonitor.h" #include <deque> #include <queue> #include <map> @@ -110,6 +110,7 @@ LLWorld::LLWorld() : gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + LLViewerRegion::sVOCacheCullingEnabled = (BOOL)gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); } @@ -133,6 +134,11 @@ void LLWorld::destroyClass() { mEdgeWaterObjects[i] = NULL; } + + //make all visible drawbles invisible. + LLDrawable::incrementVisible(); + + LLSceneMonitor::getInstance()->destroyClass(); } @@ -599,7 +605,8 @@ void LLWorld::updateVisibilities() if (part) { LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); - if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1])) { mCulledRegionList.erase(curiter); mVisibleRegionList.push_back(regionp); @@ -622,7 +629,8 @@ void LLWorld::updateVisibilities() if (part) { LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); - if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1])) { regionp->calculateCameraDistance(); regionp->getLand().updatePatchVisibilities(gAgent); @@ -660,6 +668,13 @@ void LLWorld::updateRegions(F32 max_update_time) did_one = TRUE; } } + + mNumOfActiveCachedObjects = 0; + for (region_list_t::iterator iter = mRegionList.begin(); + iter != mRegionList.end(); ++iter) + { + mNumOfActiveCachedObjects += (*iter)->getNumOfActiveCachedObjects(); + } } void LLWorld::updateParticles() @@ -692,8 +707,10 @@ void LLWorld::updateNetStats() { LLViewerRegion* regionp = *iter; regionp->updateNetStats(); - bits += regionp->mBitStat.getCurrent(); - packets += llfloor( regionp->mPacketsStat.getCurrent() ); + bits += regionp->mBitsReceived; + packets += llfloor( regionp->mPacketsReceived ); + regionp->mBitsReceived = 0.f; + regionp->mPacketsReceived = 0.f; } S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn; @@ -702,19 +719,16 @@ void LLWorld::updateNetStats() S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits(); S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); - LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); - LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); - LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); - LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); - LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); - LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); + + add(LLStatViewer::ACTUAL_IN_KBIT, LLTrace::Bits(actual_in_bits)); + add(LLStatViewer::ACTUAL_OUT_KBIT, LLTrace::Bits(actual_out_bits)); + add(LLStatViewer::KBIT, LLTrace::Bits(bits)); + add(LLStatViewer::PACKETS_IN, packets_in); + add(LLStatViewer::PACKETS_OUT, packets_out); + add(LLStatViewer::PACKETS_LOST, packets_lost); if (packets_in) { - LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in)); - } - else - { - LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f); + sample(LLStatViewer::PACKETS_LOST_PERCENT, 100.f * ((F32)packets_lost/(F32)packets_in)); } mLastPacketsIn = gMessageSystem->mPacketsIn; @@ -1127,6 +1141,7 @@ void send_agent_pause() } gObjectList.mWasPaused = TRUE; + LLViewerStats::instance().getRecording().stop(); } @@ -1156,8 +1171,8 @@ void send_agent_resume() gMessageSystem->sendReliable(regionp->getHost()); } - // Reset the FPS counter to avoid an invalid fps - LLViewerStats::getInstance()->mFPSStat.start(); + // Resume data collection to ignore invalid rates + LLViewerStats::instance().getRecording().resume(); LLAppViewer::instance()->resumeMainloopTimeout(); } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index f350009d10..8187142b2b 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -144,6 +144,7 @@ public: U64 getSpaceTimeUSec() const; void getInfo(LLSD& info); + U32 getNumOfActiveCachedObjects() const {return mNumOfActiveCachedObjects;} public: typedef std::list<LLViewerRegion*> region_list_t; @@ -181,7 +182,7 @@ private: S32 mLastPacketsIn; S32 mLastPacketsOut; S32 mLastPacketsLost; - + U32 mNumOfActiveCachedObjects; U64 mSpaceTimeUSec; BOOL mClassicCloudsEnabled; diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h index 12b6ef4792..ac1ea1607c 100644 --- a/indra/newview/llworldmapmessage.h +++ b/indra/newview/llworldmapmessage.h @@ -27,6 +27,8 @@ #ifndef LL_LLWORLDMAPMESSAGE_H #define LL_LLWORLDMAPMESSAGE_H +#include "boost/function.hpp" + // Handling of messages (send and process) as well as SLURL callback if necessary class LLMessageSystem; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index ccc513b80d..f821cb1ec1 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -302,8 +302,8 @@ void LLWorldMapView::draw() mVisibleRegions.clear(); // animate pan if necessary - sPanX = lerp(sPanX, sTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); - sPanY = lerp(sPanY, sTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); + sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f)); + sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f)); const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 0da70d398b..583196fb7a 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -25,6 +25,8 @@ */ #include "llviewerprecompiledheaders.h" +// include this to get winsock2 because openssl attempts to include winsock1 +#include "llwin32headerslean.h" #include <openssl/x509_vfy.h> #include <openssl/ssl.h> #include "llsecapi.h" diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 2051772d63..26ceaf512a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -86,6 +86,7 @@ #include "llviewerregion.h" // for audio debugging. #include "llviewerwindow.h" // For getSpinAxis #include "llvoavatarself.h" +#include "llvocache.h" #include "llvoground.h" #include "llvosky.h" #include "llvotree.h" @@ -111,6 +112,7 @@ #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindingcharacters.h" #include "llpathfindingpathtool.h" +#include "llscenemonitor.h" #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -488,7 +490,6 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_GLOW); - LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) @@ -1420,18 +1421,18 @@ S32 LLPipeline::setLightingDetail(S32 level) return mLightingDetail; } -class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable> +class LLOctreeDirtyTexture : public OctreeTraveler { public: const std::set<LLViewerFetchedTexture*>& mTextures; LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { } - virtual void visit(const LLOctreeNode<LLDrawable>* node) + virtual void visit(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) { for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) { @@ -1620,11 +1621,9 @@ void LLPipeline::addPool(LLDrawPool *new_poolp) void LLPipeline::allocDrawable(LLViewerObject *vobj) { - LLDrawable *drawable = new LLDrawable(); + LLDrawable *drawable = new LLDrawable(vobj); vobj->mDrawable = drawable; - drawable->mVObjp = vobj; - //encompass completely sheared objects by taking //the most extreme point possible (<1,1,0.5>) drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); @@ -1810,7 +1809,7 @@ void LLPipeline::resetFrameStats() { assertInitialized(); - LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); + add(LLStatViewer::TRIANGLES_DRAWN, mTrianglesDrawn); if (mBatchCount > 0) { @@ -1929,6 +1928,8 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree"); static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move"); +static LLFastTimer::DeclareTimer FTM_RETEXTURE("Retexture"); +static LLFastTimer::DeclareTimer FTM_MOVED_LIST("Moved List"); void LLPipeline::updateMove() { @@ -1942,8 +1943,7 @@ void LLPipeline::updateMove() assertInitialized(); { - static LLFastTimer::DeclareTimer ftm("Retexture"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_RETEXTURE); for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); iter != mRetexturedList.end(); ++iter) @@ -1958,8 +1958,7 @@ void LLPipeline::updateMove() } { - static LLFastTimer::DeclareTimer ftm("Moved List"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_MOVED_LIST); updateMovedList(mMovedList); } @@ -2048,7 +2047,7 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - if (drawable == *i) + if (drawable == (LLDrawable*)(*i)->getDrawable()) { llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; } @@ -2070,10 +2069,13 @@ void check_references(LLSpatialGroup* group, LLFace* face) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(drawable) + { check_references(drawable, face); } } +} void LLPipeline::checkReferences(LLFace* face) { @@ -2395,6 +2397,13 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } } } + + //scan the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->cull(camera); + } } if (bound_shader) @@ -2462,8 +2471,9 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) return; } + const LLVector4a* bounds = group->getBounds(); if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) + llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) { return; } @@ -2788,7 +2798,7 @@ void LLPipeline::updateGeom(F32 max_dtime) S32 count = 0; - max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime); + max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit<LLUnits::Seconds, F32>(max_dtime)); LLSpatialGroup* last_group = NULL; LLSpatialBridge* last_bridge = NULL; @@ -3051,14 +3061,14 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) if (priority) { - if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) + if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1)) { llassert_always(!mGroupQ1Locked); mGroupQ1.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q1); - if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) + if (group->hasState(LLSpatialGroup::IN_BUILD_Q2)) { LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); if (iter != mGroupQ2.end()) @@ -3069,7 +3079,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } } } - else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) + else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) { llassert_always(!mGroupQ2Locked); mGroupQ2.push_back(group); @@ -3144,7 +3154,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) group->setVisible(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - markVisible(*i, camera); + markVisible((LLDrawable*)(*i)->getDrawable(), camera); } if (!sDelayVBUpdate) @@ -3223,6 +3233,8 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } postSort(camera); + + LLSceneMonitor::getInstance()->fetchQueryResult(); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) @@ -3231,8 +3243,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawablep = *i; - stateSort(drawablep, camera); + stateSort((LLDrawable*)(*i)->getDrawable(), camera); } if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) @@ -3351,7 +3362,10 @@ void forAllDrawables(LLCullResult::sg_iterator begin, { for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j) { - func(*j); + if((*j)->hasDrawable()) + { + func((LLDrawable*)(*j)->getDrawable()); + } } } } @@ -3579,7 +3593,7 @@ void LLPipeline::postSort(LLCamera& camera) continue; } - if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY)) { //no way this group is going to be drawable without a rebuild group->rebuildGeom(); } @@ -3761,33 +3775,6 @@ void LLPipeline::postSort(LLCamera& camera) } } - /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence"); - static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work"); - if (use_transform_feedback) - { //using transform feedback, wait for transform feedback to complete - LLFastTimer t(FTM_TRANSFORM_WAIT); - - S32 done = 0; - //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count); - - glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); - - while (!done) - { - { - LLFastTimer t(FTM_TRANSFORM_DO_WORK); - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); - //do some useful work while we wait - LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - } - glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); - } - - mTransformFeedbackPrimitives = 0; - }*/ - //LLSpatialGroup::sNoDelete = FALSE; llpushcallstacks ; } @@ -4963,7 +4950,7 @@ void LLPipeline::renderDebug() { DebugBlip& blip = *iter; - blip.mAge += gFrameIntervalSeconds; + blip.mAge += gFrameIntervalSeconds.value(); if (blip.mAge > 2.f) { mDebugBlips.erase(iter++); @@ -4973,7 +4960,7 @@ void LLPipeline::renderDebug() iter++; } - blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; + blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f; gGL.color4fv(blip.mColor.mV); gGL.vertex3fv(blip.mPosition.mV); @@ -5784,7 +5771,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) { if (farthest_light->fade >= 0.f) { - farthest_light->fade = -gFrameIntervalSeconds; + farthest_light->fade = -(gFrameIntervalSeconds.value()); } } else @@ -5880,12 +5867,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) if (fade >= 0.f) { fade = fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds; + ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value(); } else { fade = 1.f + fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds; + ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value(); } fade = llclamp(fade,0.f,1.f); light_color *= fade; @@ -7200,7 +7187,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } else if (transition_time < 1.f) { //currently in a transition, continue interpolating - transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds; + transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); transition_time = llmin(transition_time, 1.f); F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; @@ -9192,7 +9179,7 @@ void LLPipeline::generateHighlight(LLCamera& camera) if (!mHighlightSet.empty()) { - F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime; + F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime; LLGLDisable test(GL_ALPHA_TEST); LLGLDepthTest depth(GL_FALSE); @@ -9827,7 +9814,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (gen_shadow) { - F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); + F32 fade_amt = gFrameIntervalSeconds.value() + * llmax(LLTrace::get_frame_recording().getLastRecordingPeriod().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecordingPeriod().getDuration().value(), 1.0); //update shadow targets for (U32 i = 0; i < 2; i++) diff --git a/indra/newview/skins/default/xui/da/floater_lagmeter.xml b/indra/newview/skins/default/xui/da/floater_lagmeter.xml deleted file mode 100644 index 149d174c34..0000000000 --- a/indra/newview/skins/default/xui/da/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG METER"> - <floater.string name="max_title_msg"> - Lag måler - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Lag - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Klient - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normal, vindue i baggrund - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Klients billeder/sek under [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Klients billeder/sek mellem [CLIENT_FRAME_RATE_CRITICAL] og [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Mulig årsag: 'Vis afstand' sat for højt i grafik indstillinger - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Mulig årsag: Billeder hentes - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Mulig årsag: For mange billeder i hukommelse - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Mulig årsag: For mange komplekse objekter i scenariet - </floater.string> - <floater.string name="network_text_msg"> - Netværk - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - Forbindelsen mister over [NETWORK_PACKET_LOSS_CRITICAL]% pakker - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - Forbindelsen mister [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% pakker - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Forbindelsens ping tider er over [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - Forbindelsens ping tider er [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Muligvis dårlig forbindelse eller 'båndbredde' sat for højt i netværksopsætning. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Muligvis dårlig forbindelse eller fil delings program. - </floater.string> - <floater.string name="server_text_msg"> - Server - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Simulator framerate er under [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Simulator framerate er mellem [SERVER_FRAME_RATE_CRITICAL] og [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="server_physics_cause_msg"> - Mulig årsag: For mange fysiske objekter - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Mulig årsag: For mange objekter med script - </floater.string> - <floater.string name="server_net_cause_msg"> - Mulig årsag: For meget netværks trafik - </floater.string> - <floater.string name="server_agent_cause_msg"> - Mulig årsag: For mange avatarer i bevægelse i regionen - </floater.string> - <floater.string name="server_images_cause_msg"> - Mulig årsag: For mange billed udregninger - </floater.string> - <floater.string name="server_generic_cause_msg"> - Mulig årsag: Simulator belastning for stor - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button label="" label_selected="" name="client_lagmeter" tool_tip="Status for klient lag"/> - <text name="client"> - Klient - </text> - <text name="client_text"> - Normal - </text> - <button label="" label_selected="" name="network_lagmeter" tool_tip="Network lag status"/> - <text name="network"> - Netværk - </text> - <text name="network_text"> - Normal - </text> - <button label="" label_selected="" name="server_lagmeter" tool_tip="Status for server lag"/> - <text name="server"> - Server - </text> - <text name="server_text"> - Normal - </text> - <button label=">>" name="minimize" tool_tip="Ændre størrelse"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_lagmeter.xml b/indra/newview/skins/default/xui/de/floater_lagmeter.xml deleted file mode 100644 index 45ff37c147..0000000000 --- a/indra/newview/skins/default/xui/de/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG METER"> - <floater.string name="max_title_msg"> - Lag-Anzeige - </floater.string> - <floater.string name="max_width_px"> - 350 - </floater.string> - <floater.string name="min_title_msg"> - Lag - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Client - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normal, Fenster im Hintergrund - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Client-Frame-Rate unter [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Client-Frame-Rate zwischen [CLIENT_FRAME_RATE_CRITICAL] und [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Mögliche Ursache: Sichtweite zu groß - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Mögliche Ursache: Bilder werden geladen - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Mögliche Ursache: Zu viele Bilder im Speicher - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Mögliche Ursache: Zu viele komplexe Objekte in der Szene - </floater.string> - <floater.string name="network_text_msg"> - Netzwerk - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - Paketverlust der Verbindung übersteigt [NETWORK_PACKET_LOSS_CRITICAL]% - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - Paketverlust der Verbindung liegt bei [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Ping-Zeit der Verbindung übersteigt [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - Ping-Zeit der Verbindung liegt bei [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Möglicherweise schlechte Verbindung oder zu hoher Wert für „Bandbreite“. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Möglicherweise schlechte Verbindung oder File-Sharing-Anwendung. - </floater.string> - <floater.string name="server_text_msg"> - Server - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Simulator-Frame-Rate liegt unter [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Simulator-Frame-Rate liegt zwischen [SERVER_FRAME_RATE_CRITICAL] und [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="server_physics_cause_msg"> - Mögliche Ursache: Zu viele physische Objekte - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Mögliche Ursache: Zu viele geskriptete Objekte - </floater.string> - <floater.string name="server_net_cause_msg"> - Mögliche Ursache: Zu viel Netzwerktraffic - </floater.string> - <floater.string name="server_agent_cause_msg"> - Mögliche Ursache: Zu viele Personen in Bewegung in der Region - </floater.string> - <floater.string name="server_images_cause_msg"> - Mögliche Ursache: Zu viele Bildberechnungen - </floater.string> - <floater.string name="server_generic_cause_msg"> - Mögliche Ursache: Zu hohe Simulator-Last - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button name="client_lagmeter" tool_tip="Client-Lag-Status"/> - <text name="client"> - Client - </text> - <text name="client_text"> - Normal - </text> - <button name="network_lagmeter" tool_tip="Netzwerk-Lag-Status"/> - <text name="network"> - Netzwerk - </text> - <text name="network_text"> - Normal - </text> - <button name="server_lagmeter" tool_tip="Server-Lag-Status"/> - <text name="server"> - Server - </text> - <text name="server_text"> - Normal - </text> - <button label=">> " name="minimize" tool_tip="Fenstergröße ändern"/> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml deleted file mode 100644 index b24c745bdd..0000000000 --- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml +++ /dev/null @@ -1,336 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - height="170" - layout="topleft" - name="floater_lagmeter" - help_topic="floater_lagmeter" - save_rect="true" - title="LAG METER" - width="350"> - <floater.string - name="max_title_msg"> - Lag Meter - </floater.string> - <floater.string - name="max_width_px"> - 360 - </floater.string> - <floater.string - name="min_title_msg"> - Lag - </floater.string> - <floater.string - name="min_width_px"> - 90 - </floater.string> - <floater.string - name="client_text_msg"> - Client - </floater.string> - <floater.string - name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string - name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string - name="client_frame_time_window_bg_msg"> - Normal, window in background - </floater.string> - <floater.string - name="client_frame_time_critical_msg"> - Client frame rate below [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string - name="client_frame_time_warning_msg"> - Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string - name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string - name="client_draw_distance_cause_msg"> - Possible cause: Draw distance set too high - </floater.string> - <floater.string - name="client_texture_loading_cause_msg"> - Possible cause: Images loading - </floater.string> - <floater.string - name="client_texture_memory_cause_msg"> - Possible cause: Too many images in memory - </floater.string> - <floater.string - name="client_complex_objects_cause_msg"> - Possible cause: Too many complex objects in scene - </floater.string> - <floater.string - name="network_text_msg"> - Network - </floater.string> - <floater.string - name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string - name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string - name="network_packet_loss_critical_msg"> - Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets - </floater.string> - <floater.string - name="network_packet_loss_warning_msg"> - Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets - </floater.string> - <floater.string - name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string - name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string - name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string - name="network_ping_critical_msg"> - Connection ping time is over [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string - name="network_ping_warning_msg"> - Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string - name="network_packet_loss_cause_msg"> - Possible bad connection or 'Bandwidth' pref too high. - </floater.string> - <floater.string - name="network_ping_cause_msg"> - Possible bad connection or file-sharing app. - </floater.string> - <floater.string - name="server_text_msg"> - Server - </floater.string> - <floater.string - name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string - name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string - name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string - name="server_frame_time_critical_msg"> - Simulator framerate below [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string - name="server_frame_time_warning_msg"> - Simulator framerate between [SERVER_FRAME_RATE_CRITICAL] and [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string - name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string - name="server_physics_cause_msg"> - Possible Cause: Too many physical objects - </floater.string> - <floater.string - name="server_scripts_cause_msg"> - Possible Cause: Too many scripted objects - </floater.string> - <floater.string - name="server_net_cause_msg"> - Possible Cause: Too much network traffic - </floater.string> - <floater.string - name="server_agent_cause_msg"> - Possible Cause: Too many moving people in region - </floater.string> - <floater.string - name="server_images_cause_msg"> - Possible Cause: Too many image calculations - </floater.string> - <floater.string - name="server_generic_cause_msg"> - Possible Cause: Simulator load too heavy - </floater.string> - <floater.string - name="smaller_label"> - >> - </floater.string> - <floater.string - name="bigger_label"> - << - </floater.string> - <button - follows="top|left" - height="16" - image_selected="lag_status_good.tga" - image_unselected="lag_status_good.tga" - layout="topleft" - left="8" - name="client_lagmeter" - tab_stop="false" - tool_tip="Client lag status" - top="24" - width="16" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="3" - name="client" - top_delta="0" - width="128"> - Client - </text> - <text - invisiblity_control="LagMeterShrunk" - type="string" - length="1" - bottom="40" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left="110" - name="client_text" - right="-10"> - Normal - </text> - <text - invisiblity_control="LagMeterShrunk" - bottom="56" - follows="left|top" - height="16" - layout="topleft" - left="40" - name="client_lag_cause" - right="-32" /> - <button - follows="top|left" - height="16" - image_selected="lag_status_good.tga" - image_unselected="lag_status_good.tga" - layout="topleft" - left="8" - name="network_lagmeter" - tab_stop="false" - tool_tip="Network lag status" - top="64" - width="16" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="3" - name="network" - top_delta="0" - width="128"> - Network - </text> - <text - invisiblity_control="LagMeterShrunk" - type="string" - length="1" - bottom="80" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left="110" - name="network_text" - right="-10"> - Normal - </text> - <text - invisiblity_control="LagMeterShrunk" - bottom="96" - follows="left|top" - height="16" - layout="topleft" - left="40" - name="network_lag_cause" - right="-32" /> - <button - follows="top|left" - height="16" - image_selected="lag_status_good.tga" - image_unselected="lag_status_good.tga" - layout="topleft" - left="8" - name="server_lagmeter" - tab_stop="false" - tool_tip="Server lag status" - top="104" - width="16" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="3" - name="server" - top_delta="0" - width="60"> - Server - </text> - <text - invisiblity_control="LagMeterShrunk" - type="string" - length="1" - bottom="120" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left="110" - name="server_text" - right="-10"> - Normal - </text> - <text - invisiblity_control="LagMeterShrunk" - bottom="136" - follows="left|top" - height="16" - layout="topleft" - left="40" - name="server_lag_cause" - right="-32" /> - <button - follows="left|top" - height="20" - label=">>" - layout="topleft" - left="10" - name="minimize" - tool_tip="Toggle floater size" - top_delta="24" - width="40"> - <button.commit_callback - function="LagMeter.ClickShrink" /> - </button> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml new file mode 100644 index 0000000000..f4021d210a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml @@ -0,0 +1,484 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater legacy_header_height="18" + can_resize="true" + height="400" + layout="topleft" + name="Scene Load Statistics" + save_rect="true" + save_visibility="true" + title="SCENE LOAD STATISTICS" + width="260"> + <button top="20" + bottom="60" + left="10" + width="100" + label="Pause" + name="playpause"/> + <scroll_container follows="top|left|bottom|right" + bottom="400" + layout="topleft" + left="0" + name="statistics_scroll" + reserve_scroll_corner="true" + top="60" + width="260"> + <container_view follows="top|left|bottom|right" + height="378" + layout="topleft" + left="2" + name="statistics_view" + top="20" + width="245" > +<!--Basic Section--> + <stat_view name="basic" + label="Basic" + show_label="true" + setting="OpenDebugStatBasic"> + <stat_bar name="frame difference" + label="Frame Pixel Difference" + orientation="horizontal" + unit_label="%" + stat="FramePixelDifference" + bar_max="100" + tick_spacing="10" + label_spacing="20" + unit_scale="100" + precision="0"/> + <stat_bar name="bandwidth" + label="Bandwidth" + orientation="horizontal" + unit_label="kbps" + stat="kbitstat" + bar_max="5000" + tick_spacing="500" + label_spacing="1000" + precision="0"/> + <stat_bar name="packet_loss" + label="Packet Loss" + orientation="horizontal" + unit_label=" %" + stat="packetslostpercentstat" + bar_max="5" + tick_spacing="0.5" + label_spacing="1" + precision="3" + show_bar="false" + show_mean="true"/> + </stat_view> +<!--Advanced Section--> + <stat_view name="advanced" + label="Advanced" + show_label="true" + setting="OpenDebugStatAdvanced"> + <stat_view name="render" + label="Render" + show_label="true" + setting="OpenDebugStatRender"> + <stat_bar name="objs" + label="Total Objects" + orientation="horizontal" + unit_label="" + stat="numobjectsstat" + bar_max="50000" + tick_spacing="5000" + label_spacing="10000" + precision="0" + show_bar="false"/> + <stat_bar name="newobjs" + label="New Objects" + orientation="horizontal" + unit_label="/sec" + stat="numnewobjectsstat" + bar_max="2000" + tick_spacing="200" + label_spacing="400" + show_bar="false"/> + <stat_bar name="object_cache_hits" + label="Object Cache Hit Rate" + orientation="horizontal" + stat="object_cache_hits" + bar_max="100" + unit_label="%" + tick_spacing="20" + label_spacing="20" + show_history="true" + show_bar="false"/> + </stat_view> +<!--Texture Stats--> + <stat_view name="texture" + label="Texture" + show_label="true"> + <stat_bar name="texture_cache_hits" + label="Cache Hit Rate" + orientation="horizontal" + stat="texture_cache_hits" + bar_max="100.f" + unit_label="%" + tick_spacing="20" + label_spacing="20" + show_history="true" + show_bar="false"/> + <stat_bar name="texture_cache_read_latency" + label="Cache Read Latency" + orientation="horizontal" + unit_label="msec" + stat="texture_cache_read_latency" + bar_max="1000.f" + tick_spacing="100" + label_spacing="200" + show_history="true" + show_bar="false"/> + <stat_bar name="numimagesstat" + label="Count" + orientation="horizontal" + stat="numimagesstat" + bar_max="8000.f" + tick_spacing="2000.f" + label_spacing="4000.f" + show_bar="false"/> + <stat_bar name="numrawimagesstat" + label="Raw Count" + orientation="horizontal" + stat="numrawimagesstat" + bar_max="8000.f" + tick_spacing="2000.f" + label_spacing="4000.f" + show_bar="false"/> + </stat_view> +<!--Network Stats--> + <stat_view name="network" + label="Network" + show_label="true" + setting="OpenDebugStatNet"> + <stat_bar name="packetsinstat" + label="Packets In" + orientation="horizontal" + stat="packetsinstat" + unit_label="/sec" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="packetsoutstat" + label="Packets Out" + orientation="horizontal" + stat="packetsoutstat" + unit_label="/sec" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="objectkbitstat" + label="Objects" + orientation="horizontal" + stat="objectkbitstat" + unit_label="kbps" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="texturekbitstat" + label="Texture" + orientation="horizontal" + stat="texturekbitstat" + unit_label="kbps" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="assetkbitstat" + label="Asset" + orientation="horizontal" + stat="assetkbitstat" + unit_label="kbps" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="layerskbitstat" + label="Layers" + orientation="horizontal" + stat="layerskbitstat" + unit_label="kbps" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="actualinkbitstat" + label="Actual In" + orientation="horizontal" + stat="actualinkbitstat" + unit_label="kbps" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="actualoutkbitstat" + label="Actual Out" + orientation="horizontal" + stat="actualoutkbitstat" + unit_label="kbps" + bar_max="1024.f" + tick_spacing="128.f" + label_spacing="256.f" + precision="1" + show_bar="false"/> + <stat_bar name="vfspendingoperations" + label="VFS Pending Operations" + orientation="horizontal" + stat="vfspendingoperations" + unit_label=" Ops." + show_bar="false"/> + </stat_view> + </stat_view> +<!--Sim Stats--> + <stat_view name="sim" + label="Simulator" + show_label="true" + setting="OpenDebugStatSim"> + <stat_bar name="simobjects" + label="Objects" + orientation="horizontal" + stat="simobjects" + precision="0" + bar_max="30000.f" + tick_spacing="5000.f" + label_spacing="10000.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simactiveobjects" + label="Active Objects" + orientation="horizontal" + stat="simactiveobjects" + precision="0" + bar_max="5000.f" + tick_spacing="750.f" + label_spacing="1250.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simactivescripts" + label="Active Scripts" + orientation="horizontal" + stat="simactivescripts" + precision="0" + bar_max="15000.f" + tick_spacing="1875.f" + label_spacing="3750.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="siminpps" + label="Packets In" + orientation="horizontal" + stat="siminpps" + unit_label="pps" + precision="0" + bar_max="2000.f" + tick_spacing="250.f" + label_spacing="1000.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simoutpps" + label="Packets Out" + orientation="horizontal" + stat="simoutpps" + unit_label="pps" + precision="0" + bar_max="2000.f" + tick_spacing="250.f" + label_spacing="1000.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simpendingdownloads" + label="Pending Downloads" + orientation="horizontal" + stat="simpendingdownloads" + precision="0" + bar_max="800.f" + tick_spacing="100.f" + label_spacing="200.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simpendinguploads" + label="Pending Uploads" + orientation="horizontal" + stat="simpendinguploads" + precision="0" + bar_max="100.f" + tick_spacing="25.f" + label_spacing="50.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simtotalunackedbytes" + label="Total Unacked Bytes" + orientation="horizontal" + stat="simtotalunackedbytes" + unit_label="kb" + precision="1" + bar_max="100000.f" + tick_spacing="25000.f" + label_spacing="50000.f" + show_bar="false" + show_mean="false"/> + <stat_view name="simperf" + label="Time (ms)" + show_label="true"> + <stat_bar name="simframemsec" + label="Total Frame Time" + orientation="horizontal" + stat="simframemsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simnetmsec" + label="Net Time" + orientation="horizontal" + stat="simnetmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simsimphysicsmsec" + label="Physics Time" + orientation="horizontal" + stat="simsimphysicsmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simsimothermsec" + label="Simulation Time" + orientation="horizontal" + stat="simsimothermsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simagentmsec" + label="Agent Time" + orientation="horizontal" + stat="simagentmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simimagesmsec" + label="Images Time" + orientation="horizontal" + stat="simimagesmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simscriptmsec" + label="Script Time" + orientation="horizontal" + stat="simscriptmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simsparemsec" + label="Spare Time" + orientation="horizontal" + stat="simsparemsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> +<!--2nd level time blocks under 'Details' second--> + <stat_view name="timedetails" + label="Time Details (ms)" + show_label="true"> + <stat_bar name="simsimphysicsstepmsec" + label=" Physics Step" + orientation="horizontal" + stat="simsimphysicsstepmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simsimphysicsshapeupdatemsec" + label=" Update Phys Shapes" + orientation="horizontal" + stat="simsimphysicsshapeupdatemsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simsimphysicsothermsec" + label=" Physics Other" + orientation="horizontal" + stat="simsimphysicsothermsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simsleepmsec" + label=" Sleep Time" + orientation="horizontal" + stat="simsleepmsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + <stat_bar name="simpumpiomsec" + label=" Pump IO" + orientation="horizontal" + stat="simpumpiomsec" + unit_label="ms" + precision="3" + bar_max="40.f" + tick_spacing="10.f" + label_spacing="20.f" + show_bar="false" + show_mean="false"/> + </stat_view> + </stat_view> + </stat_view> + </container_view> + </scroll_container> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index f9eb16d224..a3f2fb0b9c 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -35,6 +35,7 @@ setting="OpenDebugStatBasic"> <stat_bar name="fps" + orientation="horizontal" label="FPS" unit_label="fps" stat="fpsstat" @@ -69,7 +70,6 @@ tick_spacing="0.5" label_spacing="1" precision="3" - show_per_sec="false" show_bar="false" show_mean="true"> </stat_bar> @@ -84,7 +84,6 @@ label_spacing="1000" precision="0" show_bar="false" - show_per_sec="false" show_mean="false"> </stat_bar> </stat_view> @@ -104,6 +103,7 @@ label="KTris Drawn per Frame" unit_label="/fr" stat="trianglesdrawnstat" + unit_scale="0.001" bar_min="0" bar_max="10000" tick_spacing="1000" @@ -116,6 +116,7 @@ name="ktrissec" label="KTris Drawn per Sec" unit_label="/sec" + unit_scale="0.001" stat="trianglesdrawnstat" bar_min="0" bar_max="200000" @@ -134,7 +135,6 @@ tick_spacing="5000" label_spacing="10000" precision="0" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -146,7 +146,6 @@ bar_max="2000" tick_spacing="200" label_spacing="400" - show_per_sec="true" show_bar="false"> </stat_bar> <stat_bar @@ -159,7 +158,6 @@ tick_spacing="20" label_spacing="20" show_history="true" - show_per_sec="false" show_bar="false"> </stat_bar> </stat_view> @@ -178,7 +176,6 @@ tick_spacing="20" label_spacing="20" show_history="true" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -191,7 +188,6 @@ tick_spacing="100" label_spacing="200" show_history="true" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -202,7 +198,6 @@ bar_max="8000.f" tick_spacing="2000.f" label_spacing="4000.f" - show_per_sec="false" show_bar="false"> </stat_bar> @@ -214,7 +209,6 @@ bar_max="8000.f" tick_spacing="2000.f" label_spacing="4000.f" - show_per_sec="false" show_bar="false"> </stat_bar> @@ -222,12 +216,13 @@ name="gltexmemstat" label="GL Mem" stat="gltexmemstat" + unit_label="MB" + unit_scale="0.000001" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" label_spacing="200.f" precision="1" - show_per_sec="false" show_bar="false"> </stat_bar> @@ -235,25 +230,27 @@ name="formattedmemstat" label="Formatted Mem" stat="formattedmemstat" + unit_label="MB" + unit_scale="0.000001" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" label_spacing="200.f" - precision="1" - show_per_sec="false" + precision="3" show_bar="false"> </stat_bar> <stat_bar name="rawmemstat" label="Raw Mem" + unit_label="MB" + unit_scale="0.000001" stat="rawmemstat" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" label_spacing="200.f" - precision="1" - show_per_sec="false" + precision="3" show_bar="false"> </stat_bar> @@ -261,12 +258,13 @@ name="glboundmemstat" label="Bound Mem" stat="glboundmemstat" + unit_label="MB" + unit_scale="0.000001" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" label_spacing="200.f" - precision="1" - show_per_sec="false" + precision="3" show_bar="false"> </stat_bar> </stat_view> @@ -387,7 +385,6 @@ label="VFS Pending Operations" stat="vfspendingoperations" unit_label=" Ops." - show_per_sec="false" show_bar="false" > </stat_bar> </stat_view> @@ -407,7 +404,6 @@ bar_max="1.f" tick_spacing="0.16666f" label_spacing="0.33333f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -421,7 +417,6 @@ bar_max="45.f" tick_spacing="7.5f" label_spacing="15.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -435,7 +430,6 @@ bar_max="45.f" tick_spacing="7.5.f" label_spacing="15.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -453,7 +447,6 @@ bar_max="500.f" tick_spacing="50.f" label_spacing="100.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -467,7 +460,6 @@ bar_max="500.f" tick_spacing="50.f" label_spacing="100.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -482,7 +474,6 @@ bar_max="1024.f" tick_spacing="128.f" label_spacing="256.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -497,7 +488,6 @@ bar_max="100.f" tick_spacing="25.f" label_spacing="50.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -511,7 +501,6 @@ bar_max="80.f" tick_spacing="10.f" label_spacing="40.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -525,7 +514,6 @@ bar_max="40.f" tick_spacing="5.f" label_spacing="10.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -539,7 +527,6 @@ bar_max="30000.f" tick_spacing="5000.f" label_spacing="10000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -553,7 +540,6 @@ bar_max="5000.f" tick_spacing="750.f" label_spacing="1250.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -567,7 +553,6 @@ bar_max="15000.f" tick_spacing="1875.f" label_spacing="3750.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -581,7 +566,6 @@ tick_spacing="10" label_spacing="20" precision="3" - show_per_sec="false" show_bar="false" show_mean="true"> </stat_bar> @@ -596,7 +580,6 @@ bar_max="5000.f" tick_spacing="750.f" label_spacing="1250.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -615,7 +598,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -629,7 +611,6 @@ bar_max="45" tick_spacing="4" label_spacing="8" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -642,7 +623,6 @@ tick_spacing="10" label_spacing="20" precision="1" - show_per_sec="false" show_bar="false" show_mean="true"> </stat_bar> @@ -658,7 +638,6 @@ bar_max="2000.f" tick_spacing="250.f" label_spacing="1000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -673,7 +652,6 @@ bar_max="2000.f" tick_spacing="250.f" label_spacing="1000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -687,7 +665,6 @@ bar_max="800.f" tick_spacing="100.f" label_spacing="200.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -701,7 +678,6 @@ bar_max="100.f" tick_spacing="25.f" label_spacing="50.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -716,7 +692,6 @@ bar_max="100000.f" tick_spacing="25000.f" label_spacing="50000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -735,7 +710,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -750,7 +724,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -765,7 +738,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -780,7 +752,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -795,7 +766,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -810,7 +780,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -825,7 +794,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -840,7 +808,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -859,7 +826,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -873,7 +839,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -887,7 +852,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -901,7 +865,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -915,7 +878,6 @@ bar_max="40.f" tick_spacing="10.f" label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index caa36e7302..2f0acba23e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1376,6 +1376,14 @@ function="Floater.Toggle" parameter="stats" /> </menu_item_check> + <menu_item_call + label="Scene Load Statistics" + name="Scene Load Statistics" + shortcut="control|shift|2"> + <on_click + function="Floater.Show" + parameter="scene_load_stats" /> + </menu_item_call> <menu_item_check label="Show Draw Weight for Avatars" name="Avatar Rendering Cost"> @@ -1981,6 +1989,16 @@ function="Advanced.ToggleConsole" parameter="scene view" /> </menu_item_check> + <menu_item_check + label="Scene Loading Monitor" + name="Scene Loading Monitor"> + <menu_item_check.on_check + function="Advanced.CheckConsole" + parameter="scene monitor" /> + <menu_item_check.on_click + function="Advanced.ToggleConsole" + parameter="scene monitor" /> + </menu_item_check> <menu_item_call enabled="false" visible="false" diff --git a/indra/newview/skins/default/xui/es/floater_lagmeter.xml b/indra/newview/skins/default/xui/es/floater_lagmeter.xml deleted file mode 100644 index 227689a194..0000000000 --- a/indra/newview/skins/default/xui/es/floater_lagmeter.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="MEDIDOR DEL LAG"> - <floater.string name="max_title_msg"> - Medidor del lag - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Lag - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Cliente - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normal, ventana en segundo plano - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Frames del cliente valorados por debajo de [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Frames del cliente valorados entre [CLIENT_FRAME_RATE_CRITICAL] y [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Posible causa: distancia de dibujo fijada muy alta - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Posible causa: imágenes cargándose - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Posible causa: demasiadas imágenes en la memoria - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Posible causa: demasiados objetos complejos en la escena - </floater.string> - <floater.string name="network_text_msg"> - Red - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - La conexión deja caer más del [NETWORK_PACKET_LOSS_CRITICAL]% de los paquetes - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - La conexión deja caer [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% de los paquetes - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - El tiempo de conexión -ping- supera los [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - El tiempo de conexión -ping- es de [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Quizá una mala conexión o un ancho de banda fijado demasiado alto. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Quizá una mala conexión o una aplicación de archivos compartidos. - </floater.string> - <floater.string name="server_text_msg"> - Servidor - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Frecuencia (framerate) por debajo de [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Frecuencia (framerate) entre [SERVER_FRAME_RATE_CRITICAL] y [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="server_physics_cause_msg"> - Posible causa: demasiados objetos físicos - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Posible causa: demasiados objetos con script - </floater.string> - <floater.string name="server_net_cause_msg"> - Posible causa: demasiado tráfico en la red - </floater.string> - <floater.string name="server_agent_cause_msg"> - Posible causa: demasiada gente moviéndose en la región - </floater.string> - <floater.string name="server_images_cause_msg"> - Posible causa: demasiados cálculos de imáganes - </floater.string> - <floater.string name="server_generic_cause_msg"> - Posible causa: carga del simulador muy pesada - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button label="" label_selected="" name="client_lagmeter" tool_tip="Estado del lag del cliente"/> - <text name="client"> - Cliente - </text> - <text font="SansSerifSmall" name="client_text"> - Normal - </text> - <text left="30" name="client_lag_cause" right="-10"/> - <button label="" label_selected="" name="network_lagmeter" tool_tip="Estado del lag de la red"/> - <text name="network"> - Red - </text> - <text font="SansSerifSmall" name="network_text"> - Normal - </text> - <text left="30" name="network_lag_cause" right="-10"/> - <button label="" label_selected="" name="server_lagmeter" tool_tip="Estado del lag del servidor"/> - <text name="server"> - Servidor - </text> - <text font="SansSerifSmall" name="server_text"> - Normal - </text> - <text left="30" name="server_lag_cause" right="-32"/> - <button label=">>" name="minimize" tool_tip="Cambia el tamaño de la ventana"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml b/indra/newview/skins/default/xui/fr/floater_lagmeter.xml deleted file mode 100644 index 39a861d8bd..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="MESURE DU LAG"> - <floater.string name="max_title_msg"> - Mesure du lag - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Lag - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Client - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normal, fenêtre en arrière-plan - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Taux de défilement [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Taux de défilement entre [CLIENT_FRAME_RATE_CRITICAL] et [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Cause possible : limite d'affichage trop élevée - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Cause possible : images en cours de chargement - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Cause possible : trop d'images en mémoire - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Cause possible : trop d'objets complexes - </floater.string> - <floater.string name="network_text_msg"> - Réseau - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - La connexion perd plus de [NETWORK_PACKET_LOSS_CRITICAL] % de paquets - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - La connexion perd entre [NETWORK_PACKET_LOSS_WARNING] % et [NETWORK_PACKET_LOSS_CRITICAL] % de paquets - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Connexion ping > [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - Connexion ping entre [NETWORK_PING_WARNING] et [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Mauvaise connexion possible ou réglage de la bande passante trop élevé. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Mauvaise connexion possible ou app. de partage des fichiers - </floater.string> - <floater.string name="server_text_msg"> - Serveur - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Défilement du simulateur < [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Défilement simulateur entre [SERVER_FRAME_RATE_CRITICAL] et [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="server_physics_cause_msg"> - Cause possible : trop d'objets physiques - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Cause possible : trop d'objets scriptés - </floater.string> - <floater.string name="server_net_cause_msg"> - Cause possible : trop de trafic réseau - </floater.string> - <floater.string name="server_agent_cause_msg"> - Cause possible : trop de personnes en mouvement - </floater.string> - <floater.string name="server_images_cause_msg"> - Cause possible : trop de calculs d'images - </floater.string> - <floater.string name="server_generic_cause_msg"> - Cause possible : charge simulateur trop lourde - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button name="client_lagmeter" tool_tip="Statut du lag client"/> - <text name="client"> - Client - </text> - <text name="client_text"> - Normal - </text> - <button name="network_lagmeter" tool_tip="Statut du lag réseau"/> - <text name="network"> - Réseau - </text> - <text name="network_text"> - Normal - </text> - <button name="server_lagmeter" tool_tip="Statut du lag serveur"/> - <text name="server"> - Serveur - </text> - <text name="server_text"> - Normal - </text> - <button label=">>" name="minimize" tool_tip="Activer/désactiver la taille du floater"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_lagmeter.xml b/indra/newview/skins/default/xui/it/floater_lagmeter.xml deleted file mode 100644 index f7b2b1ab4a..0000000000 --- a/indra/newview/skins/default/xui/it/floater_lagmeter.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="MISURATORE LAG"> - <floater.string name="max_title_msg"> - Misuratore del lag - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Lag - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Programma in locale - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normale, finestra sullo sfondo - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Velocità dei frame al di sotto di [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Velocità dei frame tra [CLIENT_FRAME_RATE_CRITICAL] e [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normale - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Possibile causa: Campo visivo impostato troppo alto - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Possibile causa: Caricamento immagini - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Possibile causa: Troppe immagini in memoria - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Possibile causa: Troppi oggetti complessi intorno - </floater.string> - <floater.string name="network_text_msg"> - Network - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - La connessione sta calando al di sotto del [NETWORK_PACKET_LOSS_CRITICAL]% di pacchetti - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - La connessione sta calando tra il [NETWORK_PACKET_LOSS_WARNING]% e il [NETWORK_PACKET_LOSS_CRITICAL]% di pacchetti - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normale - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Il tempo di ping della connessione è al di sopra di [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - Il tempo di ping della connessione è tra [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Possibile cattiva connessione o la larghezza di banda impostata nelle preferenze troppo alta. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Possibile cattiva connessione o l'apertura di un programma di scambio files. - </floater.string> - <floater.string name="server_text_msg"> - Server - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Velocità dei frame al di sotto di [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Velocità dei frame tra [SERVER_FRAME_RATE_CRITICAL] e [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normale - </floater.string> - <floater.string name="server_physics_cause_msg"> - Possibile causa: troppi oggetti fisici - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Possibile causa: troppi oggetti scriptati - </floater.string> - <floater.string name="server_net_cause_msg"> - Possibile causa: eccessivo traffico sulla rete - </floater.string> - <floater.string name="server_agent_cause_msg"> - Possibile causa: troppi residenti in movimento nella regione - </floater.string> - <floater.string name="server_images_cause_msg"> - Possibile causa: troppe elaborazioni di immagini - </floater.string> - <floater.string name="server_generic_cause_msg"> - Possibile causa: carico eccessivo del simulatore - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button label="" label_selected="" name="client_lagmeter" tool_tip="Stato del lag del programma in locale"/> - <text name="client"> - Client - </text> - <text font="SansSerifSmall" left="145" name="client_text"> - Normale - </text> - <text left="30" name="client_lag_cause" right="-10"/> - <button label="" label_selected="" name="network_lagmeter" tool_tip="Stato del lag del network"/> - <text name="network"> - Rete - </text> - <text font="SansSerifSmall" name="network_text"> - Normale - </text> - <text left="30" name="network_lag_cause" right="-10"/> - <button label="" label_selected="" name="server_lagmeter" tool_tip="Stato del lag del server"/> - <text name="server"> - Server - </text> - <text font="SansSerifSmall" name="server_text"> - Normale - </text> - <text left="30" name="server_lag_cause" right="-32"/> - <button label=">>" name="minimize" tool_tip="Cambia dimensioni floater"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml deleted file mode 100644 index e3546cd837..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="ラグメーター"> - <floater.string name="max_title_msg"> - ラグ メーター - </floater.string> - <floater.string name="max_width_px"> - 350 - </floater.string> - <floater.string name="min_title_msg"> - ラグ - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - クライアント - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - ノーマル、ウィンドウは背景に - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - クライアント フレームレート < [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - クライアント フレームレート: [CLIENT_FRAME_RATE_CRITICAL] ~ [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - ノーマル - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - 考えられる原因: 描画距離の設定が大きすぎる - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - 考えられる原因: 画像のロード中 - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - 考えられる原因: メモリ内の画像数が多すぎる - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - 考えられる原因: 画面に含まれる複雑なオブジェクトが多すぎる - </floater.string> - <floater.string name="network_text_msg"> - ネットワーク - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - 接続でドロップされるパケットの割合: > [NETWORK_PACKET_LOSS_CRITICAL] - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - 接続でドロップされるパケットの割合:[NETWORK_PACKET_LOSS_WARNING] ~ [NETWORK_PACKET_LOSS_CRITICAL] - </floater.string> - <floater.string name="network_performance_normal_msg"> - ノーマル - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - 接続の ping 時間: > [NETWORK_PING_CRITICAL] ミリ秒 - </floater.string> - <floater.string name="network_ping_warning_msg"> - 接続の ping 時間: [NETWORK_PING_WARNING] ~ [NETWORK_PING_CRITICAL] ミリ秒 - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - 接続不良になっているか、帯域幅設定が高すぎます。 - </floater.string> - <floater.string name="network_ping_cause_msg"> - 接続不良になっているか、ファイル共有アプリケーションに問題があります。 - </floater.string> - <floater.string name="server_text_msg"> - サーバー - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - シミュレーターのフレームレート: < [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - シミュレーターのフレームレート: [SERVER_FRAME_RATE_CRITICAL] ~ [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - ノーマル - </floater.string> - <floater.string name="server_physics_cause_msg"> - 考えられる原因: 物理的オブジェクトが多すぎる - </floater.string> - <floater.string name="server_scripts_cause_msg"> - 考えられる原因: スクリプトを含むオブジェクトが多すぎる - </floater.string> - <floater.string name="server_net_cause_msg"> - 考えられる原因: ネットワーク トラフィック過大 - </floater.string> - <floater.string name="server_agent_cause_msg"> - 考えられる原因: 地域内にて動いているアバターが多すぎる - </floater.string> - <floater.string name="server_images_cause_msg"> - 考えられる原因: 画像計算が多すぎる - </floater.string> - <floater.string name="server_generic_cause_msg"> - 考えられる原因: シミュレーターの過負荷 - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button name="client_lagmeter" tool_tip="クライアント ラグ ステータス"/> - <text name="client"> - クライアント - </text> - <text name="client_text"> - ノーマル - </text> - <button name="network_lagmeter" tool_tip="ネットワーク ラグ ステータス"/> - <text name="network"> - ネットワーク - </text> - <text name="network_text"> - ノーマル - </text> - <button name="server_lagmeter" tool_tip="サーバー ラグ ステータス"/> - <text name="server"> - サーバー - </text> - <text name="server_text"> - ノーマル - </text> - <button label=">> " name="minimize" tool_tip="フローターのサイズをトグル"/> -</floater> diff --git a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml deleted file mode 100644 index 8038550bcb..0000000000 --- a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="POMIAR LAGÓW"> - <floater.string name="max_title_msg"> - Pomiar lagów - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Lag - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Klient - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - W normie, okno w tle - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Ilość klatek na sekundę klienta poniżej [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Ilość klatek na sekundę pomiędzy [CLIENT_FRAME_RATE_CRITICAL] i [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - W normie - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Przyczyna: dystans rysowania jest za wysoki - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Przyczyna: ładowanie obrazu - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Przyczyna: za dużo obrazów w pamięci - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Przyczyna: za dużo złożonych obiektów - </floater.string> - <floater.string name="network_text_msg"> - Sieć - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - Utrata pakietów przekracza [NETWORK_PACKET_LOSS_CRITICAL]% - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - Utrata pakietów przekracza [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% - </floater.string> - <floater.string name="network_performance_normal_msg"> - W normie - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Fatalny ping - [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - Wolny ping - [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Złe połączenie lub przepustowość. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Złe połączenie lub aplikacja współdzieląca pliki. - </floater.string> - <floater.string name="server_text_msg"> - Serwer - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Ilość klatek na sekundę poniżej [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Ilość klatek na sekundę pomiędzy [SERVER_FRAME_RATE_CRITICAL] i [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - W normie - </floater.string> - <floater.string name="server_physics_cause_msg"> - Przyczyna: za dużo obiektów fizycznych - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Przyczyna: za dużo obieków skryptowanych - </floater.string> - <floater.string name="server_net_cause_msg"> - Przyczyna: za duży ruch w sieci - </floater.string> - <floater.string name="server_agent_cause_msg"> - Przyczyna: za dużo poruszających się awatarów w regionie - </floater.string> - <floater.string name="server_images_cause_msg"> - Przyczyna: za dużo kalkulacji obrazu - </floater.string> - <floater.string name="server_generic_cause_msg"> - Przyczyna: symulator ładuje się zbyt powoli - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button label="" label_selected="" name="client_lagmeter" tool_tip="Status lagów klienta"/> - <text name="client"> - Klient - </text> - <text name="client_text"> - W normie - </text> - <button label="" label_selected="" name="network_lagmeter" tool_tip="Network lag status"/> - <text name="network"> - Sieć - </text> - <text name="network_text"> - W normie - </text> - <button label="" label_selected="" name="server_lagmeter" tool_tip="Server lag status"/> - <text name="server"> - Serwer - </text> - <text name="server_text"> - W normie - </text> - <button label=">>" name="minimize" tool_tip="Złącz rozmiar pliku xml"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml b/indra/newview/skins/default/xui/pt/floater_lagmeter.xml deleted file mode 100644 index 9932318293..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG - Índice"> - <floater.string name="max_title_msg"> - Medidor de Atraso - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Atraso - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Cliente - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normal, janela por baixo - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Taxa de quadros do Cliente abaixo de [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Taxa de quadros do Cliente entre [CLIENT_FRAME_RATE_CRITICAL] e [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Causa possível: Distância de desenho ajustada muito alta - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Causa possível: Carregamento de Imagens - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Causa possível: Muitas imagens na memória - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Causa possível: Muitos objetos complexos na cena - </floater.string> - <floater.string name="network_text_msg"> - Rede - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - Conexão está caindo para cerca de [NETWORK_PACKET_LOSS_CRITICAL]% de pacotes - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - Conexão está caindo [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% de pacotes - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Tempo de conexão de ping é cerca de [NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_ping_warning_msg"> - Tempo de conexão de ping é [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Possível conexão ruim ou 'Largura de Banda' escolhida muito alta. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Possível conexão ruim ou aplicativos compartilhando arquivos. - </floater.string> - <floater.string name="server_text_msg"> - Servidor - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Taxa de quadros abaixo de [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Taxa de quadros entre [SERVER_FRAME_RATE_CRITICAL] e [SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="server_physics_cause_msg"> - Causa possível: Muitos objetos físicos - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Causa possível: Muitos objetos com scripts - </floater.string> - <floater.string name="server_net_cause_msg"> - Causa possível: Muito tráfego na rede - </floater.string> - <floater.string name="server_agent_cause_msg"> - Causa possível: Muitas pessoas se movendo na região - </floater.string> - <floater.string name="server_images_cause_msg"> - Causa possível: Muitos cálculos de imagem - </floater.string> - <floater.string name="server_generic_cause_msg"> - Causa possível: Carga no simulador muito pesada - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button label="" label_selected="" name="client_lagmeter" tool_tip="Status de atraso no Cliente"/> - <text name="client"> - Cliente - </text> - <text font="SansSerifSmall" name="client_text"> - Normal - </text> - <text left="30" name="client_lag_cause" right="-10"/> - <button label="" label_selected="" name="network_lagmeter" tool_tip="Status de atraso na rede"/> - <text name="network"> - Rede - </text> - <text font="SansSerifSmall" name="network_text"> - Normal - </text> - <text left="30" name="network_lag_cause" right="-10"/> - <button label="" label_selected="" name="server_lagmeter" tool_tip="Status de atraso no servidor"/> - <text name="server"> - Servidor - </text> - <text font="SansSerifSmall" name="server_text"> - Normal - </text> - <text left="30" name="server_lag_cause" right="-32"/> - <button label=">>" name="minimize" tool_tip="Alternar o tamanho da janela"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml b/indra/newview/skins/default/xui/ru/floater_lagmeter.xml deleted file mode 100644 index c420006a03..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="УРОВЕНЬ ЛАГОВ"> - <floater.string name="max_title_msg"> - Уровень лагов - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Лаг - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - Клиент - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Нормально, окно в фоне - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - Частота кадров клиента ниже [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - Частота кадров клиента от [CLIENT_FRAME_RATE_CRITICAL] до [CLIENT_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Нормально - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Возможная причина: дальность отрисовки слишком велика - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Возможная причина: загрузка изображений - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Возможная причина: слишком много изображений в памяти - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Возможная причина: слишком много сложных объектов в сцене - </floater.string> - <floater.string name="network_text_msg"> - Сеть - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - Сеть теряет более [NETWORK_PACKET_LOSS_CRITICAL]% пакетов - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - Сеть теряет [NETWORK_PACKET_LOSS_WARNING]–[NETWORK_PACKET_LOSS_CRITICAL]% пакетов - </floater.string> - <floater.string name="network_performance_normal_msg"> - Нормально - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Пинг соединения более [NETWORK_PING_CRITICAL] мс - </floater.string> - <floater.string name="network_ping_warning_msg"> - Пинг соединения [NETWORK_PING_WARNING]–[NETWORK_PING_CRITICAL] мс - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Возможно, плохое соединение, или параметр «Ширина канала» слишком велик. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Возможно, плохое соединение или есть работающие файлообменные программы. - </floater.string> - <floater.string name="server_text_msg"> - Сервер - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Частота кадров сервера ниже [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Частота кадров сервера [SERVER_FRAME_RATE_CRITICAL]–[SERVER_FRAME_RATE_WARNING] - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Нормально - </floater.string> - <floater.string name="server_physics_cause_msg"> - Возможная причина: слишком много физических объектов - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Возможная причина: слишком много скриптовых объектов - </floater.string> - <floater.string name="server_net_cause_msg"> - Возможная причина: слишком большой сетевой трафик - </floater.string> - <floater.string name="server_agent_cause_msg"> - Возможная причина: слишком много людей в регионе - </floater.string> - <floater.string name="server_images_cause_msg"> - Возможная причина: слишком много изображений - </floater.string> - <floater.string name="server_generic_cause_msg"> - Возможная причина: сервер сильно загружен - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button name="client_lagmeter" tool_tip="Уровень лагов клиента"/> - <text name="client"> - Клиент - </text> - <text name="client_text"> - Нормально - </text> - <button name="network_lagmeter" tool_tip="Уровень лагов сети"/> - <text name="network"> - Сеть - </text> - <text name="network_text"> - Нормально - </text> - <button name="server_lagmeter" tool_tip="Уровень лагов сервера"/> - <text name="server"> - Сервер - </text> - <text name="server_text"> - Нормально - </text> - <button label=">>" name="minimize" tool_tip="Переключение размера"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml b/indra/newview/skins/default/xui/tr/floater_lagmeter.xml deleted file mode 100644 index 736c50be90..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="GECİKME ÖLÇER"> - <floater.string name="max_title_msg"> - Gecikme Ölçer - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - Gecikme - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - İstemci - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - Normal, pencere alt zeminde - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - İstemci kare hızı [CLIENT_FRAME_RATE_CRITICAL] altında - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - İstemci kare hızı [CLIENT_FRAME_RATE_CRITICAL] ile [CLIENT_FRAME_RATE_WARNING] arasınad - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - Muhtemel neden: Çizme mesafesi çok yüksek - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - Muhtemel neden: Görüntüler yükleniyor - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - Muhtemel neden: Bellekte çok fazla görüntü - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - Muhtemel neden: Sahnede çok fazla karmaşık nesne - </floater.string> - <floater.string name="network_text_msg"> - Ağ - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - Bağlantı paketlerin % [NETWORK_PACKET_LOSS_CRITICAL]'sinden fazlasını bırakıyor - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - Bağlantı paketlerin % [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]'sini bırakıyor - </floater.string> - <floater.string name="network_performance_normal_msg"> - Normal - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - Bağlantı ping süresi [NETWORK_PING_CRITICAL] ms.den fazla - </floater.string> - <floater.string name="network_ping_warning_msg"> - Bağlantı ping süresi [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - Muhtemel yetersiz bağlantı veya 'Bant Genişliği' tercihi çok yüksek. - </floater.string> - <floater.string name="network_ping_cause_msg"> - Muhtemel yetersiz bağlantı veya dosya paylaşım uygulaması. - </floater.string> - <floater.string name="server_text_msg"> - Sunucu - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - Simülatör kare hızı [SERVER_FRAME_RATE_CRITICAL] altında - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - Simülatör kare hızı [SERVER_FRAME_RATE_CRITICAL] ve [SERVER_FRAME_RATE_WARNING] arasında - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - Normal - </floater.string> - <floater.string name="server_physics_cause_msg"> - Muhtemel Neden: Çok fazla fiziki nesne - </floater.string> - <floater.string name="server_scripts_cause_msg"> - Muhtemel Neden: Çok fazla komut dosyalı nesne - </floater.string> - <floater.string name="server_net_cause_msg"> - Muhtemel Neden: Çok fazla ağ trafiği - </floater.string> - <floater.string name="server_agent_cause_msg"> - Muhtemel Neden: Bölgede hareket eden çok fazla insan var - </floater.string> - <floater.string name="server_images_cause_msg"> - Muhtemel Neden: Çok fazla görüntü hesabı - </floater.string> - <floater.string name="server_generic_cause_msg"> - Muhtemel Neden: Simülatör yükü çok ağır - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button name="client_lagmeter" tool_tip="İstemci gecikme durumu"/> - <text name="client"> - İstemci - </text> - <text name="client_text"> - Normal - </text> - <button name="network_lagmeter" tool_tip="Ağ gecikme durumu"/> - <text name="network"> - Ağ - </text> - <text name="network_text"> - Normal - </text> - <button name="server_lagmeter" tool_tip="Sunucu gecikme durumu"/> - <text name="server"> - Sunucu - </text> - <text name="server_text"> - Normal - </text> - <button label=">>" name="minimize" tool_tip="Gezdirici büyüklüğünü değiştir"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml deleted file mode 100644 index e9a082288a..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG 測量器"> - <floater.string name="max_title_msg"> - Lag 測量器 - </floater.string> - <floater.string name="max_width_px"> - 360 - </floater.string> - <floater.string name="min_title_msg"> - 延遲 - </floater.string> - <floater.string name="min_width_px"> - 90 - </floater.string> - <floater.string name="client_text_msg"> - 客戶端 - </floater.string> - <floater.string name="client_frame_rate_critical_fps"> - 10 - </floater.string> - <floater.string name="client_frame_rate_warning_fps"> - 15 - </floater.string> - <floater.string name="client_frame_time_window_bg_msg"> - 正常,視窗位於背景 - </floater.string> - <floater.string name="client_frame_time_critical_msg"> - 客戶端幀率低於 [CLIENT_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="client_frame_time_warning_msg"> - 客戶端幀率介於 [CLIENT_FRAME_RATE_CRITICAL] 和 [CLIENT_FRAME_RATE_WARNING] 之間 - </floater.string> - <floater.string name="client_frame_time_normal_msg"> - 正常 - </floater.string> - <floater.string name="client_draw_distance_cause_msg"> - 可能原因:可視距離設得太遠 - </floater.string> - <floater.string name="client_texture_loading_cause_msg"> - 可能原因:正在載入圖像 - </floater.string> - <floater.string name="client_texture_memory_cause_msg"> - 可能原因:記憶體裡圖像太多 - </floater.string> - <floater.string name="client_complex_objects_cause_msg"> - 可能原因:場景內複雜物件太多 - </floater.string> - <floater.string name="network_text_msg"> - 網路 - </floater.string> - <floater.string name="network_packet_loss_critical_pct"> - 10 - </floater.string> - <floater.string name="network_packet_loss_warning_pct"> - 5 - </floater.string> - <floater.string name="network_packet_loss_critical_msg"> - 這次連通丟失了至少 [NETWORK_PACKET_LOSS_CRITICAL]% 的封包 - </floater.string> - <floater.string name="network_packet_loss_warning_msg"> - 這次連通丟失了 [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% 的封包 - </floater.string> - <floater.string name="network_performance_normal_msg"> - 正常 - </floater.string> - <floater.string name="network_ping_critical_ms"> - 600 - </floater.string> - <floater.string name="network_ping_warning_ms"> - 300 - </floater.string> - <floater.string name="network_ping_critical_msg"> - 探測連通回應時間超過 [NETWORK_PING_CRITICAL] 毫秒 - </floater.string> - <floater.string name="network_ping_warning_msg"> - 探測連通回應時間為 [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] 毫秒 - </floater.string> - <floater.string name="network_packet_loss_cause_msg"> - 可能連通不良,或所設的偏好連通頻寬過高。 - </floater.string> - <floater.string name="network_ping_cause_msg"> - 可能連通不良,或使用檔案分享應用程式。 - </floater.string> - <floater.string name="server_text_msg"> - 伺服器 - </floater.string> - <floater.string name="server_frame_rate_critical_fps"> - 20 - </floater.string> - <floater.string name="server_frame_rate_warning_fps"> - 30 - </floater.string> - <floater.string name="server_single_process_max_time_ms"> - 20 - </floater.string> - <floater.string name="server_frame_time_critical_msg"> - 模擬器 framerate 低於 [SERVER_FRAME_RATE_CRITICAL] - </floater.string> - <floater.string name="server_frame_time_warning_msg"> - 模擬器 framerate 介於 [SERVER_FRAME_RATE_CRITICAL] 與 [SERVER_FRAME_RATE_WARNING] 之間 - </floater.string> - <floater.string name="server_frame_time_normal_msg"> - 正常 - </floater.string> - <floater.string name="server_physics_cause_msg"> - 可能原因:太多物理物件 - </floater.string> - <floater.string name="server_scripts_cause_msg"> - 可能原因:太多腳本物件 - </floater.string> - <floater.string name="server_net_cause_msg"> - 可能原因:太多網路流量 - </floater.string> - <floater.string name="server_agent_cause_msg"> - 可能原因:地區有太多移動的人 - </floater.string> - <floater.string name="server_images_cause_msg"> - 可能原因:太多圖像計算 - </floater.string> - <floater.string name="server_generic_cause_msg"> - 可能原因:模擬器負載過重 - </floater.string> - <floater.string name="smaller_label"> - >> - </floater.string> - <floater.string name="bigger_label"> - << - </floater.string> - <button name="client_lagmeter" tool_tip="客戶端 lag 狀態"/> - <text name="client"> - 客戶端 - </text> - <text name="client_text"> - 正常 - </text> - <button name="network_lagmeter" tool_tip="網路 lag 狀態"/> - <text name="network"> - 網路 - </text> - <text name="network_text"> - 正常 - </text> - <button name="server_lagmeter" tool_tip="伺服器 lag 狀態"/> - <text name="server"> - 伺服器 - </text> - <text name="server_text"> - 正常 - </text> - <button label=">>" name="minimize" tool_tip="切換浮動視窗尺寸"/> -</floater> diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index f8923b9868..ecdd78a1da 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -37,6 +37,11 @@ #include "llregionhandle.h" #include "../llvoavatar.h" +namespace LLStatViewer +{ + LLTrace::Measurement<> FPS_SAMPLE("fpssample"); +} + void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) { counts.resize(3); @@ -220,7 +225,18 @@ get_region(const LLSD & sd, U64 region_handle1) namespace tut { struct tst_viewerassetstats_index - {}; + { + tst_viewerassetstats_index() + { + LLTrace::init(); + } + + ~tst_viewerassetstats_index() + { + LLTrace::cleanup(); + } + + }; typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t; typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t; tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test"); @@ -230,24 +246,24 @@ namespace tut void tst_viewerassetstats_index_object_t::test<1>() { // Check that helpers aren't bothered by missing global stats - ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); + ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats)); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_response_main(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL); + LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL); } // Create a non-global instance and check the structure template<> template<> void tst_viewerassetstats_index_object_t::test<2>() { - ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); + ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats)); LLViewerAssetStats * it = new LLViewerAssetStats(); - ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain)); + ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats)); LLSD sd_full = it->asLLSD(false); @@ -314,16 +330,17 @@ namespace tut template<> template<> void tst_viewerassetstats_index_object_t::test<4>() { - gViewerAssetStatsMain = new LLViewerAssetStats(); - LLViewerAssetStatsFF::set_region_main(region1_handle); + gViewerAssetStats = new LLViewerAssetStats(); + LLViewerAssetStatsFF::set_region(region1_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - LLSD sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->updateStats(); + LLSD sd = gViewerAssetStats->asLLSD(false); ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd["regions"][0]; @@ -337,11 +354,11 @@ namespace tut // Reset and check zeros... // Reset leaves current region in place - gViewerAssetStatsMain->reset(); - sd = gViewerAssetStatsMain->asLLSD(false)["regions"][region1_handle_str]; + gViewerAssetStats->reset(); + sd = gViewerAssetStats->asLLSD(false)["regions"][region1_handle_str]; - delete gViewerAssetStatsMain; - gViewerAssetStatsMain = NULL; + delete gViewerAssetStats; + gViewerAssetStats = NULL; ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger())); ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); @@ -351,19 +368,17 @@ namespace tut template<> template<> void tst_viewerassetstats_index_object_t::test<5>() { - gViewerAssetStatsThread1 = new LLViewerAssetStats(); - gViewerAssetStatsMain = new LLViewerAssetStats(); - LLViewerAssetStatsFF::set_region_main(region1_handle); + gViewerAssetStats = new LLViewerAssetStats(); + LLViewerAssetStatsFF::set_region(region1_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - LLSD sd = gViewerAssetStatsThread1->asLLSD(false); - ensure("Other collector is empty", is_no_stats_map(sd)); - sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->updateStats(); + LLSD sd = gViewerAssetStats->asLLSD(false); ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd["regions"][0]; @@ -377,13 +392,11 @@ namespace tut // Reset and check zeros... // Reset leaves current region in place - gViewerAssetStatsMain->reset(); - sd = gViewerAssetStatsMain->asLLSD(false)["regions"][0]; + gViewerAssetStats->reset(); + sd = gViewerAssetStats->asLLSD(false)["regions"][0]; - delete gViewerAssetStatsMain; - gViewerAssetStatsMain = NULL; - delete gViewerAssetStatsThread1; - gViewerAssetStatsThread1 = NULL; + delete gViewerAssetStats; + gViewerAssetStats = NULL; ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger())); ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); @@ -393,24 +406,25 @@ namespace tut template<> template<> void tst_viewerassetstats_index_object_t::test<6>() { - gViewerAssetStatsMain = new LLViewerAssetStats(); + gViewerAssetStats = new LLViewerAssetStats(); - LLViewerAssetStatsFF::set_region_main(region1_handle); + LLViewerAssetStatsFF::set_region(region1_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::set_region_main(region2_handle); + LLViewerAssetStatsFF::set_region(region2_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); - LLSD sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->updateStats(); + LLSD sd = gViewerAssetStats->asLLSD(false); // std::cout << sd << std::endl; @@ -435,14 +449,14 @@ namespace tut // Reset and check zeros... // Reset leaves current region in place - gViewerAssetStatsMain->reset(); - sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->reset(); + sd = gViewerAssetStats->asLLSD(false); ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = sd["regions"][0]; - delete gViewerAssetStatsMain; - gViewerAssetStatsMain = NULL; + delete gViewerAssetStats; + gViewerAssetStats = NULL; ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger())); ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger())); @@ -452,39 +466,40 @@ namespace tut template<> template<> void tst_viewerassetstats_index_object_t::test<7>() { - gViewerAssetStatsMain = new LLViewerAssetStats(); + gViewerAssetStats = new LLViewerAssetStats(); - LLViewerAssetStatsFF::set_region_main(region1_handle); + LLViewerAssetStatsFF::set_region(region1_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::set_region_main(region2_handle); + LLViewerAssetStatsFF::set_region(region2_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::set_region_main(region1_handle); + LLViewerAssetStatsFF::set_region(region1_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, true, true); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, true, true); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, true, true); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, true, true); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::set_region_main(region2_handle); + LLViewerAssetStatsFF::set_region(region2_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); - LLSD sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->updateStats(); + LLSD sd = gViewerAssetStats->asLLSD(false); ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); @@ -507,15 +522,15 @@ namespace tut // Reset and check zeros... // Reset leaves current region in place - gViewerAssetStatsMain->reset(); - sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->reset(); + sd = gViewerAssetStats->asLLSD(false); ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = get_region(sd, region2_handle); ensure("Region2 is present in results", sd2.isMap()); - delete gViewerAssetStatsMain; - gViewerAssetStatsMain = NULL; + delete gViewerAssetStats; + gViewerAssetStats = NULL; ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0); ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0); @@ -525,36 +540,34 @@ namespace tut template<> template<> void tst_viewerassetstats_index_object_t::test<8>() { - gViewerAssetStatsThread1 = new LLViewerAssetStats(); - gViewerAssetStatsMain = new LLViewerAssetStats(); - LLViewerAssetStatsFF::set_region_main(region1_handle); + gViewerAssetStats = new LLViewerAssetStats(); + LLViewerAssetStatsFF::set_region(region1_handle); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, true); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, true); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, true); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, true); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, false); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, false); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, true); - LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, true); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, true); + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, true); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, true); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, true); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, false); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, false); - LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - LLSD sd = gViewerAssetStatsThread1->asLLSD(false); - ensure("Other collector is empty", is_no_stats_map(sd)); - sd = gViewerAssetStatsMain->asLLSD(false); + gViewerAssetStats->updateStats(); + LLSD sd = gViewerAssetStats->asLLSD(false); ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = get_region(sd, region1_handle); @@ -572,445 +585,14 @@ namespace tut // Reset and check zeros... // Reset leaves current region in place - gViewerAssetStatsMain->reset(); - sd = get_region(gViewerAssetStatsMain->asLLSD(false), region1_handle); + gViewerAssetStats->reset(); + sd = get_region(gViewerAssetStats->asLLSD(false), region1_handle); ensure("Region1 is present in results", sd.isMap()); - delete gViewerAssetStatsMain; - gViewerAssetStatsMain = NULL; - delete gViewerAssetStatsThread1; - gViewerAssetStatsThread1 = NULL; + delete gViewerAssetStats; + gViewerAssetStats = NULL; ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0); ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0); } - - - // LLViewerAssetStats::merge() basic functions work - template<> template<> - void tst_viewerassetstats_index_object_t::test<9>() - { - LLViewerAssetStats s1; - LLViewerAssetStats s2; - - s1.setRegion(region1_handle); - s2.setRegion(region1_handle); - - s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 5000000); - s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 6000000); - s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 8000000); - s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 7000000); - s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 9000000); - - s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 2000000); - s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 3000000); - s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 4000000); - - s2.merge(s1); - - LLSD s2_llsd = get_region(s2.asLLSD(false), region1_handle); - ensure("Region1 is present in results", s2_llsd.isMap()); - - ensure_equals("count after merge", s2_llsd["get_texture_temp_http"]["resp_count"].asInteger(), 8); - ensure_approximately_equals("min after merge", s2_llsd["get_texture_temp_http"]["resp_min"].asReal(), 2.0, 22); - ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_max"].asReal(), 9.0, 22); - ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_mean"].asReal(), 5.5, 22); - } - - // LLViewerAssetStats::merge() basic functions work without corrupting source data - template<> template<> - void tst_viewerassetstats_index_object_t::test<10>() - { - LLViewerAssetStats s1; - LLViewerAssetStats s2; - - s1.setRegion(region1_handle); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); - - - s2.setRegion(region2_handle); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); - s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); - - { - s2.merge(s1); - - LLSD src = s1.asLLSD(false); - LLSD dst = s2.asLLSD(false); - - ensure_equals("merge src has single region", src["regions"].size(), 1); - ensure_equals("merge dst has dual regions", dst["regions"].size(), 2); - - // Remove time stamps, they're a problem - src.erase("duration"); - src["regions"][0].erase("duration"); - dst.erase("duration"); - dst["regions"][0].erase("duration"); - dst["regions"][1].erase("duration"); - - LLSD s1_llsd = get_region(src, region1_handle); - ensure("Region1 is present in src", s1_llsd.isMap()); - LLSD s2_llsd = get_region(dst, region1_handle); - ensure("Region1 is present in dst", s2_llsd.isMap()); - - ensure("result from src is in dst", llsd_equals(s1_llsd, s2_llsd)); - } - - s1.setRegion(region1_handle); - s2.setRegion(region1_handle); - s1.reset(); - s2.reset(); - - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); - - - s2.setRegion(region1_handle); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); - s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); - - { - s2.merge(s1); - - LLSD src = s1.asLLSD(false); - LLSD dst = s2.asLLSD(false); - - ensure_equals("merge src has single region (p2)", src["regions"].size(), 1); - ensure_equals("merge dst has single region (p2)", dst["regions"].size(), 1); - - // Remove time stamps, they're a problem - src.erase("duration"); - src["regions"][0].erase("duration"); - dst.erase("duration"); - dst["regions"][0].erase("duration"); - - LLSD s1_llsd = get_region(src, region1_handle); - ensure("Region1 is present in src", s1_llsd.isMap()); - LLSD s2_llsd = get_region(dst, region1_handle); - ensure("Region1 is present in dst", s2_llsd.isMap()); - - ensure_equals("src counts okay (enq)", s1_llsd["get_other"]["enqueued"].asInteger(), 4); - ensure_equals("src counts okay (deq)", s1_llsd["get_other"]["dequeued"].asInteger(), 4); - ensure_equals("src resp counts okay", s1_llsd["get_other"]["resp_count"].asInteger(), 2); - ensure_approximately_equals("src respmin okay", s1_llsd["get_other"]["resp_min"].asReal(), 0.2829, 20); - ensure_approximately_equals("src respmax okay", s1_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); - - ensure_equals("dst counts okay (enq)", s2_llsd["get_other"]["enqueued"].asInteger(), 12); - ensure_equals("src counts okay (deq)", s2_llsd["get_other"]["dequeued"].asInteger(), 11); - ensure_equals("dst resp counts okay", s2_llsd["get_other"]["resp_count"].asInteger(), 4); - ensure_approximately_equals("dst respmin okay", s2_llsd["get_other"]["resp_min"].asReal(), 0.010, 20); - ensure_approximately_equals("dst respmax okay", s2_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); - } - } - - - // Maximum merges are interesting when one side contributes nothing - template<> template<> - void tst_viewerassetstats_index_object_t::test<11>() - { - LLViewerAssetStats s1; - LLViewerAssetStats s2; - - s1.setRegion(region1_handle); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - // Want to test negative numbers here but have to work in U64 - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - - s2.setRegion(region1_handle); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - { - s2.merge(s1); - - LLSD src = s1.asLLSD(false); - LLSD dst = s2.asLLSD(false); - - ensure_equals("merge src has single region", src["regions"].size(), 1); - ensure_equals("merge dst has single region", dst["regions"].size(), 1); - - // Remove time stamps, they're a problem - src.erase("duration"); - src["regions"][0].erase("duration"); - dst.erase("duration"); - dst["regions"][0].erase("duration"); - - LLSD s2_llsd = get_region(dst, region1_handle); - ensure("Region1 is present in dst", s2_llsd.isMap()); - - ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - - ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum", - s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); - } - - // Other way around - s1.setRegion(region1_handle); - s2.setRegion(region1_handle); - s1.reset(); - s2.reset(); - - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - // Want to test negative numbers here but have to work in U64 - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - { - s1.merge(s2); - - LLSD src = s2.asLLSD(false); - LLSD dst = s1.asLLSD(false); - - ensure_equals("merge src has single region", src["regions"].size(), 1); - ensure_equals("merge dst has single region", dst["regions"].size(), 1); - - // Remove time stamps, they're a problem - src.erase("duration"); - src["regions"][0].erase("duration"); - dst.erase("duration"); - dst["regions"][0].erase("duration"); - - LLSD s2_llsd = get_region(dst, region1_handle); - ensure("Region1 is present in dst", s2_llsd.isMap()); - - ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - - ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum (flipped)", - s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); - } - } - - // Minimum merges are interesting when one side contributes nothing - template<> template<> - void tst_viewerassetstats_index_object_t::test<12>() - { - LLViewerAssetStats s1; - LLViewerAssetStats s2; - - s1.setRegion(region1_handle); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); - - s2.setRegion(region1_handle); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - { - s2.merge(s1); - - LLSD src = s1.asLLSD(false); - LLSD dst = s2.asLLSD(false); - - ensure_equals("merge src has single region", src["regions"].size(), 1); - ensure_equals("merge dst has single region", dst["regions"].size(), 1); - - // Remove time stamps, they're a problem - src.erase("duration"); - src["regions"][0].erase("duration"); - dst.erase("duration"); - dst["regions"][0].erase("duration"); - - LLSD s2_llsd = get_region(dst, region1_handle); - ensure("Region1 is present in dst", s2_llsd.isMap()); - - ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - - ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum", - s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); - } - - // Other way around - s1.setRegion(region1_handle); - s2.setRegion(region1_handle); - s1.reset(); - s2.reset(); - - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); - s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); - - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - - { - s1.merge(s2); - - LLSD src = s2.asLLSD(false); - LLSD dst = s1.asLLSD(false); - - ensure_equals("merge src has single region", src["regions"].size(), 1); - ensure_equals("merge dst has single region", dst["regions"].size(), 1); - - // Remove time stamps, they're a problem - src.erase("duration"); - src["regions"][0].erase("duration"); - dst.erase("duration"); - dst["regions"][0].erase("duration"); - - LLSD s2_llsd = get_region(dst, region1_handle); - ensure("Region1 is present in dst", s2_llsd.isMap()); - - ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - - ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum (flipped)", - s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); - } - } - } |