diff options
author | Richard Linden <none@none> | 2013-06-05 19:05:43 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2013-06-05 19:05:43 -0700 |
commit | 0a96b47663c99914c587cdcb8bcdc096bbf55fa3 (patch) | |
tree | 67bca4958927ed7f6df423de05e42cd271292391 /indra/newview | |
parent | dcfb18373eca7986a73d8b9a1d34970cc0a23ed9 (diff) | |
parent | a74b5dfa923f8eeccc9b786143f0f832de3ad450 (diff) |
merge with viewer-release
Diffstat (limited to 'indra/newview')
212 files changed, 8872 insertions, 8071 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 227644f14f..639982a305 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -237,7 +237,6 @@ set(viewer_SOURCE_FILES llfloaterinspect.cpp llfloaterinventory.cpp llfloaterjoystick.cpp - llfloaterlagmeter.cpp llfloaterland.cpp llfloaterlandholdings.cpp llfloatermap.cpp @@ -262,6 +261,7 @@ set(viewer_SOURCE_FILES llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp llfloaterreporter.cpp + llfloatersceneloadstats.cpp llfloaterscriptdebug.cpp llfloaterscriptlimits.cpp llfloatersearch.cpp @@ -484,6 +484,7 @@ set(viewer_SOURCE_FILES llremoteparcelrequest.cpp llsavedsettingsglue.cpp llsaveoutfitcombobtn.cpp + llscenemonitor.cpp llsceneview.cpp llscreenchannel.cpp llscriptfloater.cpp @@ -605,6 +606,7 @@ set(viewer_SOURCE_FILES llviewernetwork.cpp llviewerobject.cpp llviewerobjectlist.cpp + llvieweroctree.cpp llviewerparcelmedia.cpp llviewerparcelmediaautoplay.cpp llviewerparcelmgr.cpp @@ -818,7 +820,6 @@ set(viewer_HEADER_FILES llfloaterinspect.h llfloaterinventory.h llfloaterjoystick.h - llfloaterlagmeter.h llfloaterland.h llfloaterlandholdings.h llfloatermap.h @@ -843,6 +844,7 @@ set(viewer_HEADER_FILES llfloaterregiondebugconsole.h llfloaterregioninfo.h llfloaterreporter.h + llfloatersceneloadstats.h llfloaterscriptdebug.h llfloaterscriptlimits.h llfloatersearch.h @@ -1055,6 +1057,7 @@ set(viewer_HEADER_FILES llrootview.h llsavedsettingsglue.h llsaveoutfitcombobtn.h + llscenemonitor.h llsceneview.h llscreenchannel.h llscriptfloater.h @@ -1176,6 +1179,7 @@ set(viewer_HEADER_FILES llviewernetwork.h llviewerobject.h llviewerobjectlist.h + llvieweroctree.h llviewerparcelmedia.h llviewerparcelmediaautoplay.h llviewerparcelmgr.h @@ -1563,7 +1567,7 @@ endif (WINDOWS) if (OPENAL) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL") -endif (OPENAL) +endif (OPENAL) if (FMODEX) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f356cff9d8..4d5b0c62e4 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -41,7 +41,7 @@ <string> Time before automatically setting AFK (away from keyboard) mode (seconds, 0=never). Valid values are: 0, 120, 300, 600, 1800 -</string> + </string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6642,6 +6642,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> @@ -7134,6 +7145,17 @@ <key>Value</key> <real>6.0</real> </map> + <key>ClothingLoadingDelay</key> + <map> + <key>Comment</key> + <string>Time to wait for avatar appearance to resolve before showing world (seconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>10.0</real> + </map> <key>PreferredMaturity</key> <map> <key>Comment</key> @@ -7689,7 +7711,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>OctreeMaxNodeCapacity</key> <map> <key>Comment</key> @@ -9766,6 +9787,39 @@ <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>SceneLoadingMonitorSampleTime</key> + <map> + <key>Comment</key> + <string>Time between screen samples when monitor scene load (seconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.25</real> + </map> + <key>SceneLoadingPixelDiffThreshold</key> + <map> + <key>Comment</key> + <string>Amount of pixels changed required to consider the scene as still loading (fraction of pixels on screen)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.0003</real> + </map> <key>ScriptHelpFollowsCursor</key> <map> <key>Comment</key> @@ -12714,6 +12768,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>UseObjectCacheOcclusion</key> + <map> + <key>Comment</key> + <string>Enable object cache level object culling based on occlusion (coverage) by other objects</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderSynchronousOcclusion</key> <map> <key>Comment</key> @@ -14480,6 +14545,28 @@ <key>Value</key> <integer>0</integer> </map> + <key>TeleportArrivalDelay</key> + <map> + <key>Comment</key> + <string>Time to wait before displaying world during teleport (seconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>2</real> + </map> + <key>TeleportLocalDelay</key> + <map> + <key>Comment</key> + <string>Delay to prevent teleports after starting an in-sim teleport. (seconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1</real> + </map> <key>DisablePrecacheDelayAfterTeleporting</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..6eeb2596b2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl @@ -0,0 +1,58 @@ +/** + * @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; +uniform sampler2D dither_tex; +uniform float dither_scale; +uniform float dither_scale_s; +uniform float dither_scale_t; + +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; + +void main() +{ + frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy)); + + vec2 dither_coord; + dither_coord[0] = vary_texcoord0[0] * dither_scale_s; + dither_coord[1] = vary_texcoord0[1] * dither_scale_t; + vec4 dither_vec = texture(dither_tex, dither_coord.xy); + + for(int i = 0; i < 3; i++) + { + if(frag_color[i] < dither_vec[i] * dither_scale) + { + frag_color[i] = 0.f; + } + } +} 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 8c42defa73..8ec74bb268 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -754,7 +754,7 @@ void LLAgent::setFlying(BOOL fly) } if( !was_flying ) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT); + add(LLStatViewer::FLY, 1); } setControlFlags(AGENT_CONTROL_FLY); } @@ -2830,10 +2830,10 @@ BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */ if (!ignore_god_mode && isGodlike()) return true; - S32 count = mGroups.count(); - for(S32 i = 0; i < count; ++i) + U32 count = mGroups.size(); + for(U32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { return TRUE; } @@ -2850,12 +2850,12 @@ BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const // GP_NO_POWERS can also mean no power is enough to grant an ability. if (GP_NO_POWERS == power) return FALSE; - S32 count = mGroups.count(); - for(S32 i = 0; i < count; ++i) + U32 count = mGroups.size(); + for(U32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { - return (BOOL)((mGroups.get(i).mPowers & power) > 0); + return (BOOL)((mGroups[i].mPowers & power) > 0); } } return FALSE; @@ -2871,12 +2871,12 @@ U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const if (isGodlike()) return GP_ALL_POWERS; - S32 count = mGroups.count(); - for(S32 i = 0; i < count; ++i) + U32 count = mGroups.size(); + for(U32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { - return (mGroups.get(i).mPowers); + return (mGroups[i].mPowers); } } @@ -2885,12 +2885,12 @@ U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const { - S32 count = mGroups.count(); + S32 count = mGroups.size(); for(S32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { - data = mGroups.get(i); + data = mGroups[i]; return TRUE; } } @@ -2899,12 +2899,12 @@ BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const S32 LLAgent::getGroupContribution(const LLUUID& group_id) const { - S32 count = mGroups.count(); + S32 count = mGroups.size(); for(S32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { - S32 contribution = mGroups.get(i).mContribution; + S32 contribution = mGroups[i].mContribution; return contribution; } } @@ -2913,12 +2913,12 @@ S32 LLAgent::getGroupContribution(const LLUUID& group_id) const BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution) { - S32 count = mGroups.count(); + S32 count = mGroups.size(); for(S32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { - mGroups.get(i).mContribution = contribution; + mGroups[i].mContribution = contribution; LLMessageSystem* msg = gMessageSystem; msg->newMessage("SetGroupContribution"); msg->nextBlock("AgentData"); @@ -2936,13 +2936,13 @@ BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution) BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile) { - S32 count = mGroups.count(); + S32 count = mGroups.size(); for(S32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + if(mGroups[i].mID == group_id) { - mGroups.get(i).mAcceptNotices = accept_notices; - mGroups.get(i).mListInProfile = list_in_profile; + mGroups[i].mAcceptNotices = accept_notices; + mGroups[i].mListInProfile = list_in_profile; LLMessageSystem* msg = gMessageSystem; msg->newMessage("SetGroupAcceptNotices"); msg->nextBlock("AgentData"); @@ -2962,7 +2962,7 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO BOOL LLAgent::canJoinGroups() const { - return mGroups.count() < gMaxAgentGroups; + return (S32)mGroups.size() < gMaxAgentGroups; } LLQuaternion LLAgent::getHeadRotation() @@ -3792,7 +3792,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 ); @@ -4109,7 +4109,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 f5f26f69d8..4153fbbfff 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -35,6 +35,7 @@ #include "llcoordframe.h" // for mFrameAgent #include "llavatarappearancedefines.h" #include "llpermissionsflags.h" +#include "lldarray.h" #include <boost/function.hpp> #include <boost/shared_ptr.hpp> @@ -251,6 +252,7 @@ public: const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; } void setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; } + 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 0896aa5972..d02817df7b 100755 --- 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); @@ -1070,8 +1070,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().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f + && (root_at * last_at_axis > 0.95f)) { LLVector3 vel = gAgentAvatarp->getVelocity(); if (vel.magVecSquared() > 4.f) @@ -1126,13 +1126,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; @@ -1234,7 +1235,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 ) { @@ -1352,7 +1353,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 { @@ -1382,7 +1383,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; @@ -1796,7 +1797,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); } @@ -1813,7 +1814,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(); @@ -1858,7 +1859,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/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index c88694ef76..861991f3c2 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -39,6 +39,7 @@ #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" +#include "lllocaltextureobject.h" #include "llmd5.h" #include "llnotificationsutil.h" #include "lloutfitobserver.h" @@ -64,10 +65,10 @@ using namespace LLAvatarAppearanceDefines; void wear_and_edit_cb(const LLUUID& inv_item) { if (inv_item.isNull()) return; - + // Request editing the item after it gets worn. gAgentWearables.requestEditingWearable(inv_item); - + // Wear it. LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); } @@ -180,7 +181,7 @@ void LLAgentWearables::initClass() } void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) -{ +{ llassert(avatar); avatar->outputRezTiming("Sending wearables request"); sendAgentWearablesRequest(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 46252afbde..862b428e48 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -34,6 +34,7 @@ #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llviewerinventory.h" +#include "llhttpclient.h" class LLWearableHoldingPattern; class LLInventoryCallback; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fdc2cdb78d..42bf9b657b 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -61,7 +61,8 @@ #include "llcalc.h" #include "llconversationlog.h" #include "lltexturestats.h" -#include "lltexturestats.h" +#include "lltrace.h" +#include "lltracethreadrecorder.h" #include "llviewerwindow.h" #include "llviewerdisplay.h" #include "llviewermedia.h" @@ -96,6 +97,7 @@ #include "llupdaterservice.h" #include "llfloatertexturefetchdebugger.h" #include "llspellcheck.h" +#include "llscenemonitor.h" // Linden library includes #include "llavatarnamecache.h" @@ -294,7 +296,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 @@ -624,7 +626,7 @@ public: while (!LLAppViewer::instance()->isQuitting()) { - LLFastTimer::writeLog(os); + LLTrace::TimeBlock::writeLog(os); os.flush(); ms_sleep(32); } @@ -722,7 +724,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 LLWearableType translation bridge. // Memory will be cleaned up in ::cleanupClass() @@ -1082,9 +1083,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"); @@ -1251,6 +1252,8 @@ LLFastTimer::DeclareTimer FTM_FRAME("Frame", true); bool LLAppViewer::mainLoop() { + llinfos << "***********************Entering main_loop***********************" << llendflush; + mMainloopTimeout = new LLWatchdogTimeout(); //------------------------------------------- @@ -1287,7 +1290,11 @@ bool LLAppViewer::mainLoop() while (!LLApp::isExiting()) { LLFastTimer _(FTM_FRAME); - LLFastTimer::nextFrame(); + LLTrace::TimeBlock::processTimes(); + LLTrace::get_frame_recording().nextPeriod(); + LLTrace::TimeBlock::logStats(); + + LLTrace::getUIThreadRecorder().pullFromSlaveThreads(); //clear call stack records llclearcallstacks; @@ -1404,7 +1411,6 @@ bool LLAppViewer::mainLoop() LLFloaterSnapshot::update(); // take snapshots gGLActive = FALSE; } - } pingMainloopTimeout("Main:Sleep"); @@ -1459,20 +1465,9 @@ 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); - work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - } - { - LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - } - { - LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - } + work_pending += updateTextureThreads(max_time); { LLFastTimer ftm(FTM_VFS); @@ -1585,11 +1580,29 @@ bool LLAppViewer::mainLoop() destroyMainloopTimeout(); - llinfos << "Exiting main_loop" << llendflush; + llinfos << "***********************Exiting main_loop***********************" << llendflush; return true; } +S32 LLAppViewer::updateTextureThreads(F32 max_time) +{ + S32 work_pending = 0; + { + LLFastTimer ftm(FTM_TEXTURE_CACHE); + work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread + } + { + LLFastTimer ftm(FTM_DECODE); + work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread + } + { + LLFastTimer ftm(FTM_DECODE); + work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread + } + return work_pending; +} + void LLAppViewer::flushVFSIO() { while (1) @@ -1613,12 +1626,15 @@ bool LLAppViewer::cleanup() // workaround for DEV-35406 crash on shutdown LLEventPumps::instance().reset(); + //dump scene loading monitor results + LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + 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), @@ -1799,7 +1815,7 @@ bool LLAppViewer::cleanup() llinfos << "Cleaning up Objects" << llendflush; LLViewerObject::cleanupVOClasses(); - + LLAvatarAppearance::cleanupClass(); LLPostProcess::cleanupClass(); @@ -1970,9 +1986,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), @@ -2097,10 +2113,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(); } @@ -2538,13 +2554,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]; @@ -2552,11 +2568,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; } } @@ -2769,7 +2785,7 @@ bool LLAppViewer::initConfiguration() } initMarkerFile(); - + if (mSecondInstance) { // This is the second instance of SL. Turn off voice support, @@ -2989,7 +3005,7 @@ namespace { relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); substitutions["INFO_URL"] = relnotes_url.getString(); } - + LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback); } @@ -3771,7 +3787,7 @@ void LLAppViewer::requestQuit() // Try to send metrics back to the grid metricsSend(!gDisconnected); - + // Try to send last batch of avatar rez metrics. if (!gDisconnected && isAgentAvatarValid()) { @@ -3972,7 +3988,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; } @@ -4229,6 +4245,14 @@ void LLAppViewer::purgeCache() gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*"); } +//purge cache immediately, do not wait until the next login. +void LLAppViewer::purgeCacheImmediate() +{ + LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL; + LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false); + LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true); +} + std::string LLAppViewer::getSecondLifeTitle() const { return LLTrans::getString("APP_NAME"); @@ -4413,6 +4437,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() @@ -4431,7 +4457,7 @@ void LLAppViewer::idle() LLFrameTimer::updateFrameCount(); LLEventTimer::updateClass(); LLNotificationsUI::LLToast::updateClass(); - LLCriticalDamp::updateInterpolants(); + LLSmoothInterpolation::updateInterpolants(); LLMortician::updateClass(); LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() @@ -4456,6 +4482,7 @@ void LLAppViewer::idle() { if (gRenderStartTime.getElapsedTimeF32() > qas) { + llinfos << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << llendl; LLAppViewer::instance()->forceQuit(); } } @@ -4554,21 +4581,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); } } @@ -4649,8 +4667,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); @@ -4697,8 +4714,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(); @@ -5102,7 +5118,7 @@ void LLAppViewer::idleNetwork() gPrintMessagesThisFrame = FALSE; } } - LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); + add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); // Retransmit unacknowledged packets. gXferManager->retransmitUnackedPackets(); @@ -5181,6 +5197,7 @@ void LLAppViewer::disconnectViewer() { LLWorld::getInstance()->destroyClass(); } + LLVOCache::deleteSingleton(); // call all self-registered classes LLDestroyClassList::instance().fireCallbacks(); @@ -5504,17 +5521,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); } } @@ -5525,7 +5532,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle) */ void LLAppViewer::metricsSend(bool enable_reporting) { - if (! gViewerAssetStatsMain) + if (! gViewerAssetStats) return; if (LLAppViewer::sTextureFetch) @@ -5538,7 +5545,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. @@ -5557,6 +5567,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 d3a8cf24d9..2e75de445f 100755 --- 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; @@ -169,6 +170,8 @@ public: void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle void purgeCache(); // Clear the local cache. + void purgeCacheImmediate(); //clear local cache immediately. + S32 updateTextureThreads(F32 max_time); // mute/unmute the system's master audio virtual void setMasterSystemAudioMute(bool mute); @@ -219,7 +222,7 @@ private: void initMarkerFile(); static void recordMarkerVersion(LLAPRFile& marker_file); bool markerIsSameVersion(const std::string& marker_name) const; - + void idle(); void idleShutdown(); // update avatar SLID and display name caches @@ -334,7 +337,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/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 0ba3669487..a113ab2508 100755 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -29,11 +29,12 @@ #ifdef INCLUDE_VLD #include "vld.h" #endif +#include "llwin32headers.h" -#include "llappviewerwin32.h" +#include "llwindowwin32.h" // *FIX: for setting gIconResource. +#include "llappviewerwin32.h" -#include "llwindowwin32.h" // *FIX: for setting gIconResource. #include "llgl.h" #include "res/resource.h" // *FIX: for setting gIconResource. diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 14583e402d..3da77857c6 100755 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -32,13 +32,10 @@ #include "llcallingcard.h" -#include <vector> #include <algorithm> -//#include <iterator> #include "indra_constants.h" -#include "llavatarnamecache.h" -#include "llcachename.h" +//#include "llcachename.h" #include "llstl.h" #include "lltimer.h" #include "lluuid.h" @@ -46,19 +43,14 @@ #include "llagent.h" #include "llavatarnamecache.h" -#include "llbutton.h" #include "llinventoryobserver.h" #include "llinventorymodel.h" #include "llnotifications.h" -#include "llnotificationsutil.h" -#include "llresmgr.h" #include "llslurl.h" #include "llimview.h" #include "lltrans.h" #include "llviewercontrol.h" -#include "llviewernetwork.h" #include "llviewerobjectlist.h" -#include "llviewerwindow.h" #include "llvoavatar.h" #include "llavataractions.h" @@ -105,8 +97,6 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, LLAvatarTracker::LLAvatarTracker() : mTrackingData(NULL), mTrackedAgentValid(false), - //mInventory(NULL), - //mInventoryObserver(NULL), mModifyMask(0x0) { } @@ -641,11 +631,11 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) payload["from_id"] = agent_id; if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights) { - LLNotificationsUtil::add("GrantedModifyRights",args, payload); + LLNotifications::instance().add("GrantedModifyRights",args, payload); } else { - LLNotificationsUtil::add("RevokedModifyRights",args, payload); + LLNotifications::instance().add("RevokedModifyRights",args, payload); } } (mBuddyInfo[agent_id])->setRightsFrom(new_rights); @@ -729,7 +719,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, if (online) { notification = - LLNotificationsUtil::add("FriendOnlineOffline", + LLNotifications::instance().add("FriendOnlineOffline", args, payload.with("respond_on_mousedown", TRUE), boost::bind(&LLAvatarActions::startIM, agent_id)); @@ -737,7 +727,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, else { notification = - LLNotificationsUtil::add("FriendOnlineOffline", args, payload); + LLNotifications::instance().add("FriendOnlineOffline", args, payload); } // If there's an open IM session with this agent, send a notification there too. diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 7d0331757b..b883941963 100755 --- 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 4588424474..d70d575eab 100755 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -424,8 +424,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 100755 --- 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/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index d7d9f82910..6fd0897919 100755 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -27,7 +27,6 @@ #include "llviewerprecompiledheaders.h" #include "lldirpicker.h" -//#include "llviewermessage.h" #include "llworld.h" #include "llviewerwindow.h" #include "llkeyboard.h" @@ -36,6 +35,7 @@ #include "lltrans.h" #include "llwindow.h" // beforeDialog() #include "llviewercontrol.h" +#include "llwin32headerslean.h" #if LL_LINUX || LL_SOLARIS # include "llfilepicker.h" diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 682f9d6476..2299341aba 100755 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -46,11 +46,6 @@ #endif -// Need commdlg.h for OPENDIRNAMEA -#ifdef LL_WINDOWS -#include <commdlg.h> -#endif - class LLFilePicker; class LLDirPicker diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 47306d3a6a..93fb484f06 100755 --- 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,43 +77,68 @@ extern bool gShiftFrame; // // static -U32 LLDrawable::sCurVisible = 0; U32 LLDrawable::sNumZombieDrawables = 0; F32 LLDrawable::sCurPixelAngle = 0; -LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList; +LLDynamicArray<LLPointer<LLDrawable>, 32 > LLDrawable::sDeadList; #define FORCE_INVISIBLE_AREA 16.f // 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); + } + + llassert(!vo_entry || vo_entry->getEntry() == mEntry); - mSpatialBridge = NULL; + 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() { /* @@ -290,7 +334,7 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { 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()); } @@ -455,7 +505,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled) //drawable became static with active parent, not acceptable llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); - + LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -518,7 +568,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); @@ -647,7 +697,7 @@ BOOL LLDrawable::updateMove() { return FALSE; } - + makeActive(); return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped(); @@ -733,7 +783,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLVOVolume* volume = getVOVolume(); if (volume) { - if (getSpatialGroup()) + if (getGroup()) { pos.set(getPositionGroup().getF32ptr()); } @@ -851,9 +901,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) { @@ -861,9 +909,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); @@ -875,40 +921,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); } } @@ -917,11 +947,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)); } } @@ -955,26 +985,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; +} + +//virtual +bool LLDrawable::isRecentlyVisible() const +{ + //currently visible or visible in the previous frame. + bool vis = LLViewerOctreeEntryData::isRecentlyVisible(); -/*if (mSpatialGroupp && (groupp != mSpatialGroupp)) + 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)); + + //precondition: groupp MUST be null or groupp MUST contain this + llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this)); - if (mSpatialGroupp != groupp && getVOVolume()) + 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 @@ -990,10 +1050,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() @@ -1012,11 +1072,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(); @@ -1035,89 +1095,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::getMinFrameRange() 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; @@ -1138,10 +1135,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLSpatialBridge::~LLSpatialBridge() { + if(mEntry) + { LLSpatialGroup* group = getSpatialGroup(); if (group) { - group->mSpatialPartition->remove(this, group); + group->getSpatialPartition()->remove(this, group); + } } //delete octree here so listeners will still be able to access bridge specific state @@ -1163,8 +1163,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; @@ -1176,7 +1177,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]; @@ -1198,12 +1199,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; @@ -1216,19 +1214,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) @@ -1262,7 +1262,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 @@ -1297,21 +1297,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); } @@ -1355,7 +1355,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* } if (!group || - LLDrawable::getCurrentFrame() - av->mVisible > 1 || + LLDrawable::getCurrentFrame() - av->getVisible() > 1 || impostor || !loaded) { @@ -1369,16 +1369,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 && @@ -1493,9 +1494,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() @@ -1503,11 +1502,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(); @@ -1518,10 +1514,10 @@ void LLSpatialBridge::cleanupReferences() LLDrawable* drawable = child->mDrawable; if (drawable) { - drawable->setSpatialGroup(NULL); + drawable->setGroup(NULL); + } } } - }*/ LLDrawable* drawablep = mDrawable; mDrawable = NULL; @@ -1590,8 +1586,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; @@ -1599,8 +1595,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 4420a34fae..98f0b51a97 100755 --- 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 getMinFrameRange()const; + void removeFromOctree(); + + void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } + LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } + // Statics static void incrementVisible(); static void cleanupDeadDrawables(); @@ -292,10 +282,6 @@ public: ACTIVE_CHILD = 0x40000000, } EDrawableFlags; -private: //aligned members - LL_ALIGN_16(LLVector4a mExtents[2]); - LL_ALIGN_16(LLVector4a mPositionGroup); - public: LLXformMatrix mXform; @@ -304,13 +290,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; @@ -319,21 +300,15 @@ 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; + static LLDynamicArray<LLPointer<LLDrawable>, 32> sDeadList; } LL_ALIGN_POSTFIX(16); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..7020db917b 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -351,7 +351,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; - if (group->mSpatialPartition->mRenderByGroup && + if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; @@ -389,15 +389,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { LLSpatialGroup* group = *i; llassert(group); - llassert(group->mSpatialPartition); + llassert(group->getSpatialPartition()); - if (group->mSpatialPartition->mRenderByGroup && + if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress. - group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && - group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; + group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && + group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 294cecc703..67dbe6de8b 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -421,7 +421,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) if (pass == 0) { - avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); + avatarp->renderSkinned(); } else { @@ -1246,7 +1246,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if( !single_avatar || (avatarp == single_avatar) ) { - avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); + avatarp->renderSkinned(); } } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5ddc15df42..9a5743919d 100755 --- 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.cpp b/indra/newview/llface.cpp index 281f852b0a..98c75a64c7 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2346,8 +2346,6 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) return 0.f ; } - //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ; - S32 i = 0 ; for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index de4d03351c..dda4bc9b3c 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -28,7 +28,6 @@ #define LL_LLFACE_H #include "llstrider.h" - #include "llrender.h" #include "v2math.h" #include "v3math.h" @@ -37,7 +36,6 @@ #include "v4coloru.h" #include "llquaternion.h" #include "xform.h" -#include "lldarrayptr.h" #include "llvertexbuffer.h" #include "llviewertexture.h" #include "lldrawable.h" @@ -47,10 +45,8 @@ class LLFacePool; class LLVolume; class LLViewerTexture; class LLTextureEntry; -class LLVertexProgram; -class LLViewerTexture; -class LLGeometryManager; class LLTextureAtlasSlot; +class LLDrawInfo; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -262,11 +258,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 fbf72b1a85..40526d3357 100755 --- 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.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(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,705 +378,48 @@ 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; - 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); - - 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); - - 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->getLastRecording().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(); - } - return 0.0; } void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch) @@ -1533,13 +916,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 ; @@ -1550,9 +933,660 @@ void LLFastTimerView::onClickCloseBtn() setVisible(false); } -LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer() +void LLFastTimerView::printLineStats() +{ + // 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->getPrevRecording(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->getPrevRecording(j).getSum(*idp), LLUnit<LLUnits::Seconds, F64>(0.000001)); + U32 calls = mRecording->getPrevRecording(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->getPrevRecording(hidx).getSum(*idp); + calls = mRecording->getPrevRecording(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 ) { - return FTM_FRAME.getNamedTimer(); + // 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->getPrevRecording(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..341adacd65 100755 --- 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,47 @@ public: virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual void draw(); - LLFastTimer::NamedTimer* getLegendID(S32 y); - F64 getTime(const std::string& name); + LLTrace::TimeBlock* getLegendID(S32 y); 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 +113,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/llfilepicker.h b/indra/newview/llfilepicker.h index 4f602f63f1..4d7b81304a 100755 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -50,6 +50,7 @@ // Need commdlg.h for OPENFILENAMEA #ifdef LL_WINDOWS +#include "llwin32headers.h" #include <commdlg.h> #endif diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index caad0afec0..83193b2e14 100755 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -339,10 +339,10 @@ void LLVolumeImplFlexible::doIdleUpdate() if (drawablep) { //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - + //ensure drawable is active drawablep->makeActive(); - + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { bool visible = drawablep->isVisible(); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 83fb887d81..93502daac7 100755 --- 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().snapshotCurRecording(); + 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/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 113aa9a8f2..76773f914d 100755 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -405,11 +405,11 @@ void LLFloaterAvatarPicker::drawFrustum() if (gFocusMgr.childHasMouseCapture(getDragHandle())) { - mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime)); + mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(mContextConeFadeTime)); } else { - mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime)); + mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime)); } } } diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 048837acfe..317bdd8d46 100755 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -37,6 +37,7 @@ #include "lluictrlfactory.h" #include "llviewerobjectlist.h" #include "llvoavatarself.h" +#include "lllocaltextureobject.h" using namespace LLAvatarAppearanceDefines; diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 42857b2aa2..84e2956b29 100755 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -202,7 +202,7 @@ public: virtual void draw(); virtual BOOL canClose(); - void onVisibilityChange ( const LLSD& new_visibility ); + void onVisibilityChanged ( const LLSD& new_visibility ); }; @@ -1008,7 +1008,7 @@ BOOL LLFloaterBuyLandUI::canClose() return can_close; } -void LLFloaterBuyLandUI::onVisibilityChange ( const LLSD& new_visibility ) +void LLFloaterBuyLandUI::onVisibilityChanged ( const LLSD& new_visibility ) { if (new_visibility.asBoolean()) { diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index a03425649f..6aebe85e7a 100755 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -529,11 +529,11 @@ void LLFloaterColorPicker::draw() if (gFocusMgr.childHasMouseCapture(getDragHandle())) { mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), - LLCriticalDamp::getInterpolant(mContextConeFadeTime)); + LLSmoothInterpolation::getInterpolant(mContextConeFadeTime)); } else { - mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime)); + mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime)); } mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 49f36a2f32..2287277acf 100755 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -841,7 +841,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/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 8ec85e1160..1b3318a730 100755..100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -41,6 +41,7 @@ #include "llchicletbar.h" #include "lldonotdisturbnotificationstorage.h" #include "llfloaterreg.h" +#include "llhttpclient.h" #include "llfloateravatarpicker.h" #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container #include "llinventoryfunctions.h" @@ -52,6 +53,7 @@ #include "lltrans.h" #include "llchathistory.h" #include "llnotifications.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "lltransientfloatermgr.h" #include "llinventorymodel.h" @@ -109,7 +111,7 @@ void LLFloaterIMSession::refresh() void LLFloaterIMSession::onTearOffClicked() { LLFloaterIMSessionTab::onTearOffClicked(); - + if(mIsP2PChat) { if(isTornOff()) @@ -170,7 +172,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data) } } -void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility) +void LLFloaterIMSession::onVisibilityChanged(const LLSD& new_visibility) { bool visible = new_visibility.asBoolean(); @@ -331,7 +333,7 @@ void LLFloaterIMSession::initIMFloater() BOOL LLFloaterIMSession::postBuild() { BOOL result = LLFloaterIMSessionTab::postBuild(); - + mInputEditor->setMaxTextLength(1023); mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5)); mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); @@ -358,7 +360,7 @@ BOOL LLFloaterIMSession::postBuild() return result; } - + void LLFloaterIMSession::onAddButtonClicked() { LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn"); @@ -371,7 +373,7 @@ void LLFloaterIMSession::onAddButtonClicked() // Need to disable 'ok' button when selected users are already in conversation. picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1)); - + if (root_floater) { root_floater->addDependentFloater(picker); @@ -426,7 +428,7 @@ bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids) } } } - + return true; } @@ -600,7 +602,7 @@ LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id) return conversation; } - + LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id) { LLFloaterIMSession* conversation = @@ -780,7 +782,7 @@ void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id) initIMSession(im_session_id); buildConversationViewParticipant(); } - + initIMFloater(); LLFloaterIMSessionTab::updateGearBtn(); //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index a0e0171b34..84abb2435a 100755..100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -62,7 +62,7 @@ public: void initIMSession(const LLUUID& session_id); void initIMFloater(); - + // LLView overrides /*virtual*/ BOOL postBuild(); /*virtual*/ void setMinimized(BOOL b); @@ -107,7 +107,7 @@ public: // called when docked floater's position has been set by chiclet void setPositioned(bool b) { mPositioned = b; }; - void onVisibilityChange(const LLSD& new_visibility); + void onVisibilityChanged(const LLSD& new_visibility); bool enableGearMenuItem(const LLSD& userdata); void GearDoToSelected(const LLSD& userdata); bool checkGearMenuItem(const LLSD& userdata); @@ -142,10 +142,10 @@ private: /*virtual*/ void onTearOffClicked(); /*virtual*/ void onClickCloseBtn(); - + // Update the window title and input field help text /*virtual*/ void updateSessionName(const std::string& name); - + bool dropPerson(LLUUID* person_id, bool drop); BOOL isInviteAllowed() const; @@ -161,7 +161,7 @@ private: bool canAddSelectedToChat(const uuid_vec_t& uuids); void onCallButtonClicked(); - + void boundVoiceChannel(); // Add the "User is typing..." indicator. diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index d0c22d25f2..b71ab4c53b 100755 --- 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::SampleStatHandle<> 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::SampleStatHandle<>* 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; @@ -69,7 +85,7 @@ void LLFloaterJoystick::draw() if (llabs(value) > maxbar) { F32 range = llabs(value); - mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f); + mAxisStatsBar[i]->setRange(-range, range, range * 0.25f); } } } @@ -85,13 +101,12 @@ 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]->setRange(-range, range, range * 0.25f, range * 0.5f); + mAxisStatsBar[i]->setStat(stat_name); + mAxisStatsBar[i]->setRange(-range, range, range * 0.25f); } } diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index dfdb108ff8..9c3752540d 100755 --- 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 100755 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 100755 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/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 8290494c22..2194c1112a 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -225,7 +225,7 @@ void LLFloaterLand::onOpen(const LLSD& key) refresh(); } -void LLFloaterLand::onVisibilityChange(const LLSD& visible) +void LLFloaterLand::onVisibilityChanged(const LLSD& visible) { if (!visible.asBoolean()) { @@ -255,7 +255,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) BOOL LLFloaterLand::postBuild() { - setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2)); + setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChanged, this, _2)); LLTabContainer* tab = getChild<LLTabContainer>("landtab"); diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 4f1c10274a..dccdfc9acb 100755 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -88,7 +88,7 @@ private: LLFloaterLand(const LLSD& seed); virtual ~LLFloaterLand(); - void onVisibilityChange(const LLSD& visible); + void onVisibilityChanged(const LLSD& visible); protected: diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 100f1d580b..85fe901fde 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; @@ -3884,14 +3882,14 @@ 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) @@ -4232,28 +4230,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); + } + } } } @@ -4442,28 +4440,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 50c013a49d..bc8a208030 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2545,8 +2545,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) { @@ -2921,7 +2919,7 @@ void LLPanelEnvironmentInfo::onOpen(const LLSD& key) } // virtual -void LLPanelEnvironmentInfo::handleVisibilityChange(BOOL new_visibility) +void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility) { // If hiding (user switched to another tab or closed the floater), // display user's preferred environment. diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index f0499f1903..dd961e21b2 100755 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -402,7 +402,7 @@ public: /*virtual*/ void onOpen(const LLSD& key); // LLView - /*virtual*/ void handleVisibilityChange(BOOL new_visibility); + /*virtual*/ void onVisibilityChange(BOOL new_visibility); // LLPanelRegionInfo /*virtual*/ bool refreshFromRegion(LLViewerRegion* region); 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 100755 --- 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/llfollowcam.cpp b/indra/newview/llfollowcam.cpp index 47612fe25c..3110d0391f 100755 --- a/indra/newview/llfollowcam.cpp +++ b/indra/newview/llfollowcam.cpp @@ -327,11 +327,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 --------------------------------------------- @@ -414,7 +414,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 ); } @@ -434,7 +434,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 ----------------------------------------------------------- @@ -489,7 +489,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 9aa86297fc..876db96085 100755 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -1139,8 +1139,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/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index cbd844cdac..ba4927e622 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -41,6 +41,7 @@ #include "llui.h" #include "message.h" #include "roles_constants.h" +#include "llhttpclient.h" #include "lltransactiontypes.h" #include "llstatusbar.h" #include "lleconomy.h" @@ -50,6 +51,7 @@ #include "llnotificationsutil.h" #include "lluictrlfactory.h" #include "lltrans.h" +#include "llviewerregion.h" #include <boost/regex.hpp> #if LL_MSVC diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 644daa0299..2bbc9c839d 100755 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -28,7 +28,6 @@ #define LL_LLHUDICON_H #include "llpointer.h" -#include "lldarrayptr.h" #include "llhudobject.h" #include "v4color.h" @@ -42,8 +41,6 @@ #include "lldarray.h" // Renders a 2D icon billboard floating at the location specified. -class LLDrawable; -class LLViewerObject; class LLViewerTexture; class LLHUDIcon : public LLHUDObject diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h index 09e79acbfc..effea8f034 100755 --- a/indra/newview/llhudmanager.h +++ b/indra/newview/llhudmanager.h @@ -30,13 +30,9 @@ // Responsible for managing all HUD elements. #include "llhudobject.h" -#include "lldarrayptr.h" +#include "lldarray.h" -class LLViewerObject; class LLHUDEffect; -//Ventrella 9/16/05 -class LLHUDAnimalControls; -// End Ventrella class LLMessageSystem; class LLHUDManager : public LLSingleton<LLHUDManager> @@ -59,7 +55,7 @@ public: static LLColor4 sChildColor; protected: - LLDynamicArrayPtr<LLPointer<LLHUDEffect> > mHUDEffects; + LLDynamicArray<LLPointer<LLHUDEffect>, 32> mHUDEffects; }; #endif // LL_LLHUDMANAGER_H diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 3336097955..f43b478f60 100755 --- 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" @@ -310,7 +311,7 @@ void LLHUDNameTag::renderText(BOOL for_select) label_top_rect.mBottom = label_top_rect.mTop - label_height; LLColor4 label_top_color = text_color; label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor; - + rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color); } @@ -737,8 +738,8 @@ void LLHUDNameTag::updateAll() current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight()); } - 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().getLastRecording().getPerSec(*camera_vel_stat); if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) { return; @@ -806,7 +807,7 @@ void LLHUDNameTag::updateAll() VisibleTextObjectIterator this_object_it; for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it) { - (*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/llimview.cpp b/indra/newview/llimview.cpp index 2c20409381..c62871236b 100755 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -68,6 +68,7 @@ #include "llviewerparcelmgr.h" #include "llconversationlog.h" #include "message.h" +#include "llviewerregion.h" const static std::string ADHOC_NAME_SUFFIX(" Conference"); @@ -1051,7 +1052,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const { LLIMSession* session = findIMSession(session_id); - if (!session) + if (!session) { llwarns << "session " << session_id << "does not exist " << llendl; return LLTrans::getString("no_session_message"); @@ -1561,7 +1562,7 @@ public: } void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content) - { + { llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:" << statusNum << "]: " << content << llendl; //throw something back to the viewer here? @@ -2684,7 +2685,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess LLChat chat(message); chat.mSourceType = CHAT_SOURCE_SYSTEM; - + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); if (nearby_chat) { diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index da6039a3ae..2d036cbc2f 100755 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -33,13 +33,12 @@ #include "lllogchat.h" #include "llvoicechannel.h" - +#include "lldarray.h" class LLAvatarName; class LLFriendObserver; class LLCallDialogManager; class LLIMSpeakerMgr; - /** * Timeout Timer for outgoing Ad-Hoc/Group IM sessions which being initialized by the server */ @@ -557,7 +556,7 @@ public: mAvatarNameCacheConnection.disconnect(); } } - + /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 9c6db3676f..ce9f17663c 100755 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -67,7 +67,7 @@ public: // Inspector will be positioned relative to current mouse position LLInspectAvatar(const LLSD& avatar_id); virtual ~LLInspectAvatar(); - + /*virtual*/ BOOL postBuild(void); // Because floater is single instance, need to re-parse data on each spawn @@ -83,7 +83,7 @@ private: // Make network requests for all the data to display in this view. // Used on construction and if avatar id changes. void requestUpdate(); - + // Set the volume slider to this user's current client-side volume setting, // hiding/disabling if the user is not nearby. void updateVolumeSlider(); @@ -221,7 +221,7 @@ void LLInspectAvatar::onOpen(const LLSD& data) requestUpdate(); updateVolumeSlider(); -} +} void LLInspectAvatar::requestUpdate() { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a5043a30ac..d05bdd0a6d 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -70,6 +70,7 @@ #include "llviewermenu.h" #include "llviewermessage.h" #include "llviewerobjectlist.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llwearablelist.h" @@ -3222,7 +3223,7 @@ void LLFolderBridge::pasteFromClipboard() LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id); llassert(vicat); if (vicat) - { + { //changeCategoryParent() implicity calls dirtyFilter changeCategoryParent(model, vicat, parent_id, FALSE); } diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 02a2475cfd..b7c4ec6f8b 100755 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -32,6 +32,7 @@ #include "lldictionary.h" #include "llinventorydefines.h" #include "llui.h" +#include "lluiimage.h" #include "llwearabletype.h" struct IconEntry : public LLDictionaryEntry @@ -49,6 +50,8 @@ public: LLIconDictionary(); }; +typedef LLPointer<LLUIImage> LLUIImagePtr; + LLIconDictionary::LLIconDictionary() { addEntry(LLInventoryType::ICONNAME_TEXTURE, new IconEntry("Inv_Texture")); diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index 2197c53bb8..bc09e32087 100755 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -30,7 +30,6 @@ #include "llassettype.h" #include "llinventorytype.h" -#include "lluiimage.h" class LLInventoryIcon { @@ -41,11 +40,11 @@ public: BOOL item_is_multi = FALSE); static const std::string& getIconName(LLInventoryType::EIconName idx); - static LLUIImagePtr getIcon(LLAssetType::EType asset_type, + static LLPointer<class LLUIImage> getIcon(LLAssetType::EType asset_type, LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, U32 misc_flag = 0, // different meanings depending on item type BOOL item_is_multi = FALSE); - static LLUIImagePtr getIcon(LLInventoryType::EIconName idx); + static LLPointer<class LLUIImage> getIcon(LLInventoryType::EIconName idx); protected: static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 8aac879a93..964adf5e50 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -31,7 +31,7 @@ #include "llfoldertype.h" #include "lldarray.h" #include "llframetimer.h" -#include "llhttpclient.h" +#include "llcurl.h" #include "lluuid.h" #include "llpermissionsflags.h" #include "llstring.h" @@ -79,7 +79,7 @@ public: typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t; typedef std::set<LLUUID> changed_items_t; - class fetchInventoryResponder : public LLHTTPClient::Responder + class fetchInventoryResponder : public LLCurl::Responder { public: fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index cf1fd4c0d0..bd3c70b7f5 100755 --- 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); if (!mViewsInitialized) return; @@ -733,7 +734,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge params.listener = bridge; params.rect = LLRect (0, 0, 0, 0); params.tool_tip = params.name; - + params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor)); params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor)); diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index dd402de394..2a131eff58 100755 --- 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/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 25df4889b0..33143b4671 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -48,6 +48,7 @@ /* misc headers */ #include "llscrolllistctrl.h" #include "llfilepicker.h" +#include "lllocaltextureobject.h" #include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerobject.h" diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 580b6dfa7e..b404345799 100755 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -30,11 +30,11 @@ #include "llavatarappearancedefines.h" #include "lleventtimer.h" -#include "llimage.h" #include "llpointer.h" #include "llwearabletype.h" class LLScrollListCtrl; +class LLImageRaw; class LLViewerObject; class LLLocalBitmap diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index d79f1040bb..9b05c75617 100755 --- 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 ae0884ac5d..15788d6ffd 100755 --- 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 b62db70ec8..01337cfaed 100755 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1904,18 +1904,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/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 2075aeed63..9298d6952f 100755 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -392,7 +392,7 @@ BOOL LLMediaCtrl::postBuild () mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( "menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); - setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2)); + setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2)); return TRUE; } @@ -422,7 +422,7 @@ BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask ) //////////////////////////////////////////////////////////////////////////////// // -void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility ) +void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility ) { llinfos << "visibility changed to " << (new_visibility?"true":"false") << llendl; if(mMediaSource) @@ -450,7 +450,7 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char) //////////////////////////////////////////////////////////////////////////////// // -void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility ) +void LLMediaCtrl::onVisibilityChanged ( const LLSD& new_visibility ) { // set state of frequent updates automatically if visibility changes if ( new_visibility.asBoolean() ) diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 7f2a5e1642..db501cdb8c 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -149,7 +149,7 @@ public: // over-rides virtual BOOL handleKeyHere( KEY key, MASK mask); - virtual void handleVisibilityChange ( BOOL new_visibility ); + virtual void onVisibilityChange ( BOOL new_visibility ); virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void draw(); @@ -171,7 +171,7 @@ public: void convertInputCoords(S32& x, S32& y); private: - void onVisibilityChange ( const LLSD& new_visibility ); + void onVisibilityChanged ( const LLSD& new_visibility ); void onPopup(const LLSD& notification, const LLSD& response); const S32 mTextureDepthBytes; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index b47fe9d4b1..55347039ac 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -26,8 +26,7 @@ #include "llviewerprecompiledheaders.h" -#include "apr_pools.h" -#include "apr_dso.h" +#include "llapr.h" #include "llhttpstatuscodes.h" #include "llmeshrepository.h" diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index dea90b9042..7cf1d177ac 100755 --- 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/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 862e4be203..50d0b4256b 100755 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -52,6 +52,7 @@ #include "llfloaterworldmap.h" #include "llviewergenericmessage.h" // send_generic_message #include "llviewerregion.h" +#include "llviewertexture.h" #include "lltrans.h" #include "llscrollcontainer.h" #include "llstatusbar.h" diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index e71dba5cae..a499fa1d87 100755 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -30,6 +30,7 @@ #include "llpanel.h" #include "llviewerwearable.h" #include "lluictrl.h" +#include "lllocaltextureobject.h" #include "llscrollingpanellist.h" #include "llvisualparam.h" #include "lltoolmorph.h" diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 445c0d811f..ef5b803f70 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1048,7 +1048,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/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a50d9074f7..74c810ea79 100755 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -202,7 +202,7 @@ void LLPanelNearByMedia::onTopLost() /*virtual*/ -void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility ) +void LLPanelNearByMedia::onVisibilityChange ( BOOL new_visibility ) { if (new_visibility) { diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index c3634de9b4..a9c1b190cf 100755 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -48,7 +48,7 @@ public: /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ void onTopLost(); - /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); + /*virtual*/ void onVisibilityChange ( BOOL new_visibility ); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index c09d4393c8..7648e12f96 100755 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -169,7 +169,7 @@ public: return menu; } - + private: static void onCreate(const LLSD& param) { @@ -481,7 +481,7 @@ BOOL LLPanelOutfitEdit::postBuild() childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); childSetCommitCallback("shop_btn_2", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); - setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChange, this, _2)); + setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChanged, this, _2)); mWearablesGearMenuBtn = getChild<LLMenuButton>("wearables_gear_menu_btn"); mGearMenuBtn = getChild<LLMenuButton>("gear_menu_btn"); @@ -767,7 +767,7 @@ void LLPanelOutfitEdit::onPlusBtnClicked(void) } } -void LLPanelOutfitEdit::onVisibilityChange(const LLSD &in_visible_chain) +void LLPanelOutfitEdit::onVisibilityChanged(const LLSD &in_visible_chain) { showAddWearablesPanel(false); mWearableItemsList->resetSelection(); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 5d4b8d4644..30870daf40 100755 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -145,7 +145,7 @@ public: void updatePlusButton(); void onPlusBtnClicked(void); - void onVisibilityChange(const LLSD &in_visible_chain); + void onVisibilityChanged(const LLSD &in_visible_chain); void applyFolderViewFilter(EFolderViewItemType type); void applyListViewFilter(EListViewItemType type); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 4740964dee..123e2891d6 100755 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -38,6 +38,7 @@ class LLFilterEditor; class LLGroupList; class LLMenuButton; class LLTabContainer; +class LLNetMap; class LLPanelPeople : public LLPanel diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 131e8e9359..79bcf15c1d 100755 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -913,7 +913,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/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 5d9971c16c..da201ca36a 100755 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -302,9 +302,9 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data) } // virtual -void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility) +void LLPanelPlaceProfile::onVisibilityChange(BOOL new_visibility) { - LLPanel::handleVisibilityChange(new_visibility); + LLPanel::onVisibilityChange(new_visibility); LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); if (!parcel_mgr) diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index f4c6145881..01adfd4940 100755 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo public: LLPanelPlaceProfile(); /*virtual*/ ~LLPanelPlaceProfile(); - + /*virtual*/ BOOL postBuild(); /*virtual*/ void resetLocation(); @@ -47,7 +47,7 @@ public: /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); - /*virtual*/ void handleVisibilityChange(BOOL new_visibility); + /*virtual*/ void onVisibilityChange(BOOL new_visibility); // Displays information about the currently selected parcel // without sending a request to the server. diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6c2a01fc82..dc18cc6081 100755 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -998,9 +998,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) } // virtual -void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility) +void LLPanelPlaces::onVisibilityChange(BOOL new_visibility) { - LLPanel::handleVisibilityChange(new_visibility); + LLPanel::onVisibilityChange(new_visibility); if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE) { diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 85bdc2c4e1..b6019ca32e 100755 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -102,7 +102,7 @@ private: void togglePickPanel(BOOL visible); void togglePlaceInfoPanel(BOOL visible); - /*virtual*/ void handleVisibilityChange(BOOL new_visibility); + /*virtual*/ void onVisibilityChange(BOOL new_visibility); void updateVerbs(); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index e2e7006773..435797bf80 100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -36,6 +36,7 @@ #include "lltabcontainer.h" #include "llviewercontrol.h" #include "llviewernetwork.h" +#include "llweb.h" static const std::string PANEL_PICKS = "panel_picks"; diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 9dd665198f..3830847d74 100755 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -169,7 +169,7 @@ BOOL LLPanelTopInfoBar::postBuild() mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( boost::bind(&LLPanelTopInfoBar::onAgentParcelChange, this)); - setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChange, this, _2)); + setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChanged, this, _2)); return TRUE; } @@ -186,7 +186,7 @@ void LLPanelTopInfoBar::onNavBarShowParcelPropertiesCtrlChanged() // when panel is shown, all minimized floaters should be shifted downwards to prevent overlapping of // PanelTopInfoBar. See EXT-7951. -void LLPanelTopInfoBar::onVisibilityChange(const LLSD& show) +void LLPanelTopInfoBar::onVisibilityChanged(const LLSD& show) { // this height is used as a vertical offset for ALREADY MINIMIZED floaters // when PanelTopInfoBar visibility changes diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h index d58d95be90..f37bd9c048 100755 --- a/indra/newview/llpaneltopinfobar.h +++ b/indra/newview/llpaneltopinfobar.h @@ -57,7 +57,7 @@ public: /** * Called when the top info bar gets shown or hidden */ - void onVisibilityChange(const LLSD& show); + void onVisibilityChanged(const LLSD& show); boost::signals2::connection setResizeCallback( const resize_signal_t::slot_type& cb ); diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp index 6be2ea6481..1782afddd9 100755 --- a/indra/newview/llpanelvoicedevicesettings.cpp +++ b/indra/newview/llpanelvoicedevicesettings.cpp @@ -85,7 +85,7 @@ BOOL LLPanelVoiceDeviceSettings::postBuild() } // virtual -void LLPanelVoiceDeviceSettings::handleVisibilityChange ( BOOL new_visibility ) +void LLPanelVoiceDeviceSettings::onVisibilityChange ( BOOL new_visibility ) { if (new_visibility) { diff --git a/indra/newview/llpanelvoicedevicesettings.h b/indra/newview/llpanelvoicedevicesettings.h index ba3bcad0dc..83464f476a 100755 --- a/indra/newview/llpanelvoicedevicesettings.h +++ b/indra/newview/llpanelvoicedevicesettings.h @@ -44,7 +44,7 @@ public: void initialize(); void cleanup(); - /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); + /*virtual*/ void onVisibilityChange ( BOOL new_visibility ); void setUseTuningMode(bool use) { mUseTuningMode = use; }; diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 5fec6d967d..59ed53815b 100755 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -35,6 +35,7 @@ #include "lltrans.h" #include "lltransientfloatermgr.h" #include "llvoiceclient.h" +#include "llweb.h" static LLRegisterPanelClassWrapper<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect"); diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp index aea7b33d7f..cb00f742cc 100755 --- a/indra/newview/llpanelvolumepulldown.cpp +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -87,7 +87,7 @@ void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask) } /*virtual*/ -void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility ) +void LLPanelVolumePulldown::onVisibilityChange ( BOOL new_visibility ) { if (new_visibility) { diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h index 0d86e6bd28..b843fab756 100755 --- a/indra/newview/llpanelvolumepulldown.h +++ b/indra/newview/llpanelvolumepulldown.h @@ -42,7 +42,7 @@ class LLPanelVolumePulldown : public LLPanel /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ void onTopLost(); - /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); + /*virtual*/ void onVisibilityChange ( BOOL new_visibility ); /*virtual*/ BOOL postBuild(); private: diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index f47928b131..bda603262d 100755 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -253,7 +253,7 @@ void LLPreviewGesture::onUpdateSucceeded() refresh(); } -void LLPreviewGesture::onVisibilityChange ( const LLSD& new_visibility ) +void LLPreviewGesture::onVisibilityChanged ( const LLSD& new_visibility ) { if (new_visibility.asBoolean()) { @@ -333,7 +333,7 @@ LLPreviewGesture::~LLPreviewGesture() BOOL LLPreviewGesture::postBuild() { - setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChange, this, _2)); + setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChanged, this, _2)); LLLineEditor* edit; LLComboBox* combo; @@ -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/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index fd4fcf9d8f..7ce5706a0d 100755 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -102,7 +102,7 @@ protected: // "Sound", "Chat", or "Wait" LLScrollListItem* addStep(const enum EStepType step_type); - void onVisibilityChange ( const LLSD& new_visibility ); + void onVisibilityChanged ( const LLSD& new_visibility ); static std::string getLabel(std::vector<std::string> labels); static void updateLabel(LLScrollListItem* item); diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 3a9360fd23..97c9de4b72 100755 --- 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 968a912ea2..516ecedbc8 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -946,7 +946,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 ) { @@ -1150,8 +1150,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; @@ -1674,8 +1673,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) { @@ -1906,8 +1903,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..dccf8a2a17 --- /dev/null +++ b/indra/newview/llscenemonitor.cpp @@ -0,0 +1,698 @@ +/** + * @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" +#include "llviewerpartsim.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 "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), + mDiffState(WAITING_FOR_NEXT_DIFF), + mDebugViewerVisible(false), + mQueryObject(0), + mDiffPixelRatio(0.5f) +{ + mFrames[0] = NULL; + mFrames[1] = NULL; +} + +LLSceneMonitor::~LLSceneMonitor() +{ + mDiffState = VIEWER_QUITTING; + reset(); + + mDitheringTexture = NULL; +} + +void LLSceneMonitor::reset() +{ + delete mFrames[0]; + delete mFrames[1]; + delete mDiff; + + mFrames[0] = NULL; + mFrames[1] = NULL; + mDiff = NULL; + + mMonitorRecording.reset(); + mSceneLoadRecording.reset(); + + unfreezeScene(); + + if(mQueryObject > 0) + { + LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(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; +} + +LLRenderTarget& LLSceneMonitor::getCaptureTarget() +{ + LLRenderTarget* cur_target = NULL; + + 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); + + cur_target = 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); + + cur_target = mFrames[1]; + } + else //swap + { + cur_target = mFrames[0]; + mFrames[0] = mFrames[1]; + mFrames[1] = cur_target; + } + + if(cur_target->getWidth() != width || cur_target->getHeight() != height) //size changed + { + cur_target->resize(width, height, GL_RGB); + } + + // we're promising the target exists + return *cur_target; +} + +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); + + //disable sky, water and clouds + gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); + + //disable particle system + LLViewerPartSim::getInstance()->enable(false); +} + +void LLSceneMonitor::unfreezeScene() +{ + //thaw all avatars + mAvatarPauseHandles.clear(); + + if(mDiffState == VIEWER_QUITTING) + { + return; + } + + // thaw everything else + gSavedSettings.setBOOL("FreezeTime", FALSE); + + //enable sky, water and clouds + gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); + + //enable particle system + LLViewerPartSim::getInstance()->enable(true); +} + +void LLSceneMonitor::capture() +{ + static U32 last_capture_time = 0; + static LLCachedControl<bool> monitor_enabled(gSavedSettings, "SceneLoadingMonitorEnabled"); + static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime"); + static LLFrameTimer timer; + + if (mEnabled + && (mMonitorRecording.getSum(*LLViewerCamera::getVelocityStat()) > 0.1f + || mMonitorRecording.getSum(*LLViewerCamera::getAngularVelocityStat()) > 0.05f)) + { + reset(); + freezeScene(); + } + + bool enabled = monitor_enabled || mDebugViewerVisible; + if(mEnabled != enabled) + { + if(mEnabled) + { + unfreezeScene(); + } + else + { + reset(); + freezeScene(); + } + + mEnabled = enabled; + } + + if(timer.getElapsedTimeF32() > scene_load_sample_time() + && mEnabled + && LLGLSLShader::sNoFixedFunction + && last_capture_time != gFrameCount) + { + mSceneLoadRecording.resume(); + mMonitorRecording.resume(); + + timer.reset(); + + last_capture_time = gFrameCount; + + LLRenderTarget& cur_target = getCaptureTarget(); + + U32 old_FBO = LLRenderTarget::sCurFBO; + + gGL.getTexUnit(0)->bind(&cur_target); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer. + + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, cur_target.getWidth(), cur_target.getHeight()); //copy the content + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, old_FBO); + + mDiffState = NEED_DIFF; + } +} + +bool LLSceneMonitor::needsUpdate() const +{ + return mDiffState == NEED_DIFF; +} + +static LLFastTimer::DeclareTimer FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE("Generate Scene Load Dither Texture"); +static LLFastTimer::DeclareTimer FTM_SCENE_LOAD_IMAGE_DIFF("Scene Load Image Diff"); + +void LLSceneMonitor::compare() +{ + if(mDiffState != NEED_DIFF) + { + return; + } + + if(!mFrames[0] || !mFrames[1]) + { + return; + } + if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight()) + { //size does not match + return; + } + + LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); + mDiffState = EXECUTE_DIFF; + + S32 width = gViewerWindow->getWindowWidthRaw(); + S32 height = gViewerWindow->getWindowHeightRaw(); + if(!mDiff) + { + LLFastTimer _(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE); + 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) + { + LLFastTimer _(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE); + 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); + + if (!mDebugViewerVisible) + { + calcDiffAggregate(); + } +} + +//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it. +void LLSceneMonitor::calcDiffAggregate() +{ + LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); + + if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible) + { + return; + } + + if(!mQueryObject) + { + mQueryObject = LLOcclusionCullingGroup::getNewOcclusionQueryObjectName(); + } + + 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(mDiffState == EXECUTE_DIFF) + { + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject); + } + + gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); + + if(mDiffState == EXECUTE_DIFF) + { + glEndQueryARB(GL_SAMPLES_PASSED_ARB); + mDiffState = WAIT_ON_RESULT; + } + + gOneTextureFilterProgram.unbind(); + + if(cur_shader != NULL) + { + cur_shader->bind(); + } + + if(!mDebugViewerVisible) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } +} + +static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference"); +void LLSceneMonitor::fetchQueryResult() +{ + LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); + + if(mDiffState == WAIT_ON_RESULT) + { + mDiffState = WAITING_FOR_NEXT_DIFF; + + GLuint available = 0; + glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + if(available) + { + 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) + + LL_DEBUGS("SceneMonitor") << "Frame difference: " << std::setprecision(4) << mDiffResult << LL_ENDL; + record(sFramePixelDiff, mDiffResult); + + static LLCachedControl<F32> diff_threshold(gSavedSettings,"SceneLoadingPixelDiffThreshold"); + if(mDiffResult > diff_threshold()) + { + mSceneLoadRecording.extend(); + llassert(mSceneLoadRecording.getAcceptedRecording().getLastRecording().getSum(LLStatViewer::FPS)); + } + else + { + mSceneLoadRecording.getPotentialRecording().nextPeriod(); + llassert(mSceneLoadRecording.getPotentialRecording().getLastRecording().getSum(LLStatViewer::FPS)); + } + } + } +} + +//dump results to a file _scene_xmonitor_results.csv +void LLSceneMonitor::dumpToFile(std::string file_name) +{ using namespace LLTrace; + + if (!hasResults()) return; + + LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL; + + std::ofstream os(file_name.c_str()); + + os << std::setprecision(3); + + PeriodicRecording& scene_load_recording = mSceneLoadRecording.getAcceptedRecording(); + const U32 frame_count = scene_load_recording.getNumPeriods(); + + LLUnit<LLUnits::Seconds, F64> frame_time; + + os << "Stat"; + for (S32 frame = 0; frame < frame_count; frame++) + { + frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); + } + os << std::endl; + + typedef TraceType<CountAccumulator> trace_count; + for (trace_count::instance_iter it = trace_count::beginInstances(), end_it = trace_count::endInstances(); + it != end_it; + ++it) + { + std::ostringstream row; + row << it->getName(); + + const char* unit_label = it->getUnitLabel(); + if(unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 0; frame < frame_count; frame++) + { + samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it); + row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getSum(*it); + } + + row << std::endl; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef TraceType<EventAccumulator> trace_event; + + for (trace_event::instance_iter it = trace_event::beginInstances(), end_it = trace_event::endInstances(); + it != end_it; + ++it) + { + std::ostringstream row; + row << it->getName(); + + const char* unit_label = it->getUnitLabel(); + if(unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 0; frame < frame_count; frame++) + { + samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it); + row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it); + } + + row << std::endl; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef TraceType<SampleAccumulator> trace_sample; + + for (trace_sample::instance_iter it = trace_sample::beginInstances(), end_it = trace_sample::endInstances(); + it != end_it; + ++it) + { + std::ostringstream row; + row << it->getName(); + + const char* unit_label = it->getUnitLabel(); + if(unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 0; frame < frame_count; frame++) + { + samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it); + row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it); + } + + row << std::endl; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef TraceType<MemStatAccumulator> trace_mem; + for (trace_mem::instance_iter it = trace_mem::beginInstances(), end_it = trace_mem::endInstances(); + it != end_it; + ++it) + { + os << it->getName() << "(KiB)"; + + for (S32 frame = 0; frame < frame_count; frame++) + { + os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).as<LLUnits::Kibibytes>().value(); + } + + os << std::endl; + } + + os.flush(); + os.close(); +} + +//------------------------------------------------------------------------------------------------------------- +//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::onVisibilityChange(BOOL visible) +{ + visible = visible && LLGLSLShader::sNoFixedFunction; + LLSceneMonitor::getInstance()->setDebugViewerVisible(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); + + 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", gSavedSettings.getF32("SceneLoadingMonitorSampleTime")); + 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..6af58b707a --- /dev/null +++ b/indra/newview/llscenemonitor.h @@ -0,0 +1,124 @@ +/** + * @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> +{ + LOG_CLASS(LLSceneMonitor); +public: + LLSceneMonitor(); + ~LLSceneMonitor(); + + void freezeAvatar(LLCharacter* avatarp); + void setDebugViewerVisible(bool visible); + + void capture(); //capture the main frame buffer + void compare(); //compare the stored two buffers. + 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 getDiffPixelRatio() const { return mDiffPixelRatio;} + bool isEnabled()const {return mEnabled;} + bool needsUpdate() const; + + const LLTrace::ExtendablePeriodicRecording* getRecording() const {return &mSceneLoadRecording;} + void dumpToFile(std::string file_name); + bool hasResults() const { return mSceneLoadRecording.getAcceptedRecording().getDuration() != 0;} + +private: + void freezeScene(); + void unfreezeScene(); + void reset(); + LLRenderTarget& getCaptureTarget(); + void generateDitheringTexture(S32 width, S32 height); + +private: + bool mEnabled; + bool mDebugViewerVisible; + + enum EDiffState + { + WAITING_FOR_NEXT_DIFF, + NEED_DIFF, + EXECUTE_DIFF, + WAIT_ON_RESULT, + VIEWER_QUITTING + } mDiffState; + + LLRenderTarget* mFrames[2]; + LLRenderTarget* mDiff; + + GLuint mQueryObject; //used for glQuery + F32 mDiffResult; //aggregate results of mDiff. + F32 mDiffTolerance; //pixels are filtered out when R+G+B < mDiffTolerance + + 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::ExtendablePeriodicRecording mSceneLoadRecording; + LLTrace::Recording mMonitorRecording; +}; + +class LLSceneMonitorView : public LLFloater +{ +public: + LLSceneMonitorView(const LLRect& rect); + + virtual void draw(); + + virtual void onVisibilityChange(BOOL visible); + +protected: + virtual void onClickCloseBtn(); +}; + +extern LLSceneMonitorView* gSceneMonitorView; + +#endif + diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index db57848320..28765fbfb1 100755 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -30,6 +30,7 @@ #include <vector> #include <openssl/x509.h> #include <ostream> +#include "llthread.h" #ifdef LL_WINDOWS #pragma warning(disable:4250) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4681efd3e5..da6ca8964a 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1545,7 +1545,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(); @@ -2980,18 +2980,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 ) { @@ -3001,31 +3001,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; @@ -3046,18 +3046,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); @@ -3096,34 +3096,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() @@ -3153,10 +3153,10 @@ 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(); @@ -3412,9 +3412,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/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 74fa5a87bb..efef422bfb 100755 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -142,7 +142,7 @@ BOOL LLSidepanelAppearance::postBuild() mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook"); - setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChange,this,_2)); + setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChanged,this,_2)); return TRUE; } @@ -181,7 +181,7 @@ void LLSidepanelAppearance::onOpen(const LLSD& key) mOpened = true; } -void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility) +void LLSidepanelAppearance::onVisibilityChanged(const LLSD &new_visibility) { LLSD visibility; visibility["visible"] = new_visibility.asBoolean(); @@ -231,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility) { gAgentCamera.changeCameraToDefault(); gAgentCamera.resetView(); - } + } } } diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 762f557a80..6359d6e86e 100755 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -47,7 +47,7 @@ public: virtual ~LLSidepanelAppearance(); /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onOpen(const LLSD& key); void refreshCurrentOutfitName(const std::string& name = ""); @@ -68,7 +68,7 @@ public: private: void onFilterEdit(const std::string& search_string); - void onVisibilityChange ( const LLSD& new_visibility ); + void onVisibilityChanged ( const LLSD& new_visibility ); void onOpenOutfitButtonClicked(); void onEditAppearanceButtonClicked(); diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index ad7c939728..090ee64801 100755 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -162,7 +162,7 @@ BOOL LLSidepanelTaskInfo::postBuild() return TRUE; } -/*virtual*/ void LLSidepanelTaskInfo::handleVisibilityChange ( BOOL visible ) +/*virtual*/ void LLSidepanelTaskInfo::onVisibilityChange ( BOOL visible ) { if (visible) { @@ -945,7 +945,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/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index 05edcda5ed..a1479ef0e7 100755 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -50,7 +50,7 @@ public: virtual ~LLSidepanelTaskInfo(); /*virtual*/ BOOL postBuild(); - /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); + /*virtual*/ void onVisibilityChange ( BOOL new_visibility ); void setObjectSelection(LLObjectSelectionHandle selection); diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h index 9d7780c4f9..80ce99b774 100755 --- 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 f85e855fd3..45130efeb9 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,32 +51,16 @@ #include "llvoavatar.h" #include "llvolumemgr.h" #include "lltextureatlas.h" -#include "llglslshader.h" #include "llviewershadermgr.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); -const F32 SG_OCCLUSION_FUDGE = 0.25f; -#define SG_DISCARD_TOLERANCE 0.01f - -#if LL_OCTREE_PARANOIA_CHECK -#define assert_octree_valid(x) x->validate() -#define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() -#else -#define assert_octree_valid(x) -#define assert_states_valid(x) -#endif - extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; -#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 - -std::set<GLuint> LLSpatialGroup::sPendingQueries; - U32 gOctreeMaxCapacity; BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -84,47 +68,6 @@ BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; static F32 sCurMaxTexPriority = 1.f; -class LLOcclusionQueryPool : public LLGLNamePool -{ -public: - LLOcclusionQueryPool() - { - mCurQuery = 1; - } - -protected: - - std::list<GLuint> mAvailableName; - GLuint mCurQuery; - - virtual GLuint allocateName() - { - GLuint ret = 0; - - if (!mAvailableName.empty()) - { - ret = mAvailableName.front(); - mAvailableName.pop_front(); - } - else - { - ret = mCurQuery++; - } - - return ret; - } - - virtual void releaseName(GLuint name) - { -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - LLSpatialGroup::sPendingQueries.erase(name); -#endif - llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); - mAvailableName.push_back(name); - } -}; - -static LLOcclusionQueryPool sQueryPool; //static counter for frame to switch LOD on @@ -138,185 +81,6 @@ void sg_assert(BOOL expr) #endif } -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; -} - - -typedef enum -{ - b000 = 0x00, - b001 = 0x01, - b010 = 0x02, - b011 = 0x03, - b100 = 0x04, - b101 = 0x05, - b110 = 0x06, - b111 = 0x07, -} eLoveTheBits; - -//contact Runitai Linden for a copy of the SL object used to write this table -//basically, you give the table a bitmask of the look-at vector to a node and it -//gives you a triangle fan index array -static U16 sOcclusionIndices[] = -{ - //000 - b111, b110, b010, b011, b001, b101, b100, b110, - //001 - b011, b010, b000, b001, b101, b111, b110, b010, - //010 - b101, b100, b110, b111, b011, b001, b000, b100, - //011 - b001, b000, b100, b101, b111, b011, b010, b000, - //100 - b110, b000, b010, b011, b111, b101, b100, b000, - //101 - b010, b100, b000, b001, b011, b111, b110, b100, - //110 - b100, b010, b110, b111, b101, b001, b000, b010, - //111 - b000, b110, b100, b101, b001, b011, b010, b110, -}; - -U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) -{ - LLVector4a origin; - origin.load3(camera->getOrigin().mV); - - S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; - - return cypher*8; -} - -U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) -{ - LLVector4a origin; - origin.load3(camera->getOrigin().mV); - - S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; - - return (U8*) (sOcclusionIndices+cypher*8); -} - -//create a vertex buffer for efficiently rendering cubes -LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) -{ - LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); - - ret->allocateBuffer(8, 64, true); - - LLStrider<LLVector3> pos; - LLStrider<U16> idx; - - ret->getVertexStrider(pos); - ret->getIndexStrider(idx); - - pos[0] = LLVector3(-1,-1,-1); - pos[1] = LLVector3(-1,-1, 1); - pos[2] = LLVector3(-1, 1,-1); - pos[3] = LLVector3(-1, 1, 1); - pos[4] = LLVector3( 1,-1,-1); - pos[5] = LLVector3( 1,-1, 1); - pos[6] = LLVector3( 1, 1,-1); - pos[7] = LLVector3( 1, 1, 1); - - for (U32 i = 0; i < 64; i++) - { - idx[i] = sOcclusionIndices[i]; - } - - ret->flush(); - - return ret; -} - -static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); - -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); - //returns: // 0 if sphere and AABB are not intersecting // 1 if they are @@ -358,24 +122,13 @@ LLSpatialGroup::~LLSpatialGroup() gPipeline.checkReferences(this); } - if (isState(DEAD)) + if (hasState(DEAD)) { sZombieGroups--; } sNodeCount--; - if (gGLManager.mHasOcclusionQuery) - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) - { - if (mOcclusionQuery[i]) - { - sQueryPool.release(mOcclusionQuery[i]); - } - } - } - clearDrawMap(); clearAtlasList() ; } @@ -509,22 +262,13 @@ void LLSpatialGroup::clearDrawMap() BOOL LLSpatialGroup::isHUDGroup() { - return mSpatialPartition && mSpatialPartition->isHUDPartition() ; + return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ; } 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() @@ -548,7 +292,7 @@ void LLSpatialGroup::validate() sg_assert(drawable->getSpatialGroup() == this); if (drawable->getSpatialBridge()) { - sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); + sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge()); } /*if (drawable->isSpatialBridge()) @@ -588,14 +332,6 @@ void LLSpatialGroup::validate() #endif } -void LLSpatialGroup::checkStates() -{ -#if LL_OCTREE_PARANOIA_CHECK - //LLOctreeStateCheck checker; - //checker.traverse(mOctreeNode); -#endif -} - void LLSpatialGroup::validateDrawMap() { #if LL_OCTREE_PARANOIA_CHECK @@ -619,7 +355,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 +369,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); @@ -662,9 +397,9 @@ void LLSpatialGroup::rebuildGeom() { if (!isDead()) { - mSpatialPartition->rebuildGeom(this); + getSpatialPartition()->rebuildGeom(this); - if (isState(LLSpatialGroup::MESH_DIRTY)) + if (hasState(LLSpatialGroup::MESH_DIRTY)) { gPipeline.markMeshDirty(this); } @@ -675,7 +410,7 @@ void LLSpatialGroup::rebuildMesh() { if (!isDead()) { - mSpatialPartition->rebuildMesh(this); + getSpatialPartition()->rebuildMesh(this); } } @@ -686,7 +421,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,137 +486,26 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) +LLSpatialGroup* LLSpatialGroup::getParent() { - 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; + return (LLSpatialGroup*)LLviewerOctreeGroup::getParent(); } -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() +BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { - if (isDead()) + if(!drawablep) { - return NULL; - } - - if(!mOctreeNode) - { - return NULL; - } - OctreeNode* parent = mOctreeNode->getOctParent(); - - if (parent) - { - return (LLSpatialGroup*) parent->getListener(0); + return FALSE; } - return NULL; -} - -BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) -{ 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); @@ -918,22 +542,22 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - if (!mSpatialPartition->mRenderByGroup && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) + if (!getSpatialPartition()->mRenderByGroup && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); } } -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 +565,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 +599,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 +612,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,144 +646,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 -{ -public: - U32 mState; - LLSpatialSetOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } -}; - -class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState -{ -public: - LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - - virtual void traverse(const LLSpatialGroup::OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (!group->isOcclusionState(mState)) - { - LLSpatialGroup::OctreeTraveler::traverse(n); - } - } -}; - - -void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialSetOcclusionStateDiff setter(state); - setter.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialSetOcclusionState setter(state); - setter.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] |= state; - - if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) - { - sQueryPool.release(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } - } - } - else - { - mOcclusionState[LLViewerCamera::sCurCameraID] |= state; - if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - } -} - -class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler -{ -public: - U32 mState; - - LLSpatialClearOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } -}; - -class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState -{ -public: - LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - - virtual void traverse(const LLSpatialGroup::OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (group->isOcclusionState(mState)) - { - LLSpatialGroup::OctreeTraveler::traverse(n); - } - } -}; - -void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialClearOcclusionStateDiff clearer(state); - clearer.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialClearOcclusionState clearer(state); - clearer.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] &= ~state; - } - } - } - else - { - mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; - } -} //====================================== // Octree Listener Implementation //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part), mObjectBoxSize(1.f), - mState(0), mGeometryBytes(0), mSurfaceArea(0.f), mBuilt(0.f), - mOctreeNode(node), - mSpatialPartition(part), mVertexBuffer(NULL), mBufferUsage(part->mBufferUsage), mDistance(0.f), @@ -1191,32 +672,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; - - OctreeNode* oct_parent = node->getOctParent(); - - LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL; - - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionQuery[i] = 0; - mOcclusionIssued[i] = 0; - mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; - mVisible[i] = 0; - } - mRadius = 1; mPixelArea = 1024.f; } @@ -1235,17 +695,17 @@ 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; } #endif if (!isEmpty()) { - mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : + mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : (F32) mOctreeNode->getSize().getLength3().getF32(); - mDistance = mSpatialPartition->calcDistance(this, camera); - mPixelArea = mSpatialPartition->calcPixelArea(this, camera); + mDistance = getSpatialPartition()->calcDistance(this, camera); + mPixelArea = getSpatialPartition()->calcPixelArea(this, camera); } } @@ -1266,9 +726,9 @@ 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()) + if (!group->getSpatialPartition()->isBridge()) { LLVector4a view_angle = eye; @@ -1336,23 +796,18 @@ F32 LLSpatialGroup::getUpdateUrgency() const } } -BOOL LLSpatialGroup::needsUpdate() -{ - return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; -} - 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; } - if (mSpatialPartition->mSlopRatio > 0.f) + if (getSpatialPartition()->mSlopRatio > 0.f) { F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); - if (fabsf(ratio) >= mSpatialPartition->mSlopRatio) + if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio) { return TRUE; } @@ -1371,17 +826,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,15 +845,22 @@ 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; + } } } //clean up avatar attachment stats - LLSpatialBridge* bridge = mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = getSpatialPartition()->asBridge(); if (bridge) { if (bridge->mAvatar.notNull()) @@ -1415,21 +877,11 @@ 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) { - new LLSpatialGroup(child, mSpatialPartition); + new LLSpatialGroup(child, getSpatialPartition()); } else { @@ -1441,11 +893,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); @@ -1463,20 +910,17 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) if (!keep_occlusion) { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - if (mOcclusionQuery[i]) - { - sQueryPool.release(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } + releaseOcclusionQueryObjectNames(); } 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,318 +932,27 @@ 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"); - -void LLSpatialGroup::checkOcclusion() -{ - if (LLPipeline::sUseOcclusion > 1) - { - LLFastTimer t(FTM_OCCLUSION_READBACK); - LLSpatialGroup* parent = getParent(); - if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //if the parent has been marked as occluded, the child is implicitly occluded - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - else if (isOcclusionState(QUERY_PENDING)) - { //otherwise, if a query is pending, read it back - - GLuint available = 0; - if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - - static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); - - if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) - { //query was issued last frame, wait until it's available - S32 max_loop = 1024; - LLFastTimer t(FTM_OCCLUSION_WAIT); - while (!available && max_loop-- > 0) - { - F32 max_time = llmin(gFrameIntervalSeconds*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 - LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - } - } - } - else - { - available = 1; - } - - if (available) - { //result is available, read it back, otherwise wait until next frame - GLuint res = 1; - if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - } - else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { //delete the query to avoid holding onto hundreds of pending queries - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - - if (isOcclusionState(DISCARD_QUERY)) - { - res = 2; - } - - if (res > 0) - { - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - assert_states_valid(this); - - setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - - assert_states_valid(this); - } - - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - } - else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //check occlusion has been issued for occluded node that has not had a query issued - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - } -} - -static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); -static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); - - - -void LLSpatialGroup::doOcclusion(LLCamera* camera) -{ - if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) - { - // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension - if (earlyFail(camera, this)) - { - LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); - setOcclusionState(LLSpatialGroup::DISCARD_QUERY); - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) - { - { //no query pending, or previous query to be discarded - LLFastTimer t(FTM_RENDER_OCCLUSION); - - if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - LLFastTimer t(FTM_OCCLUSION_ALLOCATE); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); - } - - // Depth clamp all water to avoid it being culled as a result of being - // behind the far clip plane, and in the case of edge water to avoid - // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - - LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); - -#if !LL_DARWIN - U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else - U32 mode = GL_SAMPLES_PASSED_ARB; -#endif - -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - - { - LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); - - //store which frame this query was issued on - mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; - - { - LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); - glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - } - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader); - - shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); - shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, - mBounds[1][1]+SG_OCCLUSION_FUDGE, - mBounds[1][2]+SG_OCCLUSION_FUDGE); - - if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) - { - LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); - - LLGLSquashToFarClip squash(glh_get_current_projection(), 1); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); - } - else - { - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); - } - } - else - { - LLFastTimer t(FTM_OCCLUSION_DRAW); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); - } - else - { - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); - } - } - - - { - LLFastTimer t(FTM_OCCLUSION_END_QUERY); - glEndQueryARB(mode); - } - } - } - - { - LLFastTimer t(FTM_SET_OCCLUSION_STATE); - setOcclusionState(LLSpatialGroup::QUERY_PENDING); - clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); - } - } - } - } -} - //============================================== -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) { - mOcclusionEnabled = TRUE; - mDrawableType = 0; + mRegionp = regionp; mPartitionType = LLViewerRegion::PARTITION_NONE; - mLODSeed = 0; - mLODPeriod = 1; mVertexDataMask = data_mask; mBufferUsage = buffer_usage; mDepthMask = FALSE; 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 +960,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 +986,9 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); } - drawablep->setSpatialGroup(NULL); - assert_octree_valid(mOctree); return TRUE; @@ -1851,11 +1006,11 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL BOOL was_visible = curp ? curp->isVisible() : FALSE; - if (curp && curp->mSpatialPartition != this) + if (curp && curp->getSpatialPartition() != this) { //keep drawable from being garbage collected LLPointer<LLDrawable> ptr = drawablep; - if (curp->mSpatialPartition->remove(drawablep, curp)) + if (curp->getSpatialPartition()->remove(drawablep, curp)) { put(drawablep, was_visible); return; @@ -1883,13 +1038,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 +1056,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 +1077,29 @@ public: return false; } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - 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) - { - 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 +1107,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 +1115,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 +1133,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 +1150,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 +1164,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 +1173,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 +1184,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 +1227,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 +1242,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 +1259,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,18 +1386,22 @@ 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; - if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); } @@ -2318,11 +1425,6 @@ void LLSpatialPartition::resetVertexBuffers() dirty.traverse(mOctree); } -BOOL LLSpatialPartition::isOcclusionEnabled() -{ - return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; -} - BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { LLVector4a visMina, visMaxa; @@ -2365,13 +1467,28 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif + LLOctreeSelect selecter(&camera, results); + selecter.traverse(mOctree); + + return 0; +} - if (for_select) +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); @@ -2393,50 +1510,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result return 0; } -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) -{ - if (camera->getOrigin().isExactlyZero()) - { - return FALSE; - } - - const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector4a fudge; - fudge.splat(vel); - - const LLVector4a& c = group->mBounds[0]; - LLVector4a r; - r.setAdd(group->mBounds[1], fudge); - - /*if (r.magVecSquared() > 1024.0*1024.0) - { - return TRUE; - }*/ - - LLVector4a e; - e.load3(camera->getOrigin().mV); - - LLVector4a min; - min.setSub(c,r); - LLVector4a max; - max.setAdd(c,r); - - S32 lt = e.lessThan(min).getGatheredBits() & 0x7; - if (lt) - { - return FALSE; - } - - S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; - if (gt) - { - return FALSE; - } - - return TRUE; -} - - void pushVerts(LLDrawInfo* params, U32 mask) { LLRenderPass::applyModelMatrix(*params); @@ -2508,7 +1581,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) void pushBufferVerts(LLSpatialGroup* group, U32 mask) { - if (group->mSpatialPartition->mRenderByGroup) + if (group->getSpatialPartition()->mRenderByGroup) { if (!group->mDrawMap.empty()) { @@ -2531,7 +1604,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 +1650,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,14 +1669,20 @@ 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; - if (!group->mSpatialPartition->isBridge()) + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -2634,7 +1714,7 @@ void renderOctree(LLSpatialGroup* group) } } - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.popMatrix(); } @@ -2646,7 +1726,7 @@ void renderOctree(LLSpatialGroup* group) else { if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty() - && group->mSpatialPartition->mRenderByGroup) + && group->getSpatialPartition()->mRenderByGroup) { col.setVec(0.8f, 0.4f, 0.1f, 0.1f); } @@ -2659,9 +1739,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,10 +1758,12 @@ 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) + /*if (group->getSpatialPartition()->mRenderByGroup) { gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f); for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3444,13 +2527,17 @@ 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 ) { - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -4003,17 +3090,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,11 +3141,11 @@ 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; } @@ -4070,14 +3158,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)) { @@ -4200,17 +3293,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(); @@ -4228,23 +3322,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); @@ -4255,19 +3350,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 = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) { - LLDrawable* drawable = *i; - + continue; + } renderBoundingBox(drawable, FALSE); } } @@ -4279,7 +3378,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> +class LLOctreeStateCheck : public OctreeTraveler { public: U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; @@ -4292,7 +3391,7 @@ public: } } - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); @@ -4319,7 +3418,7 @@ public: } - virtual void visit(const LLOctreeNode<LLDrawable>* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); @@ -4331,7 +3430,7 @@ public: } } - if (group->isState(LLSpatialGroup::DIRTY)) + if (group->hasState(LLSpatialGroup::DIRTY)) { assert_parent_state(group, LLSpatialGroup::DIRTY); } @@ -4342,7 +3441,7 @@ public: LLSpatialGroup* parent = group->getParent(); while (parent) { - if (!parent->isState(state)) + if (!parent->hasState(state)) { llerrs << "Spatial group failed parent state check." << llendl; } @@ -4457,7 +3556,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) return TRUE; } -class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler +class LLOctreeIntersect : public OctreeTraveler { public: LLVector3 mStart; @@ -4484,21 +3583,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); @@ -4506,15 +3605,16 @@ 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; - if (group->mSpatialPartition->isBridge()) + if (group->getSpatialPartition()->isBridge()) { - LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); + LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix(); local_matrix.invert(); local_start = mStart * local_matrix; @@ -4534,8 +3634,10 @@ public: return mHit; } - virtual bool check(LLDrawable* drawable) - { + virtual bool check(LLViewerOctreeEntry* entry) + { + LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); + if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible()) { return false; @@ -4926,5 +4028,3 @@ void LLCullResult::assertDrawMapsEmpty() } } - - diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b1706d9d35..406e796d4d 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -45,23 +45,16 @@ #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); - class LLDrawInfo : public LLRefCount { protected: @@ -192,13 +185,13 @@ public: }; LL_ALIGN_PREFIX(16) -class LLSpatialGroup : public LLOctreeListener<LLDrawable> +class LLSpatialGroup : public LLOcclusionCullingGroup { friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: - LLSpatialGroup(const LLSpatialGroup& rhs) + LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs) { *this = rhs; } @@ -219,7 +212,6 @@ public: return *this; } - static std::set<GLuint> sPendingQueries; //pending occlusion queries static U32 sNodeCount; static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE @@ -231,15 +223,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) @@ -266,104 +249,57 @@ public: typedef enum { - OCCLUDED = 0x00010000, - QUERY_PENDING = 0x00020000, - ACTIVE_OCCLUSION = 0x00040000, - DISCARD_QUERY = 0x00080000, - EARLY_FAIL = 0x00100000, - } eOcclusionState; - - 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, + GEOM_DIRTY = LLviewerOctreeGroup::INVALID_STATE, + 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; - - typedef enum - { - STATE_MODE_SINGLE = 0, //set one node - STATE_MODE_BRANCH, //set entire branch - STATE_MODE_DIFF, //set entire branch as long as current state is different - STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras - } eSetStateMode; + } eSpatialState; LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); - BOOL isHUDGroup() ; - BOOL isDead() { return isState(DEAD); } - BOOL isState(U32 state) const; - BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } - U32 getState() { return mState; } - void setState(U32 state); - void clearState(U32 state); + BOOL isHUDGroup() ; void clearDrawMap(); void validate(); - void checkStates(); void validateDrawMap(); void setState(U32 state, S32 mode); void clearState(U32 state, S32 mode); - - void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); - void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); + void clearState(U32 state) {mState &= ~state;} 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 shift(const LLVector4a &offset); void destroyGL(bool keep_occlusion = false); void updateDistance(LLCamera& camera); - BOOL needsUpdate(); F32 getUpdateUrgency() const; BOOL changeLOD(); 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); + LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;} + //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 +322,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); @@ -419,13 +340,8 @@ private: //------------------- protected: - virtual ~LLSpatialGroup(); - - U32 mState; - U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; - U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; - - S32 mLODHash; + virtual ~LLSpatialGroup(); + static S32 sLODSeed; public: @@ -435,17 +351,13 @@ public: U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node - F32 mBuilt; - OctreeNode* mOctreeNode; - LLSpatialPartition* mSpatialPartition; + F32 mBuilt; - LLPointer<LLVertexBuffer> mVertexBuffer; - GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; + LLPointer<LLVertexBuffer> mVertexBuffer; U32 mBufferUsage; draw_map_t mDrawMap; - S32 mVisible[LLViewerCamera::NUM_CAMERAS]; F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; @@ -468,10 +380,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 +410,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() ; @@ -510,26 +423,21 @@ public: void renderDebug(); void renderIntersectingBBoxes(LLCamera* camera); void restoreGL(); - void resetVertexBuffers(); - BOOL isOcclusionEnabled(); + void resetVertexBuffers(); + 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 + // to call asBridge() from the destructor + BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane - U32 mBufferUsage; - const BOOL mRenderByGroup; - U32 mLODSeed; - U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) + U32 mBufferUsage; + const BOOL mRenderByGroup; 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 +449,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 +571,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 +580,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 +596,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 +606,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 +618,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 +655,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 +666,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 +676,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 +685,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 +693,7 @@ public: class LLHUDPartition : public LLBridgePartition { public: - LLHUDPartition(); + LLHUDPartition(LLViewerRegion* regionp); virtual void shift(const LLVector4a &offset); }; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index a4582071e8..8177a50cc2 100755 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -34,7 +34,9 @@ #include "llgroupmgr.h" #include "llsdutil.h" #include "lluicolortable.h" +#include "llhttpclient.h" #include "llviewerobjectlist.h" +#include "llviewerregion.h" #include "llvoavatar.h" #include "llworld.h" @@ -416,7 +418,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) { LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; - + if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id)) { speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 82596a86b9..3c67216688 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -645,7 +645,7 @@ bool idle_startup() gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL(); } #endif - + if (gAudiop) { #if LL_WINDOWS @@ -2052,7 +2052,7 @@ bool idle_startup() static LLFrameTimer wearables_timer; const F32 wearables_time = wearables_timer.getElapsedTimeF32(); - const F32 MAX_WEARABLES_TIME = 10.f; + static LLCachedControl<F32> max_wearables_time(gSavedSettings, "ClothingLoadingDelay"); if (!gAgent.isGenderChosen() && isAgentAvatarValid()) { @@ -2072,10 +2072,10 @@ bool idle_startup() display_startup(); - if (wearables_time > MAX_WEARABLES_TIME) + if (wearables_time > max_wearables_time()) { LLNotificationsUtil::add("ClothingLoading"); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG); + record(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, wearables_time); LLStartUp::setStartupState( STATE_CLEANUP ); return TRUE; } @@ -2106,7 +2106,7 @@ bool idle_startup() display_startup(); update_texture_fetch(); display_startup(); - set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME, + set_startup_status(0.9f + 0.1f * wearables_time / max_wearables_time(), LLTrans::getString("LoginDownloadingClothing").c_str(), gAgent.mMOTD.c_str()); display_startup(); @@ -2186,9 +2186,6 @@ bool idle_startup() LLAppViewer::instance()->handleLoginComplete(); - // reset timers now that we are running "logged in" logic - LLFastTimer::reset(); - LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); display_startup(); @@ -2296,7 +2293,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..f3406d9f8d 100755 --- 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.sample_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 100755 --- 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/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 305f6fca0f..f03cc22949 100755 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -919,7 +919,7 @@ void LLTextureCache::setDirNames(ELLPath location) mFastCacheFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename); } -void LLTextureCache::purgeCache(ELLPath location) +void LLTextureCache::purgeCache(ELLPath location, bool remove_dir) { LLMutexLock lock(&mHeaderMutex); @@ -945,7 +945,7 @@ void LLTextureCache::purgeCache(ELLPath location) } //remove the current texture cache. - purgeAllTextures(true); + purgeAllTextures(remove_dir); } //is called in the main thread before initCache(...) is called. diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e3fc957fd2..5a68c31a6d 100755 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -104,7 +104,7 @@ public: /*virtual*/ S32 update(F32 max_time_ms); - void purgeCache(ELLPath location); + void purgeCache(ELLPath location, bool remove_dir = true); void setReadOnly(BOOL read_only) ; S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index e2d0fdf357..a8038b7cf2 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -187,7 +187,7 @@ protected: F32 mContextConeOpacity; LLSaveFolderState mSavedFolderState; BOOL mSelectedItemPinned; - + LLRadioGroup* mModeSelector; LLScrollListCtrl* mLocalScrollCtrl; @@ -550,11 +550,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(); @@ -1311,7 +1311,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. else if (mCommitOnSelection || op == TEXTURE_SELECT) mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - + if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work. { setTentative( FALSE ); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index be5fde9e2b..4b9a950b98 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::SampleStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); +LLTrace::SampleStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); ////////////////////////////////////////////////////////////////////////////// @@ -1246,7 +1247,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 { @@ -1264,7 +1265,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } // fall through - LLTextureFetch::sCacheHitRate.addValue(0.f); + sample(LLTextureFetch::sCacheHitRate, 0.f); } } @@ -1884,7 +1885,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe if (log_to_viewer_log || log_to_sim) { U64 timeNow = LLTimer::getTotalTime(); - mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime); + mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime.value()); mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP); mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize); mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset); @@ -2329,11 +2330,11 @@ bool LLTextureFetchWorker::writeToCacheComplete() // Threads: Ttf void LLTextureFetchWorker::recordTextureStart(bool is_http) { - if (! mMetricsStartTime) + if (! mMetricsStartTime.value()) { mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType); } @@ -2342,15 +2343,15 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http) // Threads: Ttf void LLTextureFetchWorker::recordTextureDone(bool is_http) { - if (mMetricsStartTime) + if (mMetricsStartTime.value()) { - 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); } @@ -2411,6 +2412,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() @@ -2756,7 +2761,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; @@ -2882,7 +2887,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 @@ -3789,7 +3794,7 @@ AssetReportHandler stats_handler; bool TFReqSetRegion::doWork(LLTextureFetch *) { - LLViewerAssetStatsFF::set_region_thread1(mRegionHandle); + LLViewerAssetStatsFF::set_region(mRegionHandle); return true; } @@ -3814,8 +3819,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); @@ -3825,17 +3830,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) @@ -3843,13 +3852,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, @@ -3869,11 +3879,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 902a3d7a25..2530beb722 100755 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -37,15 +37,15 @@ #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" #include "llviewertexture.h" +class LLViewerTexture; class LLTextureFetchWorker; class LLImageDecodeThread; class LLHost; @@ -309,8 +309,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::SampleStatHandle<> sCacheHitRate; + static LLTrace::SampleStatHandle<> sCacheReadLatency; LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; @@ -330,7 +330,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 e80136b286..c9ec5d9bf6 100755 --- 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,18 +507,21 @@ 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::Mibibytes, S32> bound_mem = LLViewerTexture::sBoundTextureMemory; + LLUnit<LLUnits::Mibibytes, S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem; + LLUnit<LLUnits::Mibibytes, S32> total_mem = LLViewerTexture::sTotalTextureMemory; + LLUnit<LLUnits::Mibibytes, 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::Mibibytes(LLAppViewer::getTextureCache()->getUsage()).value() ; + F32 cache_max_usage = (F32)LLTrace::Mibibytes(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); @@ -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/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 3f75f8da5e..85232f4a0b 100755 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -42,7 +42,6 @@ #include "lllineeditor.h" #include "lluictrlfactory.h" #include "llnotifications.h" -#include "llfunctorregistry.h" #include "llrootview.h" #include "lltransientfloatermgr.h" #include "llviewercontrol.h" // for gSavedSettings diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index b2318f9158..ed0f22f16a 100755 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -521,7 +521,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 e085834326..a4dce9efe8 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1094,7 +1094,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++ ) { @@ -1162,7 +1162,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(); @@ -1386,7 +1386,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/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fc9a316759..c912d81a03 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -42,6 +42,7 @@ #include "llfloaterscriptdebug.h" #include "lltooltip.h" #include "llhudeffecttrail.h" +#include "llhudicon.h" #include "llhudmanager.h" #include "llkeyboard.h" #include "llmediaentry.h" diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 641fbc5042..b7718847ae 100755 --- 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/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 7c604a04bf..0a9153eecb 100755 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -32,6 +32,7 @@ #include "llagentcamera.h" #include "llviewercontrol.h" #include "lldrawable.h" +#include "llhudicon.h" #include "llmanip.h" #include "llmenugl.h" #include "llselectmgr.h" diff --git a/indra/newview/lltoolselect.h b/indra/newview/lltoolselect.h index baa27f6071..74dababe8c 100755 --- a/indra/newview/lltoolselect.h +++ b/indra/newview/lltoolselect.h @@ -34,7 +34,7 @@ class LLObjectSelection; -class LLToolSelect : public LLTool, public LLSingleton<LLToolSelect> +class LLToolSelect : public LLTool { public: LLToolSelect( LLToolComposite* composite ); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index aaa81c57d4..3a6ee636d4 100755 --- 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,126 +80,258 @@ * */ +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::EventStatHandle<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::EventStatHandle<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) { - // mRegionHandle, mTotalTime, mStartTimestamp are left alone. + mRegionRecordings = src.mRegionRecordings; + + mCurRecording = &mRegionRecordings[mRegionHandle]; - // mFPS - if (src.mFPS.getCount() && mFPS.getCount()) + // 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) { - mFPS.merge(src.mFPS); + it->second.stop(); + it->second.makeUnique(); } - // Avatar stats - data all comes from main thread, so leave alone. + LLStopWatchControlsMixin<LLViewerAssetStats>::setPlayState(src.getPlayState()); +} - // Requests - for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) +void LLViewerAssetStats::handleStart() +{ + if (mCurRecording) { - mRequests[i].mEnqueued.merge(src.mRequests[i].mEnqueued); - mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued); - mRequests[i].mResponse.merge(src.mRequests[i].mResponse); + mCurRecording->start(); } - } - -void -LLViewerAssetStats::PerRegionStats::accumulateTime(duration_t now) +void LLViewerAssetStats::handleStop() { - mTotalTime += (now - mStartTimestamp); - mStartTimestamp = now; + if (mCurRecording) + { + mCurRecording->stop(); + } } - -// ------------------------------------------------------ -// LLViewerAssetStats class definition -// ------------------------------------------------------ -LLViewerAssetStats::LLViewerAssetStats() - : mRegionHandle(U64(0)) +void LLViewerAssetStats::handleReset() { reset(); } -LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) - : mRegionHandle(src.mRegionHandle), - mResetTimestamp(src.mResetTimestamp) -{ - 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]; -} - - -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) + // initialize new recording for current region + if (mRegionHandle) { - mCurRegionStats->reset(); + mCurRecording = &mRegionRecordings[mRegionHandle]; } - else - { - mCurRegionStats = new PerRegionStats(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) { @@ -205,410 +339,267 @@ 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::updateStats() { - const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - - ++(mCurRegionStats->mRequests[int(eac)].mEnqueued); + if (mCurRecording && mCurRecording->isStarted()) + { + mCurRecording->update(); + } } - -void -LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp) + +void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output) { - const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); + using namespace LLViewerAssetStatsFF; - ++(mCurRegionStats->mRequests[int(eac)].mDequeued); -} + stats.regions.setProvided(); -void -LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration) -{ - const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); + 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()); + } - mCurRegionStats->mRequests[int(eac)].mResponse.record(duration); -} + 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()); + } -void -LLViewerAssetStats::recordFPS(F32 fps) -{ - mCurRegionStats->mFPS.record(fps); -} + if (!compact_output + || rec.getSum(*sEnqueued[EVACWearableUDPGet]) + || rec.getSum(*sDequeued[EVACWearableUDPGet]) + || rec.getSum(*sResponse[EVACWearableUDPGet]).value()) + { + 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()); + } -LLSD -LLViewerAssetStats::asLLSD(bool compact_output) -{ - // Top-level tags - static const LLSD::String tags[EVACCount] = + if (!compact_output + || rec.getSum(*sEnqueued[EVACSoundUDPGet]) + || rec.getSum(*sDequeued[EVACSoundUDPGet]) + || rec.getSum(*sResponse[EVACSoundUDPGet]).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_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()); + } - // 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"); - - const duration_t now = LLViewerAssetStatsFF::get_timestamp(); - mCurRegionStats->accumulateTime(now); - - 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.getLastValue(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); - - return ret; + stats.duration(mCurRecording ? LLUnit<LLUnits::Microseconds, F64>(mCurRecording->getDuration()).value() : 0.0); } -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) -{ - if (! gViewerAssetStatsMain) - return; - - gViewerAssetStatsMain->setRegion(region_handle); -} - -void -record_enqueue_main(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); -} - -// 'thread1' - should be for TextureFetch thread - -void -set_region_thread1(LLViewerAssetStats::region_handle_t region_handle) +void set_region(LLViewerAssetStats::region_handle_t region_handle) { - if (! gViewerAssetStatsThread1) + if (! gViewerAssetStats) return; - gViewerAssetStatsThread1->setRegion(region_handle); + gViewerAssetStats->setRegion(region_handle); } -void -record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void record_enqueue(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->recordGetEnqueued(at, with_http, is_temp); + add(*sEnqueued[int(eac)], 1); } -void -record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp) +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->recordGetDequeued(at, with_http, is_temp); + add(*sDequeued[int(eac)], 1); } -void -record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) +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->recordGetServiced(at, with_http, is_temp, duration); + record(*sResponse[int(eac)], LLTrace::Microseconds(duration)); } - -void -init() +void init() { - if (! gViewerAssetStatsMain) - { - gViewerAssetStatsMain = new LLViewerAssetStats(); - } - if (! gViewerAssetStatsThread1) + if (! gViewerAssetStats) { - 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::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::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::AssetStats::AssetStats() +: regions("regions"), + duration("duration"), + 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 e4581d2120..1a8770f8a7 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -37,6 +37,8 @@ #include "llsimplestat.h" #include "llsd.h" #include "llvoavatar.h" +#include "lltrace.h" +#include "llinitparam.h" /** * @class LLViewerAssetStats @@ -73,29 +75,15 @@ * 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 * fetcher class, LLTextureFetch. */ - typedef U64 duration_t; + typedef LLUnit<LLUnits::Microseconds, U64> duration_t; /** * Type for the region identifier used in stats. Currently uses @@ -104,64 +92,65 @@ 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(); + Mandatory<S32> enqueued, + dequeued, + resp_count; + Mandatory<F64> resp_min, + resp_max, + resp_mean; + + AssetRequestType(); + }; - void merge(const PerRegionStats & src); + 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 AssetStats : public LLInitParam::Block<AssetStats> + { + Multiple<RegionStats> regions; + Mandatory<F64> duration; - // Apply current running time to total and reset start point. - // Return current timestamp as a convenience. - void accumulateTime(duration_t now); + Mandatory<LLUUID> session_id, + agent_id; - public: - region_handle_t mRegionHandle; - duration_t mTotalTime; - duration_t mStartTimestamp; - LLSimpleStatMMM<> mFPS; + Mandatory<std::string> message; + Mandatory<S32> sequence; + Mandatory<bool> initial, + break_; - struct prs_group - { - LLSimpleStatCounter mEnqueued; - LLSimpleStatCounter mDequeued; - LLSimpleStatMMM<duration_t> mResponse; - } - mRequests [EVACCount]; + AssetStats(); }; public: LLViewerAssetStats(); LLViewerAssetStats(const LLViewerAssetStats &); + // Default destructor is correct. LLViewerAssetStats & operator=(const LLViewerAssetStats &); // Not defined @@ -174,88 +163,32 @@ 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; }; @@ -273,12 +206,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. * @@ -303,28 +248,16 @@ 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); - -/** - * 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); +void record_avatar_stats(); } // namespace LLViewerAssetStatsFF diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index d042f62830..5c2dd20ec3 100755 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -69,12 +69,12 @@ public: protected: void recordMetrics() { - if (mMetricsStartTime) + if (mMetricsStartTime.value()) { // 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/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 094694dc06..ffdaa21c84 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -37,6 +37,7 @@ #include "llviewerwindow.h" #include "llvoiceclient.h" #include "llviewermedia.h" +#include "llviewerregion.h" #include "llprogressview.h" #include "llcallbacklist.h" #include "llstartup.h" @@ -501,11 +502,11 @@ void audio_update_wind(bool force_update) // standing still. static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f); LLVector3 scaled_wind_vec = gWindVec * wind_level; - + // Mix in the avatar's motion, subtract because when you walk north, // the apparent wind moves south. LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity(); - + // rotate the wind vector to be listener (agent) relative gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec ); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index b5aa0ac92a..ebc4f09edb 100755 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -49,11 +49,15 @@ #include "llglheaders.h" #include "llquaternion.h" #include "llwindow.h" // getPixelAspectRatio() +#include "lltracerecording.h" // System includes #include <iomanip> // for setprecision -U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; +LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity"); +LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); + +LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; //glu pick matrix implementation borrowed from Mesa3D glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) @@ -160,11 +164,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, 50); + 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..7b2887d725 100755 --- 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; @@ -80,7 +80,7 @@ public: NUM_CAMERAS } eCameraID; - static U32 sCurCameraID; + static eCameraID sCurCameraID; LLViewerCamera(); @@ -100,9 +100,9 @@ public: BOOL projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp = TRUE) const; BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const; - const LLVector3* getVelocityDir() const {return &mVelocityDir;} - LLStat *getVelocityStat() { return &mVelocityStat; } - LLStat *getAngularVelocityStat() { return &mAngularVelocityStat; } + LLVector3 getVelocityDir() const {return mVelocityDir;} + 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 cf59e67955..7ad4743d82 100755 --- 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; @@ -84,9 +85,6 @@ extern bool gShiftFrame; LLPointer<LLViewerTexture> gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport -const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain -const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. -const F32 TELEPORT_LOCAL_DELAY = 1.0f; // Delay to prevent teleports after starting an in-sim teleport. BOOL gTeleportDisplay = FALSE; LLFrameTimer gTeleportDisplayTimer; LLFrameTimer gTeleportArrivalTimer; @@ -372,7 +370,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_TELEPORT_DISPLAY); LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); - const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. + static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay"); + static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay"); S32 attach_count = 0; if (isAgentAvatarValid()) @@ -440,7 +439,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { - F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); + F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay()); if( arrival_fraction > 1.f ) { arrival_fraction = 1.f; @@ -457,7 +456,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // Short delay when teleporting in the same sim (progress screen active but not shown - did not // fall-through from TELEPORT_START) { - if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY ) + if( gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay() ) { //LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); @@ -607,7 +606,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 +747,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 +761,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); } @@ -802,6 +803,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } } + LLSceneMonitor::getInstance()->fetchQueryResult(); + LLGLState::checkStates(); LLGLState::checkClientArrays(); @@ -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()) { @@ -1221,6 +1229,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 c6b28b9e5e..39f8249300 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -28,66 +28,65 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterreg.h" - #include "llviewerfloaterreg.h" -#include "llfloaterautoreplacesettings.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 "llfloaterchatvoicevolume.h" #include "llfloaterconversationlog.h" #include "llfloaterconversationpreview.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 "llfloaterimsession.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" @@ -96,6 +95,7 @@ #include "llfloaterregiondebugconsole.h" #include "llfloaterregioninfo.h" #include "llfloaterreporter.h" +#include "llfloatersceneloadstats.h" #include "llfloaterscriptdebug.h" #include "llfloaterscriptlimits.h" #include "llfloatersearch.h" @@ -110,12 +110,14 @@ #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 "llfloatervoicevolume.h" #include "llfloaterwhitelistentry.h" #include "llfloaterwindowsize.h" @@ -136,10 +138,8 @@ #include "llpreviewscript.h" #include "llpreviewsound.h" #include "llpreviewtexture.h" -#include "llsyswellwindow.h" #include "llscriptfloater.h" -#include "llfloatermodelpreview.h" -#include "llcommandhandler.h" +#include "llsyswellwindow.h" // *NOTE: Please add files in alphabetical order to keep merges easy. @@ -231,7 +231,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>); @@ -305,6 +304,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 100755 --- 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 4ecdc31e21..49ac2735ca 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -161,6 +161,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 beca08203f..bb3f0fe932 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -124,6 +124,7 @@ #include "llwindow.h" #include "llpathfindingmanager.h" #include "boost/unordered_map.hpp" +#include "llscenemonitor.h" using namespace LLAvatarAppearanceDefines; @@ -524,7 +525,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) { @@ -552,9 +556,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) @@ -3963,24 +3967,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; } @@ -4027,72 +4031,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. @@ -7370,7 +7308,7 @@ void handle_dump_avatar_local_textures(void*) void handle_dump_timers() { - LLFastTimer::dumpCurTimes(); + LLTrace::TimeBlock::dumpCurTimes(); } void handle_debug_avatar_textures(void*) @@ -7611,6 +7549,23 @@ void handle_web_browser_test(const LLSD& param) LLWeb::loadURLInternal(url); } +bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( option == 0 ) // YES + { + //clear cache + LLAppViewer::instance()->purgeCacheImmediate(); + } + + return false; +} + +void handle_cache_clear_immediately() +{ + LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately); +} + void handle_web_content_test(const LLSD& param) { std::string url = param.asString(); @@ -8340,10 +8295,10 @@ void initialize_menus() view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway"); view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - + // Me > Movement view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); - + // Communicate > Voice morphing > Subscribe... commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe)); LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance(); @@ -8351,7 +8306,7 @@ void initialize_menus() , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing")); commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click" , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing")); - + // World menu view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); @@ -8577,6 +8532,8 @@ void initialize_menus() //Develop (Texture Fetch Debug Console) view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); + //Develop (clear cache immediately) + commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) ); // Admin >Object view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index be78603e2d..b7282a8493 100755 --- 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..3034d00b22 100755 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -31,6 +31,8 @@ #include "llassetstorage.h" #include "llinventorytype.h" #include "llfilepicker.h" +#include "llthread.h" +#include <queue> class LLTransactionID; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ace16396db..f2a3ffc3dc 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1181,7 +1181,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) } } } - + // Return "true" if we have a preview method for that asset type, "false" otherwise bool check_asset_previewable(const LLAssetType::EType asset_type) { @@ -1529,7 +1529,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& from_string = chatHistory_string = mFromName; LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm()); - + switch(button) { case IOR_SHOW: @@ -1627,7 +1627,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& { opener = discard_agent_offer; } - + if (modified_form != NULL) { modified_form->setElementEnabled("Show", false); @@ -2376,7 +2376,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLNotification::Params params; switch(dialog) - { + { case IM_CONSOLE_AND_CHAT_HISTORY: args["MESSAGE"] = message; payload["from_id"] = from_id; @@ -2628,7 +2628,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. @@ -3075,11 +3075,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); + } } } @@ -3170,10 +3170,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; @@ -4129,7 +4129,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; @@ -4340,7 +4340,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) @@ -4359,7 +4359,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; } @@ -4480,18 +4480,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... @@ -4503,11 +4503,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... @@ -4519,11 +4519,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... @@ -4535,11 +4535,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); @@ -4547,30 +4547,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 @@ -4578,9 +4590,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) { @@ -4594,18 +4609,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); - } } @@ -4817,145 +4830,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. // @@ -5864,7 +5750,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()) { @@ -6010,7 +5896,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." ) { @@ -6030,8 +5916,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) { @@ -6484,7 +6370,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data) args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL"); LLNotificationsUtil::add("UnknownScriptQuestion",args,payload); } - + if (known_questions) { LLSD payload; @@ -7471,8 +7357,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 064e96e394..9e6d8e78d1 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -39,6 +39,7 @@ #include "llfloaterreg.h" #include "llfontgl.h" #include "llframetimer.h" +#include "llhudicon.h" #include "llinventory.h" #include "llinventorydefines.h" #include "llmaterialtable.h" @@ -100,6 +101,7 @@ #include "lltrans.h" #include "llsdutil.h" #include "llmediaentry.h" +#include "llvocache.h" //#define DEBUG_UPDATE_TYPE @@ -112,6 +114,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 @@ -119,6 +124,7 @@ BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE F64 LLViewerObject::sMaxUpdateInterpolationTime = 3.0; // For motion interpolation: after X seconds with no updates, don't predict object motion F64 LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0; // For motion interpolation: after Y seconds with no updates, taper off motion prediction +std::map<std::string, U32> LLViewerObject::sObjectDataMap; static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object"); @@ -481,6 +487,8 @@ void LLViewerObject::initVOClasses() LLVOGrass::initClass(); LLVOWater::initClass(); LLVOVolume::initClass(); + + initObjectDataMap(); } void LLViewerObject::cleanupVOClasses() @@ -490,6 +498,118 @@ void LLViewerObject::cleanupVOClasses() LLVOTree::cleanupClass(); LLVOAvatar::cleanupClass(); LLVOVolume::cleanupClass(); + + sObjectDataMap.clear(); +} + +//object data map for compressed && !OUT_TERSE_IMPROVED +//static +void LLViewerObject::initObjectDataMap() +{ + U32 count = 0; + + sObjectDataMap["ID"] = count; //full id //LLUUID + count += sizeof(LLUUID); + + sObjectDataMap["LocalID"] = count; //U32 + count += sizeof(U32); + + sObjectDataMap["PCode"] = count; //U8 + count += sizeof(U8); + + sObjectDataMap["State"] = count; //U8 + count += sizeof(U8); + + sObjectDataMap["CRC"] = count; //U32 + count += sizeof(U32); + + sObjectDataMap["Material"] = count; //U8 + count += sizeof(U8); + + sObjectDataMap["ClickAction"] = count; //U8 + count += sizeof(U8); + + sObjectDataMap["Scale"] = count; //LLVector3 + count += sizeof(LLVector3); + + sObjectDataMap["Pos"] = count; //LLVector3 + count += sizeof(LLVector3); + + sObjectDataMap["Rot"] = count; //LLVector3 + count += sizeof(LLVector3); + + sObjectDataMap["SpecialCode"] = count; //U32 + count += sizeof(U32); + + sObjectDataMap["Owner"] = count; //LLUUID + count += sizeof(LLUUID); + + sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set + count += sizeof(LLVector3); + + //ParentID is after Omega if there is Omega, otherwise is after Owner + sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set + count += sizeof(U32); + + //------- + //The rest items are not included here + //------- +} + +//static +void LLViewerObject::unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name) +{ + dp->shift(sObjectDataMap[name]); + dp->unpackVector3(value, name.c_str()); + dp->reset(); +} + +//static +void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name) +{ + dp->shift(sObjectDataMap[name]); + dp->unpackUUID(value, name.c_str()); + dp->reset(); +} + +//static +void LLViewerObject::unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name) +{ + dp->shift(sObjectDataMap[name]); + dp->unpackU32(value, name.c_str()); + dp->reset(); +} + +//static +void LLViewerObject::unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name) +{ + dp->shift(sObjectDataMap[name]); + dp->unpackU8(value, name.c_str()); + dp->reset(); +} + +//static +U32 LLViewerObject::unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id) +{ + dp->shift(sObjectDataMap["SpecialCode"]); + U32 value; + dp->unpackU32(value, "SpecialCode"); + + parent_id = 0; + if(value & 0x20) + { + S32 offset = sObjectDataMap["ParentID"]; + if(!(value & 0x80)) + { + offset -= sizeof(LLVector3); + } + + dp->shift(offset); + dp->unpackU32(parent_id, "ParentID"); + } + dp->reset(); + + return parent_id; } // Replaces all name value pairs with data from \n delimited list @@ -870,6 +990,29 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url) return retval; } +//extract spatial information from object update message +//return parent_id +//static +U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot) +{ + U32 parent_id = 0; + LLViewerObject::unpackParentID(dp, parent_id); + if(parent_id > 0) + { + //is a child, no need to decode further. + return parent_id; + } + + LLViewerObject::unpackVector3(dp, scale, "Scale"); + LLViewerObject::unpackVector3(dp, pos, "Pos"); + + LLVector3 vec; + LLViewerObject::unpackVector3(dp, vec, "Rot"); + rot.unpackFromVector3(vec); + + return parent_id; +} + U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, @@ -886,10 +1029,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 +1059,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,13 +1839,12 @@ 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. - U32 flags; - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); - // keep local flags and overwrite remote-controlled flags - mFlags = (mFlags & FLAGS_LOCAL) | flags; - - // ...new objects that should come in selected need to be added to the selected list - mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); + if(mesgsys != NULL) + { + U32 flags; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); + loadFlags(flags); + } } break; @@ -1726,10 +1872,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 +1962,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 +2011,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 +2046,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 +2141,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 +2164,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 +2173,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 +2222,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() ); + record(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length())); } } @@ -2156,7 +2345,21 @@ BOOL LLViewerObject::isActive() const return TRUE; } +//load flags from cache or from message +void LLViewerObject::loadFlags(U32 flags) +{ + if(flags == (U32)(-1)) + { + return; //invalid + } + // keep local flags and overwrite remote-controlled flags + mFlags = (mFlags & FLAGS_LOCAL) | flags; + + // ...new objects that should come in selected need to be added to the selected list + mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); + return; +} void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 316dbce7d0..41a559c19d 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -30,8 +30,7 @@ #include <map> #include "llassetstorage.h" -#include "lldarrayptr.h" -#include "llhudicon.h" +//#include "llhudicon.h" #include "llinventory.h" #include "llrefcount.h" #include "llprimitive.h" @@ -43,33 +42,30 @@ #include "v3math.h" #include "llvertexbuffer.h" #include "llbbox.h" -#include "llbbox.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; class LLAudioSourceVO; -class LLDataPacker; class LLColor4; -class LLFrameTimer; +class LLDataPacker; +class LLDataPackerBinaryBuffer; class LLDrawable; -class LLHost; class LLHUDText; -class LLWorld; -class LLNameValue; -class LLNetMap; +class LLHost; class LLMessageSystem; +class LLNameValue; class LLPartSysData; -class LLPrimitive; class LLPipeline; class LLTextureEntry; -class LLViewerTexture; +class LLVOAvatar; +class LLVOInventoryListener; class LLViewerInventoryItem; class LLViewerObject; +class LLViewerObjectMedia; class LLViewerPartSourceScript; class LLViewerRegion; -class LLViewerObjectMedia; -class LLVOInventoryListener; -class LLVOAvatar; +class LLViewerTexture; +class LLWorld; typedef enum e_object_update_type { @@ -107,7 +103,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() @@ -157,6 +157,7 @@ public: INVALID_UPDATE = 0x80000000 }; + static U32 extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot); virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, @@ -505,6 +506,7 @@ public: virtual void updateRegion(LLViewerRegion *regionp); void updateFlags(BOOL physics_changed = FALSE); + void loadFlags(U32 flags); //load flags from cache or from message BOOL setFlags(U32 flag, BOOL state); BOOL setFlagsWithoutUpdate(U32 flag, BOOL state); void setPhysicsShapeType(U8 type); @@ -535,6 +537,13 @@ public: friend class LLViewerMediaList; public: + static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name); + static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name); + static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name); + static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name); + static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id); + +public: //counter-translation void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE) ; //counter-rotation @@ -557,6 +566,8 @@ private: // Motion prediction between updates void interpolateLinearMotion(const F64 & time, const F32 & dt); + static void initObjectDataMap(); + public: // // Viewer-side only types - use the LL_PCODE_APP mask. @@ -605,6 +616,7 @@ private: // Grabbed from UPDATE_FLAGS U32 mFlags; + static std::map<std::string, U32> sObjectDataMap; public: // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties U8 mPhysicsShapeType; @@ -628,9 +640,10 @@ public: // TODO: Make all this stuff private. JC LLPointer<LLHUDText> mText; - LLPointer<LLHUDIcon> mIcon; + LLPointer<class LLHUDIcon> mIcon; static BOOL sUseSharedDrawables; + static LLTrace::MemStatHandle sMemStat; protected: // delete an item in the inventory, but don't tell the @@ -666,8 +679,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 +757,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 caacf26cb3..546a7acfc6 100755 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -47,6 +47,7 @@ #include "lltooltip.h" #include "llworld.h" #include "llstring.h" +#include "llhudicon.h" #include "llhudnametag.h" #include "lldrawable.h" #include "llflexibleobject.h" @@ -76,6 +77,7 @@ #include "object_flags.h" #include "llappviewer.h" +#include "llvocache.h" extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; @@ -93,7 +95,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::SampleStatHandle<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); LLViewerObjectList::LLViewerObjectList() { @@ -106,7 +108,6 @@ LLViewerObjectList::LLViewerObjectList() mNumNewObjects = 0; mWasPaused = FALSE; mNumDeadObjectUpdates = 0; - mNumUnknownKills = 0; mNumUnknownUpdates = 0; } @@ -228,9 +229,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 +261,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 - findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); + 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 +295,89 @@ 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); + objectp->loadFlags(entry->getUpdateFlags()); //just in case, reload update flags from cache. + + 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); @@ -298,7 +395,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; @@ -346,7 +443,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++) @@ -355,57 +451,37 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, LLTimer update_timer; BOOL justCreated = FALSE; S32 msg_size = 0; + bool remove_from_cache = false; //remove from object cache if it is a full-update or terse update - 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; + 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); if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { - compressed_dp.unpackUUID(fullid, "ID"); - compressed_dp.unpackU32(local_id, "LocalID"); - compressed_dp.unpackU8(pcode, "PCode"); + U32 flags = 0; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); + + if(flags & FLAGS_TEMPORARY_ON_REZ) + { + compressed_dp.unpackUUID(fullid, "ID"); + compressed_dp.unpackU32(local_id, "LocalID"); + compressed_dp.unpackU8(pcode, "PCode"); + } + else //send to object cache + { + regionp->cacheFullUpdate(compressed_dp, flags); + continue; + } } else { + remove_from_cache = true; compressed_dp.unpackU32(local_id, "LocalID"); getUUIDFromLocal(fullid, local_id, @@ -435,6 +511,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } else // OUT_FULL only? { + remove_from_cache = true; mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i); mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); msg_size += sizeof(LLUUID); @@ -443,6 +520,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } objectp = findObject(fullid); + if(remove_from_cache) + { + objectp = regionp->forceToRemoveFromCache(local_id, objectp); + } + // This looks like it will break if the local_id of the object doesn't change // upon boundary crossing, but we check for region id matching later... // Reset object local id and region pointer if things have changed @@ -488,9 +570,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, continue; } } - else if (cached) // Cache hit only? - { - } else { if (update_type != OUT_FULL) @@ -521,13 +600,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } + justCreated = TRUE; mNumNewObjects++; - sCacheHitRate.addValue(cached ? 100.f : 0.f); - } - if (objectp->isDead()) { llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl; @@ -541,17 +618,21 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, objectp->mLocalID = local_id; } processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); + +#if 0 if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { - bCached = true; - LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); + 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, flags); + 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); +#endif } else { @@ -575,14 +656,53 @@ 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; + U32 flags; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, 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, flags, 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() @@ -853,6 +973,8 @@ private: LLSD mObjectIDs; }; +static LLFastTimer::DeclareTimer FTM_IDLE_COPY("Idle Copy"); + void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { // Update globals @@ -903,10 +1025,8 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) 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++) @@ -916,9 +1036,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; } @@ -1032,10 +1152,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() @@ -1248,16 +1368,7 @@ 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->markDead(); // does the right thing if object already dead return TRUE; } @@ -1409,10 +1520,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); @@ -1541,13 +1652,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() @@ -1893,6 +2004,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) @@ -1960,9 +2094,7 @@ S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port) { -#ifdef ORPHAN_SPAM - llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl; -#endif + LL_DEBUGS("ORPHANS") << "Orphaning object " << childp->getID() << " with parent " << parent_id << LL_ENDL; // We're an orphan, flag things appropriately. childp->mOrphaned = TRUE; @@ -2015,6 +2147,12 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) return; } + //search object cache to get orphans + if(objectp->getRegion()) + { + objectp->getRegion()->findOrphans(objectp->getLocalID()); + } + // See if we are a parent of an orphan. // Note: This code is fairly inefficient but it should happen very rarely. // It can be sped up if this is somehow a performance issue... @@ -2050,11 +2188,11 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) continue; } + LL_DEBUGS("ORPHANS") << "Reunited parent " << objectp->mID + << " with child " << childp->mID << LL_ENDL; + LL_DEBUGS("ORPHANS") << "Glob: " << objectp->getPositionGlobal() << LL_ENDL; + LL_DEBUGS("ORPHANS") << "Agent: " << objectp->getPositionAgent() << LL_ENDL; #ifdef ORPHAN_SPAM - llinfos << "Reunited parent " << objectp->mID - << " with child " << childp->mID << llendl; - llinfos << "Glob: " << objectp->getPositionGlobal() << llendl; - llinfos << "Agent: " << objectp->getPositionAgent() << llendl; addDebugBeacon(objectp->getPositionAgent(),""); #endif gPipeline.markMoved(objectp->mDrawable); @@ -2142,3 +2280,10 @@ bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const } +LLDebugBeacon::~LLDebugBeacon() +{ + if (mHUDObject.notNull()) + { + mHUDObject->markDead(); + } +} diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 449a4633ff..464554245e 100755 --- 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,6 +66,7 @@ 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); @@ -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::SampleStatHandle<> sCacheHitRate; typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t; @@ -234,20 +237,14 @@ protected: class LLDebugBeacon { public: - ~LLDebugBeacon() - { - if (mHUDObject.notNull()) - { - mHUDObject->markDead(); - } - } + ~LLDebugBeacon(); LLVector3 mPositionAgent; std::string mString; LLColor4 mColor; LLColor4 mTextColor; S32 mLineWidth; - LLPointer<LLHUDObject> mHUDObject; + LLPointer<class LLHUDObject> mHUDObject; }; diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp new file mode 100644 index 0000000000..d631985e82 --- /dev/null +++ b/indra/newview/llvieweroctree.cpp @@ -0,0 +1,1459 @@ +/** + * @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" +#include "pipeline.h" +#include "llviewercontrol.h" +#include "llappviewer.h" +#include "llglslshader.h" +#include "llviewershadermgr.h" + +//----------------------------------------------------------------------------------- +//static variables definitions +//----------------------------------------------------------------------------------- +U32 LLViewerOctreeEntryData::sCurVisible = 0; +BOOL LLViewerOctreeDebug::sInDebug = FALSE; + +//----------------------------------------------------------------------------------- +//some global functions definitions +//----------------------------------------------------------------------------------- +typedef enum +{ + b000 = 0x00, + b001 = 0x01, + b010 = 0x02, + b011 = 0x03, + b100 = 0x04, + b101 = 0x05, + b110 = 0x06, + b111 = 0x07, +} eLoveTheBits; + +//contact Runitai Linden for a copy of the SL object used to write this table +//basically, you give the table a bitmask of the look-at vector to a node and it +//gives you a triangle fan index array +static U16 sOcclusionIndices[] = +{ + //000 + b111, b110, b010, b011, b001, b101, b100, b110, + //001 + b011, b010, b000, b001, b101, b111, b110, b010, + //010 + b101, b100, b110, b111, b011, b001, b000, b100, + //011 + b001, b000, b100, b101, b111, b011, b010, b000, + //100 + b110, b000, b010, b011, b111, b101, b100, b000, + //101 + b010, b100, b000, b001, b011, b111, b110, b100, + //110 + b100, b010, b110, b111, b101, b001, b000, b010, + //111 + b000, b110, b100, b101, b001, b011, b010, b110, +}; + +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) +{ + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + + return cypher*8; +} + +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) +{ + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + + return (U8*) (sOcclusionIndices+cypher*8); +} + +//create a vertex buffer for efficiently rendering cubes +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) +{ + LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); + + ret->allocateBuffer(8, 64, true); + + LLStrider<LLVector3> pos; + LLStrider<U16> idx; + + ret->getVertexStrider(pos); + ret->getIndexStrider(idx); + + pos[0] = LLVector3(-1,-1,-1); + pos[1] = LLVector3(-1,-1, 1); + pos[2] = LLVector3(-1, 1,-1); + pos[3] = LLVector3(-1, 1, 1); + pos[4] = LLVector3( 1,-1,-1); + pos[5] = LLVector3( 1,-1, 1); + pos[6] = LLVector3( 1, 1,-1); + pos[7] = LLVector3( 1, 1, 1); + + for (U32 i = 0; i < 64; i++) + { + idx[i] = sOcclusionIndices[i]; + } + + ret->flush(); + + return ret; +} + + +#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 + +const F32 SG_OCCLUSION_FUDGE = 0.25f; +#define SG_DISCARD_TOLERANCE 0.01f + + +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 < getMinFrameRange()); +} + +void LLViewerOctreeEntryData::setVisible() const +{ + if(mEntry) + { + mEntry->mVisible = sCurVisible; + } +} + +//----------------------------------------------------------------------------------- +//class LLviewerOctreeGroup definitions +//----------------------------------------------------------------------------------- + +LLviewerOctreeGroup::~LLviewerOctreeGroup() +{ + //empty here +} + +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 << "LLviewerOctreeGroup redundancy detected." << llendl; + } + + unbound(); + + ((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} + +//virtual +void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) +{ + unbound(); +} + +LLviewerOctreeGroup* LLviewerOctreeGroup::getParent() +{ + if (isDead()) + { + return NULL; + } + + 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(); +} + +void LLviewerOctreeGroup::checkStates() +{ +#if LL_OCTREE_PARANOIA_CHECK + //LLOctreeStateCheck checker; + //checker.traverse(mOctreeNode); +#endif +} + +//------------------------------------------------------------------------------------------- +//occulsion culling functions and classes +//------------------------------------------------------------------------------------------- +std::set<U32> LLOcclusionCullingGroup::sPendingQueries; +class LLOcclusionQueryPool : public LLGLNamePool +{ +public: + LLOcclusionQueryPool() + { + mCurQuery = 1; + } + +protected: + + std::list<GLuint> mAvailableName; + GLuint mCurQuery; + + virtual GLuint allocateName() + { + GLuint ret = 0; + + if (!mAvailableName.empty()) + { + ret = mAvailableName.front(); + mAvailableName.pop_front(); + } + else + { + ret = mCurQuery++; + } + + return ret; + } + + virtual void releaseName(GLuint name) + { +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + LLSpatialGroup::sPendingQueries.erase(name); +#endif + llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); + mAvailableName.push_back(name); + } +}; + +static LLOcclusionQueryPool sQueryPool; +U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() +{ + return sQueryPool.allocate(); +} + +void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name) +{ + sQueryPool.release(name); +} + +//===================================== +// Occlusion State Set/Clear +//===================================== +class LLSpatialSetOcclusionState : public OctreeTraveler +{ +public: + U32 mState; + LLSpatialSetOcclusionState(U32 state) : mState(state) { } + virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->setOcclusionState(mState); } +}; + +class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState +{ +public: + LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } + + virtual void traverse(const OctreeNode* n) + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0); + + if (!group->isOcclusionState(mState)) + { + OctreeTraveler::traverse(n); + } + } +}; + + +LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) : + LLviewerOctreeGroup(node), + mSpatialPartition(part) +{ + part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; + mLODHash = part->mLODSeed; + + OctreeNode* oct_parent = node->getOctParent(); + LLOcclusionCullingGroup* parent = oct_parent ? (LLOcclusionCullingGroup*) oct_parent->getListener(0) : NULL; + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionQuery[i] = 0; + mOcclusionIssued[i] = 0; + mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; + mVisible[i] = 0; + } +} + +LLOcclusionCullingGroup::~LLOcclusionCullingGroup() +{ + releaseOcclusionQueryObjectNames(); +} + +BOOL LLOcclusionCullingGroup::needsUpdate() +{ + return (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; +} + +//virtual +void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +{ + if (child->getListenerCount() == 0) + { + new LLOcclusionCullingGroup(child, mSpatialPartition); + } + else + { + OCT_ERRS << "LLOcclusionCullingGroup redundancy detected." << llendl; + } + + unbound(); + + ((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} + +void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() +{ + if (gGLManager.mHasOcclusionQuery) + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + { + if (mOcclusionQuery[i]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } + } + } +} + +void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) +{ + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialSetOcclusionStateDiff setter(state); + setter.traverse(mOctreeNode); + } + else if (mode == STATE_MODE_BRANCH) + { + LLSpatialSetOcclusionState setter(state); + setter.traverse(mOctreeNode); + } + else + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] |= state; + + if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } + } + } + } + else + { + mOcclusionState[LLViewerCamera::sCurCameraID] |= state; + if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + } +} + +class LLSpatialClearOcclusionState : public OctreeTraveler +{ +public: + U32 mState; + + LLSpatialClearOcclusionState(U32 state) : mState(state) { } + virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->clearOcclusionState(mState); } +}; + +class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState +{ +public: + LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } + + virtual void traverse(const OctreeNode* n) + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0); + + if (group->isOcclusionState(mState)) + { + OctreeTraveler::traverse(n); + } + } +}; + +void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) +{ + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialClearOcclusionStateDiff clearer(state); + clearer.traverse(mOctreeNode); + } + else if (mode == STATE_MODE_BRANCH) + { + LLSpatialClearOcclusionState clearer(state); + clearer.traverse(mOctreeNode); + } + else + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] &= ~state; + } + } + } + else + { + mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; + } +} + +static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); + +BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera) +{ + if (camera->getOrigin().isExactlyZero()) + { + return FALSE; + } + + const F32 vel = SG_OCCLUSION_FUDGE*2.f; + LLVector4a fudge; + fudge.splat(vel); + + const LLVector4a* bounds = getBounds(); + const LLVector4a& c = bounds[0]; + LLVector4a r; + r.setAdd(bounds[1], fudge); + + /*if (r.magVecSquared() > 1024.0*1024.0) + { + return TRUE; + }*/ + + LLVector4a e; + e.load3(camera->getOrigin().mV); + + LLVector4a min; + min.setSub(c,r); + LLVector4a max; + max.setAdd(c,r); + + S32 lt = e.lessThan(min).getGatheredBits() & 0x7; + if (lt) + { + return FALSE; + } + + S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; + if (gt) + { + return FALSE; + } + + return TRUE; +} + +void LLOcclusionCullingGroup::checkOcclusion() +{ + if (LLPipeline::sUseOcclusion > 1) + { + LLFastTimer t(FTM_OCCLUSION_READBACK); + LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent(); + if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { //if the parent has been marked as occluded, the child is implicitly occluded + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } + else if (isOcclusionState(QUERY_PENDING)) + { //otherwise, if a query is pending, read it back + + GLuint available = 0; + if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + + static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); + + if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) + { //query was issued last frame, wait until it's available + S32 max_loop = 1024; + LLFastTimer t(FTM_OCCLUSION_WAIT); + while (!available && max_loop-- > 0) + { + //do some usefu work while we wait + F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); + LLAppViewer::instance()->updateTextureThreads(max_time); + + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + } + } + else + { + available = 1; + } + + if (available) + { //result is available, read it back, otherwise wait until next frame + GLuint res = 1; + if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + } + else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { //delete the query to avoid holding onto hundreds of pending queries + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + + if (isOcclusionState(DISCARD_QUERY)) + { + res = 2; + } + + if (res > 0) + { + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + assert_states_valid(this); + + setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + + assert_states_valid(this); + } + + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } + } + else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { //check occlusion has been issued for occluded node that has not had a query issued + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + } +} + +static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); +static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); + +void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera) +{ + if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) + { + // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension + if (earlyFail(camera)) + { + LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); + setOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) + { + { //no query pending, or previous query to be discarded + LLFastTimer t(FTM_RENDER_OCCLUSION); + + if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + LLFastTimer t(FTM_OCCLUSION_ALLOCATE); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName(); + } + + // Depth clamp all water to avoid it being culled as a result of being + // behind the far clip plane, and in the case of edge water to avoid + // it being culled while still visible. + bool const use_depth_clamp = gGLManager.mHasDepthClamp && + (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || + mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + +#if !LL_DARWIN + U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; +#else + U32 mode = GL_SAMPLES_PASSED_ARB; +#endif + +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + + { + LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); + + //store which frame this query was issued on + mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; + + { + LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); + glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + } + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + + shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); + shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, + mBounds[1][1]+SG_OCCLUSION_FUDGE, + mBounds[1][2]+SG_OCCLUSION_FUDGE); + + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) + { + LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); + + LLGLSquashToFarClip squash(glh_get_current_projection(), 1); + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + } + else + { + LLFastTimer t(FTM_OCCLUSION_DRAW); + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + } + + + { + LLFastTimer t(FTM_OCCLUSION_END_QUERY); + glEndQueryARB(mode); + } + } + } + + { + LLFastTimer t(FTM_SET_OCCLUSION_STATE); + setOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING); + clearOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); + } + } + } + } +} +//------------------------------------------------------------------------------------------- +//end of occulsion culling functions and classes +//------------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------- +//class LLViewerOctreePartition definitions +//----------------------------------------------------------------------------------- +LLViewerOctreePartition::LLViewerOctreePartition() : + mRegionp(NULL), + mOcclusionEnabled(TRUE), + mDrawableType(0), + mLODSeed(0), + mLODPeriod(1) +{ + LLVector4a center, size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new OctreeRoot(center,size, NULL); +} + +LLViewerOctreePartition::~LLViewerOctreePartition() +{ + delete mOctree; + mOctree = NULL; +} + +BOOL LLViewerOctreePartition::isOcclusionEnabled() +{ + return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; +} + +//----------------------------------------------------------------------------------- +//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); + } +} + +//-------------------------------------------------------------- +//class LLViewerOctreeDebug +//virtual +void LLViewerOctreeDebug::visit(const OctreeNode* branch) +{ +#if 0 + llinfos << "Node: " << (U32)branch << " # Elements: " << branch->getElementCount() << " # Children: " << branch->getChildCount() << llendl; + for (U32 i = 0; i < branch->getChildCount(); i++) + { + llinfos << "Child " << i << " : " << (U32)branch->getChild(i) << llendl; + } +#endif + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0); + processGroup(group); +} + +//virtual +void LLViewerOctreeDebug::processGroup(LLviewerOctreeGroup* group) +{ +#if 0 + const LLVector4a* vec4 = group->getBounds(); + LLVector3 vec[2]; + vec[0].set(vec4[0].getF32ptr()); + vec[1].set(vec4[1].getF32ptr()); + llinfos << "Bounds: " << vec[0] << " : " << vec[1] << llendl; + + vec4 = group->getExtents(); + vec[0].set(vec4[0].getF32ptr()); + vec[1].set(vec4[1].getF32ptr()); + llinfos << "Extents: " << vec[0] << " : " << vec[1] << llendl; + + vec4 = group->getObjectBounds(); + vec[0].set(vec4[0].getF32ptr()); + vec[1].set(vec4[1].getF32ptr()); + llinfos << "ObjectBounds: " << vec[0] << " : " << vec[1] << llendl; + + vec4 = group->getObjectExtents(); + vec[0].set(vec4[0].getF32ptr()); + vec[1].set(vec4[1].getF32ptr()); + llinfos << "ObjectExtents: " << vec[0] << " : " << vec[1] << llendl; +#endif +} +//-------------------------------------------------------------- diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h new file mode 100644 index 0000000000..0a96676be1 --- /dev/null +++ b/indra/newview/llvieweroctree.h @@ -0,0 +1,422 @@ +/** + * @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; +class LLViewerOctreePartition; + +typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener; +typedef LLTreeNode<LLViewerOctreeEntry> TreeNode; +typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode; +typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot; +typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler; + +#if LL_OCTREE_PARANOIA_CHECK +#define assert_octree_valid(x) x->validate() +#define assert_states_valid(x) ((LLviewerOctreeGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() +#else +#define assert_octree_valid(x) +#define assert_states_valid(x) +#endif + +// 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); + +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* 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 getMinFrameRange()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, + DEAD = 0x00000008, + INVALID_STATE = 0x00000010, + }; + +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(); + + BOOL isDead() { return hasState(DEAD); } + + 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); + +protected: + void checkStates(); +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); + +//octree group which has capability to support occlusion culling +//LL_ALIGN_PREFIX(16) +class LLOcclusionCullingGroup : public LLviewerOctreeGroup +{ +public: + typedef enum + { + OCCLUDED = 0x00010000, + QUERY_PENDING = 0x00020000, + ACTIVE_OCCLUSION = 0x00040000, + DISCARD_QUERY = 0x00080000, + EARLY_FAIL = 0x00100000, + } eOcclusionState; + + typedef enum + { + STATE_MODE_SINGLE = 0, //set one node + STATE_MODE_BRANCH, //set entire branch + STATE_MODE_DIFF, //set entire branch as long as current state is different + STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras + } eSetStateMode; + +public: + LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part); + LLOcclusionCullingGroup(const LLOcclusionCullingGroup& rhs) : LLviewerOctreeGroup(rhs) + { + *this = rhs; + } + ~LLOcclusionCullingGroup(); + + void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); + void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); + void checkOcclusion(); //read back last occlusion query (if any) + void doOcclusion(LLCamera* camera); //issue occlusion query + BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } + + BOOL needsUpdate(); + + //virtual + void handleChildAddition(const OctreeNode* parent, OctreeNode* child); + + static U32 getNewOcclusionQueryObjectName(); + static void releaseOcclusionQueryObjectName(U32 name); + +protected: + void releaseOcclusionQueryObjectNames(); + +private: + BOOL earlyFail(LLCamera* camera); + +protected: + U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; + U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; + + S32 mLODHash; + + LLViewerOctreePartition* mSpatialPartition; + U32 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; + +public: + static std::set<U32> sPendingQueries; +};//LL_ALIGN_POSTFIX(16); + +class LLViewerOctreePartition +{ +public: + LLViewerOctreePartition(); + virtual ~LLViewerOctreePartition(); + + // Cull on arbitrary frustum + virtual S32 cull(LLCamera &camera) = 0; + BOOL isOcclusionEnabled(); + +public: + U32 mPartitionType; + U32 mDrawableType; + OctreeNode* mOctree; + LLViewerRegion* mRegionp; // the region this partition belongs to. + BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed + U32 mLODSeed; + U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) +}; + +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; +}; + +//scan the octree, output the info of each node for debug use. +class LLViewerOctreeDebug : public OctreeTraveler +{ +public: + virtual void processGroup(LLviewerOctreeGroup* group); + virtual void visit(const OctreeNode* branch); + +public: + static BOOL sInDebug; +}; + +#endif diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6bd9f66b9c..a23a15da32 100755 --- 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; @@ -467,6 +467,20 @@ LLViewerPartSim::LLViewerPartSim() mID = ++id_seed; } +//enable/disable particle system +void LLViewerPartSim::enable(bool enabled) +{ + if(!enabled && sMaxParticleCount > 0) + { + sMaxParticleCount = 0; //disable + } + else if(enabled && sMaxParticleCount < 1) + { + sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT); + } + + return; +} void LLViewerPartSim::destroyClass() { diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index c91fcf0691..5c71b4c49e 100755 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -27,7 +27,6 @@ #ifndef LL_LLVIEWERPARTSIM_H #define LL_LLVIEWERPARTSIM_H -#include "lldarrayptr.h" #include "llframetimer.h" #include "llpointer.h" #include "llpartdata.h" @@ -36,7 +35,6 @@ class LLViewerTexture; class LLViewerPart; class LLViewerRegion; -class LLViewerTexture; class LLVOPartGroup; #define LL_MAX_PARTICLE_COUNT 8192 @@ -134,6 +132,8 @@ public: typedef std::vector<LLViewerPartGroup *> group_list_t; typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t; + void enable(bool enabled); + void shift(const LLVector3 &offset); void updateSimulation(); diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index a565005f30..5df456dab6 100755 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -52,11 +52,9 @@ // Library headers from llcommon project: #include "bitpack.h" -#include "lldeleteutils.h" #include "imageids.h" #include "indra_constants.h" #include "llinitparam.h" - #include "llallocator.h" #include "llapp.h" #include "llcriticaldamp.h" @@ -65,11 +63,7 @@ #include "llerror.h" #include "llfasttimer.h" #include "llframetimer.h" -#include "llhash.h" -#include "lllocalidhashmap.h" -#include "llnametable.h" #include "llpointer.h" -#include "llpriqueuemap.h" #include "llprocessor.h" #include "llrefcount.h" #include "llsafehandle.h" @@ -79,9 +73,7 @@ #include "llstrider.h" #include "llstring.h" #include "llsys.h" -#include "llthread.h" #include "lltimer.h" -#include "lluuidhashmap.h" #include "stdenums.h" #include "stdtypes.h" #include "timing.h" diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b8b53aa6e4..781a754b7c 100755 --- 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,31 +86,36 @@ 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; +BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE; + typedef std::map<std::string, std::string> CapabilityMap; class LLViewerRegionImpl { public: LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host) - : mHost(host), - mCompositionp(NULL), - mEventPoll(NULL), - mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), - mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), - mSeedCapAttempts(0), - mHttpResponderID(0), - // 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 - // setRegionNameAndZone() replace the instance. Would that pose - // consistency problems? Can we even request a capability before calling - // setRegionNameAndZone()? - // For testability -- the new Michael Feathers paradigm -- - // LLCapabilityListener binds all the globals it expects to need at - // construction time. - mCapabilityListener(host.getString(), gMessageSystem, *region, - gAgent.getID(), gAgent.getSessionID()) - { - } + : mHost(host), + mCompositionp(NULL), + mEventPoll(NULL), + mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), + mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), + mSeedCapAttempts(0), + mHttpResponderID(0), + mLastCameraUpdate(0), + mLastCameraOrigin(), + mVOCachePartition(NULL), + mLandp(NULL), + // 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 + // setRegionNameAndZone() replace the instance. Would that pose + // consistency problems? Can we even request a capability before calling + // setRegionNameAndZone()? + // For testability -- the new Michael Feathers paradigm -- + // LLCapabilityListener binds all the globals it expects to need at + // construction time. + mCapabilityListener(host.getString(), gMessageSystem, *region, + gAgent.getID(), gAgent.getSessionID()) + {} void buildCapabilityNames(LLSD& capabilityNames); @@ -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< LLPointer<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? @@ -143,7 +156,7 @@ public: CapabilityMap mCapabilities; CapabilityMap mSecondCapabilitiesTracker; - + LLEventPoll* mEventPoll; S32 mSeedCapMaxAttempts; @@ -158,7 +171,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 @@ -350,7 +366,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); @@ -382,17 +401,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(); } @@ -413,6 +435,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... @@ -427,10 +455,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; } @@ -471,9 +499,13 @@ void LLViewerRegion::loadObjectCache() // Presume success. If it fails, we don't want to try again. mCacheLoaded = TRUE; - if(LLVOCache::hasInstance()) + if(LLVOCache::instanceExists()) { LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; + if (mImpl->mCacheMap.empty()) + { + mCacheDirty = TRUE; + } } } @@ -490,16 +522,15 @@ void LLViewerRegion::saveObjectCache() return; } - if(LLVOCache::hasInstance()) + if(LLVOCache::instanceExists()) { - LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ; + const F32 start_time_threshold = 600.0f; //seconds + bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. + + LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ; mCacheDirty = FALSE; } - for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) - { - delete iter->second; - } mImpl->mCacheMap.clear(); } @@ -765,8 +796,339 @@ void LLViewerRegion::dirtyHeights() } } +void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) +{ + U32 state = LLVOCacheEntry::INACTIVE; + bool in_vo_tree = false; + + if(old_entry) + { + old_entry->moveTo(new_entry); + state = old_entry->getState(); + in_vo_tree = (state == LLVOCacheEntry::INACTIVE && old_entry->getGroup() != NULL); + 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 || in_vo_tree) + { + 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; + } + + 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); +} + +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; + } + } +#endif + + //process visible groups + std::set< LLPointer<LLviewerOctreeGroup> >::iterator group_iter = mImpl->mVisibleGroups.begin(); + for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) + { + LLPointer<LLviewerOctreeGroup> group = *group_iter; + if(group->getNumRefs() < 3 || //group to be deleted + !group->getOctreeNode() || group->isEmpty()) //group empty + { + continue; + } + + for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + if((*i)->hasVOCacheEntry()) + { + LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); + + if(vo_entry->getParentID() > 0) //is a child + { + //child visibility depends on its parent. + continue; + } + + vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); + mImpl->mWaitingList.insert(vo_entry); + } + } + } + + 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); @@ -776,9 +1138,146 @@ 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; + } + + if(!sVOCacheCullingEnabled) + { + return did_update; + } + + //kill invisible objects + max_update_time = killInvisibleObjects(max_update_time); + + max_update_time = updateVisibleEntries(max_update_time); + createVisibleObjects(max_update_time); + + mImpl->mVisibleGroups.clear(); + return did_update; } +F32 LLViewerRegion::killInvisibleObjects(F32 max_time) +{ +#if 1 + if(!sVOCacheCullingEnabled) + { + return max_time; + } + if(mImpl->mActiveSet.empty()) + { + return max_time; + } + + static LLVOCacheEntry* last_visited_entry = NULL; + + const size_t MAX_UPDATE = 32; + std::vector<LLDrawable*> delete_list; + S32 update_counter = llmin(MAX_UPDATE, mImpl->mActiveSet.size()); + LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(last_visited_entry); + + for(; update_counter > 0; --update_counter, ++iter) + { + if(iter == mImpl->mActiveSet.end()) + { + iter = mImpl->mActiveSet.begin(); + } + + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + + if(iter == mImpl->mActiveSet.end()) + { + last_visited_entry = NULL; + } + else + { + last_visited_entry = *iter; + } + + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); +#endif + 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; +} + +//remove from object cache if the object receives a full-update or terse update +LLViewerObject* LLViewerRegion::forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp) +{ + LLVOCacheEntry* entry = getCacheEntry(local_id); + if (!entry) + { + return objectp; //not in the cache, do nothing. + } + if(!objectp) //object not created + { + entry->setTouched(FALSE); //mark this entry invalid + + //create a new object before delete it from cache. + objectp = gObjectList.processObjectUpdateFromCache(entry, this); + } + + //remove from cache. + killCacheEntry(entry); + + return objectp; +} // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() @@ -956,9 +1455,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; } @@ -1234,12 +1732,118 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) mSimulatorFeatures = sim_features; } -LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +//this is called when the parent is not cacheable. +//move all orphan children out of cache and insert to rendering octree. +void LLViewerRegion::findOrphans(U32 parent_id) +{ + orphan_list_t::iterator iter = mOrphanMap.find(parent_id); + if(iter != mOrphanMap.end()) + { + std::vector<U32>* children = &mOrphanMap[parent_id]; + for(S32 i = 0; i < children->size(); i++) + { + forceToRemoveFromCache((*children)[i], NULL); + } + children->clear(); + mOrphanMap.erase(parent_id); + } +} + +void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) +{ + if(!sVOCacheCullingEnabled) + { + gObjectList.processObjectUpdateFromCache(entry, this); + return; + } + + if(entry != NULL && !entry->getEntry()) + { + entry->setOctreeEntry(NULL); + } + else if(entry->getGroup() != NULL) + { + return; //already in octree, no post processing. + } + + LLVector3 pos; + LLVector3 scale; + LLQuaternion rot; + + //decode spatial info and parent info + U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot); + + if(parent_id > 0) //has parent + { + entry->setParentID(parent_id); + + //1, find the parent in cache + LLVOCacheEntry* parent = getCacheEntry(parent_id); + + //2, parent is not in the cache, put into the orphan list. + if(!parent) + { + mOrphanMap[parent_id].push_back(entry->getLocalID()); + } + else //parent in cache + { + if(!parent->isState(LLVOCacheEntry::INACTIVE)) + { + //parent is visible, so is the child. + addVisibleCacheEntry(entry); + } + else + { + parent->addChild(entry); + } + } + + return; + } + + // + //no parent + // + entry->setBoundingInfo(pos, scale); + if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addToVOCacheTree(entry); + } + + if(!parent_id) //a potential parent + { + //find all children and update their bounding info + orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID()); + if(iter != mOrphanMap.end()) + { + std::vector<U32>* orphans = &mOrphanMap[entry->getLocalID()]; + S32 size = orphans->size(); + for(S32 i = 0; i < size; i++) + { + LLVOCacheEntry* child = getCacheEntry((*orphans)[i]); + if(child) + { + entry->addChild(child); + } + } + orphans->clear(); + mOrphanMap.erase(entry->getLocalID()); + } + } + + return ; +} + +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags) { - U32 local_id = objectp->getLocalID(); - U32 crc = objectp->getCRC(); + eCacheUpdateResult result; + U32 crc; + U32 local_id; - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLViewerObject::unpackU32(&dp, local_id, "LocalID"); + LLViewerObject::unpackU32(&dp, crc, "CRC"); + + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1248,41 +1852,110 @@ 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); - // Update the cache entry - mImpl->mCacheMap.erase(local_id); - delete entry; + //if visible, update it + if(!entry->isState(LLVOCacheEntry::INACTIVE)) + { + replaceCacheEntry(entry, new_entry); + } + else //invisible + { + //remove old entry + killCacheEntry(entry); + entry = new_entry; + + mImpl->mCacheMap[local_id] = entry; + decodeBoundingInfo(entry); + } + + result = CACHE_UPDATE_CHANGED; + } + } + else + { + // we haven't seen this object before + // Create new entry and add to map + result = CACHE_UPDATE_ADDED; entry = new LLVOCacheEntry(local_id, crc, dp); + mImpl->mCacheMap[local_id] = entry; - return CACHE_UPDATE_CHANGED; + + decodeBoundingInfo(entry); } + entry->setUpdateFlags(flags); + + return result; +} - // we haven't seen this object before +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags) +{ + eCacheUpdateResult result = cacheFullUpdate(dp, flags); - // Create new entry and add to map - eCacheUpdateResult result = CACHE_UPDATE_ADDED; - if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) +#if 0 + LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()]; + if(!entry) { - delete mImpl->mCacheMap.begin()->second ; - mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); - result = CACHE_UPDATE_REPLACED; + return result; + } + if(objectp->mDrawable.notNull() && !entry->getEntry()) + { + entry->setOctreeEntry(objectp->mDrawable->getEntry()); + } + if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addActiveCacheEntry(entry); } - entry = new LLVOCacheEntry(local_id, crc, dp); +#endif - mImpl->mCacheMap[local_id] = entry; return result; } +LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) +{ + if(!sVOCacheCullingEnabled) + { + return NULL; + } + + LLVOCacheEntry* entry = getCacheEntry(local_id); + removeFromVOCacheTree(entry); + + return entry; +} + +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; +} + +void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type) +{ +#if 0 + mCacheMissList.insert(CacheMissItem(id, miss_type)); +#else + mCacheMissList.push_back(CacheMissItem(id, miss_type)); +#endif +} + // 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, U32 flags, 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) { @@ -1291,45 +1964,57 @@ 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); + cache_miss_type = CACHE_MISS_TYPE_NONE; + entry->setUpdateFlags(flags); + + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags); + return true; + } + + if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) + { + return true; + } + + decodeBoundingInfo(entry); + return true; } else { // llinfos << "CRC miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_CRC; - mCacheMissCRC.put(local_id); + + addCacheMiss(local_id, CACHE_MISS_TYPE_CRC); } } else { // llinfos << "Cache miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_FULL; - mCacheMissFull.put(local_id); + addCacheMiss(local_id, CACHE_MISS_TYPE_FULL); } - return NULL; + return false; } void LLViewerRegion::addCacheMissFull(const U32 local_id) { - mCacheMissFull.put(local_id); + addCacheMiss(local_id, CACHE_MISS_TYPE_FULL); } void LLViewerRegion::requestCacheMisses() { - S32 full_count = mCacheMissFull.count(); - S32 crc_count = mCacheMissCRC.count(); - if (full_count == 0 && crc_count == 0) return; + if (!mCacheMissList.size()) + { + return; + } LLMessageSystem* msg = gMessageSystem; BOOL start_new_message = TRUE; S32 blocks = 0; - S32 i; - // Send full cache miss updates. For these, we KNOW we don't - // have a viewer object. - for (i = 0; i < full_count; i++) + //send requests for all cache-missed objects + for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter) { if (start_new_message) { @@ -1341,34 +2026,8 @@ void LLViewerRegion::requestCacheMisses() } msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL); - msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]); - blocks++; - - if (blocks >= 255) - { - sendReliableMessage(); - start_new_message = TRUE; - blocks = 0; - } - } - - // Send CRC miss updates. For these, we _might_ have a viewer object, - // but probably not. - for (i = 0; i < crc_count; i++) - { - if (start_new_message) - { - msg->newMessageFast(_PREHASH_RequestMultipleObjects); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - start_new_message = FALSE; - } - - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC); - msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]); + msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType); + msg->addU32Fast(_PREHASH_ID, (*iter).mID); blocks++; if (blocks >= 255) @@ -1384,13 +2043,13 @@ void LLViewerRegion::requestCacheMisses() { sendReliableMessage(); } - mCacheMissFull.reset(); - mCacheMissCRC.reset(); mCacheDirty = TRUE ; // llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; - LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count); + LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size()); LLViewerStatsRecorder::instance().log(0.2f); + + mCacheMissList.clear(); } void LLViewerRegion::dumpCache() @@ -1568,8 +2227,20 @@ void LLViewerRegion::unpackRegionHandshake() msg->addUUID("AgentID", gAgent.getID()); msg->addUUID("SessionID", gAgent.getSessionID()); msg->nextBlock("RegionInfo"); - msg->addU32("Flags", 0x0 ); + + U32 flags = 0; + if(sVOCacheCullingEnabled) + { + flags = 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. + if(mImpl->mCacheMap.empty()) + { + flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. + } + } + msg->addU32("Flags", flags ); msg->sendReliable(host); + + mRegionTimer.reset(); //reset region timer. } void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) @@ -1587,7 +2258,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("EventQueueGet"); if (gSavedSettings.getBOOL("UseHTTPInventory")) - { + { capabilityNames.append("FetchLib2"); capabilityNames.append("FetchLibDescendents2"); capabilityNames.append("FetchInventory2"); @@ -1606,7 +2277,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"); @@ -1646,7 +2317,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ViewerMetrics"); capabilityNames.append("ViewerStartAuction"); capabilityNames.append("ViewerStats"); - + // Please add new capabilities alphabetically to reduce // merge conflicts. } @@ -1654,7 +2325,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) void LLViewerRegion::setSeedCapability(const std::string& url) { if (getCapability("Seed") == url) - { + { //llwarns << "Ignoring duplicate seed capability" << llendl; //Instead of just returning we build up a second set of seed caps and compare them //to the "original" seed cap received and determine why there is problem! @@ -1864,9 +2535,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 b5fe4677b7..b39bac62bc 100755 --- 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 { @@ -85,6 +87,7 @@ public: PARTITION_VOLUME, PARTITION_BRIDGE, PARTITION_HUD_PARTICLE, + PARTITION_VO_CACHE, PARTITION_NONE, NUM_PARTITIONS } eObjectPartitions; @@ -223,6 +226,11 @@ 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 // Like idleUpdate, but forces everything to complete regardless of // how long it takes. @@ -315,10 +323,16 @@ 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(LLDataPackerBinaryBuffer &dp, U32 flags); + eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); + LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); + LLVOCacheEntry* getCacheEntry(U32 local_id); + bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type); void requestCacheMisses(); void addCacheMissFull(const U32 local_id); + //remove from object cache if the object receives a full-update or terse update + LLViewerObject* forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp); + void findOrphans(U32 parent_id); void dumpCache(); @@ -332,7 +346,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; @@ -342,7 +358,21 @@ public: void getNeighboringRegionsStatus( std::vector<S32>& regions ); const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } LLViewerRegionImpl * getRegionImplNC() { return mImpl; } - + +private: + void addToVOCacheTree(LLVOCacheEntry* entry); + LLViewerObject* addNewObject(LLVOCacheEntry* entry); + void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list); + 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 + + void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type); + void decodeBoundingInfo(LLVOCacheEntry* entry); public: struct CompareDistance { @@ -362,9 +392,8 @@ public: LLWind mWind; LLViewerParcelOverlay *mParcelOverlay; - LLStat mBitStat; - LLStat mPacketsStat; - LLStat mPacketsLostStat; + F32 mBitsReceived; + F32 mPacketsReceived; LLMatrix4 mRenderMatrix; @@ -376,8 +405,10 @@ public: LLDynamicArray<U32> mMapAvatars; LLDynamicArray<LLUUID> mMapAvatarIDs; + static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not. private: LLViewerRegionImpl * mImpl; + LLFrameTimer mRegionTimer; F32 mWidth; // Width of region on a side (meters) U64 mHandle; @@ -421,18 +452,29 @@ 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; + typedef std::map<U32, std::vector<U32> > orphan_list_t; + orphan_list_t mOrphanMap; - bool mAlive; // can become false if circuit disconnects - bool mCapabilitiesReceived; - caps_received_signal_t mCapabilitiesReceivedSignal; + class CacheMissItem + { + public: + CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type){} + + U32 mID; //local object id + LLViewerRegion::eCacheMissType mType; //cache miss type - BOOL mReleaseNotesRequested; + typedef std::list<CacheMissItem> cache_miss_list_t; + }; + CacheMissItem::cache_miss_list_t mCacheMissList; + caps_received_signal_t mCapabilitiesReceivedSignal; LLSD mSimulatorFeatures; }; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ba9818946c..78775c7205 100755 --- 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,38 @@ 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); + gTwoTextureCompareProgram.uniform1i("dither_tex", 2); + } + } + + 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 e3d28f2f5c..24f9111d3d 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -232,6 +232,10 @@ extern LLGLSLShader gClipProgram; //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; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 35bba4184e..be477f7f9a 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -61,363 +61,242 @@ #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("framesrendered"), + 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"), + 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::Kibibits> 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> 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::SampleStatHandle<> 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"), + 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; -}; +static LLTrace::SampleStatHandle<S64> CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); -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::SampleStatHandle<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"); -}; + +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); -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; - } +LLTrace::SampleStatHandle<LLTrace::Milliseconds> FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), + FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), + SIM_PING("simpingstat"); + +LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); + +LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"); - if (LLTimer::knownBadTimer()) - { - mStats[ST_HAS_BAD_TIMER] = 1.0; - } +LLTrace::EventStatHandle<LLTrace::Milliseconds> 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"); - mAgentPositionSnaps.reset(); -} +LLTrace::EventStatHandle<LLTrace::Seconds> AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearance"), + 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"); -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); + record(LLStatViewer::FPS_2_TIME, time_diff_seconds); } if (time_diff >= 0.125) { - incStat(ST_FPS_8_SECONDS, time_diff); + record(LLStatViewer::FPS_8_TIME, time_diff_seconds); } if (time_diff >= 0.1) { - incStat(ST_FPS_10_SECONDS, time_diff); + record(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 +void LLViewerStats::addToMessage(LLSD &body) { 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 +305,68 @@ 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); + record(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds); } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); + record(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds); } else if (LLFloaterReg::instanceVisible("build")) { - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); + record(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")); - - stats.setStat(LLViewerStats::ST_FRAME_SECS, 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")); + + LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); + + 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, gSavedSettings.getBOOL("UseChatBubbles")); + + typedef LLInstanceTracker<LLTrace::TraceType<LLTrace::TimeBlockAccumulator>, std::string> trace_type_t; + + LLUnit<LLUnits::Seconds, F64> idle_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Idle")); + LLUnit<LLUnits::Seconds, F64> network_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Network")); + + record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Frame"))); + record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs); + record(LLStatViewer::NETWORK_STACKTIME, network_secs); + record(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Update Images"))); + record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Sort Draw State"))); + record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Render 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)); + } + + if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS)) + { + sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS)); } + add(LLStatViewer::FPS, 1); - stats.mFPSStat.addValue(1); 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 +387,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 +403,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 +552,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::Kibibytes(gTotalWorldData).value(); + download["object_kbytes"] = LLTrace::Kibibytes(gTotalObjectData).value(); + download["texture_kbytes"] = LLTrace::Kibibytes(gTotalTextureData).value(); download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; LLSD &in = body["stats"]["net"]["in"]; @@ -775,7 +659,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 6b2461be41..bfba7bca9a 100755 --- 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,171 +27,187 @@ #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::SampleStatHandle<T>, public SimMeasurementSampler +{ + SimMeasurement(const char* name, const char* description, ESimStatID stat_id) + : LLTrace::SampleStatHandle<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, + 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::Kibibits> KBIT, + LAYERS_KBIT, + OBJECT_KBIT, + ASSET_KBIT, + TEXTURE_KBIT, + ACTUAL_IN_KBIT, + ACTUAL_OUT_KBIT; + +extern LLTrace::CountStatHandle<LLTrace::Seconds> 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::SampleStatHandle<> 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, + PENDING_VFS_OPERATIONS, + PACKETS_LOST_PERCENT, + WINDOW_WIDTH, + WINDOW_HEIGHT; + +extern LLTrace::SampleStatHandle<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::SampleStatHandle<LLTrace::Milliseconds> FRAMETIME_JITTER, + FRAMETIME_SLEW, + SIM_PING; + +extern LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP; + +extern LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY; + +extern LLTrace::EventStatHandle<LLTrace::Milliseconds> REGION_CROSSING_TIME, + FRAME_STACKTIME, + UPDATE_STACKTIME, + NETWORK_STACKTIME, + IMAGE_STACKTIME, + REBUILD_STACKTIME, + RENDER_STACKTIME; + +extern LLTrace::EventStatHandle<LLTrace::Seconds> AVATAR_EDIT_TIME, + TOOLBOX_TIME, + MOUSELOOK_TIME, + FPS_10_TIME, + FPS_8_TIME, + FPS_2_TIME; + +} 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; + void addToMessage(LLSD &body); struct StatsAccumulator { @@ -263,7 +279,7 @@ public: mCountOfNextUpdatesToIgnore = 0; } - inline LLSD getData() const + inline LLSD asLLSD() const { LLSD data; data["mean"] = getMean(); @@ -275,8 +291,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; @@ -294,16 +308,18 @@ 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); phase_map_t::iterator begin() { return mPhaseMap.begin(); } phase_map_t::iterator end() { return mPhaseMap.end(); } }; + 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 }; @@ -315,7 +331,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 f9a725547f..acd8f6a29c 100755 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -224,15 +224,15 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) } } 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 diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 777e1f9c76..4cd4375146 100755 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -364,7 +364,7 @@ void LLViewerTexLayerSetBuffer::doUpload() { LLViewerTexLayerSet* layer_set = getViewerTexLayerSet(); LL_DEBUGS("Avatar") << "Uploading baked " << layer_set->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/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index eb6c453e76..e0a88bfad6 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -65,6 +65,11 @@ #include "lltexturecache.h" /////////////////////////////////////////////////////////////////////////////// +// extern +const LLUnit<LLUnits::Mibibytes, S32> gMinVideoRam = 32; +const LLUnit<LLUnits::Mibibytes, S32> gMaxVideoRam = 512; + + // statics LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL; LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL; @@ -83,11 +88,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::Mibibytes, S32> LLViewerTexture::sMaxBoundTextureMem = 0; +LLUnit<LLUnits::Mibibytes, 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 @@ -277,7 +282,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture( } LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( - const std::string& filename, + const std::string& filename, FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, @@ -290,7 +295,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( } //static -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, @@ -397,7 +402,7 @@ void LLViewerTextureManager::init() LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); LLViewerTexture::initClass() ; - + // Create a texture manager bridge. gTextureManagerBridgep = new LLViewerTextureManagerBridge; @@ -527,17 +532,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 @@ -553,8 +558,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 @@ -572,8 +577,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 @@ -676,6 +681,30 @@ void LLViewerTexture::setBoostLevel(S32 level) { mSelectedTime = gFrameTimeSeconds; } + +} + +bool LLViewerTexture::isActiveFetching() +{ + return false; +} + +bool LLViewerTexture::bindDebugImage(const S32 stage) +{ + if (stage < 0) return false; + + bool res = true; + if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get())) + { + res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep); + } + + if(!res) + { + return bindDefaultImage(stage); + } + + return res; } bool LLViewerTexture::bindDefaultImage(S32 stage) @@ -1177,7 +1206,7 @@ void LLViewerFetchedTexture::destroyTexture() { return ; } - + //LL_DEBUGS("Avatar") << mID << llendl; destroyGLTexture() ; mFullyLoaded = FALSE ; @@ -1704,6 +1733,13 @@ bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) return true; } +bool LLViewerFetchedTexture::isActiveFetching() +{ + static LLCachedControl<bool> monitor_enabled(gSavedSettings,"DebugShowTextureInfo"); + + return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE. +} + bool LLViewerFetchedTexture::updateFetch() { static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); @@ -3064,13 +3100,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 f2e1a90713..e939731cf2 100755 --- 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::Mibibytes, S32> gMinVideoRam; +extern const LLUnit<LLUnits::Mibibytes, S32> gMaxVideoRam; class LLFace; class LLImageGL ; @@ -124,7 +125,9 @@ public: virtual void dump(); // debug info to llinfos /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; + /*virtual*/ bool bindDebugImage(const S32 stage = 0) ; /*virtual*/ void forceImmediateUpdate() ; + /*virtual*/ bool isActiveFetching(); /*virtual*/ const LLUUID& getID() const { return mID; } void setBoostLevel(S32 level); @@ -202,11 +205,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::Mibibytes, S32> sMaxBoundTextureMem; + static LLUnit<LLUnits::Mibibytes, S32> sMaxTotalTextureMem; + static LLUnit<LLUnits::Bytes, S32> sMaxDesiredTextureMem ; static S8 sCameraMovingDiscardBias; static F32 sCameraMovingBias; static S32 sMaxSculptRez ; @@ -395,12 +398,15 @@ public: void loadFromFastCache(); void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } bool isInFastCacheList() { return mInFastCacheList; } + + /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline. + protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; private: - void init(bool firstinit) ; + void init(bool firstinit) ; void cleanup() ; void saveRawImage() ; @@ -447,7 +453,7 @@ protected: S8 mHasFetcher; // We've made a fecth request S8 mIsFetching; // Fetch request is active bool mCanUseHTTP ; //This texture can be fetched through http if true. - + FTType mFTType; // What category of image is this - map tile, server bake, etc? mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d2af48f528..f3b3a6086d 100755 --- 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" - +#include "llstartup.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"); @@ -324,7 +317,7 @@ void LLViewerTextureList::restoreGL() /////////////////////////////////////////////////////////////////////////////// -LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, @@ -376,7 +369,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& } LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id); - + if (!imagep.isNull()) { LLViewerFetchedTexture *texture = imagep.get(); @@ -432,7 +425,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& } -LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, @@ -475,7 +468,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, { llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl; } - + } if (imagep.isNull()) { @@ -488,7 +481,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, } //when this function is called, there is no such texture in the gTextureList with image_id. -LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, @@ -649,9 +642,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) { @@ -665,14 +660,17 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = FALSE; - LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); + LLAppViewer::getTextureFetch()->setTextureBandwidth(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_KBIT)); - 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)); + { + 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 @@ -753,8 +751,18 @@ 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); + F32 lazy_flush_timeout = 30.f; // stop decoding + F32 max_inactive_time = 20.f; // actually delete + S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference + if(LLStartUp::getStartupState() < STATE_STARTED) + { + //do not remove pre-fetched images if viewer does not finish logging in. + lazy_flush_timeout = 30000.f; + max_inactive_time = 20000.f; + } + + 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.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()) @@ -776,14 +784,10 @@ void LLViewerTextureList::updateImagesDecodePriorities() // // Flush formatted images using a lazy flush // - const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding - const F32 MAX_INACTIVE_TIME = 20.f; // actually delete - S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference - S32 num_refs = imagep->getNumRefs(); if (num_refs == min_refs) { - if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > LAZY_FLUSH_TIMEOUT) + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) { // Remove the unused image from the image list deleteImage(imagep); @@ -795,7 +799,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() { if(imagep->hasSavedRawImage()) { - if(imagep->getElapsedLastReferencedSavedRawImageTime() > MAX_INACTIVE_TIME) + if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time) { imagep->destroySavedRawImage() ; } @@ -812,7 +816,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() } else if(imagep->isInactive()) { - if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time) { imagep->setDeletionCandidate() ; } @@ -988,11 +992,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 @@ -1229,7 +1233,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 @@ -1279,7 +1283,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; } @@ -1367,8 +1371,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; @@ -1440,8 +1444,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 136042620d..5b6e927e32 100755 --- 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,11 +30,11 @@ #include "lluuid.h" //#include "message.h" #include "llgl.h" -#include "llstat.h" #include "llviewertexture.h" #include "llui.h" #include <list> #include <set> +#include "lluiimage.h" const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; @@ -204,17 +204,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 100755 --- 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/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index e8425dc76a..c7e97cfe94 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -30,6 +30,7 @@ #include "llagentcamera.h" #include "llagentwearables.h" #include "llfloatersidepanelcontainer.h" +#include "lllocaltextureobject.h" #include "llnotificationsutil.h" #include "llsidepanelappearance.h" #include "lltextureentry.h" diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fe4d5b3e4d..349849a267 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -40,6 +40,7 @@ #include "llagentcamera.h" #include "llcommunicationchannel.h" #include "llfloaterreg.h" +#include "llhudicon.h" #include "llmeshrepository.h" #include "llnotificationhandler.h" #include "llpanellogin.h" @@ -81,7 +82,6 @@ #include "llmediaentry.h" #include "llurldispatcher.h" #include "raytrace.h" -#include "llstat.h" // newview includes #include "llagent.h" @@ -253,6 +253,9 @@ std::string LLViewerWindow::sSnapshotDir; std::string LLViewerWindow::sMovieBaseName; +LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); + + class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole> { public: @@ -457,6 +460,8 @@ public: if (gSavedSettings.getBOOL("DebugShowRenderInfo")) { + LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); + if (gPipeline.getUseVertexShaders() == 0) { addText(xpos, ypos, "Shaders Disabled"); @@ -562,7 +567,7 @@ public: addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount)); ypos += y_inc; - addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount)); + addText(xpos, ypos, llformat("%d Render Calls", last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize))); ypos += y_inc; addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); @@ -577,15 +582,10 @@ public: gPipeline.mTextureMatrixOps = 0; gPipeline.mMatrixOpCount = 0; - if (gPipeline.mBatchCount > 0) - { - addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize, - gPipeline.mTrianglesDrawn/gPipeline.mBatchCount)); - - gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize; - gPipeline.mMaxBatchSize = 0; - gPipeline.mBatchCount = 0; - } + if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0) + { + addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", last_frame_recording.getMin(LLPipeline::sStatBatchSize), last_frame_recording.getMax(LLPipeline::sStatBatchSize), last_frame_recording.getMean(LLPipeline::sStatBatchSize))); + } ypos += y_inc; addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); @@ -596,9 +596,9 @@ public: ypos += y_inc; - if (!LLSpatialGroup::sPendingQueries.empty()) + if (!LLOcclusionCullingGroup::sPendingQueries.empty()) { - addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size())); + addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size())); ypos += y_inc; } @@ -738,7 +738,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::Mibibytes, F32>(gTotalTextureBytesPerBoostLevel[i]).value())); ypos += y_inc; } } @@ -1409,10 +1409,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); @@ -1547,8 +1548,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 @@ -2089,8 +2089,6 @@ LLViewerWindow::~LLViewerWindow() delete mDebugText; mDebugText = NULL; - - delete mMouseVelocityStat; } @@ -2201,8 +2199,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(); } @@ -2796,11 +2794,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; @@ -3268,8 +3267,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); @@ -3280,7 +3279,7 @@ void LLViewerWindow::updateMouseDelta() mouse_vel.setVec((F32) dx, (F32) dy); } - mMouseVelocityStat->addValue(mouse_vel.magVec()); + sample(sMouseVelocityStat, mouse_vel.magVec()); } void LLViewerWindow::updateKeyboardFocus() @@ -4771,7 +4770,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; } } @@ -5272,8 +5271,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 b33488fd78..e0943d9825 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -45,12 +45,12 @@ #include "llnotifications.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; @@ -251,7 +251,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::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -432,7 +432,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; @@ -487,6 +486,8 @@ private: // Object temporarily hovered over while dragging LLPointer<LLViewerObject> mDragHoveredObject; + + static LLTrace::SampleStatHandle<> sMouseVelocityStat; }; // diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 06fb23b84b..d4c31fd4b0 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -51,7 +51,6 @@ #include "llpolyskeletaldistortion.h" #include "lleditingmotion.h" #include "llemote.h" -//#include "llfirstuse.h" #include "llfloatertools.h" #include "llheadrotmotion.h" #include "llhudeffecttrail.h" @@ -81,6 +80,7 @@ #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "llviewershadermgr.h" #include "llviewerstats.h" #include "llviewerwearable.h" @@ -100,6 +100,7 @@ #include "lldebugmessagebox.h" #include "llsdutil.h" +#include "llscenemonitor.h" #include "llsdserialize.h" extern F32 SPEED_ADJUST_MAX; @@ -250,7 +251,7 @@ struct LLAppearanceMessageContents std::vector<F32> mParamWeights; std::vector<LLVisualParam*> mParams; }; - + struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint> { Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone; @@ -769,6 +770,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 @@ -1196,7 +1202,7 @@ void LLVOAvatar::initInstance(void) registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create ); registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create ); } - + LLAvatarAppearance::initInstance(); // preload specific motions here @@ -1542,7 +1548,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector return hit; } - + LLVOAvatar* LLVOAvatar::asAvatar() { return this; @@ -2446,7 +2452,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); @@ -2469,11 +2475,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); @@ -2541,7 +2547,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) mVisibleChat = visible_chat; new_name = TRUE; } - + if (sRenderGroupTitles != mRenderGroupTitles) { mRenderGroupTitles = sRenderGroupTitles; @@ -2746,7 +2752,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) mNameText->setFont(LLFontGL::getFontSansSerif()); mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - + std::deque<LLChat>::iterator chat_iter = mChats.begin(); mNameText->clearString(); @@ -2899,7 +2905,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) mTargetRootToHeadOffset = head_offset; } - mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f)); + mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f)); LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot); name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); @@ -3364,7 +3370,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) { @@ -3707,7 +3713,7 @@ bool LLVOAvatar::shouldAlphaMask() //----------------------------------------------------------------------------- // renderSkinned() //----------------------------------------------------------------------------- -U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) +U32 LLVOAvatar::renderSkinned() { U32 num_indices = 0; @@ -3868,75 +3874,62 @@ 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) + bool should_alpha_mask = shouldAlphaMask(); + LLGLState test(GL_ALPHA_TEST, should_alpha_mask); + + if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) { - - bool should_alpha_mask = shouldAlphaMask(); - LLGLState test(GL_ALPHA_TEST, should_alpha_mask); - - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - } - - BOOL first_pass = TRUE; - if (!LLDrawPoolAvatar::sSkipOpaque) + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + } + + BOOL first_pass = TRUE; + if (!LLDrawPoolAvatar::sSkipOpaque) + { + if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { - if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) + if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) { - if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) + LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); + if (head_mesh) { - LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); - if (head_mesh) - { - num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); - } - first_pass = FALSE; - } - } - if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) - { - LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); - if (upper_mesh) - { - num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } - - if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) - { - LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); - if (lower_mesh) - { - num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); } first_pass = FALSE; } } - - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) + if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); + if (upper_mesh) + { + num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; } - - if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) + + if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) { - LLGLState blend(GL_BLEND, !mIsDummy); - LLGLState test(GL_ALPHA_TEST, !mIsDummy); - num_indices += renderTransparent(first_pass); + LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); + if (lower_mesh) + { + num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; } } - LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; + if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) + { + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } - //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; - - //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f); + if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) + { + LLGLState blend(GL_BLEND, !mIsDummy); + LLGLState test(GL_ALPHA_TEST, !mIsDummy); + num_indices += renderTransparent(first_pass); + } return num_indices; } @@ -5108,7 +5101,7 @@ BOOL LLVOAvatar::loadSkeletonNode () { return FALSE; } - + // ATTACHMENTS { LLAvatarXmlInfo::attachment_info_list_t::iterator iter; @@ -6082,7 +6075,7 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse record["grid_y"] = LLSD::Integer(grid_y); record["is_using_server_bakes"] = ((bool) isUsingServerBakes()); record["is_self"] = isSelf(); - + if (isAgentAvatarValid()) { gAgentAvatarp->addMetricsTimerRecord(record); @@ -6290,11 +6283,11 @@ void LLVOAvatar::updateMeshTextures() use_lkg_baked_layer[i], last_id_string.c_str()); } - + for (U32 i=0; i < mBakedTextureDatas.size(); i++) { debugColorizeSubMeshes(i, LLColor4::white); - + LLViewerTexLayerSet* layerset = getTexLayerSet(i); if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) { @@ -6754,7 +6747,7 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) // param_location_name(vparam->getParamLocation()).c_str() ); } - + void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, const LLAppearanceMessageContents& contents) @@ -6821,7 +6814,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe // For future use: //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); } - + // Parse visual params, if any. S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing @@ -7245,7 +7238,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu LLUUID *avatar_idp = (LLUUID *)userdata; LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); - + if (selfp) { LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; @@ -7559,14 +7552,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(); } } } @@ -7619,7 +7612,7 @@ void LLVOAvatar::setIsUsingServerBakes(BOOL newval) // virtual void LLVOAvatar::removeMissingBakedTextures() -{ +{ } //virtual diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 85f6f25009..c814d4c129 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -33,7 +33,7 @@ #include <string> #include <vector> -#include <boost/signals2.hpp> +#include <boost/signals2/trackable.hpp> #include "imageids.h" // IMG_INVISIBLE #include "llavatarappearance.h" @@ -74,6 +74,7 @@ struct LLVOAvatarChildJoint; //class LLViewerJoint; struct LLAppearanceMessageContents; struct LLVOAvatarSkeletonInfo; +class LLViewerJointMesh; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar @@ -372,7 +373,7 @@ public: bool isVisuallyMuted() const; U32 renderRigid(); - U32 renderSkinned(EAvatarRenderPass pass); + U32 renderSkinned(); F32 getLastSkinTime() { return mLastSkinTime; } U32 renderTransparent(BOOL first_pass); void renderCollisionVolumes(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d54eb5f040..9ab910f7fd 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -43,6 +43,7 @@ #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llinventoryfunctions.h" +#include "lllocaltextureobject.h" #include "llnotificationsutil.h" #include "llselectmgr.h" #include "lltoolgrab.h" // for needsRenderBeam @@ -789,7 +790,10 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, updateMeshTextures(); // unpack the texture UUIDs to the texture slots - retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); + if(mesgsys != NULL) + { + retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) 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++) @@ -896,17 +900,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(); + record(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) { @@ -2233,7 +2231,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; } @@ -2351,7 +2349,7 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records, accum_it != accum.end(); ++accum_it) { LLSD out_record = accum_it->first; - out_record["stats"] = accum_it->second.getData(); + out_record["stats"] = accum_it->second.asLLSD(); result.append(out_record); } return result; @@ -2586,7 +2584,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe { F32 desired_pixels; desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); - + imagep->setBoostLevel(getAvatarBoostLevel()); imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; imagep->resetTextureStats(); @@ -2851,7 +2849,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); } } } @@ -2887,7 +2885,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 { @@ -3076,7 +3074,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..5e2d2efc5e 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -29,6 +29,12 @@ #include "llerror.h" #include "llregionhandle.h" #include "llviewercontrol.h" +#include "llviewerobjectlist.h" +#include "lldrawable.h" +#include "llviewerregion.h" +#include "pipeline.h" + +LLTrace::MemStatHandle LLVOCachePartition::sMemStat("LLVOCachePartition"); BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { @@ -46,12 +52,18 @@ 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), + mUpdateFlags(-1), mHitCount(0), mDupeCount(0), - mCRCChangeCount(0) + mCRCChangeCount(0), + mState(INACTIVE), + mMinFrameRange(64), + mSceneContrib(0.f), + mTouched(TRUE), + mParentID(0) { mBuffer = new U8[dp.getBufferSize()]; mDP.assignBuffer(mBuffer, dp.getBufferSize()); @@ -59,24 +71,39 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer & } LLVOCacheEntry::LLVOCacheEntry() - : + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(0), mCRC(0), + mUpdateFlags(-1), mHitCount(0), mDupeCount(0), mCRCChangeCount(0), - mBuffer(NULL) + mBuffer(NULL), + mState(INACTIVE), + mMinFrameRange(64), + mSceneContrib(0.f), + mTouched(TRUE), + mParentID(0) { mDP.assignBuffer(mBuffer, 0); } LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) - : mBuffer(NULL) + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), + mBuffer(NULL), + mUpdateFlags(-1), + mState(INACTIVE), + mMinFrameRange(64), + mSceneContrib(0.f), + mTouched(FALSE), + mParentID(0) { S32 size = -1; BOOL success; mDP.assignBuffer(mBuffer, 0); + setOctreeEntry(NULL); + success = check_read(apr_file, &mLocalID, sizeof(U32)); if(success) { @@ -132,32 +159,88 @@ 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; + LLViewerObject::unpackUUID(&mDP, fullid, "ID"); + + LLViewerObject* obj = gObjectList.findObject(fullid); + if(obj && obj->mDrawable) + { + entry = obj->mDrawable->getEntry(); + } + } -// New CRC means the object has changed. -void LLVOCacheEntry::assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp) + LLViewerOctreeEntryData::setOctreeEntry(entry); +} + +void LLVOCacheEntry::moveTo(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)); + } + mChildrenList.clear(); +} - mDP.freeBuffer(); - mBuffer = new U8[dp.getBufferSize()]; - mDP.assignBuffer(mBuffer, dp.getBufferSize()); - mDP = dp; +void LLVOCacheEntry::setState(U32 state) +{ + mState = state; + + if(getState() == ACTIVE) + { + const S32 MIN_REAVTIVE_INTERVAL = 32; + U32 last_visible = getVisible(); + + setVisible(); + + if(getVisible() - last_visible < MIN_REAVTIVE_INTERVAL + mMinFrameRange) + { + mMinFrameRange = llmin(mMinFrameRange * 2, 2048); + } + else + { + mMinFrameRange = 64; //reset + } } } +//virtual +S32 LLVOCacheEntry::getMinFrameRange()const +{ + return mMinFrameRange; +} + +void LLVOCacheEntry::addChild(LLVOCacheEntry* entry) +{ + llassert(entry != NULL); + + mChildrenList.push_back(entry); +} + LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc) { if ( (mCRC != crc) @@ -170,9 +253,20 @@ 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() { + setTouched(); mHitCount++; } @@ -189,6 +283,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) @@ -221,49 +320,183 @@ 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(); +} + +void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scale) +{ + LLVector4a center, newMin, newMax; + center.load3(pos.mV); + LLVector4a size; + size.load3(scale.mV); + newMin.setSub(center, size); + newMax.setAdd(center, size); + + setPositionGroup(center); + setSpatialExtents(newMin, newMax); + setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f)); +} + //------------------------------------------------------------------- -//LLVOCache +//LLVOCachePartition //------------------------------------------------------------------- -// Format string used to construct filename for the object cache -static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) +{ + mLODPeriod = 16; + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + + new LLOcclusionCullingGroup(mOctree, this); +} -const U32 MAX_NUM_OBJECT_ENTRIES = 128 ; -const U32 MIN_ENTRIES_TO_PURGE = 16 ; -const U32 INVALID_TIME = 0 ; -const char* object_cache_dirname = "objectcache"; -const char* header_filename = "object.cache"; +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ + llassert(entry->hasVOCacheEntry()); -LLVOCache* LLVOCache::sInstance = NULL; + mOctree->insert(entry); +} + +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ + entry->getVOCacheEntry()->setGroup(NULL); -//static -LLVOCache* LLVOCache::getInstance() -{ - if(!sInstance) + llassert(!entry->getGroup()); +} + +class LLVOCacheOctreeCull : public LLViewerOctreeCull +{ +public: + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift, bool use_object_cache_occlusion) + : LLViewerOctreeCull(camera), + mRegionp(regionp) { - sInstance = new LLVOCache() ; + mLocalShift = shift; + mUseObjectCacheOcclusion = (use_object_cache_occlusion && LLPipeline::sUseOcclusion); } - return sInstance ; -} -//static -BOOL LLVOCache::hasInstance() -{ - return sInstance != NULL ; -} + virtual bool earlyFail(LLviewerOctreeGroup* base_group) + { + if( mUseObjectCacheOcclusion && + base_group->getOctreeNode()->getParent()) //never occlusion cull the root node + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + if(group->needsUpdate()) + { + return false; //needs to issue new occlusion culling check. + } + + group->checkOcclusion(); + + if (group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + return true; + } + } + + return false; + } + + 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; + } -//static -void LLVOCache::destroyClass() + virtual void processGroup(LLviewerOctreeGroup* base_group) + { + if(mUseObjectCacheOcclusion && base_group->getOctreeNode()->getParent()) + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) + { + ((LLOcclusionCullingGroup*)group)->doOcclusion(mCamera); + group->setVisible(); + return; //wait for occlusion culling results + } + } + mRegionp->addVisibleGroup(base_group); + } + +private: + LLViewerRegion* mRegionp; + LLVector3 mLocalShift; //shift vector from agent space to local region space. + bool mUseObjectCacheOcclusion; +}; + +S32 LLVOCachePartition::cull(LLCamera &camera) { - if(sInstance) + static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion"); + + if(!LLViewerRegion::sVOCacheCullingEnabled) { - delete sInstance ; - sInstance = NULL ; + return 0; } + + ((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound(); + + //localize the camera + LLVector3 region_agent = mRegionp->getOriginAgent(); + camera.calcRegionFrustumPlanes(region_agent); + + LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion); + culler.traverse(mOctree); + + return 0; } +//------------------------------------------------------------------- +//LLVOCache +//------------------------------------------------------------------- +// Format string used to construct filename for the object cache +static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; + +const U32 MAX_NUM_OBJECT_ENTRIES = 128 ; +const U32 MIN_ENTRIES_TO_PURGE = 16 ; +const U32 INVALID_TIME = 0 ; +const char* object_cache_dirname = "objectcache"; +const char* header_filename = "object.cache"; + + LLVOCache::LLVOCache(): - mInitialized(FALSE), - mReadOnly(TRUE), + mInitialized(false), + mReadOnly(true), mNumEntries(0), mCacheSize(1) { @@ -300,7 +533,7 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) llwarns << "Cache already initialized." << llendl; return ; } - mInitialized = TRUE ; + mInitialized = true; setDirNames(location); if (!mReadOnly) @@ -325,13 +558,19 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) } } -void LLVOCache::removeCache(ELLPath location) +void LLVOCache::removeCache(ELLPath location, bool started) { + if(started) + { + removeCache(); + return; + } + if(mReadOnly) { llwarns << "Not removing cache at " << location << ": Cache is currently in read-only mode." << llendl; return ; - } + } llinfos << "about to remove the object cache due to settings." << llendl ; @@ -342,22 +581,25 @@ void LLVOCache::removeCache(ELLPath location) LLFile::rmdir(cache_dir); clearCacheInMemory(); - mInitialized = FALSE ; + mInitialized = false; } void LLVOCache::removeCache() { - llassert_always(mInitialized) ; + if(!mInitialized) + { + //OK to remove cache even it is not initialized. + llwarns << "Object cache is not initialized yet." << llendl; + } + if(mReadOnly) { llwarns << "Not clearing object cache: Cache is currently in read-only mode." << llendl; return ; } - llinfos << "about to remove the object cache due to some error." << llendl ; - std::string mask = "*"; - llinfos << "Removing cache at " << mObjectCacheDirName << llendl; + llinfos << "Removing object cache at " << mObjectCacheDirName << llendl; gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask); clearCacheInMemory() ; @@ -366,23 +608,23 @@ void LLVOCache::removeCache() void LLVOCache::removeEntry(HeaderEntryInfo* entry) { - llassert_always(mInitialized) ; + llassert_always(mInitialized); if(mReadOnly) { - return ; + return; } if(!entry) { - return ; + return; } - header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry) ; + header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry); if(iter != mHeaderEntryQueue.end()) { - mHandleEntryMap.erase(entry->mHandle) ; - mHeaderEntryQueue.erase(iter) ; - removeFromCache(entry) ; - delete entry ; + mHandleEntryMap.erase(entry->mHandle); + mHeaderEntryQueue.erase(iter); + removeFromCache(entry); + delete entry; mNumEntries = mHandleEntryMap.size() ; } @@ -625,11 +867,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 ; } @@ -665,7 +906,7 @@ void LLVOCache::purgeEntries(U32 size) mNumEntries = mHandleEntryMap.size() ; } -void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) +void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled) { if(!mEnabled) { @@ -738,7 +979,10 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry: for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter) { - success = iter->second->writeToFile(&apr_file) ; + if(!removal_enabled || iter->second->isTouched()) + { + success = iter->second->writeToFile(&apr_file) ; + } } } } diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 14e3b4c793..e46fec9dc3 100755 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -29,51 +29,138 @@ #include "lluuid.h" #include "lldatapacker.h" -#include "lldlinked.h" #include "lldir.h" - +#include "llvieweroctree.h" +#include "llapr.h" //--------------------------------------------------------------------------- // Cache entries class LLVOCacheEntry; +class LLCamera; -class LLVOCacheEntry +class LLVOCacheEntry : public LLViewerOctreeEntryData { public: + enum //low 16-bit state + { + 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. + }; + + 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;} + bool isState(U32 state) {return mState == state;} + bool hasState(U32 state) {return mState & state;} + U32 getState() const {return mState;} + U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mCRC; } S32 getHitCount() const { return mHitCount; } S32 getCRCChangeCount() const { return mCRCChangeCount; } + S32 getMinFrameRange()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 moveTo(LLVOCacheEntry* new_entry); //copy variables + /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry); + + void setParentID(U32 id) {mParentID = id;} + U32 getParentID() const {return mParentID;} + + void addChild(LLVOCacheEntry* entry); + LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];} + S32 getNumOfChildren() {return mChildrenList.size();} + void clearChildrenList() {mChildrenList.clear();} + + //called from processing object update message + void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); + + void setTouched(BOOL touched = TRUE) {mTouched = touched;} + BOOL isTouched() const {return mTouched;} + + void setUpdateFlags(U32 flags) {mUpdateFlags = flags;} + U32 getUpdateFlags() const {return mUpdateFlags;} 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; + U32 mParentID; U32 mCRC; + U32 mUpdateFlags; //receive from sim S32 mHitCount; S32 mDupeCount; S32 mCRCChangeCount; LLDataPackerBinaryBuffer mDP; U8 *mBuffer; + + F32 mSceneContrib; //projected scene contributuion of this object. + S32 mMinFrameRange; + U32 mState; //high 16 bits reserved for special use. + std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set. + + BOOL mTouched; //if set, this entry is valid, otherwise it is invalid. +}; + +class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTrackable<LLVOCachePartition> +{ +public: + LLVOCachePartition(LLViewerRegion* regionp); + + void addEntry(LLViewerOctreeEntry* entry); + void removeEntry(LLViewerOctreeEntry* entry); + /*virtual*/ S32 cull(LLCamera &camera); + + static LLTrace::MemStatHandle sMemStat; }; // //Note: LLVOCache is not thread-safe // -class LLVOCache +class LLVOCache : public LLSingleton<LLVOCache> { private: struct HeaderEntryInfo @@ -106,19 +193,20 @@ private: typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t; typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t; private: + friend class LLSingleton<LLVOCache>; LLVOCache() ; public: ~LLVOCache() ; void initCache(ELLPath location, U32 size, U32 cache_version) ; - void removeCache(ELLPath location) ; + void removeCache(ELLPath location, bool started = false) ; void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ; - void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ; + void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled); void removeEntry(U64 handle) ; - void setReadOnly(BOOL read_only) {mReadOnly = read_only;} + void setReadOnly(bool read_only) {mReadOnly = read_only;} private: void setDirNames(ELLPath location); @@ -134,9 +222,9 @@ private: BOOL updateEntry(const HeaderEntryInfo* entry); private: - BOOL mEnabled; - BOOL mInitialized ; - BOOL mReadOnly ; + bool mEnabled; + bool mInitialized ; + bool mReadOnly ; HeaderMetaInfo mMetaInfo; U32 mCacheSize; U32 mNumEntries; @@ -145,12 +233,6 @@ private: LLVolatileAPRPool* mLocalAPRFilePoolp ; header_entry_queue_t mHeaderEntryQueue; handle_entry_map_t mHandleEntryMap; - - static LLVOCache* sInstance ; -public: - static LLVOCache* getInstance() ; - static BOOL hasInstance() ; - static void destroyClass() ; }; #endif diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 6a25b765cf..e9efc7db9a 100755 --- 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/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index ac2a34ba1e..312842a70f 100755 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -28,12 +28,14 @@ #include "llagent.h" #include "llfloaterreg.h" +#include "llhttpclient.h" #include "llimview.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpanel.h" #include "llrecentpeople.h" #include "llviewercontrol.h" +#include "llviewerregion.h" #include "llvoicechannel.h" diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 714dd6a9f2..bd9ea029a9 100755 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -34,7 +34,6 @@ class LLVOAvatar; #include "lliosocket.h" #include "v3math.h" #include "llframetimer.h" -#include "llviewerregion.h" #include "llcallingcard.h" // for LLFriendObserver #include "llsecapi.h" #include "llcontrol.h" diff --git a/indra/newview/llvoinventorylistener.h b/indra/newview/llvoinventorylistener.h index bf14d19b01..c50c475478 100755 --- a/indra/newview/llvoinventorylistener.h +++ b/indra/newview/llvoinventorylistener.h @@ -30,7 +30,9 @@ #ifndef LL_LLVOINVENTORYLISTENER_H #define LL_LLVOINVENTORYLISTENER_H -#include "llviewerobject.h" +#include "llinventory.h" + +class LLViewerObject; class LLVOInventoryListener { diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 0b34bbb90f..41b306007d 100755 --- 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 36793017ed..0a119e853a 100755 --- 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 de15f0ef43..5b7aee2427 100755 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1052,8 +1052,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/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a15878368e..21693e85e1 100755 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -33,6 +33,8 @@ class LLSurfacePatch; class LLDrawPool; class LLVector2; +class LLFacePool; +class LLFace; class LLVOSurfacePatch : public LLStaticViewerObject { diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 145a0380d6..9a044968d2 100755 --- 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 8730ef66bb..126055c8fb 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -406,7 +406,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, dp->dumpBufferToLog(); llwarns << "Flushing cache files" << llendl; - if(LLVOCache::hasInstance() && getRegion()) + if(LLVOCache::instanceExists() && getRegion()) { LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; } @@ -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,7 +1157,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 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; } @@ -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); } @@ -4190,7 +4190,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOAvatar* pAvatarVO = NULL; - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (bridge) { if (bridge->mAvatar.isNull()) @@ -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(); @@ -4226,10 +4227,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) std::vector<LLFace*> simple_faces; std::vector<LLFace*> alpha_faces; - U32 useage = group->mSpatialPartition->mBufferUsage; + U32 useage = group->getSpatialPartition()->mBufferUsage; - U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); - U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -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); @@ -4829,7 +4837,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: #endif //calculate maximum number of vertices to store in a single buffer - U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); { @@ -5220,7 +5228,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) { //initialize to default usage for this partition - U32 usage = group->mSpatialPartition->mBufferUsage; + U32 usage = group->getSpatialPartition()->mBufferUsage; //clear off any old faces mFaceList.clear(); @@ -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 100755 --- 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 4e26587184..0f2f49a975 100755 --- 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/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 4f582fc2db..c852f1869b 100755 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llwatchdog.h" +#include "llthread.h" const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000; diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index ef1a953f59..79c2778253 100755 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -148,7 +148,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/llwindebug.h b/indra/newview/llwindebug.h index 3837825d31..6f274c6f16 100755 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -28,6 +28,7 @@ #define LL_LLWINDEBUG_H #include "stdtypes.h" +#include "llwin32headerslean.h" #include <dbghelp.h> class LLWinDebug: diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 793becf0c8..42a0be9e2f 100755 --- 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 = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled") && gSavedSettings.getBOOL("ObjectCacheEnabled"); } @@ -122,10 +123,7 @@ void LLWorld::destroyClass() LLViewerRegion* region_to_delete = *region_it++; removeRegion(region_to_delete->getHost()); } - if(LLVOCache::hasInstance()) - { - LLVOCache::getInstance()->destroyClass() ; - } + LLViewerPartSim::getInstance()->destroyClass(); mDefaultWaterTexturep = NULL ; @@ -133,6 +131,11 @@ void LLWorld::destroyClass() { mEdgeWaterObjects[i] = NULL; } + + //make all visible drawbles invisible. + LLDrawable::incrementVisible(); + + LLSceneMonitor::deleteSingleton(); } @@ -599,7 +602,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 +626,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 +665,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 +704,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 +716,17 @@ 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); + F32 packet_loss = 100.f * ((F32)packets_lost/(F32)packets_in); + sample(LLStatViewer::PACKETS_LOST_PERCENT, packet_loss); } mLastPacketsIn = gMessageSystem->mPacketsIn; @@ -1127,6 +1139,7 @@ void send_agent_pause() } gObjectList.mWasPaused = TRUE; + LLViewerStats::instance().getRecording().stop(); } @@ -1156,8 +1169,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 100755 --- 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 100755 --- 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 1940cf541e..6759328b84 100755 --- 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 100755 --- 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 7eed9acb4b..dd5c153d55 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -87,6 +87,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" @@ -112,6 +113,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 @@ -197,6 +199,7 @@ BOOL LLPipeline::CameraOffset; F32 LLPipeline::CameraMaxCoF; F32 LLPipeline::CameraDoFResScale; F32 LLPipeline::RenderAutoHideSurfaceAreaLimit; +LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize"); const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; @@ -404,17 +407,9 @@ bool addDeferredAttachments(LLRenderTarget& target) LLPipeline::LLPipeline() : mBackfaceCull(FALSE), - mBatchCount(0), mMatrixOpCount(0), mTextureMatrixOps(0), - mMaxBatchSize(0), - mMinBatchSize(0), - mMeanBatchSize(0), - mTrianglesDrawn(0), mNumVisibleNodes(0), - mVerticesRelit(0), - mLightingChanges(0), - mGeometryChanges(0), mNumVisibleFaces(0), mInitialized(FALSE), @@ -491,7 +486,6 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_GLOW); - LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) @@ -1433,18 +1427,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) { @@ -1633,11 +1627,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()); @@ -1677,7 +1669,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) if (drawablep->getSpatialGroup()) { LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION); - if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup())) + if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) { #ifdef LL_RELEASE_FOR_DOWNLOAD llwarns << "Couldn't remove object from spatial group!" << llendl; @@ -1823,17 +1815,7 @@ void LLPipeline::resetFrameStats() { assertInitialized(); - LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); - - if (mBatchCount > 0) - { - mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount; - } - mTrianglesDrawn = 0; sCompiles = 0; - mVerticesRelit = 0; - mLightingChanges = 0; - mGeometryChanges = 0; mNumVisibleFaces = 0; if (mOldRenderDebugMask != mRenderDebugMask) @@ -1841,7 +1823,6 @@ void LLPipeline::resetFrameStats() gObjectList.clearDebugText(); mOldRenderDebugMask = mRenderDebugMask; } - } //external functions for asynchronous updating @@ -1942,6 +1923,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() { @@ -1955,8 +1938,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) @@ -1971,8 +1953,7 @@ void LLPipeline::updateMove() } { - static LLFastTimer::DeclareTimer ftm("Moved List"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_MOVED_LIST); updateMovedList(mMovedList); } @@ -2061,7 +2042,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; } @@ -2083,10 +2064,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) { @@ -2263,7 +2247,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& min = LLVector3(X,X,X); max = LLVector3(-X,-X,-X); - U32 saved_camera_id = LLViewerCamera::sCurCameraID; + LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; BOOL res = TRUE; @@ -2408,6 +2392,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) @@ -2475,15 +2466,16 @@ 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; } assertInitialized(); - if (!group->mSpatialPartition->mRenderByGroup) + if (!group->getSpatialPartition()->mRenderByGroup) { //render by drawable sCull->pushDrawableGroup(group); } @@ -2588,7 +2580,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) if (update_complete && assertInitialized()) { drawablep->setState(LLDrawable::BUILT); - mGeometryChanges++; } return update_complete; } @@ -2732,7 +2723,7 @@ void LLPipeline::rebuildGroups() { group->rebuildGeom(); - if (group->mSpatialPartition->mRenderByGroup) + if (group->getSpatialPartition()->mRenderByGroup) { count++; } @@ -2801,7 +2792,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; @@ -3055,23 +3046,23 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group) void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { - if (group && !group->isDead() && group->mSpatialPartition) + if (group && !group->isDead() && group->getSpatialPartition()) { - if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) { priority = TRUE; } 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()) @@ -3082,7 +3073,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); @@ -3157,7 +3148,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) @@ -3244,8 +3235,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) @@ -3346,7 +3336,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - mNumVisibleFaces += drawablep->getNumFaces(); } @@ -3359,7 +3348,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()); + } } } } @@ -3587,7 +3579,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(); } @@ -3625,7 +3617,7 @@ void LLPipeline::postSort(LLCamera& camera) if (alpha != group->mDrawMap.end()) { //store alpha groups for sorting - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { if (bridge) @@ -3769,33 +3761,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 ; } @@ -4539,10 +4504,8 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) count = index_count/3; } - mTrianglesDrawn += count; - mBatchCount++; - mMaxBatchSize = llmax(mMaxBatchSize, count); - mMinBatchSize = llmin(mMinBatchSize, count); + record(sStatBatchSize, count); + add(LLStatViewer::TRIANGLES_DRAWN, count); if (LLPipeline::sRenderFrameTest) { @@ -4971,7 +4934,7 @@ void LLPipeline::renderDebug() { DebugBlip& blip = *iter; - blip.mAge += gFrameIntervalSeconds; + blip.mAge += gFrameIntervalSeconds.value(); if (blip.mAge > 2.f) { mDebugBlips.erase(iter++); @@ -4981,7 +4944,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); @@ -5223,7 +5186,7 @@ void LLPipeline::renderDebug() continue; } - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) { @@ -5787,7 +5750,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) { if (farthest_light->fade >= 0.f) { - farthest_light->fade = -gFrameIntervalSeconds; + farthest_light->fade = -(gFrameIntervalSeconds.value()); } } else @@ -5883,12 +5846,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; @@ -6828,7 +6791,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) } void LLPipeline::resetVertexBuffers() -{ +{ mResetVertexBuffers = true; } @@ -7218,7 +7181,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; @@ -9207,7 +9170,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); @@ -9465,7 +9428,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowFrustPoints[j].clear(); } - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); //restore render matrices glh_set_current_modelview(saved_view); @@ -9842,12 +9805,14 @@ 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().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); //update shadow targets for (U32 i = 0; i < 2; i++) { //for each current shadow - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); if (mShadowSpotLight[i].notNull() && (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || @@ -9966,7 +9931,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) static LLCullResult result[2]; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); @@ -10016,7 +9981,7 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu LLSpatialGroup* group = *i; if (!group->isDead() && (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && - gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && group->mDrawMap.find(type) != group->mDrawMap.end()) { pass->renderGroup(group,type,mask,texture); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a8db93585e..530d484dbd 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -29,8 +29,6 @@ #include "llcamera.h" #include "llerror.h" -#include "lldarrayptr.h" -#include "lldqueueptr.h" #include "lldrawpool.h" #include "llspatialpartition.h" #include "m4math.h" @@ -42,25 +40,13 @@ #include <stack> -#include <stack> - -#include <stack> - class LLViewerTexture; -class LLEdge; class LLFace; class LLViewerObject; -class LLAgent; -class LLDisplayPrimitive; class LLTextureEntry; -class LLRenderFunc; -class LLCubeMap; class LLCullResult; class LLVOAvatar; class LLGLSLShader; -class LLCurlRequest; - -class LLMeshResponder; typedef enum e_avatar_skinning_method { @@ -514,23 +500,14 @@ public: LLQuaternion mFlyCamRotation; BOOL mBackfaceCull; - S32 mBatchCount; S32 mMatrixOpCount; S32 mTextureMatrixOps; - S32 mMaxBatchSize; - S32 mMinBatchSize; - S32 mMeanBatchSize; - S32 mTrianglesDrawn; S32 mNumVisibleNodes; - S32 mVerticesRelit; S32 mDebugTextureUploadCost; S32 mDebugSculptUploadCost; S32 mDebugMeshUploadCost; - S32 mLightingChanges; - S32 mGeometryChanges; - S32 mNumVisibleFaces; static S32 sCompiles; @@ -564,6 +541,8 @@ public: static S32 sVisibleLightCount; static F32 sMinRenderSize; + static LLTrace::EventStatHandle<S64> sStatBatchSize; + //screen texture U32 mScreenWidth; U32 mScreenHeight; 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 100755 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 100755 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 100755 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..246e8bb256 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml @@ -0,0 +1,446 @@ +<?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 follows="top|left" + 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" + unit_scale="100" + precision="0"/> + <stat_bar name="bandwidth" + label="Bandwidth" + orientation="horizontal" + unit_label="kbps" + stat="kbitstat" + bar_max="5000" + tick_spacing="500" + precision="0"/> + <stat_bar name="packet_loss" + label="Packet Loss" + orientation="horizontal" + unit_label=" %" + stat="packetslostpercentstat" + bar_max="5" + tick_spacing="0.5" + 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" + 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" + 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" + 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" + 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" + show_history="true" + show_bar="false"/> + <stat_bar name="numimagesstat" + label="Count" + orientation="horizontal" + stat="numimagesstat" + bar_max="8000.f" + tick_spacing="2000.f" + show_bar="false"/> + <stat_bar name="numrawimagesstat" + label="Raw Count" + orientation="horizontal" + stat="numrawimagesstat" + bar_max="8000.f" + tick_spacing="2000.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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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..0493f487d4 100755 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -31,17 +31,17 @@ <stat_view name="basic" label="Basic" + follows="left|top|right" show_label="true" setting="OpenDebugStatBasic"> <stat_bar name="fps" label="FPS" unit_label="fps" - stat="fpsstat" + stat="framesrendered" bar_min="0" bar_max="60" tick_spacing="6" - label_spacing="12" precision="1" show_bar="true" show_history="true"> @@ -54,7 +54,6 @@ bar_min="0" bar_max="5000" tick_spacing="500" - label_spacing="1000" precision="0" show_bar="true" show_history="false"> @@ -67,9 +66,7 @@ bar_min="0" bar_max="5" tick_spacing="0.5" - label_spacing="1" precision="3" - show_per_sec="false" show_bar="false" show_mean="true"> </stat_bar> @@ -81,10 +78,8 @@ bar_min="0" bar_max="5000" tick_spacing="500" - label_spacing="1000" precision="0" show_bar="false" - show_per_sec="false" show_mean="false"> </stat_bar> </stat_view> @@ -92,11 +87,13 @@ <stat_view name="advanced" label="Advanced" + follows="left|top|right" show_label="true" setting="OpenDebugStatAdvanced"> <stat_view name="render" label="Render" + follows="left|top|right" show_label="true" setting="OpenDebugStatRender"> <stat_bar @@ -104,10 +101,10 @@ label="KTris Drawn per Frame" unit_label="/fr" stat="trianglesdrawnstat" + unit_scale="0.001" bar_min="0" bar_max="10000" tick_spacing="1000" - label_spacing="2000" precision="0" show_per_sec="false" show_bar="false"> @@ -116,11 +113,11 @@ name="ktrissec" label="KTris Drawn per Sec" unit_label="/sec" + unit_scale="0.001" stat="trianglesdrawnstat" bar_min="0" bar_max="200000" tick_spacing="25000" - label_spacing="50000" precision="0" show_bar="false"> </stat_bar> @@ -132,9 +129,7 @@ bar_min="0" bar_max="50000" tick_spacing="5000" - label_spacing="10000" precision="0" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -145,8 +140,6 @@ bar_min="0" bar_max="2000" tick_spacing="200" - label_spacing="400" - show_per_sec="true" show_bar="false"> </stat_bar> <stat_bar @@ -157,9 +150,7 @@ bar_max="100" unit_label="%" tick_spacing="20" - label_spacing="20" show_history="true" - show_per_sec="false" show_bar="false"> </stat_bar> </stat_view> @@ -167,6 +158,7 @@ <stat_view name="texture" label="Texture" + follows="left|top|right" show_label="true"> <stat_bar name="texture_cache_hits" @@ -176,9 +168,7 @@ bar_max="100.f" unit_label="%" tick_spacing="20" - label_spacing="20" show_history="true" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -189,9 +179,7 @@ bar_min="0.f" bar_max="1000.f" tick_spacing="100" - label_spacing="200" show_history="true" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -201,8 +189,6 @@ bar_min="0.f" bar_max="8000.f" tick_spacing="2000.f" - label_spacing="4000.f" - show_per_sec="false" show_bar="false"> </stat_bar> @@ -213,8 +199,6 @@ bar_min="0.f" bar_max="8000.f" tick_spacing="2000.f" - label_spacing="4000.f" - show_per_sec="false" show_bar="false"> </stat_bar> @@ -222,12 +206,12 @@ 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 +219,25 @@ 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 +245,12 @@ 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> @@ -274,6 +258,7 @@ <stat_view name="network" label="Network" + follows="left|top|right" show_label="true" setting="OpenDebugStatNet"> <stat_bar @@ -284,7 +269,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false"> </stat_bar> @@ -297,7 +281,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" > </stat_bar> @@ -310,7 +293,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" > </stat_bar> @@ -323,7 +305,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" > </stat_bar> @@ -336,7 +317,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" > </stat_bar> @@ -349,7 +329,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" > </stat_bar> @@ -362,7 +341,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" show_history="false" > @@ -376,7 +354,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" precision="1" show_bar="false" show_history="false"> @@ -387,7 +364,6 @@ label="VFS Pending Operations" stat="vfspendingoperations" unit_label=" Ops." - show_per_sec="false" show_bar="false" > </stat_bar> </stat_view> @@ -396,6 +372,7 @@ <stat_view name="sim" label="Simulator" + follows="left|top|right" show_label="true" setting="OpenDebugStatSim"> <stat_bar @@ -406,8 +383,6 @@ bar_min="0.f" bar_max="1.f" tick_spacing="0.16666f" - label_spacing="0.33333f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -420,8 +395,6 @@ bar_min="0.f" bar_max="45.f" tick_spacing="7.5f" - label_spacing="15.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -434,8 +407,6 @@ bar_min="0.f" 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> @@ -443,6 +414,7 @@ <stat_view name="physicsdetail" label="Physics Details" + follows="left|top|right" show_label="true"> <stat_bar name="physicspinnedtasks" @@ -452,8 +424,6 @@ bar_min="0.f" bar_max="500.f" tick_spacing="50.f" - label_spacing="100.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -466,8 +436,6 @@ bar_min="0.f" bar_max="500.f" tick_spacing="50.f" - label_spacing="100.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -481,8 +449,6 @@ bar_min="0.f" bar_max="1024.f" tick_spacing="128.f" - label_spacing="256.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -496,8 +462,6 @@ bar_min="0.f" bar_max="100.f" tick_spacing="25.f" - label_spacing="50.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -510,8 +474,6 @@ bar_min="0.f" bar_max="80.f" tick_spacing="10.f" - label_spacing="40.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -524,8 +486,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="5.f" - label_spacing="10.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -538,8 +498,6 @@ bar_min="0.f" bar_max="30000.f" tick_spacing="5000.f" - label_spacing="10000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -552,8 +510,6 @@ bar_min="0.f" bar_max="5000.f" tick_spacing="750.f" - label_spacing="1250.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -566,8 +522,6 @@ bar_min="0.f" bar_max="15000.f" tick_spacing="1875.f" - label_spacing="3750.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -579,9 +533,7 @@ bar_min="0" bar_max="100" tick_spacing="10" - label_spacing="20" precision="3" - show_per_sec="false" show_bar="false" show_mean="true"> </stat_bar> @@ -595,8 +547,6 @@ bar_min="0.f" bar_max="5000.f" tick_spacing="750.f" - label_spacing="1250.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -604,6 +554,7 @@ <stat_view name="simpathfinding" label="Pathfinding" + follows="left|top|right" show_label="true"> <stat_bar name="simsimaistepmsec" @@ -614,8 +565,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -628,8 +577,6 @@ bar_min="0" bar_max="45" tick_spacing="4" - label_spacing="8" - show_per_sec="false" show_bar="false"> </stat_bar> <stat_bar @@ -640,9 +587,7 @@ bar_min="0" bar_max="100" tick_spacing="10" - label_spacing="20" precision="1" - show_per_sec="false" show_bar="false" show_mean="true"> </stat_bar> @@ -657,8 +602,6 @@ bar_min="0.f" bar_max="2000.f" tick_spacing="250.f" - label_spacing="1000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -672,8 +615,6 @@ bar_min="0.f" bar_max="2000.f" tick_spacing="250.f" - label_spacing="1000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -686,8 +627,6 @@ bar_min="0.f" bar_max="800.f" tick_spacing="100.f" - label_spacing="200.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -700,8 +639,6 @@ bar_min="0.f" bar_max="100.f" tick_spacing="25.f" - label_spacing="50.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -715,8 +652,6 @@ bar_min="0.f" bar_max="100000.f" tick_spacing="25000.f" - label_spacing="50000.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -724,6 +659,7 @@ <stat_view name="simperf" label="Time (ms)" + follows="left|top|right" show_label="true"> <stat_bar name="simframemsec" @@ -734,8 +670,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -749,8 +683,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -764,8 +696,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -779,8 +709,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -794,8 +722,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -809,8 +735,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -824,8 +748,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -839,8 +761,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -848,6 +768,7 @@ <stat_view name="timedetails" label="Time Details (ms)" + follows="left|top|right" show_label="true"> <stat_bar name="simsimphysicsstepmsec" @@ -858,8 +779,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -872,8 +791,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -886,8 +803,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -900,8 +815,6 @@ bar_min="0.f" bar_max="40.f" tick_spacing="10.f" - label_spacing="20.f" - show_per_sec="false" show_bar="false" show_mean="false" > </stat_bar> @@ -914,8 +827,6 @@ bar_min="0.f" 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 a11cd13fdb..d50b7b18e7 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1300,7 +1300,7 @@ parameter="hud" /> </menu_item_call>--> <menu_item_separator/> - + <menu_item_call label="User’s guide" name="User’s guide"> @@ -1475,6 +1475,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"> @@ -2080,6 +2088,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" @@ -2831,6 +2849,16 @@ function="ToggleControl" parameter="RenderHoverGlowEnable" /> </menu_item_check> + <menu_item_separator /> + + <menu_item_call + enabled="true" + label="Clear Cache Immediately" + name="Cache Clear"> + <menu_item_call.on_click + function="Develop.ClearCache" /> + </menu_item_call> + </menu> <menu diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 970a11c6c4..540618ef9a 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6923,7 +6923,7 @@ Do not allow access if you do not fully understand why it wants access to your a [FOOTERTEXT] </footer> </notification> - + <notification icon="notify.tga" name="UnknownScriptQuestion" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 3b57ff5fd6..e0a85877eb 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -416,7 +416,7 @@ Please try logging in again in a minute.</string> <string name="OverrideYourAnimations">Replace your default animations</string> <string name="ScriptReturnObjects">Return objects on your behalf</string> <string name="UnknownScriptPermission">(unknown)!</string> - + <!-- Sim Access labels --> <string name="SIM_ACCESS_PG">General</string> <string name="SIM_ACCESS_MATURE">Moderate</string> 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 a331d9aa9e..561c2bb286 100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -37,6 +37,35 @@ #include "llregionhandle.h" #include "../llvoavatar.h" +namespace LLStatViewer +{ + LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"); +} + +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ + counts.resize(3); + counts[0] = 0; + counts[1] = 0; + counts[2] = 1; +} + +// static +std::string LLVOAvatar::rezStatusToString(S32 rez_status) +{ + if (rez_status==0) return "cloud"; + if (rez_status==1) return "gray"; + if (rez_status==2) return "textured"; + return "unknown"; +} + +// static +LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) +{ + static LLViewerStats::StatsAccumulator junk; + return junk; +} + static const char * all_keys[] = { "duration", @@ -199,7 +228,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"); @@ -209,24 +249,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); @@ -293,17 +333,18 @@ 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); + gViewerAssetStats->updateStats(); LLSD sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + 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]; @@ -316,11 +357,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())); @@ -330,20 +371,18 @@ 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); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + gViewerAssetStats->updateStats(); + LLSD sd = gViewerAssetStatsMain->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]; @@ -356,13 +395,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())); @@ -372,24 +409,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; @@ -420,8 +458,8 @@ namespace tut 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())); @@ -431,39 +469,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_double_key_map(sd, "duration", "regions")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); @@ -493,8 +532,8 @@ namespace tut 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); @@ -504,35 +543,33 @@ 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)); + gViewerAssetStats->updateStats(); sd = gViewerAssetStatsMain->asLLSD(false); ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); @@ -551,445 +588,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); - } - } - } |