diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
---|---|---|
committer | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
commit | 1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch) | |
tree | ab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llviewerstats.cpp | |
parent | 6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff) | |
parent | e1623bb276f83a43ce7a197e388720c05bdefe61 (diff) |
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts:
# autobuild.xml
# indra/cmake/CMakeLists.txt
# indra/cmake/GoogleMock.cmake
# indra/llaudio/llaudioengine_fmodstudio.cpp
# indra/llaudio/llaudioengine_fmodstudio.h
# indra/llaudio/lllistener_fmodstudio.cpp
# indra/llaudio/lllistener_fmodstudio.h
# indra/llaudio/llstreamingaudio_fmodstudio.cpp
# indra/llaudio/llstreamingaudio_fmodstudio.h
# indra/llcharacter/llmultigesture.cpp
# indra/llcharacter/llmultigesture.h
# indra/llimage/llimage.cpp
# indra/llimage/llimagepng.cpp
# indra/llimage/llimageworker.cpp
# indra/llimage/tests/llimageworker_test.cpp
# indra/llmessage/tests/llmockhttpclient.h
# indra/llprimitive/llgltfmaterial.h
# indra/llrender/llfontfreetype.cpp
# indra/llui/llcombobox.cpp
# indra/llui/llfolderview.cpp
# indra/llui/llfolderviewmodel.h
# indra/llui/lllineeditor.cpp
# indra/llui/lllineeditor.h
# indra/llui/lltextbase.cpp
# indra/llui/lltextbase.h
# indra/llui/lltexteditor.cpp
# indra/llui/lltextvalidate.cpp
# indra/llui/lltextvalidate.h
# indra/llui/lluictrl.h
# indra/llui/llview.cpp
# indra/llwindow/llwindowmacosx.cpp
# indra/newview/app_settings/settings.xml
# indra/newview/llappearancemgr.cpp
# indra/newview/llappearancemgr.h
# indra/newview/llavatarpropertiesprocessor.cpp
# indra/newview/llavatarpropertiesprocessor.h
# indra/newview/llbreadcrumbview.cpp
# indra/newview/llbreadcrumbview.h
# indra/newview/llbreastmotion.cpp
# indra/newview/llbreastmotion.h
# indra/newview/llconversationmodel.h
# indra/newview/lldensityctrl.cpp
# indra/newview/lldensityctrl.h
# indra/newview/llface.inl
# indra/newview/llfloatereditsky.cpp
# indra/newview/llfloatereditwater.cpp
# indra/newview/llfloateremojipicker.h
# indra/newview/llfloaterimsessiontab.cpp
# indra/newview/llfloaterprofiletexture.cpp
# indra/newview/llfloaterprofiletexture.h
# indra/newview/llgesturemgr.cpp
# indra/newview/llgesturemgr.h
# indra/newview/llimpanel.cpp
# indra/newview/llimpanel.h
# indra/newview/llinventorybridge.cpp
# indra/newview/llinventorybridge.h
# indra/newview/llinventoryclipboard.cpp
# indra/newview/llinventoryclipboard.h
# indra/newview/llinventoryfunctions.cpp
# indra/newview/llinventoryfunctions.h
# indra/newview/llinventorygallery.cpp
# indra/newview/lllistbrowser.cpp
# indra/newview/lllistbrowser.h
# indra/newview/llpanelobjectinventory.cpp
# indra/newview/llpanelprofile.cpp
# indra/newview/llpanelprofile.h
# indra/newview/llpreviewgesture.cpp
# indra/newview/llsavedsettingsglue.cpp
# indra/newview/llsavedsettingsglue.h
# indra/newview/lltooldraganddrop.cpp
# indra/newview/llurllineeditorctrl.cpp
# indra/newview/llvectorperfoptions.cpp
# indra/newview/llvectorperfoptions.h
# indra/newview/llviewerparceloverlay.cpp
# indra/newview/llviewertexlayer.cpp
# indra/newview/llviewertexturelist.cpp
# indra/newview/macmain.h
# indra/test/test.cpp
Diffstat (limited to 'indra/newview/llviewerstats.cpp')
-rw-r--r-- | indra/newview/llviewerstats.cpp | 1884 |
1 files changed, 942 insertions, 942 deletions
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 795b283009..5304c7baf0 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -1,942 +1,942 @@ -/** - * @file llviewerstats.cpp - * @brief LLViewerStats class implementation - * - * $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$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llviewerstats.h" -#include "llviewerthrottle.h" - -#include "message.h" -#include "llfloaterreg.h" -#include "llmemory.h" -#include "lltimer.h" - -#include "llappviewer.h" - -#include "pipeline.h" -#include "lltexturefetch.h" -#include "llviewerobjectlist.h" -#include "llviewertexturelist.h" -#include "lltexlayer.h" -#include "lltexlayerparams.h" -#include "llsurface.h" -#include "llvlmanager.h" -#include "llagent.h" -#include "llagentcamera.h" -#include "llviewercontrol.h" -#include "llversioninfo.h" -#include "llfloatertools.h" -#include "lldebugview.h" -#include "llfasttimerview.h" -#include "llviewerregion.h" -#include "llvoavatar.h" -#include "llvoavatarself.h" -#include "llworld.h" -#include "llfeaturemanager.h" -#include "llviewernetwork.h" -#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived -#include "llperfstats.h" -#include "llsdserialize.h" -#include "llsdutil.h" -#include "llcorehttputil.h" -#include "llvoicevivox.h" -#include "llinventorymodel.h" -#include "lluiusage.h" -#include "lltranslate.h" - -// "Minimal Vulkan" to get max API Version - -// Calls - #if defined(_WIN32) - #define VKAPI_ATTR - #define VKAPI_CALL __stdcall - #define VKAPI_PTR VKAPI_CALL - #else - #define VKAPI_ATTR - #define VKAPI_CALL - #define VKAPI_PTR - #endif // _WIN32 - -// Macros - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // <variant> <-------major-------><-----------minor-----------> <--------------patch--------------> - // 0x7 0x7F 0x3FF 0xFFF - #define VK_API_VERSION_MAJOR( version) (((uint32_t)(version) >> 22) & 0x07FU) // 7 bits - #define VK_API_VERSION_MINOR( version) (((uint32_t)(version) >> 12) & 0x3FFU) // 10 bits - #define VK_API_VERSION_PATCH( version) (((uint32_t)(version) ) & 0xFFFU) // 12 bits - #define VK_API_VERSION_VARIANT(version) (((uint32_t)(version) >> 29) & 0x007U) // 3 bits - - // NOTE: variant is first parameter! This is to match vulkan/vulkan_core.h - #define VK_MAKE_API_VERSION(variant, major, minor, patch) (0\ - | (((uint32_t)(major & 0x07FU)) << 22) \ - | (((uint32_t)(minor & 0x3FFU)) << 12) \ - | (((uint32_t)(patch & 0xFFFU)) ) \ - | (((uint32_t)(variant & 0x007U)) << 29) ) - - #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; - -// Types - VK_DEFINE_HANDLE(VkInstance); - - typedef enum VkResult - { - VK_SUCCESS = 0, - VK_RESULT_MAX_ENUM = 0x7FFFFFFF - } VkResult; - -// Prototypes - typedef void (VKAPI_PTR *PFN_vkVoidFunction )(void); - typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr )(VkInstance instance, const char* pName); - typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion); - -namespace LLStatViewer -{ - -LLTrace::CountStatHandle<> FPS("FPS", "Frames rendered"), - PACKETS_IN("Packets In", "Packets received"), - PACKETS_LOST("packetsloststat", "Packets lost"), - PACKETS_OUT("packetsoutstat", "Packets sent"), - TEXTURE_PACKETS("texturepacketsstat", "Texture data packets received"), - CHAT_COUNT("chatcount", "Chat messages sent"), - IM_COUNT("imcount", "IMs sent"), - OBJECT_CREATE("objectcreate", "Number of objects created"), - 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", "Number of times avatar textures have been baked"), - TEX_REBAKES("texrebakes", "Number of times avatar textures have been forced to rebake"), - NUM_NEW_OBJECTS("numnewobjectsstat", "Number of objects in scene that were not previously in cache"); - -LLTrace::CountStatHandle<LLUnit<F64, LLUnits::Kilotriangles> > - TRIANGLES_DRAWN("trianglesdrawnstat"); - -LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Kilotriangles> > - TRIANGLES_DRAWN_PER_FRAME("trianglesdrawnperframestat"); - -LLTrace::CountStatHandle<F64Kilobytes > - ACTIVE_MESSAGE_DATA_RECEIVED("activemessagedatareceived", "Message system data received on all active regions"), - LAYERS_NETWORK_DATA_RECEIVED("layersdatareceived", "Network data received for layer data (terrain)"), - OBJECT_NETWORK_DATA_RECEIVED("objectdatareceived", "Network data received for objects"), - ASSET_UDP_DATA_RECEIVED("assetudpdatareceived", "Network data received for assets (animations, sounds) over UDP message system"), - TEXTURE_NETWORK_DATA_RECEIVED("texturedatareceived", "Network data received for textures"), - MESSAGE_SYSTEM_DATA_IN("messagedatain", "Incoming message system network data"), - MESSAGE_SYSTEM_DATA_OUT("messagedataout", "Outgoing message system network data"); - -LLTrace::CountStatHandle<F64Seconds > - 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", "Simulator time scale", LL_SIM_STAT_TIME_DILATION), - SIM_FPS("simfps", "Simulator framerate", LL_SIM_STAT_FPS), - SIM_PHYSICS_FPS("simphysicsfps", "Simulator physics framerate", 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_MAIN_AGENTS("simmainagents", "Number of avatars in current region", LL_SIM_STAT_NUMAGENTMAIN), - SIM_CHILD_AGENTS("simchildagents", "Number of avatars in neighboring regions", LL_SIM_STAT_NUMAGENTCHILD), - SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS), - SIM_ACTIVE_OBJECTS("simactiveobjects", "Number of scripted and/or moving objects", LL_SIM_STAT_NUMTASKSACTIVE), - SIM_ACTIVE_SCRIPTS("simactivescripts", "Number of scripted objects", LL_SIM_STAT_NUMSCRIPTSACTIVE), - 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); - -SimMeasurement<LLUnit<F64, LLUnits::Percent> > - SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun", "", LL_SIM_STAT_PCTSCRIPTSRUN), - SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters", "", LL_SIM_STAT_PCTSTEPPEDCHARACTERS); - -LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"), - NUM_IMAGES("numimagesstat"), - NUM_RAW_IMAGES("numrawimagesstat"), - NUM_MATERIALS("nummaterials"), - NUM_OBJECTS("numobjectsstat"), - NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), - ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), - VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), - SHADER_OBJECTS("shaderobjects", "Object Shaders"), - DRAW_DISTANCE("drawdistance", "Draw Distance"), - WINDOW_WIDTH("windowwidth", "Window width"), - WINDOW_HEIGHT("windowheight", "Window height"); - -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > - PACKETS_LOST_PERCENT("packetslostpercentstat"); - -static LLTrace::SampleStatHandle<bool> - CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); - -LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM("formattedmemstat"); -LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), - MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); - - -SimMeasurement<F64Milliseconds > 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<F64Kilobytes > SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES); -SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); - -LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), - FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), - FRAMETIME("frametime", "Measured frame time"), - SIM_PING("simpingstat"); - -LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); - -LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"); - -LLTrace::EventStatHandle<F64Milliseconds > 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"); - -LLTrace::EventStatHandle<F64Seconds > 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"); - -LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits"); - -LLTrace::EventStatHandle<F64Seconds > TEXTURE_FETCH_TIME("texture_fetch_time"); - -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SCENERY_FRAME_PCT("scenery_frame_pct"); -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > AVATAR_FRAME_PCT("avatar_frame_pct"); -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > HUDS_FRAME_PCT("huds_frame_pct"); -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > UI_FRAME_PCT("ui_frame_pct"); -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SWAP_FRAME_PCT("swap_frame_pct"); -LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > IDLE_FRAME_PCT("idle_frame_pct"); -} - -LLViewerStats::LLViewerStats() -: mLastTimeDiff(0.0) -{ - getRecording().start(); -} - -LLViewerStats::~LLViewerStats() -{} - -void LLViewerStats::resetStats() -{ - getRecording().reset(); -} - -void LLViewerStats::updateFrameStats(const F64Seconds time_diff) -{ - if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > F32Percent(5.0)) - { - add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff); - } - - F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS); - if (0.f < sim_fps && sim_fps < 20.f) - { - add(LLStatViewer::SIM_20_FPS_TIME, time_diff); - } - - F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS); - - if (0.f < sim_physics_fps && sim_physics_fps < 20.f) - { - add(LLStatViewer::SIM_PHYSICS_20_FPS_TIME, time_diff); - } - - if (time_diff >= (F64Seconds)0.5) - { - record(LLStatViewer::FPS_2_TIME, time_diff); - } - if (time_diff >= (F64Seconds)0.125) - { - record(LLStatViewer::FPS_8_TIME, time_diff); - } - if (time_diff >= (F64Seconds)0.1) - { - record(LLStatViewer::FPS_10_TIME, time_diff); - } - - if (gFrameCount && mLastTimeDiff > (F64Seconds)0.0) - { - // new "stutter" meter - add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0); - - sample(LLStatViewer::FRAMETIME, time_diff); - - // old stats that were never really used - F64Seconds jit = (F64Seconds) std::fabs((mLastTimeDiff - time_diff)); - sample(LLStatViewer::FRAMETIME_JITTER, jit); - - F32Seconds average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; - sample(LLStatViewer::FRAMETIME_SLEW, F64Milliseconds (average_frametime - time_diff)); - - F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); - F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; - sample(LLStatViewer::DELTA_BANDWIDTH, F64Bits(delta_bandwidth)); - sample(LLStatViewer::MAX_BANDWIDTH, F64Bits(max_bandwidth)); - } - - mLastTimeDiff = time_diff; -} - -void LLViewerStats::addToMessage(LLSD &body) -{ - LLSD &misc = body["misc"]; - - misc["Version"] = true; - //TODO RN: get last value, not mean - misc["Vertex Buffers Enabled"] = getRecording().getMean(LLStatViewer::ENABLE_VBO); - - body["AgentPositionSnaps"] = getRecording().getSum(LLStatViewer::AGENT_POSITION_SNAP).value(); //mAgentPositionSnaps.asLLSD(); - LL_INFOS() << "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) << LL_ENDL; -} - -// *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, - gTotalWaterIn = 0, - gTotalWaterOut = 0; - -F32 gAveLandCompression = 0.f, - gAveWaterCompression = 0.f, - gBestLandCompression = 1.f, - gBestWaterCompression = 1.f, - gWorstLandCompression = 0.f, - gWorstWaterCompression = 0.f; - -U32Bytes gTotalWorldData, - gTotalObjectData, - gTotalTextureData; -U32 gSimPingCount = 0; -U32Bits gObjectData; -F32Milliseconds gAvgSimPing(0.f); -// rely on default initialization -U32Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY]; - -extern U32 gVisCompared; -extern U32 gVisTested; - -void update_statistics() -{ - LL_PROFILE_ZONE_SCOPED; - - 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) - { - record(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds); - } - else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) - { - record(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds); - } - else if (LLFloaterReg::instanceVisible("build")) - { - record(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds); - } - } - - LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - - record(LLStatViewer::TRIANGLES_DRAWN_PER_FRAME, last_frame_recording.getSum(LLStatViewer::TRIANGLES_DRAWN)); - - sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); - sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip")); - sample(LLStatViewer::CHAT_BUBBLES, gSavedSettings.getBOOL("UseChatBubbles")); - - typedef LLTrace::StatType<LLTrace::TimeBlockAccumulator>::instance_tracker_t stat_type_t; - - record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Frame"))); - - if (gAgent.getRegion() && isAgentAvatarValid()) - { - LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); - if (cdp) - { - sample(LLStatViewer::SIM_PING, F64Milliseconds(cdp->getPingDelay())); - gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1); - gSimPingCount++; - } - else - { - sample(LLStatViewer::SIM_PING, U32Seconds(10)); - } - } - - if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS)) - { - sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS)); - } - add(LLStatViewer::FPS, 1); - - F64Bits layer_bits = gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits(); - add(LLStatViewer::LAYERS_NETWORK_DATA_RECEIVED, layer_bits); - add(LLStatViewer::OBJECT_NETWORK_DATA_RECEIVED, gObjectData); - add(LLStatViewer::ASSET_UDP_DATA_RECEIVED, F64Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET))); - gTransferManager.resetTransferBitsIn(LLTCT_ASSET); - - sample(LLStatViewer::VISIBLE_AVATARS, LLVOAvatar::sNumVisibleAvatars); - LLWorld *world = LLWorld::getInstance(); // not LLSingleton - if (world) - { - world->updateNetStats(); - world->requestCacheMisses(); - } - - // Reset all of these values. - gVLManager.resetBitCounts(); - gObjectData = (U32Bytes)0; -// gDecodedBits = 0; - - // Only update texture stats periodically so that they are less noisy - { - static const F32 texture_stats_freq = 10.f; - static LLFrameTimer texture_stats_timer; - if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) - { - gTotalTextureData = LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED); - texture_stats_timer.reset(); - } - } - - if (LLFloaterReg::instanceVisible("scene_load_stats")) - { - static const F32 perf_stats_freq = 1; - static LLFrameTimer perf_stats_timer; - if (perf_stats_timer.getElapsedTimeF32() >= perf_stats_freq) - { - LLStringUtil::format_map_t args; - LLPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment - - auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME); - // cumulative avatar time (includes idle processing, attachments and base av) - auto tot_avatar_time_raw = LLPerfStats::us_to_raw(LLVOAvatar::getTotalGPURenderTime()); - // cumulative avatar render specific time (a bit arbitrary as the processing is too.) - // auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE); - // auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw; - // the time spent this frame on the "display()" call. Treated as "tot time rendering" - auto tot_render_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_DISPLAY); - // sleep time is basically forced sleep when window out of focus - auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP); - // time spent on UI - auto tot_ui_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_UI); - // cumulative time spent rendering HUDS - auto tot_huds_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_HUDS); - // "idle" time. This is the time spent in the idle poll section of the main loop - auto tot_idle_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_IDLE); - // similar to sleep time, induced by FPS limit - //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT); - // swap time is time spent in swap buffer - auto tot_swap_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SWAP); - - LLPerfStats::bufferToggleLock.unlock(); - - auto tot_frame_time_ns = LLPerfStats::raw_to_ns(tot_frame_time_raw); - auto tot_avatar_time_ns = LLPerfStats::raw_to_ns(tot_avatar_time_raw); - auto tot_huds_time_ns = LLPerfStats::raw_to_ns(tot_huds_time_raw); - // UI time includes HUD time so dedut that before we calc percentages - auto tot_ui_time_ns = LLPerfStats::raw_to_ns(tot_ui_time_raw - tot_huds_time_raw); - - // auto tot_sleep_time_ns = LLPerfStats::raw_to_ns( tot_sleep_time_raw ); - // auto tot_limit_time_ns = LLPerfStats::raw_to_ns( tot_limit_time_raw ); - - // auto tot_render_time_ns = LLPerfStats::raw_to_ns( tot_render_time_raw ); - auto tot_idle_time_ns = LLPerfStats::raw_to_ns(tot_idle_time_raw); - auto tot_swap_time_ns = LLPerfStats::raw_to_ns(tot_swap_time_raw); - auto tot_scene_time_ns = LLPerfStats::raw_to_ns(tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw); - // auto tot_overhead_time_ns = LLPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw ); - - // // remove time spent sleeping for fps limit or out of focus. - // tot_frame_time_ns -= tot_limit_time_ns; - // tot_frame_time_ns -= tot_sleep_time_ns; - - if (tot_frame_time_ns != 0) - { - auto pct_avatar_time = (tot_avatar_time_ns * 100) / tot_frame_time_ns; - auto pct_huds_time = (tot_huds_time_ns * 100) / tot_frame_time_ns; - auto pct_ui_time = (tot_ui_time_ns * 100) / tot_frame_time_ns; - auto pct_idle_time = (tot_idle_time_ns * 100) / tot_frame_time_ns; - auto pct_swap_time = (tot_swap_time_ns * 100) / tot_frame_time_ns; - auto pct_scene_render_time = (tot_scene_time_ns * 100) / tot_frame_time_ns; - pct_avatar_time = llclamp(pct_avatar_time, 0., 100.); - pct_huds_time = llclamp(pct_huds_time, 0., 100.); - pct_ui_time = llclamp(pct_ui_time, 0., 100.); - pct_idle_time = llclamp(pct_idle_time, 0., 100.); - pct_swap_time = llclamp(pct_swap_time, 0., 100.); - pct_scene_render_time = llclamp(pct_scene_render_time, 0., 100.); - if (tot_sleep_time_raw == 0) - { - sample(LLStatViewer::SCENERY_FRAME_PCT, (U32)llround(pct_scene_render_time)); - sample(LLStatViewer::AVATAR_FRAME_PCT, (U32)llround(pct_avatar_time)); - sample(LLStatViewer::HUDS_FRAME_PCT, (U32)llround(pct_huds_time)); - sample(LLStatViewer::UI_FRAME_PCT, (U32)llround(pct_ui_time)); - sample(LLStatViewer::SWAP_FRAME_PCT, (U32)llround(pct_swap_time)); - sample(LLStatViewer::IDLE_FRAME_PCT, (U32)llround(pct_idle_time)); - } - } - else - { - LL_WARNS("performance") << "Scene time 0. Skipping til we have data." << LL_ENDL; - } - perf_stats_timer.reset(); - } - } -} - -/* - * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats. - * - * There's also a compatibility shim for the old fixed-format sim - * stats in newsim/llagentinfo.cpp:processViewerStats. - * - * If you move stats around here, make the corresponding changes in - * those locations, too. - */ -void send_viewer_stats(bool include_preferences) -{ - // IW 9/23/02 I elected not to move this into LLViewerStats - // because it depends on too many viewer.cpp globals. - // Someday we may want to merge all our stats into a central place - // but that day is not today. - - // Only send stats if the agent is connected to a region. - if (!gAgent.getRegion()) - { - return; - } - - LLSD body; - std::string url = gAgent.getRegion()->getCapability("ViewerStats"); - - if (url.empty()) { - LL_WARNS() << "Could not get ViewerStats capability" << LL_ENDL; - return; - } - - LLViewerStats::instance().getRecording().pause(); - - LLSD &agent = body["agent"]; - - time_t ltime; - time(<ime); - F32 run_time = F32(LLFrameTimer::getElapsedSeconds()); - - agent["start_time"] = S32(ltime - S32(run_time)); - - // The first stat set must have a 0 run time if it doesn't actually - // contain useful data in terms of FPS, etc. We use half the - // SEND_STATS_PERIOD seconds as the point at which these statistics become - // valid. Data warehouse uses a 0 value here to easily discard these - // records with non-useful FPS values etc. - if (run_time < (SEND_STATS_PERIOD / 2)) - { - agent["run_time"] = 0.0f; - } - else - { - agent["run_time"] = run_time; - } - - // send fps only for time app spends in foreground - agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32(); - agent["version"] = LLVersionInfo::instance().getChannelAndVersion(); - std::string language = LLUI::getLanguage(); - agent["language"] = language; - - agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) / - (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime); - - gSimLastTime = gRenderStartTime.getElapsedTimeF32(); - gSimFrames = (F32) gFrameCount; - - agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars; - agent["ping"] = gAvgSimPing.value(); - agent["meters_traveled"] = gAgent.getDistanceTraveled(); - agent["regions_visited"] = gAgent.getRegionsVisited(); - agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0; - agent["translation"] = LLTranslate::instance().asLLSD(); - - LLSD &system = body["system"]; - - system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value(); - system["os"] = LLOSInfo::instance().getOSStringSimple(); - system["cpu"] = gSysCPU.getCPUString(); - system["cpu_sse"] = gSysCPU.getSSEVersions(); - system["address_size"] = ADDRESS_SIZE; - system["os_bitness"] = LLOSInfo::instance().getOSBitness(); - system["hardware_concurrency"] = (LLSD::Integer) std::thread::hardware_concurrency(); - unsigned char MACAddress[MAC_ADDRESS_BYTES]; - LLUUID::getNodeID(MACAddress); - std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x", - MACAddress[0],MACAddress[1],MACAddress[2], - MACAddress[3],MACAddress[4],MACAddress[5]); - system["mac_address"] = macAddressString; - system["serial_number"] = LLAppViewer::instance()->getSerialNumber(); - std::string gpu_desc = llformat( - "%-6s Class %d ", - gGLManager.mGLVendorShort.substr(0,6).c_str(), - (S32)LLFeatureManager::getInstance()->getGPUClass()) - + gGLManager.getRawGLString(); - - system["gpu"] = gpu_desc; - system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass(); - system["gpu_memory_bandwidth"] = LLFeatureManager::getInstance()->getGPUMemoryBandwidth(); - system["gpu_vendor"] = gGLManager.mGLVendorShort; - system["gpu_version"] = gGLManager.mDriverVersionVendorString; - system["opengl_version"] = gGLManager.mGLVersionString; - - gGLManager.asLLSD(system["gl"]); - - - S32 shader_level = 0; - if (LLPipeline::sRenderDeferred) - { - if (LLPipeline::RenderShadowDetail > 0) - { - shader_level = 5; - } - else if (LLPipeline::RenderDeferredSSAO) - { - shader_level = 4; - } - else - { - shader_level = 3; - } - } - else - { - shader_level = 2; - } - - - - system["shader_level"] = shader_level; - - LLSD &download = body["downloads"]; - - download["world_kbytes"] = F64Kilobytes(gTotalWorldData).value(); - download["object_kbytes"] = F64Kilobytes(gTotalObjectData).value(); - download["texture_kbytes"] = F64Kilobytes(gTotalTextureData).value(); - download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; - - LLSD &in = body["stats"]["net"]["in"]; - - in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0; - in["packets"] = (S32) gMessageSystem->mPacketsIn; - in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn; - in["savings"] = (gMessageSystem->mUncompressedBytesIn - - gMessageSystem->mCompressedBytesIn) / 1024.0; - - LLSD &out = body["stats"]["net"]["out"]; - - out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0; - out["packets"] = (S32) gMessageSystem->mPacketsOut; - out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut; - out["savings"] = (gMessageSystem->mUncompressedBytesOut - - gMessageSystem->mCompressedBytesOut) / 1024.0; - - LLSD &fail = body["stats"]["failures"]; - - fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount; - fail["dropped"] = (S32) gMessageSystem->mDroppedPackets; - fail["resent"] = (S32) gMessageSystem->mResentPackets; - fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets; - fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets; - fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets; - fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing(); - - LLSD &inventory = body["inventory"]; - inventory["usable"] = gInventory.isInventoryUsable(); - LLSD& validation_info = inventory["validation_info"]; - gInventory.mValidationInfo->asLLSD(validation_info); - - body["ui"] = LLUIUsage::instance().asLLSD(); - - body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read(); - - // Misc stats, two strings and two ints - // These are not expecticed to persist across multiple releases - // Comment any changes with your name and the expected release revision - // If the current revision is recent, ping the previous author before overriding - LLSD &misc = body["stats"]["misc"]; - -#ifdef LL_WINDOWS - // Probe for Vulkan capability (Dave Houlton 05/2020) - // - // Check for presense of a Vulkan loader dll, as a proxy for a Vulkan-capable gpu. - // False-positives and false-negatives are possible, but unlikely. We'll get a good - // approximation of Vulkan capability within current user systems from this. More - // detailed information on versions and extensions can come later. - static bool vulkan_oneshot = false; - static bool vulkan_detected = false; - static std::string vulkan_max_api_version( "0.0" ); // Unknown/None - - if (!vulkan_oneshot) - { - // The 32-bit and 64-bit versions normally exist in: - // C:\Windows\System32 - // C:\Windows\SysWOW64 - HMODULE vulkan_loader = LoadLibraryA("vulkan-1.dll"); - if (NULL != vulkan_loader) - { - vulkan_detected = true; - vulkan_max_api_version = "1.0"; // We have at least 1.0. See the note about vkEnumerateInstanceVersion() below. - - // We use Run-Time Dynamic Linking (via GetProcAddress()) instead of Load-Time Dynamic Linking (via directly calling vkGetInstanceProcAddr()). - // This allows us to: - // a) not need the header: #include <vulkan/vulkan.h> - // (and not need to set the corresponding "Additional Include Directories" as long as we provide the equivalent Vulkan types/prototypes/etc.) - // b) not need to link to: vulkan-1.lib - // (and not need to set the corresponding "Additional Library Directories") - // The former will allow Second Life to start and run even if the vulkan.dll is missing. - // The latter will require us to: - // a) link with vulkan-1.lib - // b) cause a System Error at startup if the .dll is not found: - // "The code execution cannot proceed because vulkan-1.dll was not found." - // - // See: - // https://docs.microsoft.com/en-us/windows/win32/dlls/using-run-time-dynamic-linking - // https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking - - // NOTE: Technically we can use GetProcAddress() as a replacement for vkGetInstanceProcAddr() - // but the canonical recommendation (mandate?) is to use vkGetInstanceProcAddr(). - PFN_vkGetInstanceProcAddr pGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) GetProcAddress(vulkan_loader, "vkGetInstanceProcAddr"); - if(pGetInstanceProcAddr) - { - // Check for vkEnumerateInstanceVersion. If it exists then we have at least 1.1 and can query the max API version. - // NOTE: Each VkPhysicalDevice that supports Vulkan has its own VkPhysicalDeviceProperties.apiVersion which is separate from the max API version! - // See: https://www.lunarg.com/wp-content/uploads/2019/02/Vulkan-1.1-Compatibility-Statement_01_19.pdf - PFN_vkEnumerateInstanceVersion pEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) pGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion"); - if(pEnumerateInstanceVersion) - { - uint32_t version = VK_MAKE_API_VERSION(0,1,1,0); // e.g. 4202631 = 1.2.135.0 - VkResult status = pEnumerateInstanceVersion( &version ); - if (status != VK_SUCCESS) - { - LL_INFOS("Vulkan") << "Failed to get Vulkan version. Assuming 1.0" << LL_ENDL; - } - else - { - // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers - int major = VK_API_VERSION_MAJOR ( version ); - int minor = VK_API_VERSION_MINOR ( version ); - int patch = VK_API_VERSION_PATCH ( version ); - int variant = VK_API_VERSION_VARIANT( version ); - - vulkan_max_api_version = llformat( "%d.%d.%d.%d", major, minor, patch, variant ); - LL_INFOS("Vulkan") << "Vulkan API version: " << vulkan_max_api_version << ", Raw version: " << version << LL_ENDL; - } - } - } - else - { - LL_WARNS("Vulkan") << "FAILED to get Vulkan vkGetInstanceProcAddr()!" << LL_ENDL; - } - FreeLibrary(vulkan_loader); - } - vulkan_oneshot = true; - } - - misc["string_1"] = vulkan_detected ? llformat("Vulkan driver is detected") : llformat("No Vulkan driver detected"); - misc["VulkanMaxApiVersion"] = vulkan_max_api_version; - -#else - misc["string_1"] = llformat("Unused"); -#endif // LL_WINDOWS - - misc["string_2"] = llformat("Unused"); - misc["int_1"] = LLSD::Integer(0); - misc["int_2"] = LLSD::Integer(0); - - LL_INFOS() << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << LL_ENDL; - LL_INFOS() << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << LL_ENDL; - - body["DisplayNamesEnabled"] = gSavedSettings.getBOOL("UseDisplayNames"); - body["DisplayNamesShowUsername"] = gSavedSettings.getBOOL("NameTagShowUsernames"); - - // Preferences - if (include_preferences) - { - bool diffs_only = true; // only log preferences that differ from default - body["preferences"]["settings"] = gSavedSettings.asLLSD(diffs_only); - body["preferences"]["settings_per_account"] = gSavedPerAccountSettings.asLLSD(diffs_only); - } - - body["MinimalSkin"] = false; - - - LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL; - LL_DEBUGS("LogViewerStatsPacket"); - std::string filename("viewer_stats_packet.xml"); - llofstream of(filename.c_str()); - LLSDSerialize::toPrettyXML(body,of); - LL_ENDL; - - // The session ID token must never appear in logs - body["session_id"] = gAgentSessionID; - - LLViewerStats::getInstance()->addToMessage(body); - - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body, - "Statistics posted to sim", "Failed to post statistics to sim"); - LLViewerStats::instance().getRecording().resume(); -} - -LLTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) -{ - phase_map_t::iterator iter = mPhaseMap.find(phase_name); - if (iter == mPhaseMap.end()) - { - LLTimer timer; - mPhaseMap[phase_name] = timer; - } - LLTimer& timer = mPhaseMap[phase_name]; - return timer; -} - -void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name) -{ - LLTimer& timer = getPhaseTimer(phase_name); - timer.start(); - //LL_DEBUGS("Avatar") << "startPhase " << phase_name << LL_ENDL; -} - -void LLViewerStats::PhaseMap::clearPhases() -{ - //LL_DEBUGS("Avatar") << "clearPhases" << LL_ENDL; - - mPhaseMap.clear(); -} - -LLSD LLViewerStats::PhaseMap::asLLSD() -{ - LLSD result; - for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter) - { - const std::string& phase_name = iter->first; - result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted())); - result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); - } - return result; -} - -// static initializer -//static -LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats; - -LLViewerStats::PhaseMap::PhaseMap() -{ -} - -void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) -{ - phase_map_t::iterator iter = mPhaseMap.find(phase_name); - if (iter != mPhaseMap.end()) - { - if (iter->second.getStarted()) - { - // Going from started to stopped state - record stats. - iter->second.stop(); - } - } -} - -// static -LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) -{ - phase_stats_t::iterator it = sStats.find(phase_name); - if (it == sStats.end()) - { - LLViewerStats::StatsAccumulator new_stats; - sStats[phase_name] = new_stats; - } - return sStats[phase_name]; -} - -// static -void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value) -{ - LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name); - stats.push(value); -} - - -bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed) -{ - phase_map_t::iterator iter = mPhaseMap.find(phase_name); - bool found = false; - if (iter != mPhaseMap.end()) - { - found = true; - elapsed = iter->second.getElapsedTimeF32(); - completed = !iter->second.getStarted(); - //LL_DEBUGS("Avatar") << " phase_name " << phase_name << " elapsed " << elapsed << " completed " << completed << " timer addr " << (S32)(&iter->second) << LL_ENDL; - } - else - { - //LL_DEBUGS("Avatar") << " phase_name " << phase_name << " NOT FOUND" << LL_ENDL; - } - - return found; -} +/**
+ * @file llviewerstats.cpp
+ * @brief LLViewerStats class implementation
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerstats.h"
+#include "llviewerthrottle.h"
+
+#include "message.h"
+#include "llfloaterreg.h"
+#include "llmemory.h"
+#include "lltimer.h"
+
+#include "llappviewer.h"
+
+#include "pipeline.h"
+#include "lltexturefetch.h"
+#include "llviewerobjectlist.h"
+#include "llviewertexturelist.h"
+#include "lltexlayer.h"
+#include "lltexlayerparams.h"
+#include "llsurface.h"
+#include "llvlmanager.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llviewercontrol.h"
+#include "llversioninfo.h"
+#include "llfloatertools.h"
+#include "lldebugview.h"
+#include "llfasttimerview.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llworld.h"
+#include "llfeaturemanager.h"
+#include "llviewernetwork.h"
+#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
+#include "llperfstats.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+#include "llcorehttputil.h"
+#include "llvoicevivox.h"
+#include "llinventorymodel.h"
+#include "lluiusage.h"
+#include "lltranslate.h"
+
+// "Minimal Vulkan" to get max API Version
+
+// Calls
+ #if defined(_WIN32)
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+ #else
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+ #endif // _WIN32
+
+// Macros
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // <variant> <-------major-------><-----------minor-----------> <--------------patch-------------->
+ // 0x7 0x7F 0x3FF 0xFFF
+ #define VK_API_VERSION_MAJOR( version) (((uint32_t)(version) >> 22) & 0x07FU) // 7 bits
+ #define VK_API_VERSION_MINOR( version) (((uint32_t)(version) >> 12) & 0x3FFU) // 10 bits
+ #define VK_API_VERSION_PATCH( version) (((uint32_t)(version) ) & 0xFFFU) // 12 bits
+ #define VK_API_VERSION_VARIANT(version) (((uint32_t)(version) >> 29) & 0x007U) // 3 bits
+
+ // NOTE: variant is first parameter! This is to match vulkan/vulkan_core.h
+ #define VK_MAKE_API_VERSION(variant, major, minor, patch) (0\
+ | (((uint32_t)(major & 0x07FU)) << 22) \
+ | (((uint32_t)(minor & 0x3FFU)) << 12) \
+ | (((uint32_t)(patch & 0xFFFU)) ) \
+ | (((uint32_t)(variant & 0x007U)) << 29) )
+
+ #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+// Types
+ VK_DEFINE_HANDLE(VkInstance);
+
+ typedef enum VkResult
+ {
+ VK_SUCCESS = 0,
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+ } VkResult;
+
+// Prototypes
+ typedef void (VKAPI_PTR *PFN_vkVoidFunction )(void);
+ typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr )(VkInstance instance, const char* pName);
+ typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion);
+
+namespace LLStatViewer
+{
+
+LLTrace::CountStatHandle<> FPS("FPS", "Frames rendered"),
+ PACKETS_IN("Packets In", "Packets received"),
+ PACKETS_LOST("packetsloststat", "Packets lost"),
+ PACKETS_OUT("packetsoutstat", "Packets sent"),
+ TEXTURE_PACKETS("texturepacketsstat", "Texture data packets received"),
+ CHAT_COUNT("chatcount", "Chat messages sent"),
+ IM_COUNT("imcount", "IMs sent"),
+ OBJECT_CREATE("objectcreate", "Number of objects created"),
+ 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", "Number of times avatar textures have been baked"),
+ TEX_REBAKES("texrebakes", "Number of times avatar textures have been forced to rebake"),
+ NUM_NEW_OBJECTS("numnewobjectsstat", "Number of objects in scene that were not previously in cache");
+
+LLTrace::CountStatHandle<LLUnit<F64, LLUnits::Kilotriangles> >
+ TRIANGLES_DRAWN("trianglesdrawnstat");
+
+LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Kilotriangles> >
+ TRIANGLES_DRAWN_PER_FRAME("trianglesdrawnperframestat");
+
+LLTrace::CountStatHandle<F64Kilobytes >
+ ACTIVE_MESSAGE_DATA_RECEIVED("activemessagedatareceived", "Message system data received on all active regions"),
+ LAYERS_NETWORK_DATA_RECEIVED("layersdatareceived", "Network data received for layer data (terrain)"),
+ OBJECT_NETWORK_DATA_RECEIVED("objectdatareceived", "Network data received for objects"),
+ ASSET_UDP_DATA_RECEIVED("assetudpdatareceived", "Network data received for assets (animations, sounds) over UDP message system"),
+ TEXTURE_NETWORK_DATA_RECEIVED("texturedatareceived", "Network data received for textures"),
+ MESSAGE_SYSTEM_DATA_IN("messagedatain", "Incoming message system network data"),
+ MESSAGE_SYSTEM_DATA_OUT("messagedataout", "Outgoing message system network data");
+
+LLTrace::CountStatHandle<F64Seconds >
+ 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", "Simulator time scale", LL_SIM_STAT_TIME_DILATION),
+ SIM_FPS("simfps", "Simulator framerate", LL_SIM_STAT_FPS),
+ SIM_PHYSICS_FPS("simphysicsfps", "Simulator physics framerate", 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_MAIN_AGENTS("simmainagents", "Number of avatars in current region", LL_SIM_STAT_NUMAGENTMAIN),
+ SIM_CHILD_AGENTS("simchildagents", "Number of avatars in neighboring regions", LL_SIM_STAT_NUMAGENTCHILD),
+ SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS),
+ SIM_ACTIVE_OBJECTS("simactiveobjects", "Number of scripted and/or moving objects", LL_SIM_STAT_NUMTASKSACTIVE),
+ SIM_ACTIVE_SCRIPTS("simactivescripts", "Number of scripted objects", LL_SIM_STAT_NUMSCRIPTSACTIVE),
+ 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);
+
+SimMeasurement<LLUnit<F64, LLUnits::Percent> >
+ SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun", "", LL_SIM_STAT_PCTSCRIPTSRUN),
+ SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters", "", LL_SIM_STAT_PCTSTEPPEDCHARACTERS);
+
+LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"),
+ NUM_IMAGES("numimagesstat"),
+ NUM_RAW_IMAGES("numrawimagesstat"),
+ NUM_MATERIALS("nummaterials"),
+ NUM_OBJECTS("numobjectsstat"),
+ NUM_ACTIVE_OBJECTS("numactiveobjectsstat"),
+ ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"),
+ VISIBLE_AVATARS("visibleavatars", "Visible Avatars"),
+ SHADER_OBJECTS("shaderobjects", "Object Shaders"),
+ DRAW_DISTANCE("drawdistance", "Draw Distance"),
+ WINDOW_WIDTH("windowwidth", "Window width"),
+ WINDOW_HEIGHT("windowheight", "Window height");
+
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >
+ PACKETS_LOST_PERCENT("packetslostpercentstat");
+
+static LLTrace::SampleStatHandle<bool>
+ CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled");
+
+LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM("formattedmemstat");
+LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
+ MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting");
+
+
+SimMeasurement<F64Milliseconds > 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<F64Kilobytes > SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES);
+SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY);
+
+LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),
+ FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
+ FRAMETIME("frametime", "Measured frame time"),
+ SIM_PING("simpingstat");
+
+LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections");
+
+LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load");
+
+LLTrace::EventStatHandle<F64Milliseconds > 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");
+
+LLTrace::EventStatHandle<F64Seconds > 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");
+
+LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits");
+
+LLTrace::EventStatHandle<F64Seconds > TEXTURE_FETCH_TIME("texture_fetch_time");
+
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SCENERY_FRAME_PCT("scenery_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > AVATAR_FRAME_PCT("avatar_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > HUDS_FRAME_PCT("huds_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > UI_FRAME_PCT("ui_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SWAP_FRAME_PCT("swap_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > IDLE_FRAME_PCT("idle_frame_pct");
+}
+
+LLViewerStats::LLViewerStats()
+: mLastTimeDiff(0.0)
+{
+ getRecording().start();
+}
+
+LLViewerStats::~LLViewerStats()
+{}
+
+void LLViewerStats::resetStats()
+{
+ getRecording().reset();
+}
+
+void LLViewerStats::updateFrameStats(const F64Seconds time_diff)
+{
+ if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > F32Percent(5.0))
+ {
+ add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff);
+ }
+
+ F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS);
+ if (0.f < sim_fps && sim_fps < 20.f)
+ {
+ add(LLStatViewer::SIM_20_FPS_TIME, time_diff);
+ }
+
+ F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS);
+
+ if (0.f < sim_physics_fps && sim_physics_fps < 20.f)
+ {
+ add(LLStatViewer::SIM_PHYSICS_20_FPS_TIME, time_diff);
+ }
+
+ if (time_diff >= (F64Seconds)0.5)
+ {
+ record(LLStatViewer::FPS_2_TIME, time_diff);
+ }
+ if (time_diff >= (F64Seconds)0.125)
+ {
+ record(LLStatViewer::FPS_8_TIME, time_diff);
+ }
+ if (time_diff >= (F64Seconds)0.1)
+ {
+ record(LLStatViewer::FPS_10_TIME, time_diff);
+ }
+
+ if (gFrameCount && mLastTimeDiff > (F64Seconds)0.0)
+ {
+ // new "stutter" meter
+ add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0);
+
+ sample(LLStatViewer::FRAMETIME, time_diff);
+
+ // old stats that were never really used
+ F64Seconds jit = (F64Seconds) std::fabs((mLastTimeDiff - time_diff));
+ sample(LLStatViewer::FRAMETIME_JITTER, jit);
+
+ F32Seconds average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
+ sample(LLStatViewer::FRAMETIME_SLEW, F64Milliseconds (average_frametime - time_diff));
+
+ F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
+ F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
+ sample(LLStatViewer::DELTA_BANDWIDTH, F64Bits(delta_bandwidth));
+ sample(LLStatViewer::MAX_BANDWIDTH, F64Bits(max_bandwidth));
+ }
+
+ mLastTimeDiff = time_diff;
+}
+
+void LLViewerStats::addToMessage(LLSD &body)
+{
+ LLSD &misc = body["misc"];
+
+ misc["Version"] = true;
+ //TODO RN: get last value, not mean
+ misc["Vertex Buffers Enabled"] = getRecording().getMean(LLStatViewer::ENABLE_VBO);
+
+ body["AgentPositionSnaps"] = getRecording().getSum(LLStatViewer::AGENT_POSITION_SNAP).value(); //mAgentPositionSnaps.asLLSD();
+ LL_INFOS() << "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) << LL_ENDL;
+}
+
+// *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,
+ gTotalWaterIn = 0,
+ gTotalWaterOut = 0;
+
+F32 gAveLandCompression = 0.f,
+ gAveWaterCompression = 0.f,
+ gBestLandCompression = 1.f,
+ gBestWaterCompression = 1.f,
+ gWorstLandCompression = 0.f,
+ gWorstWaterCompression = 0.f;
+
+U32Bytes gTotalWorldData,
+ gTotalObjectData,
+ gTotalTextureData;
+U32 gSimPingCount = 0;
+U32Bits gObjectData;
+F32Milliseconds gAvgSimPing(0.f);
+// rely on default initialization
+U32Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY];
+
+extern U32 gVisCompared;
+extern U32 gVisTested;
+
+void update_statistics()
+{
+ LL_PROFILE_ZONE_SCOPED;
+
+ 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)
+ {
+ record(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds);
+ }
+ else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
+ {
+ record(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds);
+ }
+ else if (LLFloaterReg::instanceVisible("build"))
+ {
+ record(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds);
+ }
+ }
+
+ LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
+
+ record(LLStatViewer::TRIANGLES_DRAWN_PER_FRAME, last_frame_recording.getSum(LLStatViewer::TRIANGLES_DRAWN));
+
+ sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
+ sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip"));
+ sample(LLStatViewer::CHAT_BUBBLES, gSavedSettings.getBOOL("UseChatBubbles"));
+
+ typedef LLTrace::StatType<LLTrace::TimeBlockAccumulator>::instance_tracker_t stat_type_t;
+
+ record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Frame")));
+
+ if (gAgent.getRegion() && isAgentAvatarValid())
+ {
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
+ if (cdp)
+ {
+ sample(LLStatViewer::SIM_PING, F64Milliseconds(cdp->getPingDelay()));
+ gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
+ gSimPingCount++;
+ }
+ else
+ {
+ sample(LLStatViewer::SIM_PING, U32Seconds(10));
+ }
+ }
+
+ if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS))
+ {
+ sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS));
+ }
+ add(LLStatViewer::FPS, 1);
+
+ F64Bits layer_bits = gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits();
+ add(LLStatViewer::LAYERS_NETWORK_DATA_RECEIVED, layer_bits);
+ add(LLStatViewer::OBJECT_NETWORK_DATA_RECEIVED, gObjectData);
+ add(LLStatViewer::ASSET_UDP_DATA_RECEIVED, F64Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET)));
+ gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
+
+ sample(LLStatViewer::VISIBLE_AVATARS, LLVOAvatar::sNumVisibleAvatars);
+ LLWorld *world = LLWorld::getInstance(); // not LLSingleton
+ if (world)
+ {
+ world->updateNetStats();
+ world->requestCacheMisses();
+ }
+
+ // Reset all of these values.
+ gVLManager.resetBitCounts();
+ gObjectData = (U32Bytes)0;
+// gDecodedBits = 0;
+
+ // Only update texture stats periodically so that they are less noisy
+ {
+ static const F32 texture_stats_freq = 10.f;
+ static LLFrameTimer texture_stats_timer;
+ if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
+ {
+ gTotalTextureData = LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED);
+ texture_stats_timer.reset();
+ }
+ }
+
+ if (LLFloaterReg::instanceVisible("scene_load_stats"))
+ {
+ static const F32 perf_stats_freq = 1;
+ static LLFrameTimer perf_stats_timer;
+ if (perf_stats_timer.getElapsedTimeF32() >= perf_stats_freq)
+ {
+ LLStringUtil::format_map_t args;
+ LLPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment
+
+ auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
+ // cumulative avatar time (includes idle processing, attachments and base av)
+ auto tot_avatar_time_raw = LLPerfStats::us_to_raw(LLVOAvatar::getTotalGPURenderTime());
+ // cumulative avatar render specific time (a bit arbitrary as the processing is too.)
+ // auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE);
+ // auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw;
+ // the time spent this frame on the "display()" call. Treated as "tot time rendering"
+ auto tot_render_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_DISPLAY);
+ // sleep time is basically forced sleep when window out of focus
+ auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
+ // time spent on UI
+ auto tot_ui_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_UI);
+ // cumulative time spent rendering HUDS
+ auto tot_huds_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_HUDS);
+ // "idle" time. This is the time spent in the idle poll section of the main loop
+ auto tot_idle_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_IDLE);
+ // similar to sleep time, induced by FPS limit
+ //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);
+ // swap time is time spent in swap buffer
+ auto tot_swap_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SWAP);
+
+ LLPerfStats::bufferToggleLock.unlock();
+
+ auto tot_frame_time_ns = LLPerfStats::raw_to_ns(tot_frame_time_raw);
+ auto tot_avatar_time_ns = LLPerfStats::raw_to_ns(tot_avatar_time_raw);
+ auto tot_huds_time_ns = LLPerfStats::raw_to_ns(tot_huds_time_raw);
+ // UI time includes HUD time so dedut that before we calc percentages
+ auto tot_ui_time_ns = LLPerfStats::raw_to_ns(tot_ui_time_raw - tot_huds_time_raw);
+
+ // auto tot_sleep_time_ns = LLPerfStats::raw_to_ns( tot_sleep_time_raw );
+ // auto tot_limit_time_ns = LLPerfStats::raw_to_ns( tot_limit_time_raw );
+
+ // auto tot_render_time_ns = LLPerfStats::raw_to_ns( tot_render_time_raw );
+ auto tot_idle_time_ns = LLPerfStats::raw_to_ns(tot_idle_time_raw);
+ auto tot_swap_time_ns = LLPerfStats::raw_to_ns(tot_swap_time_raw);
+ auto tot_scene_time_ns = LLPerfStats::raw_to_ns(tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw);
+ // auto tot_overhead_time_ns = LLPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw );
+
+ // // remove time spent sleeping for fps limit or out of focus.
+ // tot_frame_time_ns -= tot_limit_time_ns;
+ // tot_frame_time_ns -= tot_sleep_time_ns;
+
+ if (tot_frame_time_ns != 0)
+ {
+ auto pct_avatar_time = (tot_avatar_time_ns * 100) / tot_frame_time_ns;
+ auto pct_huds_time = (tot_huds_time_ns * 100) / tot_frame_time_ns;
+ auto pct_ui_time = (tot_ui_time_ns * 100) / tot_frame_time_ns;
+ auto pct_idle_time = (tot_idle_time_ns * 100) / tot_frame_time_ns;
+ auto pct_swap_time = (tot_swap_time_ns * 100) / tot_frame_time_ns;
+ auto pct_scene_render_time = (tot_scene_time_ns * 100) / tot_frame_time_ns;
+ pct_avatar_time = llclamp(pct_avatar_time, 0., 100.);
+ pct_huds_time = llclamp(pct_huds_time, 0., 100.);
+ pct_ui_time = llclamp(pct_ui_time, 0., 100.);
+ pct_idle_time = llclamp(pct_idle_time, 0., 100.);
+ pct_swap_time = llclamp(pct_swap_time, 0., 100.);
+ pct_scene_render_time = llclamp(pct_scene_render_time, 0., 100.);
+ if (tot_sleep_time_raw == 0)
+ {
+ sample(LLStatViewer::SCENERY_FRAME_PCT, (U32)llround(pct_scene_render_time));
+ sample(LLStatViewer::AVATAR_FRAME_PCT, (U32)llround(pct_avatar_time));
+ sample(LLStatViewer::HUDS_FRAME_PCT, (U32)llround(pct_huds_time));
+ sample(LLStatViewer::UI_FRAME_PCT, (U32)llround(pct_ui_time));
+ sample(LLStatViewer::SWAP_FRAME_PCT, (U32)llround(pct_swap_time));
+ sample(LLStatViewer::IDLE_FRAME_PCT, (U32)llround(pct_idle_time));
+ }
+ }
+ else
+ {
+ LL_WARNS("performance") << "Scene time 0. Skipping til we have data." << LL_ENDL;
+ }
+ perf_stats_timer.reset();
+ }
+ }
+}
+
+/*
+ * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
+ *
+ * There's also a compatibility shim for the old fixed-format sim
+ * stats in newsim/llagentinfo.cpp:processViewerStats.
+ *
+ * If you move stats around here, make the corresponding changes in
+ * those locations, too.
+ */
+void send_viewer_stats(bool include_preferences)
+{
+ // IW 9/23/02 I elected not to move this into LLViewerStats
+ // because it depends on too many viewer.cpp globals.
+ // Someday we may want to merge all our stats into a central place
+ // but that day is not today.
+
+ // Only send stats if the agent is connected to a region.
+ if (!gAgent.getRegion())
+ {
+ return;
+ }
+
+ LLSD body;
+ std::string url = gAgent.getRegion()->getCapability("ViewerStats");
+
+ if (url.empty()) {
+ LL_WARNS() << "Could not get ViewerStats capability" << LL_ENDL;
+ return;
+ }
+
+ LLViewerStats::instance().getRecording().pause();
+
+ LLSD &agent = body["agent"];
+
+ time_t ltime;
+ time(<ime);
+ F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
+
+ agent["start_time"] = S32(ltime - S32(run_time));
+
+ // The first stat set must have a 0 run time if it doesn't actually
+ // contain useful data in terms of FPS, etc. We use half the
+ // SEND_STATS_PERIOD seconds as the point at which these statistics become
+ // valid. Data warehouse uses a 0 value here to easily discard these
+ // records with non-useful FPS values etc.
+ if (run_time < (SEND_STATS_PERIOD / 2))
+ {
+ agent["run_time"] = 0.0f;
+ }
+ else
+ {
+ agent["run_time"] = run_time;
+ }
+
+ // send fps only for time app spends in foreground
+ agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
+ agent["version"] = LLVersionInfo::instance().getChannelAndVersion();
+ std::string language = LLUI::getLanguage();
+ agent["language"] = language;
+
+ agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) /
+ (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime);
+
+ gSimLastTime = gRenderStartTime.getElapsedTimeF32();
+ gSimFrames = (F32) gFrameCount;
+
+ agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars;
+ agent["ping"] = gAvgSimPing.value();
+ agent["meters_traveled"] = gAgent.getDistanceTraveled();
+ agent["regions_visited"] = gAgent.getRegionsVisited();
+ agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0;
+ agent["translation"] = LLTranslate::instance().asLLSD();
+
+ LLSD &system = body["system"];
+
+ system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
+ system["os"] = LLOSInfo::instance().getOSStringSimple();
+ system["cpu"] = gSysCPU.getCPUString();
+ system["cpu_sse"] = gSysCPU.getSSEVersions();
+ system["address_size"] = ADDRESS_SIZE;
+ system["os_bitness"] = LLOSInfo::instance().getOSBitness();
+ system["hardware_concurrency"] = (LLSD::Integer) std::thread::hardware_concurrency();
+ unsigned char MACAddress[MAC_ADDRESS_BYTES];
+ LLUUID::getNodeID(MACAddress);
+ std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
+ MACAddress[0],MACAddress[1],MACAddress[2],
+ MACAddress[3],MACAddress[4],MACAddress[5]);
+ system["mac_address"] = macAddressString;
+ system["serial_number"] = LLAppViewer::instance()->getSerialNumber();
+ std::string gpu_desc = llformat(
+ "%-6s Class %d ",
+ gGLManager.mGLVendorShort.substr(0,6).c_str(),
+ (S32)LLFeatureManager::getInstance()->getGPUClass())
+ + gGLManager.getRawGLString();
+
+ system["gpu"] = gpu_desc;
+ system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
+ system["gpu_memory_bandwidth"] = LLFeatureManager::getInstance()->getGPUMemoryBandwidth();
+ system["gpu_vendor"] = gGLManager.mGLVendorShort;
+ system["gpu_version"] = gGLManager.mDriverVersionVendorString;
+ system["opengl_version"] = gGLManager.mGLVersionString;
+
+ gGLManager.asLLSD(system["gl"]);
+
+
+ S32 shader_level = 0;
+ if (LLPipeline::sRenderDeferred)
+ {
+ if (LLPipeline::RenderShadowDetail > 0)
+ {
+ shader_level = 5;
+ }
+ else if (LLPipeline::RenderDeferredSSAO)
+ {
+ shader_level = 4;
+ }
+ else
+ {
+ shader_level = 3;
+ }
+ }
+ else
+ {
+ shader_level = 2;
+ }
+
+
+
+ system["shader_level"] = shader_level;
+
+ LLSD &download = body["downloads"];
+
+ download["world_kbytes"] = F64Kilobytes(gTotalWorldData).value();
+ download["object_kbytes"] = F64Kilobytes(gTotalObjectData).value();
+ download["texture_kbytes"] = F64Kilobytes(gTotalTextureData).value();
+ download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0;
+
+ LLSD &in = body["stats"]["net"]["in"];
+
+ in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0;
+ in["packets"] = (S32) gMessageSystem->mPacketsIn;
+ in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn;
+ in["savings"] = (gMessageSystem->mUncompressedBytesIn -
+ gMessageSystem->mCompressedBytesIn) / 1024.0;
+
+ LLSD &out = body["stats"]["net"]["out"];
+
+ out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0;
+ out["packets"] = (S32) gMessageSystem->mPacketsOut;
+ out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut;
+ out["savings"] = (gMessageSystem->mUncompressedBytesOut -
+ gMessageSystem->mCompressedBytesOut) / 1024.0;
+
+ LLSD &fail = body["stats"]["failures"];
+
+ fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount;
+ fail["dropped"] = (S32) gMessageSystem->mDroppedPackets;
+ fail["resent"] = (S32) gMessageSystem->mResentPackets;
+ fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
+ fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
+ fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
+ fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing();
+
+ LLSD &inventory = body["inventory"];
+ inventory["usable"] = gInventory.isInventoryUsable();
+ LLSD& validation_info = inventory["validation_info"];
+ gInventory.mValidationInfo->asLLSD(validation_info);
+
+ body["ui"] = LLUIUsage::instance().asLLSD();
+
+ body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read();
+
+ // Misc stats, two strings and two ints
+ // These are not expecticed to persist across multiple releases
+ // Comment any changes with your name and the expected release revision
+ // If the current revision is recent, ping the previous author before overriding
+ LLSD &misc = body["stats"]["misc"];
+
+#ifdef LL_WINDOWS
+ // Probe for Vulkan capability (Dave Houlton 05/2020)
+ //
+ // Check for presense of a Vulkan loader dll, as a proxy for a Vulkan-capable gpu.
+ // False-positives and false-negatives are possible, but unlikely. We'll get a good
+ // approximation of Vulkan capability within current user systems from this. More
+ // detailed information on versions and extensions can come later.
+ static bool vulkan_oneshot = false;
+ static bool vulkan_detected = false;
+ static std::string vulkan_max_api_version( "0.0" ); // Unknown/None
+
+ if (!vulkan_oneshot)
+ {
+ // The 32-bit and 64-bit versions normally exist in:
+ // C:\Windows\System32
+ // C:\Windows\SysWOW64
+ HMODULE vulkan_loader = LoadLibraryA("vulkan-1.dll");
+ if (NULL != vulkan_loader)
+ {
+ vulkan_detected = true;
+ vulkan_max_api_version = "1.0"; // We have at least 1.0. See the note about vkEnumerateInstanceVersion() below.
+
+ // We use Run-Time Dynamic Linking (via GetProcAddress()) instead of Load-Time Dynamic Linking (via directly calling vkGetInstanceProcAddr()).
+ // This allows us to:
+ // a) not need the header: #include <vulkan/vulkan.h>
+ // (and not need to set the corresponding "Additional Include Directories" as long as we provide the equivalent Vulkan types/prototypes/etc.)
+ // b) not need to link to: vulkan-1.lib
+ // (and not need to set the corresponding "Additional Library Directories")
+ // The former will allow Second Life to start and run even if the vulkan.dll is missing.
+ // The latter will require us to:
+ // a) link with vulkan-1.lib
+ // b) cause a System Error at startup if the .dll is not found:
+ // "The code execution cannot proceed because vulkan-1.dll was not found."
+ //
+ // See:
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/using-run-time-dynamic-linking
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking
+
+ // NOTE: Technically we can use GetProcAddress() as a replacement for vkGetInstanceProcAddr()
+ // but the canonical recommendation (mandate?) is to use vkGetInstanceProcAddr().
+ PFN_vkGetInstanceProcAddr pGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) GetProcAddress(vulkan_loader, "vkGetInstanceProcAddr");
+ if(pGetInstanceProcAddr)
+ {
+ // Check for vkEnumerateInstanceVersion. If it exists then we have at least 1.1 and can query the max API version.
+ // NOTE: Each VkPhysicalDevice that supports Vulkan has its own VkPhysicalDeviceProperties.apiVersion which is separate from the max API version!
+ // See: https://www.lunarg.com/wp-content/uploads/2019/02/Vulkan-1.1-Compatibility-Statement_01_19.pdf
+ PFN_vkEnumerateInstanceVersion pEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) pGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+ if(pEnumerateInstanceVersion)
+ {
+ uint32_t version = VK_MAKE_API_VERSION(0,1,1,0); // e.g. 4202631 = 1.2.135.0
+ VkResult status = pEnumerateInstanceVersion( &version );
+ if (status != VK_SUCCESS)
+ {
+ LL_INFOS("Vulkan") << "Failed to get Vulkan version. Assuming 1.0" << LL_ENDL;
+ }
+ else
+ {
+ // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers
+ int major = VK_API_VERSION_MAJOR ( version );
+ int minor = VK_API_VERSION_MINOR ( version );
+ int patch = VK_API_VERSION_PATCH ( version );
+ int variant = VK_API_VERSION_VARIANT( version );
+
+ vulkan_max_api_version = llformat( "%d.%d.%d.%d", major, minor, patch, variant );
+ LL_INFOS("Vulkan") << "Vulkan API version: " << vulkan_max_api_version << ", Raw version: " << version << LL_ENDL;
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("Vulkan") << "FAILED to get Vulkan vkGetInstanceProcAddr()!" << LL_ENDL;
+ }
+ FreeLibrary(vulkan_loader);
+ }
+ vulkan_oneshot = true;
+ }
+
+ misc["string_1"] = vulkan_detected ? llformat("Vulkan driver is detected") : llformat("No Vulkan driver detected");
+ misc["VulkanMaxApiVersion"] = vulkan_max_api_version;
+
+#else
+ misc["string_1"] = llformat("Unused");
+#endif // LL_WINDOWS
+
+ misc["string_2"] = llformat("Unused");
+ misc["int_1"] = LLSD::Integer(0);
+ misc["int_2"] = LLSD::Integer(0);
+
+ LL_INFOS() << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << LL_ENDL;
+ LL_INFOS() << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << LL_ENDL;
+
+ body["DisplayNamesEnabled"] = gSavedSettings.getBOOL("UseDisplayNames");
+ body["DisplayNamesShowUsername"] = gSavedSettings.getBOOL("NameTagShowUsernames");
+
+ // Preferences
+ if (include_preferences)
+ {
+ bool diffs_only = true; // only log preferences that differ from default
+ body["preferences"]["settings"] = gSavedSettings.asLLSD(diffs_only);
+ body["preferences"]["settings_per_account"] = gSavedPerAccountSettings.asLLSD(diffs_only);
+ }
+
+ body["MinimalSkin"] = false;
+
+
+ LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
+ LL_DEBUGS("LogViewerStatsPacket");
+ std::string filename("viewer_stats_packet.xml");
+ llofstream of(filename.c_str());
+ LLSDSerialize::toPrettyXML(body,of);
+ LL_ENDL;
+
+ // The session ID token must never appear in logs
+ body["session_id"] = gAgentSessionID;
+
+ LLViewerStats::getInstance()->addToMessage(body);
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "Statistics posted to sim", "Failed to post statistics to sim");
+ LLViewerStats::instance().getRecording().resume();
+}
+
+LLTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name)
+{
+ phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+ if (iter == mPhaseMap.end())
+ {
+ LLTimer timer;
+ mPhaseMap[phase_name] = timer;
+ }
+ LLTimer& timer = mPhaseMap[phase_name];
+ return timer;
+}
+
+void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)
+{
+ LLTimer& timer = getPhaseTimer(phase_name);
+ timer.start();
+ //LL_DEBUGS("Avatar") << "startPhase " << phase_name << LL_ENDL;
+}
+
+void LLViewerStats::PhaseMap::clearPhases()
+{
+ //LL_DEBUGS("Avatar") << "clearPhases" << LL_ENDL;
+
+ mPhaseMap.clear();
+}
+
+LLSD LLViewerStats::PhaseMap::asLLSD()
+{
+ LLSD result;
+ for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)
+ {
+ const std::string& phase_name = iter->first;
+ result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted()));
+ result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32();
+ }
+ return result;
+}
+
+// static initializer
+//static
+LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats;
+
+LLViewerStats::PhaseMap::PhaseMap()
+{
+}
+
+void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
+{
+ phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+ if (iter != mPhaseMap.end())
+ {
+ if (iter->second.getStarted())
+ {
+ // Going from started to stopped state - record stats.
+ iter->second.stop();
+ }
+ }
+}
+
+// static
+LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
+{
+ phase_stats_t::iterator it = sStats.find(phase_name);
+ if (it == sStats.end())
+ {
+ LLViewerStats::StatsAccumulator new_stats;
+ sStats[phase_name] = new_stats;
+ }
+ return sStats[phase_name];
+}
+
+// static
+void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value)
+{
+ LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name);
+ stats.push(value);
+}
+
+
+bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed)
+{
+ phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+ bool found = false;
+ if (iter != mPhaseMap.end())
+ {
+ found = true;
+ elapsed = iter->second.getElapsedTimeF32();
+ completed = !iter->second.getStarted();
+ //LL_DEBUGS("Avatar") << " phase_name " << phase_name << " elapsed " << elapsed << " completed " << completed << " timer addr " << (S32)(&iter->second) << LL_ENDL;
+ }
+ else
+ {
+ //LL_DEBUGS("Avatar") << " phase_name " << phase_name << " NOT FOUND" << LL_ENDL;
+ }
+
+ return found;
+}
|