diff options
Diffstat (limited to 'indra/newview')
83 files changed, 4176 insertions, 1582 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9aaefa9c6a..0a267cbad0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -30,7 +30,6 @@ include(LLUI) include(LLVFS) include(LLWindow) include(LLXML) -include(LLXUIXML) include(LScript) include(Linking) include(NDOF) @@ -66,7 +65,6 @@ include_directories( ${LLVFS_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} - ${LLXUIXML_INCLUDE_DIRS} ${LSCRIPT_INCLUDE_DIRS} ${LSCRIPT_INCLUDE_DIRS}/lscript_compile ${LLLOGIN_INCLUDE_DIRS} @@ -237,6 +235,7 @@ set(viewer_SOURCE_FILES llfloatertelehub.cpp llfloatertestinspectors.cpp llfloatertestlistview.cpp + llfloatertexturefetchdebugger.cpp llfloatertools.cpp llfloatertopobjects.cpp llfloatertos.cpp @@ -490,6 +489,7 @@ set(viewer_SOURCE_FILES lltoastnotifypanel.cpp lltoastpanel.cpp lltoastscripttextbox.cpp + lltoastscriptquestion.cpp lltool.cpp lltoolbarview.cpp lltoolbrush.cpp @@ -793,6 +793,7 @@ set(viewer_HEADER_FILES llfloatertelehub.h llfloatertestinspectors.h llfloatertestlistview.h + llfloatertexturefetchdebugger.h llfloatertools.h llfloatertopobjects.h llfloatertos.h @@ -1037,6 +1038,7 @@ set(viewer_HEADER_FILES lltoastnotifypanel.h lltoastpanel.h lltoastscripttextbox.h + lltoastscriptquestion.h lltool.h lltoolbarview.h lltoolbrush.h @@ -1746,7 +1748,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${LLXML_LIBRARIES} - ${LLXUIXML_LIBRARIES} ${LSCRIPT_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 15434f2b8f..be79f91919 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -1,45 +1,101 @@ <?xml version="1.0"?> <llsd> <map> - <key>help</key> + <!-- Please insert new keys in alphabetical order. --> + <key>analyzeperformance</key> <map> <key>desc</key> - <string>display this help message</string> + <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string> + <key>map-to</key> + <string>AnalyzePerformance</string> + </map> - <key>short</key> - <string>h</string> + <key>autologin</key> + <map> + <key>desc</key> + <string>log in as last saved user</string> + <key>map-to</key> + <string>AutoLogin</string> </map> - <key>port</key> + <key>channel</key> <map> <key>count</key> <integer>1</integer> - <key>map-to</key> - <string>UserConnectionPort</string> + <!-- Special case. Not mapped to a setting. --> </map> - <key>drop</key> + <key>console</key> <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>PacketDropPercentage</string> + <string>ShowConsoleWindow</string> </map> - <key>inbw</key> + <key>cooperative</key> <map> + <key>desc</key> + <string>Yield some idle time to local host.</string> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>InBandwidth</string> + <string>YieldTime</string> </map> - <key>outbw</key> + <key>crashonstartup</key> + <map> + <key>desc</key> + <string>Crashes on startup. For QA use.</string> + <key>map-to</key> + <string>CrashOnStartup</string> + </map> + + <key>debugsession</key> + <map> + <key>desc</key> + <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string> + <key>map-to</key> + <string>DebugSession</string> + </map> + + <key>debugviews</key> + <map> + <key>map-to</key> + <string>DebugViews</string> + </map> + + <key>disablecrashlogger</key> + <map> + <key>desc</key> + <string>Disables the crash logger and lets the OS handle crashes</string> + <key>map-to</key> + <string>DisableCrashLogger</string> + </map> + + <key>drop</key> <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>OutBandwidth</string> + <string>PacketDropPercentage</string> + </map> + + <key>god</key> + <map> + <key>desc</key> + <string>Log in a god if you have god access.</string> + <key>map-to</key> + <string>ConnectAsGod</string> + </map> + + <key>graphicslevel</key> + <map> + <key>desc</key> + <string>Set the detail level. +0 - low, 1 - medium, 2 - high, 3 - ultra</string> + <key>count</key> + <integer>1</integer> </map> <key>grid</key> @@ -52,16 +108,13 @@ <string>CmdLineGridChoice</string> </map> - <key>loginuri</key> + <key>help</key> <map> <key>desc</key> - <string>login server and CGI script to use</string> - <key>count</key> - <integer>1</integer> - <key>compose</key> - <boolean>true</boolean> - <key>map-to</key> - <string>CmdLineLoginURI</string> + <string>display this help message</string> + + <key>short</key> + <string>h</string> </map> <key>helperuri</key> @@ -74,44 +127,73 @@ <string>CmdLineHelperURI</string> </map> - <key>debugviews</key> + <key>ignorepixeldepth</key> <map> + <key>desc</key> + <string>Ignore pixel depth settings.</string> <key>map-to</key> - <string>DebugViews</string> + <string>IgnorePixelDepth</string> </map> - <key>skin</key> + <key>inbw</key> + <map> + <key>count</key> + <integer>1</integer> + <key>map-to</key> + <string>InBandwidth</string> + </map> + + <key>leap</key> <map> <key>desc</key> - <string>ui/branding skin folder to use</string> + <string>command line to run an LLSD Event API Plugin</string> <key>count</key> <integer>1</integer> + <!-- you can specify multiple such plugins --> + <key>compose</key> + <boolean>true</boolean> <key>map-to</key> - <string>SkinFolder</string> + <string>LeapCommand</string> </map> - <key>autologin</key> + <key>logfile</key> + <map> + <key>count</key> + <integer>1</integer> + <key>map-to</key> + <string>UserLogFile</string> + </map> + + <key>login</key> <map> <key>desc</key> - <string>log in as last saved user</string> + <string>3 tokens: first, last and password</string> + <key>count</key> + <integer>3</integer> <key>map-to</key> - <string>AutoLogin</string> + <string>UserLoginInfo</string> </map> - <key>quitafter</key> + <key>loginpage</key> <map> + <key>desc</key> + <string>Login authentication page to use.</string> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>QuitAfterSeconds</string> + <string>LoginPage</string> </map> - <key>logperformance</key> + <key>loginuri</key> <map> <key>desc</key> - <string>Log performance metrics for benchmarking</string> + <string>login server and CGI script to use</string> + <key>count</key> + <integer>1</integer> + <key>compose</key> + <boolean>true</boolean> <key>map-to</key> - <string>LogPerformance</string> + <string>CmdLineLoginURI</string> </map> <key>logmetrics</key> @@ -123,29 +205,35 @@ <key>map-to</key> <string>LogMetrics</string> </map> - - <key>analyzeperformance</key> + + <key>logperformance</key> <map> <key>desc</key> - <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string> + <string>Log performance metrics for benchmarking</string> <key>map-to</key> - <string>AnalyzePerformance</string> + <string>LogPerformance</string> </map> - <key>debugsession</key> + <key>multiple</key> <map> <key>desc</key> - <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string> + <string>Allow multiple viewers.</string> <key>map-to</key> - <string>DebugSession</string> + <string>AllowMultipleViewers</string> </map> - <key>replaysession</key> + <key>noaudio</key> + <map> + <key>map-to</key> + <string>NoAudio</string> + </map> + + <key>noinvlib</key> <map> <key>desc</key> - <string>After login, replay last recorded session and quit.</string> + <string>Do not request the inventory library.</string> <key>map-to</key> - <string>ReplaySession</string> + <string>NoInventoryLibrary</string> </map> <key>nonotifications</key> @@ -156,22 +244,10 @@ <string>IgnoreAllNotifications</string> </map> - <key>rotate</key> - <map> - <key>map-to</key> - <string>RotateRight</string> - </map> - - <key>noaudio</key> - <map> - <key>map-to</key> - <string>NoAudio</string> - </map> - - <key>nosound</key> + <key>nopreload</key> <map> <key>map-to</key> - <string>NoAudio</string> + <string>NoPreload</string> </map> <key>noprobe</key> @@ -186,151 +262,134 @@ <string>NoQuickTime</string> </map> - <key>nopreload</key> + <key>nosound</key> <map> <key>map-to</key> - <string>NoPreload</string> + <string>NoAudio</string> </map> - <key>purge</key> + <key>no-verify-ssl-cert</key> <map> - <key>desc</key> - <string>Delete files in the cache.</string> <key>map-to</key> - <string>PurgeCacheOnNextStartup</string> + <string>NoVerifySSLCert</string> </map> - <key>noinvlib</key> + <key>novoice</key> <map> <key>desc</key> - <string>Do not request the inventory library.</string> + <string>Disable voice.</string> <key>map-to</key> - <string>NoInventoryLibrary</string> + <string>CmdLineDisableVoice</string> </map> - <key>logfile</key> + <key>outbw</key> <map> <key>count</key> <integer>1</integer> <key>map-to</key> - <string>UserLogFile</string> + <string>OutBandwidth</string> </map> - <key>graphicslevel</key> + <key>port</key> <map> - <key>desc</key> - <string>Set the detail level. -0 - low, 1 - medium, 2 - high, 3 - ultra</string> <key>count</key> <integer>1</integer> + <key>map-to</key> + <string>UserConnectionPort</string> </map> - <key>setdefault</key> + <key>purge</key> <map> <key>desc</key> - <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string> - <key>count</key> - <integer>2</integer> - <!-- Special case. Mapped to settings procedurally. --> + <string>Delete files in the cache.</string> + <key>map-to</key> + <string>PurgeCacheOnNextStartup</string> </map> - <key>set</key> + <key>qa</key> <map> <key>desc</key> - <string>specify the value of a particular configuration variable that overrides all other settings.</string> - <key>count</key> - <integer>2</integer> - <key>compose</key> - <boolean>true</boolean> - <!-- Special case. Mapped to settings procedurally. --> + <string>Activated debugging menu in Advanced Settings.</string> + <key>map-to</key> + <string>QAMode</string> </map> - <key>settings</key> + <key>quitafter</key> <map> - <key>desc</key> - <string>Specify the filename of a configuration file.</string> <key>count</key> <integer>1</integer> - <!-- Special case. Mapped to settings procedurally. --> + <key>map-to</key> + <string>QuitAfterSeconds</string> </map> - - <key>sessionsettings</key> + + <key>replaysession</key> <map> <key>desc</key> - <string>Specify the filename of a configuration file that contains temporary per-session configuration overrides.</string> - <key>count</key> - <integer>1</integer> - <!-- Special case. Mapped to settings procedurally. --> + <string>After login, replay last recorded session and quit.</string> + <key>map-to</key> + <string>ReplaySession</string> </map> - <key>usersessionsettings</key> - <map> - <key>desc</key> - <string>Specify the filename of a configuration file that contains temporary per-session configuration user overrides.</string> - <key>count</key> - <integer>1</integer> - <!-- Special case. Mapped to settings procedurally. --> - </map> - - <key>login</key> + <key>rotate</key> <map> - <key>desc</key> - <string>3 tokens: first, last and password</string> - <key>count</key> - <integer>3</integer> <key>map-to</key> - <string>UserLoginInfo</string> + <string>RotateRight</string> </map> - <key>god</key> + <key>safe</key> <map> <key>desc</key> - <string>Log in a god if you have god access.</string> + <string>Reset preferences, run in safe mode.</string> <key>map-to</key> - <string>ConnectAsGod</string> + <string>SafeMode</string> </map> - <key>console</key> + <key>sessionsettings</key> <map> + <key>desc</key> + <string>Specify the filename of a configuration file that contains temporary per-session configuration overrides.</string> <key>count</key> <integer>1</integer> - <key>map-to</key> - <string>ShowConsoleWindow</string> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>safe</key> + <key>set</key> <map> <key>desc</key> - <string>Reset preferences, run in safe mode.</string> - <key>map-to</key> - <string>SafeMode</string> + <string>specify the value of a particular configuration variable that overrides all other settings.</string> + <key>count</key> + <integer>2</integer> + <key>compose</key> + <boolean>true</boolean> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>multiple</key> + <key>setdefault</key> <map> <key>desc</key> - <string>Allow multiple viewers.</string> - <key>map-to</key> - <string>AllowMultipleViewers</string> + <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string> + <key>count</key> + <integer>2</integer> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>novoice</key> + <key>settings</key> <map> <key>desc</key> - <string>Disable voice.</string> - <key>map-to</key> - <string>CmdLineDisableVoice</string> + <string>Specify the filename of a configuration file.</string> + <key>count</key> + <integer>1</integer> + <!-- Special case. Mapped to settings procedurally. --> </map> - <key>url</key> + <key>skin</key> <map> <key>desc</key> - <string>Startup location</string> + <string>ui/branding skin folder to use</string> <key>count</key> <integer>1</integer> - <key>last_option</key> - <boolean>true</boolean> - <!-- Special case. Not mapped to a setting. --> + <key>map-to</key> + <string>SkinFolder</string> </map> <key>slurl</key> @@ -346,69 +405,24 @@ <!-- Special case. Not mapped to a setting. --> </map> - <key>ignorepixeldepth</key> - <map> - <key>desc</key> - <string>Ignore pixel depth settings.</string> - <key>map-to</key> - <string>IgnorePixelDepth</string> - </map> - - <key>cooperative</key> + <key>url</key> <map> <key>desc</key> - <string>Yield some idle time to local host.</string> - <key>count</key> - <integer>1</integer> - <key>map-to</key> - <string>YieldTime</string> - </map> - - <key>no-verify-ssl-cert</key> - <map> - <key>map-to</key> - <string>NoVerifySSLCert</string> - </map> - - <key>channel</key> - <map> + <string>Startup location</string> <key>count</key> <integer>1</integer> + <key>last_option</key> + <boolean>true</boolean> <!-- Special case. Not mapped to a setting. --> </map> - <key>loginpage</key> + <key>usersessionsettings</key> <map> <key>desc</key> - <string>Login authentication page to use.</string> + <string>Specify the filename of a configuration file that contains temporary per-session configuration user overrides.</string> <key>count</key> <integer>1</integer> - <key>map-to</key> - <string>LoginPage</string> - </map> - - <key>qa</key> - <map> - <key>desc</key> - <string>Activated debugging menu in Advanced Settings.</string> - <key>map-to</key> - <string>QAMode</string> - </map> - - <key>crashonstartup</key> - <map> - <key>desc</key> - <string>Crashes on startup. For QA use.</string> - <key>map-to</key> - <string>CrashOnStartup</string> - </map> - - <key>disablecrashlogger</key> - <map> - <key>desc</key> - <string>Disables the crash logger and lets the OS handle crashes</string> - <key>map-to</key> - <string>DisableCrashLogger</string> + <!-- Special case. Mapped to settings procedurally. --> </map> </map> </llsd> diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index a76eb3cd37..64122bbb6c 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -20,7 +20,7 @@ <key>tags</key> <array> <string>AppInit</string> - <string>Capabilities</string> + <string>Capabilities</string> <string>SystemInfo</string> <string>TextureCache</string> <string>AppCache</string> @@ -42,8 +42,10 @@ </array> <key>tags</key> <array> - <!-- sample entry for debugging a specific item --> -<!-- <string>Voice</string> --> + <!-- sample entry for debugging specific items + <string>Avatar</string> + <string>Voice</string> + --> </array> </map> </array> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b7b040f98b..1928e53699 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -335,17 +335,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AuditTexture</key> - <map> - <key>Comment</key> - <string>Enable texture auditting.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>AutoAcceptNewInventory</key> <map> <key>Comment</key> @@ -1936,7 +1925,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>DebugBeaconLineWidth</key> <map> @@ -4601,6 +4590,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>LeapCommand</key> + <map> + <key>Comment</key> + <string>Zero or more command lines to run LLSD Event API Plugin programs.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>LLSD</string> + <key>Value</key> + <array /> + </map> <key>LSLFindCaseInsensitivity</key> <map> <key>Comment</key> @@ -7164,7 +7164,7 @@ <key>QAModeEventHostPort</key> <map> <key>Comment</key> - <string>Port on which lleventhost should listen</string> + <string>DEPRECATED: Port on which lleventhost should listen</string> <key>Persist</key> <integer>0</integer> <key>Type</key> @@ -7183,6 +7183,17 @@ <key>Value</key> <integer>-1</integer> </map> + <key>QAModeMetrics</key> + <map> + <key>Comment</key> + <string>"Enables QA features (logging, faster cycling) for metrics collector"</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>QuietSnapshotsToDisk</key> <map> <key>Comment</key> @@ -10690,6 +10701,39 @@ <key>Value</key> <real>20.0</real> </map> + <key>TexelPixelRatio</key> + <map> + <key>Comment</key> + <string>texel pixel ratio = texel / pixel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.0</real> + </map> + <key>TextureCameraMotionThreshold</key> + <map> + <key>Comment</key> + <string>If the overall motion is lower than this value, textures will be loaded faster</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.2</real> + </map> + <key>TextureCameraMotionBoost</key> + <map> + <key>Comment</key> + <string>Progressive discard level decrement when the camera is still</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>3</integer> + </map> <key>TextureDecodeDisabled</key> <map> <key>Comment</key> @@ -10723,6 +10767,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureFetchDebuggerEnabled</key> + <map> + <key>Comment</key> + <string>Enable the texture fetching debugger if set</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>TextureLoadFullRes</key> <map> <key>Comment</key> @@ -10745,6 +10800,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureNewByteRange</key> + <map> + <key>Comment</key> + <string>Use the new more accurate byte range computation for j2c discard levels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>TexturePickerShowFolders</key> <map> <key>Comment</key> @@ -10767,6 +10833,17 @@ <key>Value</key> <integer>2</integer> </map> + <key>TextureReverseByteRange</key> + <map> + <key>Comment</key> + <string>Minimal percent of the optimal byte range allowed to render a given discard level</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>50</integer> + </map> <key>ThrottleBandwidthKBPS</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index cf8cf8364a..bced4a5577 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -29,11 +29,11 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif -uniform float minimum_alpha; - uniform sampler2D diffuseMap; -VARYING vec4 post_pos; +VARYING float pos_zd2; +VARYING float pos_w; +VARYING float target_pos_x; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; @@ -41,12 +41,20 @@ void main() { float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a; - if (alpha < minimum_alpha) + if (alpha < 0.05) // treat as totally transparent { discard; } + if (alpha < 0.88) // treat as semi-transparent + { + if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) + { + discard; + } + } + frag_color = vec4(1,1,1,1); - gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); + gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl index 7d3b06c56e..c1f2d90712 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl @@ -25,12 +25,15 @@ uniform mat4 texture_matrix0; uniform mat4 modelview_projection_matrix; +uniform float shadow_target_width; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec2 texcoord0; -VARYING vec4 post_pos; +VARYING float pos_zd2; +VARYING float pos_w; +VARYING float target_pos_x; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; @@ -39,8 +42,11 @@ void passTextureIndex(); void main() { //transform vertex - vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0); - post_pos = pos; + vec4 pre_pos = vec4(position.xyz, 1.0); + vec4 pos = modelview_projection_matrix * pre_pos; + target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + pos_w = pos.w; + pos_zd2 = pos.z * 0.5; gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 08f6ec63fe..8db4cb58cf 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -58,20 +58,22 @@ uniform float shadow_bias; uniform mat4 inv_proj; -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; + + stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; + + return shadow*0.2; } @@ -101,7 +103,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; + shadow += pcfShadow(shadowMap3, lpos)*w; weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } @@ -114,7 +116,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap2, lpos)*w; weight += w; } @@ -126,7 +128,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; - shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap1, lpos)*w; weight += w; } @@ -138,7 +140,7 @@ void main() float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; - shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; + shadow += pcfShadow(shadowMap0, lpos)*w; weight += w; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl index aae6a070e2..33958a5010 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -71,20 +71,22 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; + + stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; + + return shadow*0.2; } @@ -114,7 +116,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; + shadow += pcfShadow(shadowMap3, lpos)*w; weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } @@ -127,7 +129,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap2, lpos)*w; weight += w; } @@ -139,7 +141,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; - shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap1, lpos)*w; weight += w; } @@ -151,7 +153,7 @@ void main() float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; - shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; + shadow += pcfShadow(shadowMap0, lpos)*w; weight += w; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index d6848c8dc1..2093fc37dc 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -72,20 +72,22 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; + + stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; + + return shadow*0.2; } @@ -122,7 +124,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; + shadow += pcfShadow(shadowMap3, lpos)*w; weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } @@ -135,7 +137,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap2, lpos)*w; weight += w; } @@ -147,7 +149,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; - shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap1, lpos)*w; weight += w; } @@ -159,7 +161,7 @@ void main() float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; - shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; + shadow += pcfShadow(shadowMap0, lpos)*w; weight += w; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 8c4ccf9cb3..db3d760359 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -78,42 +78,42 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += shadow_bias*scl; - + + stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); // add some jitter to X sample pos according to Y to disguise the snapping going on here + float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, -1.5, 0.0)).x; - return shadow/5.0; - - //return shadow; + return shadow*0.2; } -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += spot_shadow_bias*scl; + stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - vec2 off = 1.5/proj_shadow_res; + vec2 off = 1.0/proj_shadow_res; + off.y *= 1.5; - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); - - return shadow/5.0; - - //return shadow; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; + + return shadow*0.2; } void main() @@ -166,7 +166,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; + shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } @@ -179,7 +179,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w; weight += w; } @@ -191,7 +191,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; - shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w; weight += w; } @@ -203,7 +203,7 @@ void main() float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; - shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; + shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; weight += w; } @@ -237,11 +237,11 @@ void main() //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; - frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8); + frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen); //spotlight shadow 2 lpos = shadow_matrix[5]*spos; - frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8); + frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen); //frag_color.rgb = pos.xyz; //frag_color.b = shadow; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 02075a7687..dfe108eb01 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -90,7 +90,7 @@ vec2 getKern(int i) kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; - + return kern[i]; } @@ -139,42 +139,42 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) return min(ret, 1.0); } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += shadow_bias*scl; + + stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); - - return shadow/5.0; - //return shadow; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; + shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; + + return shadow*0.2; } -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += spot_shadow_bias*scl; + stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - vec2 off = 1.5/proj_shadow_res; + vec2 off = 1.0/proj_shadow_res; + off.y *= 1.5; - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); - shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); - - return shadow/5.0; - - //return shadow; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; + + return shadow*0.2; } void main() @@ -227,7 +227,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap3, lpos, 0.25)*w; + shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; weight += w; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } @@ -240,7 +240,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; - shadow += pcfShadow(shadowMap2, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w; weight += w; } @@ -252,7 +252,7 @@ void main() float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; - shadow += pcfShadow(shadowMap1, lpos, 0.75)*w; + shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w; weight += w; } @@ -264,7 +264,7 @@ void main() float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; - shadow += pcfShadow(shadowMap0, lpos, 1.0)*w; + shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w; weight += w; } @@ -298,11 +298,11 @@ void main() //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; - frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8); + frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen); //spotlight shadow 2 lpos = shadow_matrix[5]*spos; - frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8); + frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen); //frag_color.rgb = pos.xyz; //frag_color.b = shadow; diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 283a28a0aa..20936c6460 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -110,22 +110,34 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" # fi #fi -export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"${LD_LIBRARY_PATH}"' -export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin' -export SL_OPT="`cat etc/gridargs.dat` $@" - -# Run the program -eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr +export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" + +# Have to deal specially with gridargs.dat; typical contents look like: +# --channel "Second Life Developer" --settings settings_developer.xml +# Simply embedding $(<etc/gridargs.dat) into a command line treats each of +# Second, Life and Developer as separate args -- no good. We need bash to +# process quotes using eval. +# First read it without scanning, then scan that string. Break quoted words +# into a bash array. Note that if gridargs.dat is empty, or contains only +# whitespace, the resulting gridargs array will be empty -- zero entries -- +# therefore "${gridargs[@]}" entirely vanishes from the command line below, +# just as we want. +eval gridargs=("$(<etc/gridargs.dat)") + +# Run the program. +# Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the +# command line. But DO quote "$@": preserve separate args as individually +# quoted. Similar remarks about the contents of gridargs. +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@" +LL_RUN_ERR=$? # Handle any resulting errors -if [ -n "$LL_RUN_ERR" ]; then - LL_RUN_ERR_MSG="" - if [ "$LL_RUN_ERR" = "runerr" ]; then - # generic error running the binary - echo '*** Bad shutdown. ***' - if [ "`uname -m`" = "x86_64" ]; then - echo - cat << EOFMARKER +if [ $LL_RUN_ERR -ne 0 ]; then + # generic error running the binary + echo '*** Bad shutdown ($LL_RUN_ERR). ***' + if [ "$(uname -m)" = "x86_64" ]; then + echo + cat << EOFMARKER You are running the Second Life Viewer on a x86_64 platform. The most common problems when launching the Viewer (particularly 'bin/do-not-directly-run-secondlife-bin: not found' and 'error while @@ -134,10 +146,8 @@ distribution's 32-bit compatibility packages. For example, on Ubuntu and other Debian-based Linuxes you might run: $ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl EOFMARKER - fi fi fi - echo echo '*******************************************************' diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3870a3be2e..3367604753 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3253,6 +3253,10 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **) void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data) { gAgentQueryManager.mNumPendingQueries--; + if (gAgentQueryManager.mNumPendingQueries == 0) + { + selfStopPhase("fetch_texture_cache_entries"); + } if (!isAgentAvatarValid() || gAgentAvatarp->isDead()) { @@ -3302,13 +3306,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * else { // no cache of this bake. request upload. - gAgentAvatarp->requestLayerSetUpload(baked_index); + gAgentAvatarp->invalidateComposite(gAgentAvatarp->getLayerSet(baked_index),TRUE); } } } } } - llinfos << "Received cached texture response for " << num_results << " textures." << llendl; gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them"); @@ -3775,7 +3778,15 @@ void LLAgent::sendAgentSetAppearance() return; } - llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl; + if (!gAgentWearables.changeInProgress()) + { + // Change is fully resolved, can close some open phases. + gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update"); + gAgentAvatarp->getPhases().stopPhase("wear_inventory_category"); + } + + gAgentAvatarp->sendAppearanceChangeMetrics(); + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL; //dumpAvatarTEs( "sendAgentSetAppearance()" ); LLMessageSystem* msg = gMessageSystem; @@ -3822,14 +3833,14 @@ void LLAgent::sendAgentSetAppearance() // only update cache entries if we have all our baked textures if (textures_current) { - llinfos << "TAT: Sending cached texture data" << llendl; + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { BOOL generate_valid_hash = TRUE; if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index)) { generate_valid_hash = FALSE; - llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl; + LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL; } const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash); diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index a8d2222c03..a4c0b056ac 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -126,6 +126,17 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n" "[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at", &LLAgentListener::lookAt); + add("getGroups", + "Send information about the agent's groups on [\"reply\"]:\n" + "[\"groups\"]: array of group information\n" + "[\"id\"]: group id\n" + "[\"name\"]: group name\n" + "[\"insignia\"]: group insignia texture id\n" + "[\"notices\"]: boolean indicating if this user accepts notices from this group\n" + "[\"display\"]: boolean indicating if this group is listed in the user's profile\n" + "[\"contrib\"]: user's land contribution to this group\n", + &LLAgentListener::getGroups, + LLSDMap("reply", LLSD())); } void LLAgentListener::requestTeleport(LLSD const & event_data) const diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index dd02a74a38..e441f21f90 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -955,6 +955,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs if (isAgentAvatarValid()) { + //gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading. + gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update"); gAgentAvatarp->outputRezTiming("Received initial wearables update"); } @@ -1448,7 +1450,16 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); gAgentAvatarp->updateVisualParams(); - gAgentAvatarp->invalidateAll(); + + // If we have not yet declouded, we may want to use + // baked texture UUIDs sent from the first objectUpdate message + // don't overwrite these. If we have already declouded, we've saved + // these ids as the last known good textures and can invalidate without + // re-clouding. + if (!gAgentAvatarp->getIsCloud()) + { + gAgentAvatarp->invalidateAll(); + } } // Start rendering & update the server @@ -1630,10 +1641,11 @@ void LLAgentWearables::queryWearableCache() { if (isAgentAvatarValid()) { + selfStartPhase("fetch_texture_cache_entries"); gAgentAvatarp->outputRezTiming("Fetching textures from cache"); } - llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; + LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL; gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); gAgentQueryManager.mNumPendingQueries++; gAgentQueryManager.mWearablesCacheQueryID++; @@ -2081,6 +2093,11 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_ return mLoadedSignal.connect(cb); } +bool LLAgentWearables::changeInProgress() const +{ + return mCOFChangeInProgress; +} + void LLAgentWearables::notifyLoadingStarted() { mCOFChangeInProgress = true; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 01cae3ffd8..5932be21c6 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -233,6 +233,7 @@ public: typedef boost::signals2::signal<void()> loaded_signal_t; boost::signals2::connection addLoadedCallback(loaded_callback_t cb); + bool changeInProgress() const; void notifyLoadingStarted(); void notifyLoadingFinished(); diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 8cba54347e..e2417cdddb 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -89,6 +89,7 @@ LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) : { if (isAgentAvatarValid()) { + gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch"); gAgentAvatarp->outputRezTiming("Initial wearables fetch started"); } } @@ -107,6 +108,7 @@ void LLInitialWearablesFetch::done() doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this)); if (isAgentAvatarValid()) { + gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch"); gAgentAvatarp->outputRezTiming("Initial wearables fetch done"); } } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 33f5373d7e..faadfb4b87 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -50,6 +50,11 @@ #include "llviewerregion.h" #include "llwearablelist.h" +std::string self_av_string() +{ + return gAgentAvatarp->avString(); +} + // RAII thingy to guarantee that a variable gets reset when the Setter // goes out of scope. More general utility would be handy - TODO: // check boost. @@ -156,6 +161,10 @@ public: { mCatID = cat_id; mAppend = append; + + LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + + selfStartPhase("wear_inventory_category_callback"); } void fire(const LLUUID& item_id) { @@ -167,13 +176,16 @@ public: * after the last item has fired the event and dereferenced it -- if all * the events actually fire! */ + LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL; } protected: ~LLWearInventoryCategoryCallback() { - llinfos << "done all inventory callbacks" << llendl; + LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL; + selfStopPhase("wear_inventory_category_callback"); + // Is the destructor called by ordinary dereference, or because the app's shutting down? // If the inventory callback manager goes away, we're shutting down, no longer want the callback. if( LLInventoryCallbackManager::is_instantiated() ) @@ -182,7 +194,7 @@ protected: } else { - llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; + llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; } } @@ -212,11 +224,14 @@ LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit mFireCount(0), mUpdateBaseOrder(update_base_outfit_ordering) { + selfStartPhase("update_appearance_on_destroy"); } LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() { - llinfos << "done update appearance on destroy" << llendl; + LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL; + + selfStopPhase("update_appearance_on_destroy"); if (!LLApp::isExiting()) { @@ -229,7 +244,7 @@ void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item) LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item); const std::string item_name = item ? item->getName() : "ITEM NOT FOUND"; #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL; #endif mFireCount++; } @@ -339,11 +354,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern(): } sActiveHoldingPatterns.insert(this); + selfStartPhase("holding_pattern"); } LLWearableHoldingPattern::~LLWearableHoldingPattern() { sActiveHoldingPatterns.erase(this); + if (isMostRecent()) + { + selfStopPhase("holding_pattern"); + } } bool LLWearableHoldingPattern::isMostRecent() @@ -390,9 +410,10 @@ void LLWearableHoldingPattern::checkMissingWearables() { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway why don't we actually skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } - + std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0); std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0); for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it) @@ -408,7 +429,7 @@ void LLWearableHoldingPattern::checkMissingWearables() { if (requested_by_type[type] > found_by_type[type]) { - llwarns << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl; + llwarns << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl; } if (found_by_type[type] > 0) continue; @@ -425,11 +446,13 @@ void LLWearableHoldingPattern::checkMissingWearables() mTypesToRecover.insert(type); mTypesToLink.insert(type); recoverMissingWearable((LLWearableType::EType)type); - llwarns << "need to replace " << type << llendl; + llwarns << self_av_string() << "need to replace " << type << llendl; } } resetTime(60.0F); + + selfStartPhase("get_missing_wearables"); if (!pollMissingWearables()) { doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); @@ -445,13 +468,14 @@ void LLWearableHoldingPattern::onAllComplete() if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway need to skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } // Activate all gestures in this folder if (mGestItems.count() > 0) { - llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.count() << " gestures" << LL_ENDL; LLGestureMgr::instance().activateGestures(mGestItems); @@ -468,13 +492,13 @@ void LLWearableHoldingPattern::onAllComplete() } // Update wearables. - llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; + LL_INFOS("Avatar") << self_av_string() << "Updating agent wearables with " << mResolved << " wearable items " << LL_ENDL; LLAppearanceMgr::instance().updateAgentWearables(this, false); // Update attachments to match those requested. if (isAgentAvatarValid()) { - llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.count() << " attachments" << LL_ENDL; LLAgentWearables::userUpdateAttachments(mObjItems); } @@ -492,9 +516,12 @@ void LLWearableHoldingPattern::onAllComplete() void LLWearableHoldingPattern::onFetchCompletion() { + selfStopPhase("get_wearables"); + if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } checkMissingWearables(); @@ -505,7 +532,8 @@ bool LLWearableHoldingPattern::pollFetchCompletion() { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } bool completed = isFetchCompleted(); @@ -514,14 +542,14 @@ bool LLWearableHoldingPattern::pollFetchCompletion() if (done) { - llinfos << "polling, done status: " << completed << " timed out " << timed_out - << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + LL_INFOS("Avatar") << self_av_string() << "polling, done status: " << completed << " timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL; mFired = true; if (timed_out) { - llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; + llwarns << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; } onFetchCompletion(); @@ -543,6 +571,7 @@ public: if (!mHolder->isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? } llinfos << "Recovered item link for type " << mType << llendl; @@ -569,12 +598,12 @@ public: } else { - llwarns << "inventory item not found for recovered wearable" << llendl; + llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; } } else { - llwarns << "inventory link not found for recovered wearable" << llendl; + llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; } } private: @@ -596,10 +625,11 @@ public: { if (!mHolder->isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } - llinfos << "Recovered item for type " << mType << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL; LLViewerInventoryItem *itemp = gInventory.getItem(item_id); mWearable->setItemID(item_id); LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder); @@ -626,7 +656,8 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } // Try to recover by replacing missing wearable with a new one. @@ -665,7 +696,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable)) { // Wearable link that was never resolved; remove links to it from COF - llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl; + LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL; LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false); } } @@ -675,7 +706,8 @@ bool LLWearableHoldingPattern::pollMissingWearables() { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + // runway skip here? + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } bool timed_out = isTimedOut(); @@ -684,15 +716,17 @@ bool LLWearableHoldingPattern::pollMissingWearables() if (!done) { - llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() + LL_INFOS("Avatar") << self_av_string() << "polling missing wearables, waiting for items " << mTypesToRecover.size() << " links " << mTypesToLink.size() << " wearables, timed out " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() - << " done " << done << llendl; + << " done " << done << LL_ENDL; } if (done) { + selfStopPhase("get_missing_wearables"); + gAgentAvatarp->debugWearablesLoaded(); // BAP - if we don't call clearCOFLinksForMissingWearables() @@ -722,14 +756,14 @@ void LLWearableHoldingPattern::handleLateArrivals() } if (!isMostRecent()) { - llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl; + llwarns << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << llendl; } if (!mIsAllComplete) { - llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl; + llwarns << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << llendl; } - llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl; + LL_INFOS("Avatar") << self_av_string() << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL; // Update mFoundList using late-arriving wearables. std::set<LLWearableType::EType> replaced_types; @@ -805,19 +839,19 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) { if (!isMostRecent()) { - llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; + llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; } mResolved += 1; // just counting callbacks, not successes. - llinfos << "resolved " << mResolved << "/" << getFoundList().size() << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL; if (!wearable) { - llwarns << "no wearable found" << llendl; + llwarns << self_av_string() << "no wearable found" << llendl; } if (mFired) { - llwarns << "called after holder fired" << llendl; + llwarns << self_av_string() << "called after holder fired" << llendl; if (wearable) { mLateArrivals.insert(wearable); @@ -843,7 +877,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable) // Failing this means inventory or asset server are corrupted in a way we don't handle. if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType)) { - llwarns << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl; + llwarns << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl; break; } @@ -1391,8 +1425,8 @@ void LLAppearanceMgr::filterWearableItems( // Create links to all listed items. void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, - LLInventoryModel::item_array_t& items, - LLPointer<LLInventoryCallback> cb) + LLInventoryModel::item_array_t& items, + LLPointer<LLInventoryCallback> cb) { for (S32 i=0; i<items.count(); i++) { @@ -1408,7 +1442,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid); const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND"; #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL; #endif } } @@ -1416,7 +1450,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) { LLViewerInventoryCategory *pcat = gInventory.getCategory(category); - llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl; + LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL; const LLUUID cof = getCOF(); @@ -1478,26 +1512,26 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) gInventory.notifyObservers(); // Create links to new COF contents. - llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL; LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking body items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL; #endif linkAll(cof, body_items, link_waiter); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking wear items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL; #endif linkAll(cof, wear_items, link_waiter); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking obj items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL; #endif linkAll(cof, obj_items, link_waiter); #ifndef LL_RELEASE_FOR_DOWNLOAD - llinfos << "Linking gesture items" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL; #endif linkAll(cof, gest_items, link_waiter); @@ -1506,7 +1540,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) { createBaseOutfitLink(category, link_waiter); } - llinfos << "waiting for LLUpdateAppearanceOnDestroy" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL; } void LLAppearanceMgr::updatePanelOutfitName(const std::string& name) @@ -1663,7 +1697,7 @@ void LLAppearanceMgr::enforceItemRestrictions() ++it) { LLViewerInventoryItem *item = *it; - llinfos << "purging duplicate or excess item " << item->getName() << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "purging duplicate or excess item " << item->getName() << LL_ENDL; gInventory.purgeObject(item->getUUID()); } gInventory.notifyObservers(); @@ -1678,9 +1712,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) return; } + LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof"); + BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); - llinfos << "starting" << llendl; + LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; //checking integrity of the COF in terms of ordering of wearables, //checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) @@ -1772,12 +1808,14 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) } } + selfStartPhase("get_wearables"); + for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin(); it != holder->getFoundList().end(); ++it) { LLFoundData& found = *it; - lldebugs << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; + lldebugs << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; // Fetch the wearables about to be worn. LLWearableList::instance().getAsset(found.mAssetID, @@ -1849,11 +1887,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool { if(!category) return; + selfClearPhases(); + selfStartPhase("wear_inventory_category"); + gAgentWearables.notifyLoadingStarted(); - llinfos << "wearInventoryCategory( " << category->getName() - << " )" << llendl; + LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName() + << " )" << LL_ENDL; + selfStartPhase("wear_inventory_category_fetch"); callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, &LLAppearanceMgr::instance(), category->getUUID(), copy, append)); @@ -1861,7 +1903,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append) { - llinfos << "starting" << llendl; + LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + + selfStopPhase("wear_inventory_category_fetch"); // We now have an outfit ready to be copied to agent inventory. Do // it, and wear that outfit normally. @@ -1944,8 +1988,8 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego // wearables being dirty. if(!category) return; - llinfos << "wearInventoryCategoryOnAvatar( " << category->getName() - << " )" << llendl; + LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName() + << "'" << LL_ENDL; if (gAgentCamera.cameraCustomizeAvatar()) { @@ -1958,7 +2002,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego void LLAppearanceMgr::wearOutfitByName(const std::string& name) { - llinfos << "Wearing category " << name << llendl; + LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL; //inc_busy_count(); LLInventoryModel::cat_array_t cat_array; @@ -2281,7 +2325,7 @@ const std::string OTHER_GESTURES_FOLDER = "Other Gestures"; void LLAppearanceMgr::copyLibraryGestures() { - llinfos << "Copying library gestures" << llendl; + LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL; // Copy gestures LLUUID lib_gesture_cat_id = @@ -2337,11 +2381,11 @@ void LLAppearanceMgr::copyLibraryGestures() LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name); if (cat_id.isNull()) { - llwarns << "failed to find gesture folder for " << folder_name << llendl; + llwarns << self_av_string() << "failed to find gesture folder for " << folder_name << llendl; } else { - llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL; callAfterCategoryFetch(cat_id, boost::bind(&LLAppearanceMgr::shallowCopyCategory, &LLAppearanceMgr::instance(), @@ -2355,7 +2399,7 @@ void LLAppearanceMgr::autopopulateOutfits() // If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account) // then auto-populate outfits from the library into the My Outfits folder. - llinfos << "avatar fully visible" << llendl; + LL_INFOS("Avatar") << self_av_string() << "avatar fully visible" << LL_ENDL; static bool check_populate_my_outfits = true; if (check_populate_my_outfits && @@ -2731,7 +2775,7 @@ void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg) } void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, - const std::string& msg) + const std::string& msg) { for (S32 i=0; i<items.count(); i++) { @@ -2742,9 +2786,8 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, { asset_id = linked_item->getAssetUUID(); } - llinfos << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << llendl; + LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL; } - llinfos << llendl; } LLAppearanceMgr::LLAppearanceMgr(): diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3fabb48e21..062551a3e8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -94,6 +94,7 @@ #include "llsecondlifeurls.h" #include "llupdaterservice.h" #include "llcallfloater.h" +#include "llfloatertexturefetchdebugger.h" // Linden library includes #include "llavatarnamecache.h" @@ -112,6 +113,8 @@ #include "llnotifications.h" #include "llnotificationsutil.h" +#include "llleap.h" + // Third party library includes #include <boost/bind.hpp> #include <boost/foreach.hpp> @@ -125,7 +128,6 @@ #endif #include "llapr.h" -#include "apr_dso.h" #include <boost/lexical_cast.hpp> #include "llviewerkeyboard.h" @@ -162,6 +164,7 @@ #include "llcontainerview.h" #include "lltooltip.h" +#include "llsdutil.h" #include "llsdserialize.h" #include "llworld.h" @@ -562,7 +565,6 @@ static void settings_modify() LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession; gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); - gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); } class LLFastTimerLogThread : public LLThread @@ -736,12 +738,12 @@ bool LLAppViewer::init() { // Viewer metrics initialization - static LLCachedControl<bool> metrics_submode(gSavedSettings, - "QAModeMetrics", - false, - "Enables QA features (logging, faster cycling) for metrics collector"); + //static LLCachedControl<bool> metrics_submode(gSavedSettings, + // "QAModeMetrics", + // false, + // "Enables QA features (logging, faster cycling) for metrics collector"); - if (metrics_submode) + if (gSavedSettings.getBOOL("QAModeMetrics")) { app_metrics_qa_mode = true; app_metrics_interval = METRICS_INTERVAL_QA; @@ -1052,11 +1054,38 @@ bool LLAppViewer::init() gGLActive = FALSE; + + // Iterate over --leap command-line options. But this is a bit tricky: if + // there's only one, it won't be an array at all. + LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand")); + LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL; + if (LeapCommand.isDefined() && ! LeapCommand.isArray()) + { + // If LeapCommand is actually a scalar value, make an array of it. + // Have to do it in two steps because LeapCommand.append(LeapCommand) + // trashes content! :-P + LLSD item(LeapCommand); + LeapCommand.append(item); + } + BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand)) + { + LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL; + // We don't have any better description of this plugin than the + // user-specified command line. Passing "" causes LLLeap to derive a + // description from the command line itself. + // Suppress LLLeap::Error exception: trust LLLeap's own logging. We + // don't consider any one --leap command mission-critical, so if one + // fails, log it, shrug and carry on. + LLLeap::create("", leap, false); // exception=false + } + if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0) { - loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort")); + LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: " + << "lleventhost no longer supported as a dynamic library" + << LL_ENDL; } - + LLViewerMedia::initClass(); LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ; @@ -1235,7 +1264,7 @@ bool LLAppViewer::mainLoop() if(mem_leak_instance) { mem_leak_instance->idle() ; - } + } // canonical per-frame event mainloop.post(newFrame); @@ -1357,13 +1386,11 @@ bool LLAppViewer::mainLoop() ms_sleep(500); } - static const F64 FRAME_SLOW_THRESHOLD = 0.5; //2 frames per seconds const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second idleTimer.reset(); - bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ; S32 total_work_pending = 0; S32 total_io_pending = 0; - while(!is_slow)//do not unpause threads if the frame rates are very low. + while(1) { S32 work_pending = 0; S32 io_pending = 0; @@ -1423,6 +1450,17 @@ bool LLAppViewer::mainLoop() LLLFSThread::sLocal->pause(); } + //texture fetching debugger + if(LLTextureFetchDebugger::isEnabled()) + { + LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = + LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); + if(tex_fetch_debugger_instance) + { + tex_fetch_debugger_instance->idle() ; + } + } + if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && (frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) { @@ -1531,17 +1569,24 @@ bool LLAppViewer::cleanup() gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp"); } - // *TODO - generalize this and move DSO wrangling to a helper class -brad - std::set<struct apr_dso_handle_t *>::const_iterator i; - for(i = mPlugins.begin(); i != mPlugins.end(); ++i) { - int (*ll_plugin_stop_func)(void) = NULL; - apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop"); - ll_plugin_stop_func(); - - rv = apr_dso_unload(*i); - } - mPlugins.clear(); + // Kill off LLLeap objects. We can find them all because LLLeap is derived + // from LLInstanceTracker. But collect instances first: LLInstanceTracker + // specifically forbids adding/deleting instances while iterating. + std::vector<LLLeap*> leaps; + leaps.reserve(LLLeap::instanceCount()); + for (LLLeap::instance_iter li(LLLeap::beginInstances()), lend(LLLeap::endInstances()); + li != lend; ++li) + { + leaps.push_back(&*li); + } + // Okay, now trash them all. We don't have to NULL or erase the entry + // in 'leaps' because the whole vector is going away momentarily. + BOOST_FOREACH(LLLeap* leap, leaps) + { + delete leap; + } + } // destroy 'leaps' //flag all elements as needing to be destroyed immediately // to ensure shutdown order @@ -1966,7 +2011,7 @@ bool LLAppViewer::initThreads() static const bool enable_threads = true; #endif - LLImage::initClass(); + LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); LLVFSThread::initClass(enable_threads && false); LLLFSThread::initClass(enable_threads && false); @@ -4214,6 +4259,7 @@ void LLAppViewer::idle() // The 5-second interval is nice for this purpose. If the object debug // bit moves or is disabled, please give this a suitable home. LLViewerAssetStatsFF::record_fps_main(gFPSClamped); + LLViewerAssetStatsFF::record_avatar_stats(); } } @@ -4261,7 +4307,8 @@ void LLAppViewer::idle() static LLTimer report_interval; // *TODO: Add configuration controls for this - if (report_interval.getElapsedTimeF32() >= app_metrics_interval) + F32 seconds = report_interval.getElapsedTimeF32(); + if (seconds >= app_metrics_interval) { metricsSend(! gDisconnected); report_interval.reset(); @@ -4971,87 +5018,6 @@ void LLAppViewer::handleLoginComplete() writeDebugInfo(); } -// *TODO - generalize this and move DSO wrangling to a helper class -brad -void LLAppViewer::loadEventHostModule(S32 listen_port) -{ - std::string dso_name = -#if LL_WINDOWS - "lleventhost.dll"; -#elif LL_DARWIN - "liblleventhost.dylib"; -#else - "liblleventhost.so"; -#endif - - std::string dso_path = gDirUtilp->findFile(dso_name, - gDirUtilp->getAppRODataDir(), - gDirUtilp->getExecutableDir()); - - if(dso_path == "") - { - llerrs << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl; - return; - } - - LL_INFOS("eventhost") << "Found lleventhost at '" << dso_path << "'" << LL_ENDL; -#if ! defined(LL_WINDOWS) - { - std::string outfile("/tmp/lleventhost.file.out"); - std::string command("file '" + dso_path + "' > '" + outfile + "' 2>&1"); - int rc = system(command.c_str()); - if (rc != 0) - { - LL_WARNS("eventhost") << command << " ==> " << rc << ':' << LL_ENDL; - } - else - { - LL_INFOS("eventhost") << command << ':' << LL_ENDL; - } - { - std::ifstream reader(outfile.c_str()); - std::string line; - while (std::getline(reader, line)) - { - size_t len = line.length(); - if (len && line[len-1] == '\n') - line.erase(len-1); - LL_INFOS("eventhost") << line << LL_ENDL; - } - } - remove(outfile.c_str()); - } -#endif // LL_WINDOWS - - apr_dso_handle_t * eventhost_dso_handle = NULL; - apr_pool_t * eventhost_dso_memory_pool = NULL; - - //attempt to load the shared library - apr_pool_create(&eventhost_dso_memory_pool, NULL); - apr_status_t rv = apr_dso_load(&eventhost_dso_handle, - dso_path.c_str(), - eventhost_dso_memory_pool); - llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle)); - llassert_always(eventhost_dso_handle != NULL); - - int (*ll_plugin_start_func)(LLSD const &) = NULL; - rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_start_func, eventhost_dso_handle, "ll_plugin_start"); - - llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle)); - llassert_always(ll_plugin_start_func != NULL); - - LLSD args; - args["listen_port"] = listen_port; - - int status = ll_plugin_start_func(args); - - if(status != 0) - { - llerrs << "problem loading eventhost plugin, status: " << status << llendl; - } - - mPlugins.insert(eventhost_dso_handle); -} - void LLAppViewer::launchUpdater() { LLSD query_map = LLSD::emptyMap(); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 71a7868191..f7d019ccba 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -41,8 +41,6 @@ class LLTextureFetch; class LLWatchdogTimeout; class LLUpdaterService; -struct apr_dso_handle_t; - class LLAppViewer : public LLApp { public: @@ -220,8 +218,6 @@ private: void sendLogoutRequest(); void disconnectViewer(); - - void loadEventHostModule(S32 listen_port); // *FIX: the app viewer class should be some sort of singleton, no? // Perhaps its child class is the singleton and this should be an abstract base. @@ -270,8 +266,6 @@ private: LLAllocator mAlloc; - std::set<struct apr_dso_handle_t*> mPlugins; - LLFrameTimer mMemCheckTimer; boost::scoped_ptr<LLUpdaterService> mUpdater; diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index b1cd83a1fb..706bc42ea0 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -33,6 +33,7 @@ #include "llagentpicksinfo.h" #include "lldateutil.h" #include "llviewergenericmessage.h" +#include "llstartup.h" // Linden library includes #include "llavatarconstants.h" // AVATAR_TRANSACTED, etc. @@ -113,6 +114,14 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) { + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this, the AvatarPropertiesRequest message + // won't work so don't bother trying + if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) + { + return; + } + if (isPendingRequest(avatar_id, APT_PROPERTIES)) { // waiting for a response, don't re-request diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 65c61c4a8b..17d403bbe1 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -342,6 +342,15 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv) return parseAndStoreResults(clp); } +// TODO: +// - Break out this funky parsing logic into separate method +// - Unit-test it with tests like LLStringUtil::getTokens() (the command-line +// overload that supports quoted tokens) +// - Unless this logic offers significant semantic benefits, replace it with +// LLStringUtil::getTokens(). This would fix a known bug: you cannot --set a +// string-valued variable to the empty string, because empty strings are +// eliminated below. + bool LLCommandLineParser::parseCommandLineString(const std::string& str) { // Split the string content into tokens diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 7d3170cb76..29b1d23d7d 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -68,8 +68,6 @@ LLDebugView::~LLDebugView() gDebugView = NULL; gTextureView = NULL; gSceneView = NULL; - gTextureSizeView = NULL; - gTextureCategoryView = NULL; } void LLDebugView::init() @@ -117,35 +115,11 @@ void LLDebugView::init() LLTextureView::Params tvp; tvp.name("gTextureView"); tvp.rect(r); - tvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); + tvp.follows.flags(FOLLOWS_TOP|FOLLOWS_LEFT); tvp.visible(false); gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp); addChild(gTextureView); //gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); - - - if(gAuditTexture) - { - r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); - LLTextureSizeView::Params tsv ; - tsv.name("gTextureSizeView"); - tsv.rect(r); - tsv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); - tsv.visible(false); - gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsv); - addChild(gTextureSizeView); - gTextureSizeView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_SIZE) ; - - r.set(150, rect.getHeight() - 50, 900 + LLViewerTexture::getTotalNumOfCategories() * 30, 100); - LLTextureSizeView::Params tcv ; - tcv.name("gTextureCategoryView"); - tcv.rect(r); - tcv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); - tcv.visible(false); - gTextureCategoryView = LLUICtrlFactory::create<LLTextureSizeView>(tcv); - gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY); - addChild(gTextureCategoryView); - } } void LLDebugView::draw() diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index a93b2b71de..bf8338e5f2 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -216,12 +216,14 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } +#if 0 //THIS CAUSES MAINT-1092 bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete(); if (use_fbo) { gPipeline.mWaterDis.bindTarget(); } +#endif LLGLSLShader::bindNoShader(); LLVertexBuffer::unbind(); @@ -256,10 +258,12 @@ BOOL LLViewerDynamicTexture::updateAllInstances() } } +#if 0 if (use_fbo) { gPipeline.mWaterDis.flush(); } +#endif return ret; } diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp index ed1d7e860a..9480e54809 100644 --- a/indra/newview/llexternaleditor.cpp +++ b/indra/newview/llexternaleditor.cpp @@ -29,6 +29,9 @@ #include "lltrans.h" #include "llui.h" +#include "llprocess.h" +#include "llsdutil.h" +#include <boost/foreach.hpp> // static const std::string LLExternalEditor::sFilenameMarker = "%s"; @@ -45,19 +48,8 @@ LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env return EC_NOT_SPECIFIED; } - // Add the filename marker if missing. - if (cmd.find(sFilenameMarker) == std::string::npos) - { - cmd += " \"" + sFilenameMarker + "\""; - llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl; - } - string_vec_t tokens; - if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s) - { - llwarns << "Error parsing editor command" << llendl; - return EC_PARSE_ERROR; - } + tokenize(tokens, cmd); // Check executable for existence. std::string bin_path = tokens[0]; @@ -68,51 +60,48 @@ LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env } // Save command. - mProcess.setExecutable(bin_path); - mArgs.clear(); + mProcessParams = LLProcess::Params(); + mProcessParams.executable = bin_path; for (size_t i = 1; i < tokens.size(); ++i) { - if (i > 1) mArgs += " "; - mArgs += "\"" + tokens[i] + "\""; + mProcessParams.args.add(tokens[i]); } - llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl; + + // Add the filename marker if missing. + if (cmd.find(sFilenameMarker) == std::string::npos) + { + mProcessParams.args.add(sFilenameMarker); + llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl; + } + + llinfos << "Setting command [" << mProcessParams << "]" << llendl; return EC_SUCCESS; } LLExternalEditor::EErrorCode LLExternalEditor::run(const std::string& file_path) { - std::string args = mArgs; - if (mProcess.getExecutable().empty() || args.empty()) + if (std::string(mProcessParams.executable).empty() || mProcessParams.args.empty()) { llwarns << "Editor command not set" << llendl; return EC_NOT_SPECIFIED; } - // Substitute the filename marker in the command with the actual passed file name. - LLStringUtil::replaceString(args, sFilenameMarker, file_path); - - // Split command into separate tokens. - string_vec_t tokens; - tokenize(tokens, args); + // Copy params block so we can replace sFilenameMarker + LLProcess::Params params; + params.executable = mProcessParams.executable; - // Set process arguments taken from the command. - mProcess.clearArguments(); - for (string_vec_t::const_iterator arg_it = tokens.begin(); arg_it != tokens.end(); ++arg_it) - { - mProcess.addArgument(*arg_it); - } - - // Run the editor. - llinfos << "Running editor command [" << mProcess.getExecutable() + " " + args << "]" << llendl; - int result = mProcess.launch(); - if (result == 0) + // Substitute the filename marker in the command with the actual passed file name. + BOOST_FOREACH(const std::string& arg, mProcessParams.args) { - // Prevent killing the process in destructor (will add it to the zombies list). - mProcess.orphan(); + std::string fixed(arg); + LLStringUtil::replaceString(fixed, sFilenameMarker, file_path); + params.args.add(fixed); } - return result == 0 ? EC_SUCCESS : EC_FAILED_TO_RUN; + // Run the editor. Prevent killing the process in destructor. + params.autokill = false; + return LLProcess::create(params) ? EC_SUCCESS : EC_FAILED_TO_RUN; } // static @@ -130,6 +119,12 @@ std::string LLExternalEditor::getErrorMessage(EErrorCode code) return LLTrans::getString("Unknown"); } +// TODO: +// - Unit-test this with tests like LLStringUtil::getTokens() (the +// command-line overload that supports quoted tokens) +// - Unless there are significant semantic differences, eliminate this method +// and use LLStringUtil::getTokens() instead. + // static size_t LLExternalEditor::tokenize(string_vec_t& tokens, const std::string& str) { diff --git a/indra/newview/llexternaleditor.h b/indra/newview/llexternaleditor.h index ef5db56c6e..fd2c25020c 100644 --- a/indra/newview/llexternaleditor.h +++ b/indra/newview/llexternaleditor.h @@ -27,7 +27,7 @@ #ifndef LL_LLEXTERNALEDITOR_H #define LL_LLEXTERNALEDITOR_H -#include <llprocesslauncher.h> +#include "llprocess.h" /** * Usage: @@ -97,9 +97,7 @@ private: */ static const std::string sSetting; - - std::string mArgs; - LLProcessLauncher mProcess; + LLProcess::Params mProcessParams; }; #endif // LL_LLEXTERNALEDITOR_H diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp new file mode 100644 index 0000000000..2b34b72055 --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -0,0 +1,390 @@ +/** + * @file llfloatertexturefetchdebugger.cpp + * @brief LLFloaterTextureFetchDebugger class definition + * + * $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 "llfloatertexturefetchdebugger.h" + +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llspinctrl.h" +#include "llresmgr.h" + +#include "llmath.h" +#include "llviewerwindow.h" +#include "llappviewer.h" +#include "lltexturefetch.h" +#include "llviewercontrol.h" + +LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) + : LLFloater(key), + mDebugger(NULL) +{ + setTitle("Texture Fetching Debugger Floater"); + + mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this)); + + mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this)); + + mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this)); + + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); +} +//---------------------------------------------- + +BOOL LLFloaterTextureFetchDebugger::postBuild(void) +{ + mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); + + //set states for buttons + mButtonStateMap["start_btn"] = true; + mButtonStateMap["close_btn"] = true; + mButtonStateMap["clear_btn"] = true; + mButtonStateMap["cacheread_btn"] = false; + mButtonStateMap["cachewrite_btn"] = false; + mButtonStateMap["http_btn"] = false; + mButtonStateMap["decode_btn"] = false; + mButtonStateMap["gl_btn"] = false; + + mButtonStateMap["refetchviscache_btn"] = true; + mButtonStateMap["refetchvishttp_btn"] = true; + + updateButtons(); + + getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio")); + + return TRUE ; +} + +LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() +{ + //stop everything + mDebugger->stopDebug(); +} + +void LLFloaterTextureFetchDebugger::updateButtons() +{ + for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter) + { + if(iter->second) + { + childEnable(iter->first.c_str()); + } + else + { + childDisable(iter->first.c_str()); + } + } +} + +void LLFloaterTextureFetchDebugger::disableButtons() +{ + childDisable("start_btn"); + childDisable("clear_btn"); + childDisable("cacheread_btn"); + childDisable("cachewrite_btn"); + childDisable("http_btn"); + childDisable("decode_btn"); + childDisable("gl_btn"); + childDisable("refetchviscache_btn"); + childDisable("refetchvishttp_btn"); +} + +void LLFloaterTextureFetchDebugger::idle() +{ + LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); + + if(mDebugger->update()) + { + switch(state) + { + case LLTextureFetchDebugger::IDLE: + break; + case LLTextureFetchDebugger::READ_CACHE: + mButtonStateMap["cachewrite_btn"] = true; + mButtonStateMap["decode_btn"] = true; + updateButtons(); + break; + case LLTextureFetchDebugger::WRITE_CACHE: + updateButtons(); + break; + case LLTextureFetchDebugger::DECODING: + mButtonStateMap["gl_btn"] = true; + updateButtons(); + break; + case LLTextureFetchDebugger::HTTP_FETCHING: + mButtonStateMap["cacheread_btn"] = true; + mButtonStateMap["cachewrite_btn"] = true; + mButtonStateMap["decode_btn"] = true; + updateButtons(); + break; + case LLTextureFetchDebugger::GL_TEX: + updateButtons(); + break; + case LLTextureFetchDebugger::REFETCH_VIS_CACHE: + updateButtons(); + case LLTextureFetchDebugger::REFETCH_VIS_HTTP: + updateButtons(); + break; + default: + break; + } + } +} + +//---------------------- +void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio() +{ + gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal()); +} + +void LLFloaterTextureFetchDebugger::onClickStart() +{ + disableButtons(); + + mDebugger->startDebug(); + + mButtonStateMap["start_btn"] = false; + mButtonStateMap["cacheread_btn"] = true; + mButtonStateMap["http_btn"] = true; + updateButtons(); +} + +void LLFloaterTextureFetchDebugger::onClickClose() +{ + setVisible(FALSE); + + //stop everything + mDebugger->stopDebug(); +} + +void LLFloaterTextureFetchDebugger::onClickClear() +{ + mButtonStateMap["start_btn"] = true; + mButtonStateMap["close_btn"] = true; + mButtonStateMap["clear_btn"] = true; + mButtonStateMap["cacheread_btn"] = false; + mButtonStateMap["cachewrite_btn"] = false; + mButtonStateMap["http_btn"] = false; + mButtonStateMap["decode_btn"] = false; + mButtonStateMap["gl_btn"] = false; + mButtonStateMap["refetchviscache_btn"] = true; + mButtonStateMap["refetchvishttp_btn"] = true; + updateButtons(); + + //stop everything + mDebugger->stopDebug(); + mDebugger->clearHistory(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheRead() +{ + disableButtons(); + + mDebugger->debugCacheRead(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheWrite() +{ + disableButtons(); + + mDebugger->debugCacheWrite(); +} + +void LLFloaterTextureFetchDebugger::onClickHTTPLoad() +{ + disableButtons(); + + mDebugger->debugHTTP(); +} + +void LLFloaterTextureFetchDebugger::onClickDecode() +{ + disableButtons(); + + mDebugger->debugDecoder(); +} + +void LLFloaterTextureFetchDebugger::onClickGLTexture() +{ + disableButtons(); + + mDebugger->debugGLTextureCreation(); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() +{ + disableButtons(); + + mDebugger->debugRefetchVisibleFromCache(); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() +{ + disableButtons(); + + mDebugger->debugRefetchVisibleFromHTTP(); +} + +void LLFloaterTextureFetchDebugger::draw() +{ + //total number of fetched textures + { + getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures())); + } + + //total number of fetching requests + { + getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests())); + } + + //total number of cache hits + { + getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits())); + } + + //total number of visible textures + { + getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures())); + } + + //total number of visible texture fetching requests + { + getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests())); + } + + //total number of fetched data + { + getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10)); + getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10)); + getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f)); + } + + //total number of visible fetched data + { + getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10)); + getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10)); + } + + //total number of rendered fetched data + { + getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10)); + getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10)); + getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f)); + } + + //total time on cache readings + if(mDebugger->getCacheReadTime() < 0.f) + { + getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime())); + } + + //total time on cache writings + if(mDebugger->getCacheWriteTime() < 0.f) + { + getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime())); + } + + //total time on decoding + if(mDebugger->getDecodeTime() < 0.f) + { + getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime())); + } + + //total time on gl texture creation + if(mDebugger->getGLCreationTime() < 0.f) + { + getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime())); + } + + //total time on HTTP fetching + if(mDebugger->getHTTPTime() < 0.f) + { + getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime())); + } + + //total time on entire fetching + { + getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime())); + } + + //total time on refetching visible textures from cache + if(mDebugger->getRefetchVisCacheTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); + } + + //total time on refetching visible textures from http + if(mDebugger->getRefetchVisHTTPTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); + } + + LLFloater::draw(); +} diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h new file mode 100644 index 0000000000..33012c6a3d --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -0,0 +1,71 @@ +/** + * @file llfloatertexturefetchdebugger.h + * @brief texture fetching debugger window, debug use only + * + * $LicenseInfo:firstyear=2004&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_FLOATER_TEXTURE_FETCH_DEBUGGER__H +#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H + +#include "llfloater.h" +class LLTextureFetchDebugger; + +class LLFloaterTextureFetchDebugger : public LLFloater +{ + friend class LLFloaterReg; +public: + /// initialize all the callbacks for the menu + + virtual BOOL postBuild() ; + virtual void draw() ; + + void onChangeTexelPixelRatio(); + + void onClickStart(); + void onClickClear(); + void onClickClose(); + + void onClickCacheRead(); + void onClickCacheWrite(); + void onClickHTTPLoad(); + void onClickDecode(); + void onClickGLTexture(); + + void onClickRefetchVisCache(); + void onClickRefetchVisHTTP(); +public: + void idle() ; + +private: + LLFloaterTextureFetchDebugger(const LLSD& key); + virtual ~LLFloaterTextureFetchDebugger(); + + void updateButtons(); + void disableButtons(); + +private: + LLTextureFetchDebugger* mDebugger; + std::map<std::string, bool> mButtonStateMap; +}; + +#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 5485242236..6e23d7c701 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1764,6 +1764,7 @@ bool LLInventoryModel::loadSkeleton( update_map_t child_counts; cat_array_t categories; item_array_t items; + item_array_t possible_broken_links; cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded. std::string owner_id_str; owner_id.toString(owner_id_str); @@ -1812,7 +1813,7 @@ bool LLInventoryModel::loadSkeleton( LLViewerInventoryCategory* tcat = *cit; // we can safely ignore anything loaded from file, but - // not sent down in the skeleton. + // not sent down in the skeleton. Must have been removed from inventory. if(cit == not_cached) { continue; @@ -1850,6 +1851,8 @@ bool LLInventoryModel::loadSkeleton( // Add all the items loaded which are parented to a // category with a correctly cached parent S32 bad_link_count = 0; + S32 good_link_count = 0; + S32 recovered_link_count = 0; cat_map_t::iterator unparented = mCategoryMap.end(); for(item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); @@ -1866,26 +1869,56 @@ bool LLInventoryModel::loadSkeleton( // This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache. if (item->getIsBrokenLink()) { - bad_link_count++; + //bad_link_count++; lldebugs << "Attempted to add cached link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ). Ignoring and invalidating " << cat->getName() << " . " << llendl; - invalid_categories.insert(cit->second); + possible_broken_links.push_back(item); continue; } + else if (item->getIsLinkType()) + { + good_link_count++; + } addItem(item); cached_item_count += 1; ++child_counts[cat->getUUID()]; } } } - if (bad_link_count > 0) + if (possible_broken_links.size() > 0) { - llinfos << "Attempted to add " << bad_link_count - << " cached link items without baseobj present. " - << "The corresponding categories were invalidated." << llendl; + for(item_array_t::const_iterator item_iter = possible_broken_links.begin(); + item_iter != possible_broken_links.end(); + ++item_iter) + { + LLViewerInventoryItem *item = (*item_iter).get(); + const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID()); + const LLViewerInventoryCategory* cat = cit->second.get(); + if (item->getIsBrokenLink()) + { + bad_link_count++; + invalid_categories.insert(cit->second); + //llinfos << "link still broken: " << item->getName() << " in folder " << cat->getName() << llendl; + } + else + { + // was marked as broken because of loading order, its actually fine to load + addItem(item); + cached_item_count += 1; + ++child_counts[cat->getUUID()]; + recovered_link_count++; + } + } + + llinfos << "Attempted to add " << bad_link_count + << " cached link items without baseobj present. " + << good_link_count << " link items were successfully added. " + << recovered_link_count << " links added in recovery. " + << "The corresponding categories were invalidated." << llendl; } + } else { @@ -2783,7 +2816,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) { LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem; titem->unpackMessage(msg, _PREHASH_ItemData, i); - llinfos << "unpaked item '" << titem->getName() << "' in " + llinfos << "unpacked item '" << titem->getName() << "' in " << titem->getParentUUID() << llendl; U32 callback_id; msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 705046a517..00ff81724c 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -34,6 +34,7 @@ #include "llfirstuse.h" #include "llnearbychatbar.h" +#include "llnearbychatbarlistener.h" #include "llagent.h" #include "llgesturemgr.h" #include "llmultigesture.h" @@ -80,6 +81,7 @@ LLNearbyChatBar::LLNearbyChatBar(const LLSD& key) mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT) { mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); + mListener.reset(new LLNearbyChatBarListener(*this)); } //virtual diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 0b1c3a4ca4..662496d338 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -35,6 +35,8 @@ #include "lloutputmonitorctrl.h" #include "llspeakers.h" +class LLNearbyChatBarListener; + class LLNearbyChatBar : public LLFloater { LOG_CLASS(LLNearbyChatBar); @@ -95,6 +97,8 @@ protected: LLLocalSpeakerMgr* mSpeakerMgr; S32 mExpandedHeight; + + boost::shared_ptr<LLNearbyChatBarListener> mListener; }; #endif diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index 995915206b..398f54c6f7 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -101,7 +101,7 @@ bool LLScriptHandler::processNotification(const LLSD& notify) } else { - LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); + LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); LLToast::Params p; p.notif_id = notification->getID(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d82b62dc19..bd335576ba 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3656,6 +3656,110 @@ void renderShadowFrusta(LLDrawInfo* params) gGL.setSceneBlendType(LLRender::BT_ALPHA); } +void renderTexelDensity(LLDrawable* drawable) +{ + if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF + || LLViewerTexture::sCheckerBoardImagep.isNull()) + { + return; + } + + LLGLEnable _(GL_BLEND); + //gObjectFullbrightProgram.bind(); + + LLMatrix4 checkerboard_matrix; + S32 discard_level = -1; + + for (S32 f = 0; f < drawable->getNumFaces(); f++) + { + LLFace* facep = drawable->getFace(f); + LLVertexBuffer* buffer = facep->getVertexBuffer(); + LLViewerTexture* texturep = facep->getTexture(); + + if (texturep == NULL) continue; + + switch(LLViewerTexture::sDebugTexelsMode) + { + case LLViewerTexture::DEBUG_TEXELS_CURRENT: + discard_level = -1; + break; + case LLViewerTexture::DEBUG_TEXELS_DESIRED: + { + LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep); + discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; + break; + } + default: + case LLViewerTexture::DEBUG_TEXELS_FULL: + discard_level = 0; + break; + } + + checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + + gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix); + + if (buffer && (facep->getGeomCount() >= 3)) + { + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); + U16 start = facep->getGeomStart(); + U16 end = start + facep->getGeomCount()-1; + U32 count = facep->getIndicesCount(); + U16 offset = facep->getIndicesStart(); + buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + } + + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + + //S32 num_textures = llmax(1, (S32)params->mTextureList.size()); + + //for (S32 i = 0; i < num_textures; i++) + //{ + // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get(); + // if (texturep == NULL) continue; + + // LLMatrix4 checkboard_matrix; + // S32 discard_level = -1; + // switch(LLViewerTexture::sDebugTexelsMode) + // { + // case LLViewerTexture::DEBUG_TEXELS_CURRENT: + // discard_level = -1; + // break; + // case LLViewerTexture::DEBUG_TEXELS_DESIRED: + // { + // LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep); + // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; + // break; + // } + // default: + // case LLViewerTexture::DEBUG_TEXELS_FULL: + // discard_level = 0; + // break; + // } + + // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + // gGL.getTexUnit(i)->activate(); + + // glMatrixMode(GL_TEXTURE); + // glPushMatrix(); + // glLoadIdentity(); + // //gGL.matrixMode(LLRender::MM_TEXTURE); + // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix); + + // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + + // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL ); + + // glPopMatrix(); + // glMatrixMode(GL_MODELVIEW); + // //gGL.matrixMode(LLRender::MM_MODELVIEW); + //} +} + void renderLights(LLDrawable* drawablep) { @@ -4055,6 +4159,10 @@ public: { renderComplexityDisplay(drawable); } + if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + renderTexelDensity(drawable); + } LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); @@ -4307,7 +4415,8 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_AGENT_TARGET | //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | - LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY)) + LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY | + LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) { return; } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0ac8c1fe39..6b0fc26db7 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -240,6 +240,7 @@ static bool mLoginStatePastUI = false; boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState")); boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); +boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap); // // local function declaration @@ -2705,7 +2706,10 @@ void LLStartUp::setStartupState( EStartupState state ) LL_INFOS("AppInit") << "Startup state changing from " << getStartupStateString() << " to " << startupStateToString(state) << LL_ENDL; + + sPhases->stopPhase(getStartupStateString()); gStartupState = state; + sPhases->startPhase(getStartupStateString()); postStartupState(); } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 0a18ef1b2d..3754aaf966 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -34,6 +34,8 @@ class LLEventPump; class LLStartupListener; class LLSLURL; +#include "llviewerstats.h" + // functions bool idle_startup(); void release_start_screen(); @@ -113,6 +115,7 @@ public: static bool startLLProxy(); // Initialize the SOCKS 5 proxy + static LLViewerStats::PhaseMap& getPhases() { return *sPhases; } private: static LLSLURL sStartSLURL; @@ -120,6 +123,7 @@ private: static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState static boost::scoped_ptr<LLEventPump> sStateWatcher; static boost::scoped_ptr<LLStartupListener> sListener; + static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases; }; diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 6f6d5dbf12..467115c928 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -55,6 +55,9 @@ using namespace LLVOAvatarDefines; static const S32 BAKE_UPLOAD_ATTEMPTS = 7; static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt +// runway consolidate +extern std::string self_av_string(); + class LLTexLayerInfo { friend class LLTexLayer; @@ -494,7 +497,6 @@ void LLTexLayerSetBuffer::doUpload() } LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C; - compressedImage->setRate(0.f); const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask) if (compressedImage->encode(baked_image, comment_text)) { @@ -577,7 +579,7 @@ void LLTexLayerSetBuffer::doUpload() args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); args["RESOLUTION"] = lod_str; LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args); - llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL; } } else @@ -631,7 +633,7 @@ void LLTexLayerSetBuffer::doUpdate() args["BODYREGION"] = mTexLayerSet->getBodyRegionName(); args["RESOLUTION"] = lod_str; LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args); - llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL; } } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index f18aa8b4e6..7e6dfbc9d9 100644..100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -52,12 +52,20 @@ #include "llviewerstats.h" #include "llviewerassetstats.h" #include "llworld.h" +#include "llsdutil.h" +#include "llstartup.h" +#include "llviewerstats.h" + +bool LLTextureFetchDebugger::sDebuggerEnabled = false ; +LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); +LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); ////////////////////////////////////////////////////////////////////////////// class LLTextureFetchWorker : public LLWorkerClass { friend class LLTextureFetch; friend class HTTPGetResponder; + friend class LLTextureFetchDebugger; private: class CacheReadResponder : public LLTextureCache::ReadResponder @@ -242,6 +250,8 @@ private: S32 mDecodedDiscard; LLFrameTimer mRequestedTimer; LLFrameTimer mFetchTimer; + LLTimer mCacheReadTimer; + F32 mCacheReadTime; LLTextureCache::handle_t mCacheReadHandle; LLTextureCache::handle_t mCacheWriteHandle; U8* mBuffer; @@ -258,6 +268,7 @@ private: BOOL mNeedsAux; BOOL mHaveAllData; BOOL mInLocalCache; + BOOL mInCache; bool mCanUseHTTP ; bool mCanUseNET ; //can get from asset server. S32 mHTTPFailCount; @@ -653,6 +664,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mRequestedDiscard(-1), mLoadedDiscard(-1), mDecodedDiscard(-1), + mCacheReadTime(0.f), mCacheReadHandle(LLTextureCache::nullHandle()), mCacheWriteHandle(LLTextureCache::nullHandle()), mBuffer(NULL), @@ -669,6 +681,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mNeedsAux(FALSE), mHaveAllData(FALSE), mInLocalCache(FALSE), + mInCache(FALSE), mCanUseHTTP(true), mHTTPFailCount(0), mRetryAttempt(0), @@ -838,6 +851,8 @@ void LLTextureFetchWorker::startWork(S32 param) // Called from LLWorkerThread::processRequest() bool LLTextureFetchWorker::doWork(S32 param) { + static const F32 FETCHING_TIMEOUT = 120.f;//seconds + LLMutexLock lock(&mWorkMutex); if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) @@ -896,6 +911,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mCacheReadHandle = LLTextureCache::nullHandle(); mCacheWriteHandle = LLTextureCache::nullHandle(); mState = LOAD_FROM_TEXTURE_CACHE; + mInCache = FALSE; mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; @@ -926,6 +942,7 @@ bool LLTextureFetchWorker::doWork(S32 param) CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority, offset, size, responder); + mCacheReadTimer.reset(); } else if (mUrl.empty()) { @@ -934,6 +951,7 @@ bool LLTextureFetchWorker::doWork(S32 param) CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, offset, size, responder); + mCacheReadTimer.reset(); } else if(mCanUseHTTP) { @@ -982,11 +1000,12 @@ bool LLTextureFetchWorker::doWork(S32 param) llassert_always(mFormattedImage->getDataSize() > 0); mLoadedDiscard = mDesiredDiscard; mState = DECODE_IMAGE; + mInCache = TRUE; mWriteToCacheState = NOT_WRITE ; LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; - // fall through + LLTextureFetch::sCacheHitRate.addValue(100.f); } else { @@ -1002,6 +1021,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mState = LOAD_FROM_NETWORK; } // fall through + LLTextureFetch::sCacheHitRate.addValue(0.f); } } @@ -1177,6 +1197,8 @@ bool LLTextureFetchWorker::doWork(S32 param) bool res = false; if (!mUrl.empty()) { + mRequestedTimer.reset(); + mLoaded = FALSE; mGetStatus = 0; mGetReason.clear(); @@ -1335,6 +1357,13 @@ bool LLTextureFetchWorker::doWork(S32 param) } else { + if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32()) + { + //timeout, abort. + mState = DONE; + return true; + } + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; } @@ -1396,6 +1425,11 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mDecoded) { + if(mFetcher->getFetchDebugger() && !mInLocalCache) + { + mFetcher->getFetchDebugger()->addHistoryEntry(this); + } + if (mDecodedDiscard < 0) { LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL; @@ -1780,6 +1814,7 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag mDecoded = TRUE; // llinfos << mID << " : DECODE COMPLETE " << llendl; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + mCacheReadTime = mCacheReadTimer.getElapsedTimeF32(); } ////////////////////////////////////////////////////////////////////////////// @@ -1824,11 +1859,19 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mHTTPTextureBits(0), mTotalHTTPRequests(0), mCurlGetRequest(NULL), - mQAMode(qa_mode) + mQAMode(qa_mode), + mFetchDebugger(NULL), + mFetcherLocked(FALSE) { mCurlPOSTRequestCount = 0; mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); + + LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); + if(LLTextureFetchDebugger::isEnabled()) + { + mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; + } } LLTextureFetch::~LLTextureFetch() @@ -1843,11 +1886,17 @@ LLTextureFetch::~LLTextureFetch() } // ~LLQueuedThread() called here + + delete mFetchDebugger; } bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { + if(mFetcherLocked) + { + return false; + } if (mDebugPause) { return false; @@ -2092,6 +2141,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, discard_level = worker->mDecodedDiscard; raw = worker->mRawImage; aux = worker->mAuxImage; + F32 cache_read_time = worker->mCacheReadTime; + if (cache_read_time != 0.f) + { + sCacheReadLatency.addValue(cache_read_time * 1000.f); + } res = true; LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; worker->unlockWorkMutex(); @@ -2222,7 +2276,13 @@ S32 LLTextureFetch::update(F32 max_time_ms) if (!mDebugPause) { - sendRequestListToSimulators(); + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this, the RequestImages message sent by sendRequestListToSimulators + // won't work so don't bother trying + if (LLStartUp::getStartupState() > STATE_AGENT_SEND) + { + sendRequestListToSimulators(); + } } if (!mThreaded) @@ -2258,6 +2318,11 @@ void LLTextureFetch::startThread() { // Construct mCurlGetRequest from Worker Thread mCurlGetRequest = new LLCurlRequest(); + + if(mFetchDebugger) + { + mFetchDebugger->setCurlGetRequest(mCurlGetRequest); + } } // WORKER THREAD @@ -2266,6 +2331,10 @@ void LLTextureFetch::endThread() // Destroy mCurlGetRequest from Worker Thread delete mCurlGetRequest; mCurlGetRequest = NULL; + if(mFetchDebugger) + { + mFetchDebugger->setCurlGetRequest(NULL); + } } // WORKER THREAD @@ -2803,7 +2872,6 @@ void LLTextureFetch::cmdDoWork() } } - ////////////////////////////////////////////////////////////////////////////// // Private (anonymous) class methods implementing the command scheme. @@ -2959,7 +3027,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // In QA mode, Metrics submode, log the result for ease of testing if (fetcher->isQAMode()) { - LL_INFOS("Textures") << merged_llsd << LL_ENDL; + LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL; } gViewerAssetStatsThread1->reset(); @@ -3007,5 +3075,659 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics) } // end of anonymous namespace +/////////////////////////////////////////////////////////////////////////////////////////// +//Start LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// +//--------------------- +class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder +{ +public: + LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image) + : mDebugger(debugger), mID(id) + { + setImage(image); + } + virtual void completed(bool success) + { + mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal); + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mID; +}; + +class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder +{ +public: + LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id) + : mDebugger(debugger), mID(id) + { + } + virtual void completed(bool success) + { + mDebugger->callbackCacheWrite(mID, success); + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mID; +}; + +class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder +{ +public: + LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id) + : mDebugger(debugger), mID(id) + { + } + virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) + { + mDebugger->callbackDecoded(mID, success, raw, aux); + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mID; +}; + +class LLDebuggerHTTPResponder : public LLCurl::Responder +{ +public: + LLDebuggerHTTPResponder(LLTextureFetchDebugger* debugger, S32 index) + : mDebugger(debugger), mIndex(index) + { + } + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + bool success = false; + bool partial = false; + if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES) + { + success = true; + if (HTTP_PARTIAL_CONTENT == status) // partial information + { + partial = true; + } + } + if (!success) + { + llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl; + } + mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success); + } + virtual bool followRedir() + { + return true; + } +private: + LLTextureFetchDebugger* mDebugger; + S32 mIndex; +}; + +LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : + mFetcher(fetcher), + mTextureCache(cache), + mImageDecodeThread(imagedecodethread), + mCurlGetRequest(NULL) +{ + init(); +} + +LLTextureFetchDebugger::~LLTextureFetchDebugger() +{ + mFetchingHistory.clear(); + stopDebug(); +} + +void LLTextureFetchDebugger::init() +{ + mState = IDLE; + + mCacheReadTime = -1.f; + mCacheWriteTime = -1.f; + mDecodingTime = -1.f; + mHTTPTime = -1.f; + mGLCreationTime = -1.f; + mTotalFetchingTime = 0.f; + mRefetchVisCacheTime = -1.f; + mRefetchVisHTTPTime = -1.f; + + mNumFetchedTextures = 0; + mNumCacheHits = 0; + mNumVisibleFetchedTextures = 0; + mNumVisibleFetchingRequests = 0; + mFetchedData = 0; + mDecodedData = 0; + mVisibleFetchedData = 0; + mVisibleDecodedData = 0; + mRenderedData = 0; + mRenderedDecodedData = 0; + mFetchedPixels = 0; + mRenderedPixels = 0; + mRefetchedData = 0; + mRefetchedPixels = 0; + + mFreezeHistory = FALSE; +} + +void LLTextureFetchDebugger::startDebug() +{ + //lock the fetcher + mFetcher->lockFetcher(true); + mFreezeHistory = TRUE; + + //clear the current fetching queue + gTextureList.clearFetchingRequests(); + + //wait for all works to be done + while(1) + { + S32 pending = 0; + pending += LLAppViewer::getTextureCache()->update(1); + pending += LLAppViewer::getImageDecodeThread()->update(1); + pending += LLAppViewer::getTextureFetch()->update(1); + if(!pending) + { + break; + } + } + + //collect statistics + mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + + std::set<LLUUID> fetched_textures; + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size; i++) + { + bool in_list = true; + if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end()) + { + fetched_textures.insert(mFetchingHistory[i].mID); + in_list = false; + } + + LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID); + if(tex && tex->isJustBound()) //visible + { + if(!in_list) + { + mNumVisibleFetchedTextures++; + } + mNumVisibleFetchingRequests++; + + mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; + mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; + + if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) + { + mRenderedData += mFetchingHistory[i].mFetchedSize; + mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; + mRenderedPixels += tex->getWidth() * tex->getHeight(); + } + } + } + + mNumFetchedTextures = fetched_textures.size(); +} + +void LLTextureFetchDebugger::stopDebug() +{ + //clear the current debug work + S32 size = mFetchingHistory.size(); + switch(mState) + { + case READ_CACHE: + for(S32 i = 0 ; i < size; i++) + { + if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle()) + { + mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); + } + } + break; + case WRITE_CACHE: + for(S32 i = 0 ; i < size; i++) + { + if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle()) + { + mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true); + } + } + break; + case DECODING: + break; + case HTTP_FETCHING: + break; + case GL_TEX: + break; + default: + break; + } + + while(1) + { + if(update()) + { + break; + } + } + + //unlock the fetcher + mFetcher->lockFetcher(false); + mFreezeHistory = FALSE; + mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset +} + +//called in the main thread and when the fetching queue is empty +void LLTextureFetchDebugger::clearHistory() +{ + mFetchingHistory.clear(); + init(); +} + +void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) +{ + if(mFreezeHistory) + { + mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + mRefetchedData += worker->mFormattedImage->getDataSize(); + return; + } + + if(worker->mInCache) + { + mNumCacheHits++; + } + mFetchedData += worker->mFormattedImage->getDataSize(); + mDecodedData += worker->mRawImage->getDataSize(); + mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + + mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); + //mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(), + //worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); +} + +void LLTextureFetchDebugger::lockCache() +{ +} + +void LLTextureFetchDebugger::unlockCache() +{ +} + +void LLTextureFetchDebugger::debugCacheRead() +{ + lockCache(); + llassert_always(mState == IDLE); + mTimer.reset(); + mState = READ_CACHE; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + mFetchingHistory[i].mFormattedImage = NULL; + mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize, + new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); + } +} + +void LLTextureFetchDebugger::clearCache() +{ + S32 size = mFetchingHistory.size(); + { + std::set<LLUUID> deleted_list; + for(S32 i = 0 ; i < size ; i++) + { + if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end()) + { + deleted_list.insert(mFetchingHistory[i].mID); + mTextureCache->removeFromCache(mFetchingHistory[i].mID); + } + } + } +} + +void LLTextureFetchDebugger::debugCacheWrite() +{ + //remove from cache + clearCache(); + + lockCache(); + llassert_always(mState == IDLE); + mTimer.reset(); + mState = WRITE_CACHE; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + if(mFetchingHistory[i].mFormattedImage.notNull()) + { + mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, + mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, + mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1, + new LLDebuggerCacheWriteResponder(this, i)); + } + } +} + +void LLTextureFetchDebugger::lockDecoder() +{ +} + +void LLTextureFetchDebugger::unlockDecoder() +{ +} + +void LLTextureFetchDebugger::debugDecoder() +{ + lockDecoder(); + llassert_always(mState == IDLE); + mTimer.reset(); + mState = DECODING; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + if(mFetchingHistory[i].mFormattedImage.isNull()) + { + continue; + } + + mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL, + mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, + new LLDebuggerDecodeResponder(this, i)); + } +} + +void LLTextureFetchDebugger::debugHTTP() +{ + llassert_always(mState == IDLE); + + LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + llinfos << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << llendl; + return; + } + + mHTTPUrl = region->getHttpUrl(); + if (mHTTPUrl.empty()) + { + llinfos << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << llendl; + return; + } + + mTimer.reset(); + mState = HTTP_FETCHING; + + S32 size = mFetchingHistory.size(); + for (S32 i = 0 ; i < size ; i++) + { + mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; + mFetchingHistory[i].mCurlReceivedSize = 0; + mFetchingHistory[i].mHTTPFailCount = 0; + } + mNbCurlRequests = 0; + mNbCurlCompleted = 0; + + fillCurlQueue(); +} + +S32 LLTextureFetchDebugger::fillCurlQueue() +{ + if (mNbCurlRequests == 24) + return mNbCurlRequests; + + S32 size = mFetchingHistory.size(); + for (S32 i = 0 ; i < size ; i++) + { + if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) + continue; + std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str(); + S32 requestedSize = mFetchingHistory[i].mRequestedSize; + // We request the whole file if the size was not set. + requestedSize = llmax(0,requestedSize); + // We request the whole file if the size was set to an absurdly high value (meaning all file) + requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); + std::vector<std::string> headers; + headers.push_back("Accept: image/x-j2c"); + bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i)); + if (res) + { + mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; + mNbCurlRequests++; + // Hack + if (mNbCurlRequests == 24) + break; + } + else + { + break; + } + } + //llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl; + return mNbCurlRequests; +} + +void LLTextureFetchDebugger::debugGLTextureCreation() +{ + llassert_always(mState == IDLE); + mState = GL_TEX; + std::vector<LLViewerFetchedTexture*> tex_list; + + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + if(mFetchingHistory[i].mRawImage.notNull()) + { + LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; + if(tex && !tex->isForSculptOnly()) + { + tex->destroyGLTexture() ; + tex_list.push_back(tex); + } + } + } + + mTimer.reset(); + S32 j = 0 ; + S32 size1 = tex_list.size(); + for(S32 i = 0 ; i < size && j < size1; i++) + { + if(mFetchingHistory[i].mRawImage.notNull()) + { + if(mFetchingHistory[i].mID == tex_list[j]->getID()) + { + tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel()); + j++; + } + } + } + + mGLCreationTime = mTimer.getElapsedTimeF32() ; + return; +} + +//clear fetching results of all textures. +void LLTextureFetchDebugger::clearTextures() +{ + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size ; i++) + { + LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; + if(tex) + { + tex->clearFetchedResults() ; + } + } +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromCache() +{ + llassert_always(mState == IDLE); + mState = REFETCH_VIS_CACHE; + + clearTextures(); + + mTimer.reset(); + mFetcher->lockFetcher(false); +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() +{ + llassert_always(mState == IDLE); + mState = REFETCH_VIS_HTTP; + + clearCache(); + clearTextures(); + + mTimer.reset(); + mFetcher->lockFetcher(false); +} + +bool LLTextureFetchDebugger::update() +{ + switch(mState) + { + case READ_CACHE: + if(!mTextureCache->update(1)) + { + mCacheReadTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + unlockCache(); + } + break; + case WRITE_CACHE: + if(!mTextureCache->update(1)) + { + mCacheWriteTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + unlockCache(); + } + break; + case DECODING: + if(!mImageDecodeThread->update(1)) + { + mDecodingTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + unlockDecoder(); + } + break; + case HTTP_FETCHING: + mCurlGetRequest->process(); + LLCurl::getCurlThread()->update(1); + if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) + { + mHTTPTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + } + break; + case GL_TEX: + mState = IDLE; + break; + case REFETCH_VIS_CACHE: + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mState = IDLE; + mFetcher->lockFetcher(true); + } + break; + case REFETCH_VIS_HTTP: + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mState = IDLE; + mFetcher->lockFetcher(true); + } + break; + default: + mState = IDLE; + break; + } + + return mState == IDLE; +} + +void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, + S32 imagesize, BOOL islocal) +{ + if (success) + { + mFetchingHistory[id].mFormattedImage = image; + } + mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false); + mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success) +{ + mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle); + mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux) +{ + if (success) + { + llassert_always(raw); + mFetchingHistory[id].mRawImage = raw; + } +} + +void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer, + bool partial, bool success) +{ + mNbCurlRequests--; + if (success) + { + mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; + mNbCurlCompleted++; + + S32 data_size = buffer->countAfter(channels.in(), NULL); + mFetchingHistory[id].mCurlReceivedSize += data_size; + //llinfos << "Fetch Debugger : got results for " << id << ", data_size = " << data_size << ", received = " << mFetchingHistory[id].mCurlReceivedSize << ", requested = " << mFetchingHistory[id].mRequestedSize << ", partial = " << partial << llendl; + if ((mFetchingHistory[id].mCurlReceivedSize >= mFetchingHistory[id].mRequestedSize) || !partial || (mFetchingHistory[id].mRequestedSize == 600)) + { + U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); + buffer->readAfter(channels.in(), NULL, d_buffer, data_size); + + llassert_always(mFetchingHistory[id].mFormattedImage.isNull()); + { + // For now, create formatted image based on extension + std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str(); + std::string extension = gDirUtilp->getExtension(texture_url); + mFetchingHistory[id].mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); + if (mFetchingHistory[id].mFormattedImage.isNull()) + { + mFetchingHistory[id].mFormattedImage = new LLImageJ2C; // default + } + } + + mFetchingHistory[id].mFormattedImage->setData(d_buffer, data_size); + } + } + else //failed + { + mFetchingHistory[id].mHTTPFailCount++; + if(mFetchingHistory[id].mHTTPFailCount < 5) + { + // Fetch will have to be redone + mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE; + } + else //skip + { + mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; + mNbCurlCompleted++; + } + } +} + + +//--------------------- +/////////////////////////////////////////////////////////////////////////////////////////// +//End LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 35df7d816f..107e1623b0 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -34,14 +34,17 @@ #include "llcurl.h" #include "lltextureinfo.h" #include "llapr.h" +#include "llimageworker.h" +//#include "lltexturecache.h" class LLViewerTexture; class LLTextureFetchWorker; class HTTPGetResponder; -class LLTextureCache; class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; +class LLTextureFetchDebugger; +class LLTextureCache; // Interface class class LLTextureFetch : public LLWorkerThread @@ -164,6 +167,9 @@ private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. + static LLStat sCacheHitRate; + static LLStat sCacheReadLatency; + LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; LLCurlRequest* mCurlGetRequest; @@ -209,7 +215,195 @@ public: // attempt to log metrics follows a break in the metrics stream // reporting due to either startup or a problem POSTing data. static volatile bool svMetricsDataBreak; + +private: + //debug use + LLTextureFetchDebugger* mFetchDebugger; + bool mFetcherLocked; + +public: + //debug use + LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} + void lockFetcher(bool lock) { mFetcherLocked = lock;} }; +//debug use +class LLTextureFetchDebugger +{ + friend class LLTextureFetch; +public: + LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ; + ~LLTextureFetchDebugger(); + +public: + enum e_debug_state + { + IDLE = 0, + READ_CACHE, + WRITE_CACHE, + DECODING, + HTTP_FETCHING, + GL_TEX, + REFETCH_VIS_CACHE, + REFETCH_VIS_HTTP, + REFETCH_ALL_CACHE, + REFETCH_ALL_HTTP, + INVALID + }; + +private: + struct FetchEntry + { + enum e_curl_state + { + CURL_NOT_DONE = 0, + CURL_IN_PROGRESS, + CURL_DONE + }; + LLUUID mID; + S32 mRequestedSize; + S32 mDecodedLevel; + S32 mFetchedSize; + S32 mDecodedSize; + BOOL mNeedsAux; + U32 mCacheHandle; + LLPointer<LLImageFormatted> mFormattedImage; + LLPointer<LLImageRaw> mRawImage; + e_curl_state mCurlState; + S32 mCurlReceivedSize; + S32 mHTTPFailCount; + + FetchEntry() : + mDecodedLevel(-1), + mFetchedSize(0), + mDecodedSize(0) + {} + FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : + mID(id), + mRequestedSize(r_size), + mDecodedLevel(level), + mFetchedSize(f_size), + mDecodedSize(d_size), + mNeedsAux(false), + mHTTPFailCount(0) + {} + }; + std::vector<FetchEntry> mFetchingHistory; + + e_debug_state mState; + + F32 mCacheReadTime; + F32 mCacheWriteTime; + F32 mDecodingTime; + F32 mHTTPTime; + F32 mGLCreationTime; + + F32 mTotalFetchingTime; + F32 mRefetchVisCacheTime; + F32 mRefetchVisHTTPTime; + + LLTimer mTimer; + + LLTextureFetch* mFetcher; + LLTextureCache* mTextureCache; + LLImageDecodeThread* mImageDecodeThread; + LLCurlRequest* mCurlGetRequest; + + S32 mNumFetchedTextures; + S32 mNumCacheHits; + S32 mNumVisibleFetchedTextures; + S32 mNumVisibleFetchingRequests; + U32 mFetchedData; + U32 mDecodedData; + U32 mVisibleFetchedData; + U32 mVisibleDecodedData; + U32 mRenderedData; + U32 mRenderedDecodedData; + U32 mFetchedPixels; + U32 mRenderedPixels; + U32 mRefetchedData; + U32 mRefetchedPixels; + + BOOL mFreezeHistory; + + std::string mHTTPUrl; + S32 mNbCurlRequests; + S32 mNbCurlCompleted; + +public: + bool update(); //called in the main thread once per frame + + //fetching history + void clearHistory(); + void addHistoryEntry(LLTextureFetchWorker* worker); + + void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;} + + void startDebug(); + void stopDebug(); //stop everything + void debugCacheRead(); + void debugCacheWrite(); + void debugHTTP(); + void debugDecoder(); + void debugGLTextureCreation(); + void debugRefetchVisibleFromCache(); + void debugRefetchVisibleFromHTTP(); + + void callbackCacheRead(S32 id, bool success, LLImageFormatted* image, + S32 imagesize, BOOL islocal); + void callbackCacheWrite(S32 id, bool success); + void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); + void callbackHTTP(S32 id, const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer, + bool partial, bool success); + + + e_debug_state getState() {return mState;} + S32 getNumFetchedTextures() {return mNumFetchedTextures;} + S32 getNumFetchingRequests() {return mFetchingHistory.size();} + S32 getNumCacheHits() {return mNumCacheHits;} + S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;} + S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;} + U32 getFetchedData() {return mFetchedData;} + U32 getDecodedData() {return mDecodedData;} + U32 getVisibleFetchedData() {return mVisibleFetchedData;} + U32 getVisibleDecodedData() {return mVisibleDecodedData;} + U32 getRenderedData() {return mRenderedData;} + U32 getRenderedDecodedData() {return mRenderedDecodedData;} + U32 getFetchedPixels() {return mFetchedPixels;} + U32 getRenderedPixels() {return mRenderedPixels;} + U32 getRefetchedData() {return mRefetchedData;} + U32 getRefetchedPixels() {return mRefetchedPixels;} + + F32 getCacheReadTime() {return mCacheReadTime;} + F32 getCacheWriteTime() {return mCacheWriteTime;} + F32 getDecodeTime() {return mDecodingTime;} + F32 getGLCreationTime() {return mGLCreationTime;} + F32 getHTTPTime() {return mHTTPTime;} + F32 getTotalFetchingTime() {return mTotalFetchingTime;} + F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;} + F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;} + +private: + void init(); + void clearTextures();//clear fetching results of all textures. + void clearCache(); + + void lockFetcher(); + void unlockFetcher(); + + void lockCache(); + void unlockCache(); + + void lockDecoder(); + void unlockDecoder(); + + S32 fillCurlQueue(); + +private: + static bool sDebuggerEnabled; +public: + static bool isEnabled() {return sDebuggerEnabled;} +}; #endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 5b41a05f2a..425bf7ee87 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -57,8 +57,6 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; -LLTextureSizeView *gTextureSizeView = NULL; -LLTextureSizeView *gTextureCategoryView = NULL; #define HIGH_PRIORITY 100000000.f @@ -512,8 +510,8 @@ void LLGLTexMemBar::draw() 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()) ; - S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); - S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); + S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); + 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() ; @@ -527,80 +525,24 @@ void LLGLTexMemBar::draw() LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6, 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 Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", + 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, LLRenderTarget::sBytesAllocated/(1024*1024), LLImageRaw::sGlobalRawMemory >> 20, discard_bias, - cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests); - //, cache_entries, cache_max_entries - - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, + cache_usage, cache_max_usage); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4, text_color, LLFontGL::LEFT, LLFontGL::TOP); - //---------------------------------------------------------------------------- -#if 0 - S32 bar_left = 400; - S32 bar_width = 200; - S32 top = line_height*3 - 2 + v_offset; - S32 bottom = top - 6; - S32 left = bar_left; - S32 right = left + bar_width; - F32 bar_scale; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // GL Mem Bar - - left = bar_left; - text = "GL"; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3, + text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", + total_texture_downloaded, total_object_downloaded, total_http_requests); + //, cache_entries, cache_max_entries + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP); - - left = bar_left+20; - right = left + bar_width; - - gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey - gl_rect_2d(left, top, right, bottom); - - bar_scale = (F32)bar_width / (max_total_mem * 1.5f); - right = left + llfloor(total_mem * bar_scale); - right = llclamp(right, bar_left, bar_left + bar_width); - - color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green : - (total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red; - color[VALPHA] = .75f; - gGL.diffuseColor4fv(color.mV); - - gl_rect_2d(left, top, right, bottom); // red/yellow/green - - // - bar_left += bar_width + bar_space; - //top = bottom - 2; bottom = top - 6; - - // Bound Mem Bar - - left = bar_left; - text = "GL"; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - left = bar_left + 20; - right = left + bar_width; - - gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); - gl_rect_2d(left, top, right, bottom); - - color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green : - (bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red; - color[VALPHA] = .75f; - gGL.diffuseColor4fv(color.mV); - gl_rect_2d(left, top, right, bottom); -#else S32 left = 0 ; -#endif //---------------------------------------------------------------------------- text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d", @@ -669,8 +611,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask) LLRect LLGLTexMemBar::getRequiredRect() { LLRect rect; - //rect.mTop = 50; - rect.mTop = 0; + rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6; return rect; } @@ -954,9 +895,11 @@ void LLTextureView::draw() LLRect tmbr; tmbp.name("gl texmem bar"); tmbp.rect(tmbr); + tmbp.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP; tmbp.texture_view(this); mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp); - addChildInBack(mGLTexMemBar); + addChild(mGLTexMemBar); + sendChildToFront(mGLTexMemBar); LLAvatarTexBar::Params atbp; LLRect atbr; @@ -965,16 +908,13 @@ void LLTextureView::draw() atbp.rect(atbr); mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp); addChild(mAvatarTexBar); + sendChildToFront(mAvatarTexBar); reshape(getRect().getWidth(), getRect().getHeight(), TRUE); - /* - count = gTextureList.getNumImages(); - std::string info_string; - info_string = llformat("Global Info:\nTexture Count: %d", count); - mInfoTextp->setText(info_string); - */ - + LLUI::popMatrix(); + LLUI::pushMatrix(); + LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom); for (child_list_const_iter_t child_iter = getChildList()->begin(); child_iter != getChildList()->end(); ++child_iter) @@ -1049,302 +989,4 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent) return FALSE; } -//----------------------------------------------------------------- -LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p) -{ - setVisible(FALSE) ; - - mTextureSizeBarWidth = 30 ; -} - -LLTextureSizeView::~LLTextureSizeView() -{ - if(mTextureSizeBar.size()) - { - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - delete mTextureSizeBar[i] ; - } - mTextureSizeBar.clear() ; - } -} -void LLTextureSizeView::draw() -{ - if(mType == TEXTURE_MEM_OVER_SIZE) - { - drawTextureSizeGraph(); - } - else - { - drawTextureCategoryGraph() ; - } - - LLView::draw(); -} - -BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) -{ - if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) - { - mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ; - } - - return TRUE ; -} - -//draw real-time texture mem bar over size -void LLTextureSizeView::drawTextureSizeGraph() -{ - if(mTextureSizeBar.size() == 0) - { - S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); - mTextureSizeBar.resize(LLImageGL::sTextureLoadedCounter.size()) ; - mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; - - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , - line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; - } - } - - F32 size_bar_scale = drawTextureSizeDistributionGraph() ; - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i]->setTop(LLImageGL::sTextureLoadedCounter[i], LLImageGL::sTextureBoundCounter[i], size_bar_scale) ; - mTextureSizeBar[i]->draw() ; - } - LLImageGL::resetCurTexSizebar(); -} - -//draw background of texture size bar graph -F32 LLTextureSizeView::drawTextureSizeDistributionGraph() -{ - //scale - F32 scale = 1.0f ; - - LLGLSUIDefault gls_ui; - - { - S32 count = 0 ; - for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++) - { - if(LLImageGL::sTextureLoadedCounter[i] > count) - { - count = LLImageGL::sTextureLoadedCounter[i] ; - } - } - if(count > mTextureSizeBarRect.getHeight()) - { - scale = (F32)mTextureSizeBarRect.getHeight() / count ; - } - } - - S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); - S32 left = mTextureSizeBarRect.mLeft ; - S32 bottom = mTextureSizeBarRect.mBottom ; - S32 right = mTextureSizeBarRect.mRight ; - S32 top = mTextureSizeBarRect.mTop ; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //background rect - gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); - gl_line_2d(left, bottom, right, bottom) ; //x axis - gl_line_2d(left, bottom, left, top) ; //y axis - - //ruler - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - gl_line_2d(left, i, right, i) ; - } - - //texts - //-------------------------------------------------- - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; - std::string text; - - //------- - //x axis: size label - text = llformat("%d", 0) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) - { - text = llformat("%d", (1 << (i / 2)) + ((i & 1) ? ((1 << (i / 2)) >> 1) : 0)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - text = llformat("(w + h)/2") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 10, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - //------- - - //y axis: number label - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - text = llformat("%d", (S32)((i - bottom) / scale)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - - //-------------------------------------------------- - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; - text = llformat("Loaded") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, - loaded_color, LLFontGL::LEFT, LLFontGL::TOP); - - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; - text = llformat("Bound") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, - bound_color, LLFontGL::LEFT, LLFontGL::TOP); - - //-------------------------------------------------- - - //title - text = llformat("Texture Size Distribution") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - return scale ; -} - -//draw real-time texture mem bar over category -void LLTextureSizeView::drawTextureCategoryGraph() -{ - if(mTextureSizeBar.size() == 0) - { - S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); - mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ; - mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; - - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , - line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; - } - } - - F32 size_bar_scale = drawTextureCategoryDistributionGraph() ; - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - U32 k = LLViewerTexture::getIndexFromCategory(i) ; - mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ; - mTextureSizeBar[i]->draw() ; - } - LLImageGL::resetCurTexSizebar(); -} - -//draw background for TEXTURE_MEM_OVER_CATEGORY -F32 LLTextureSizeView::drawTextureCategoryDistributionGraph() -{ - //scale - F32 scale = 4.0f ; - - LLGLSUIDefault gls_ui; - { - S32 count = 0 ; - for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) - { - S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; - if(tmp > count) - { - count = tmp ; - } - } - if(count > mTextureSizeBarRect.getHeight() * 0.25f) - { - scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ; - } - } - - S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); - S32 left = mTextureSizeBarRect.mLeft ; - S32 bottom = mTextureSizeBarRect.mBottom ; - S32 right = mTextureSizeBarRect.mRight ; - S32 top = mTextureSizeBarRect.mTop ; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //background rect - gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); - gl_line_2d(left, bottom, right, bottom) ; //x axis - gl_line_2d(left, bottom, left, top) ; //y axis - - //ruler - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - gl_line_2d(left, i, right, i) ; - } - - //texts - //-------------------------------------------------- - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; - std::string text; - - //------- - //x axis: size label - static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] = - {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ; - - text = llformat("%s", category[0]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) - { - text = llformat("%s", category[i]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - //------- - - //y axis: number label - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - text = llformat("%d", (S32)((i - bottom) / scale)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - - text = llformat("MB") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - //-------------------------------------------------- - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; - text = llformat("Loaded") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, - loaded_color, - LLFontGL::LEFT, LLFontGL::TOP); - - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; - text = llformat("Bound") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, - bound_color, LLFontGL::LEFT, LLFontGL::TOP); - - //-------------------------------------------------- - - //title - text = llformat("Texture Category Distribution") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - - return scale ; -} diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h index 3723eb737b..900b4e17d8 100644 --- a/indra/newview/lltextureview.h +++ b/indra/newview/lltextureview.h @@ -75,41 +75,6 @@ public: }; class LLGLTexSizeBar; -class LLTextureSizeView : public LLContainerView -{ -protected: - LLTextureSizeView(const Params&); - friend class LLUICtrlFactory; -public: - ~LLTextureSizeView(); - - /*virtual*/ void draw(); - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) ; - - void setType(S32 type) {mType = type ;} - enum - { - TEXTURE_MEM_OVER_SIZE, - TEXTURE_MEM_OVER_CATEGORY - }; -private: - //draw background for TEXTURE_MEM_OVER_SIZE - F32 drawTextureSizeDistributionGraph() ; - //draw real-time texture mem bar over size - void drawTextureSizeGraph(); - - //draw background for TEXTURE_MEM_OVER_CATEGORY - F32 drawTextureCategoryDistributionGraph() ; - //draw real-time texture mem bar over category - void drawTextureCategoryGraph(); -private: - std::vector<LLGLTexSizeBar*> mTextureSizeBar ; - LLRect mTextureSizeBarRect ; - S32 mTextureSizeBarWidth ; - S32 mType ; -}; extern LLTextureView *gTextureView; -extern LLTextureSizeView *gTextureSizeView; -extern LLTextureSizeView *gTextureCategoryView; #endif // LL_TEXTURE_VIEW_H diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index a8060649ba..a473ee7ce0 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -52,7 +52,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; -LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) : +LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) : LLToastPanel(notification), mTextBox(NULL), mInfoPanel(NULL), @@ -536,7 +536,7 @@ void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id } } -void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification) +void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification) { LLSD response = notification->getResponse(); for (LLSD::map_const_iterator response_it = response.beginMap(); diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 57711b3d80..db517ec858 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -60,7 +60,7 @@ public: * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to * implement right class for desired toast panel. @see LLGenericTipPanel as example. */ - LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); + LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); virtual ~LLToastNotifyPanel(); LLPanel * getControlPanel() { return mControlPanel; } @@ -118,7 +118,7 @@ protected: /** * Process response data. Will disable selected options */ - void disableRespondedOptions(LLNotificationPtr& notification); + void disableRespondedOptions(const LLNotificationPtr& notification); bool mIsTip; bool mAddedDefaultBtn; diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index d2a4ce8745..c33fde99c5 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -29,7 +29,9 @@ #include "llpanelgenerictip.h" #include "llpanelonlinestatus.h" #include "llnotifications.h" +#include "lltoastnotifypanel.h" #include "lltoastpanel.h" +#include "lltoastscriptquestion.h" //static const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32) @@ -106,6 +108,17 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification( res = new LLPanelGenericTip(notification); } } + else if("notify" == notification->getType()) + { + if (notification->getPriority() == NOTIFICATION_PRIORITY_CRITICAL) + { + res = new LLToastScriptQuestion(notification); + } + else + { + res = new LLToastNotifyPanel(notification); + } + } /* else if(...) create all other specific non-public toast panel diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp new file mode 100644 index 0000000000..feeb8ca77b --- /dev/null +++ b/indra/newview/lltoastscriptquestion.cpp @@ -0,0 +1,130 @@ +/** + * @file lltoastscriptquestion.cpp + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "llbutton.h" +#include "llnotifications.h" +#include "lltoastscriptquestion.h" + +const int LEFT_PAD = 10; +const int BUTTON_HEIGHT = 27; +const int MAX_LINES_COUNT = 50; + +LLToastScriptQuestion::LLToastScriptQuestion(const LLNotificationPtr& notification) +: +LLToastPanel(notification) +{ + buildFromFile("panel_script_question_toast.xml"); +} + +BOOL LLToastScriptQuestion::postBuild() +{ + createButtons(); + + LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); + LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message"); + + mMessage->setValue(mNotification->getMessage()); + mFooter->setValue(mNotification->getFooter()); + + snapToMessageHeight(); + + return TRUE; +} +void LLToastScriptQuestion::snapToMessageHeight() +{ + LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); + LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message"); + if (!mMessage || !mFooter) + { + return; + } + + if (mMessage->getVisible() && mFooter->getVisible()) + { + S32 heightDelta = 0; + S32 maxTextHeight = (mMessage->getDefaultFont()->getLineHeight() * MAX_LINES_COUNT) + + (mFooter->getDefaultFont()->getLineHeight() * MAX_LINES_COUNT); + + LLRect messageRect = mMessage->getRect(); + LLRect footerRect = mFooter->getRect(); + + S32 oldTextHeight = messageRect.getHeight() + footerRect.getHeight(); + + S32 requiredTextHeight = mMessage->getTextBoundingRect().getHeight() + mFooter->getTextBoundingRect().getHeight(); + S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); + + heightDelta = newTextHeight - oldTextHeight - heightDelta; + + reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT)); + } +} + +void LLToastScriptQuestion::createButtons() +{ + LLNotificationFormPtr form = mNotification->getForm(); + int num_elements = form->getNumElements(); + int buttons_width = 0; + + for (int i = 0; i < num_elements; ++i) + { + LLSD form_element = form->getElement(i); + if ("button" == form_element["type"].asString()) + { + LLButton::Params p; + const LLFontGL* font = LLFontGL::getFontSansSerif(); + p.name(form_element["name"].asString()); + p.label(form_element["text"].asString()); + p.layout("topleft"); + p.font(font); + p.rect.height(BUTTON_HEIGHT); + p.click_callback.function(boost::bind(&LLToastScriptQuestion::onButtonClicked, this, form_element["name"].asString())); + p.rect.left = LEFT_PAD; + p.rect.width = font->getWidth(form_element["text"].asString()); + p.auto_resize = true; + p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); + p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + + LLButton* button = LLUICtrlFactory::create<LLButton>(p); + button->autoResize(); + getChild<LLPanel>("buttons_panel")->addChild(button); + + LLRect rect = button->getRect(); + rect.setLeftTopAndSize(buttons_width, rect.mTop, rect.getWidth(), rect.getHeight()); + button->setRect(rect); + + buttons_width += rect.getWidth() + LEFT_PAD; + } + } +} + +void LLToastScriptQuestion::onButtonClicked(std::string btn_name) +{ + LLSD response = mNotification->getResponseTemplate(); + response[btn_name] = true; + mNotification->respond(response); +} diff --git a/indra/newview/lltoastscriptquestion.h b/indra/newview/lltoastscriptquestion.h new file mode 100644 index 0000000000..3a557f60f6 --- /dev/null +++ b/indra/newview/lltoastscriptquestion.h @@ -0,0 +1,49 @@ +/** + * @file lltoastscriptquestion.h + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "lltoastpanel.h" + +#ifndef LLTOASTSCRIPTQUESTION_H_ +#define LLTOASTSCRIPTQUESTION_H_ + +class LLToastScriptQuestion : public LLToastPanel +{ + LOG_CLASS(LLToastScriptQuestion); + +public: + LLToastScriptQuestion(const LLNotificationPtr& notification); + virtual BOOL postBuild(); + virtual ~LLToastScriptQuestion(){}; + +private: + void snapToMessageHeight(); + + void createButtons(); + void onButtonClicked(std::string btn_name); +}; + +#endif /* LLTOASTSCRIPTQUESTION_H_ */ diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index e621cf647e..4c59fd0371 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -30,6 +30,7 @@ #include "llregionhandle.h" #include "stdtypes.h" +#include "llvoavatar.h" /* * Classes and utility functions for per-thread and per-region @@ -126,6 +127,8 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta mFPS.merge(src.mFPS); } + // Avatar stats - data all comes from main thread, so leave alone. + // Requests for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) { @@ -133,6 +136,7 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued); mRequests[i].mResponse.merge(src.mRequests[i].mResponse); } + } @@ -156,7 +160,9 @@ LLViewerAssetStats::LLViewerAssetStats() LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) : mRegionHandle(src.mRegionHandle), - mResetTimestamp(src.mResetTimestamp) + mResetTimestamp(src.mResetTimestamp), + mPhaseStats(src.mPhaseStats), + mAvatarRezStates(src.mAvatarRezStates) { const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) @@ -252,6 +258,17 @@ LLViewerAssetStats::recordFPS(F32 fps) mCurRegionStats->mFPS.record(fps); } +void +LLViewerAssetStats::recordAvatarStats() +{ + std::vector<S32> rez_counts; + LLVOAvatar::getNearbyRezzedStats(rez_counts); + mAvatarRezStates = rez_counts; + mPhaseStats.clear(); + mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); + mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); +} + LLSD LLViewerAssetStats::asLLSD(bool compact_output) { @@ -282,6 +299,11 @@ LLViewerAssetStats::asLLSD(bool compact_output) static const LLSD::String max_tag("max"); static const LLSD::String mean_tag("mean"); + // Avatar sub-tags + static const LLSD::String avatar_tag("avatar"); + static const LLSD::String avatar_nearby_tag("nearby"); + static const LLSD::String avatar_phase_stats_tag("phase_stats"); + const duration_t now = LLViewerAssetStatsFF::get_timestamp(); mCurRegionStats->accumulateTime(now); @@ -329,7 +351,6 @@ LLViewerAssetStats::asLLSD(bool compact_output) slot[max_tag] = LLSD(F64(stats.mFPS.getMax())); slot[mean_tag] = LLSD(F64(stats.mFPS.getMean())); } - 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); @@ -341,6 +362,16 @@ LLViewerAssetStats::asLLSD(bool compact_output) LLSD ret = LLSD::emptyMap(); ret["regions"] = regions; ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); + LLSD avatar_info; + avatar_info[avatar_nearby_tag] = LLSD::emptyArray(); + for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) + { + std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); + avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat]; + } + avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData(); + avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData(); + ret[avatar_tag] = avatar_info; return ret; } @@ -439,6 +470,14 @@ record_fps_main(F32 fps) gViewerAssetStatsMain->recordFPS(fps); } +void +record_avatar_stats() +{ + if (! gViewerAssetStatsMain) + return; + + gViewerAssetStatsMain->recordAvatarStats(); +} // 'thread1' - should be for TextureFetch thread diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 73ec5974b2..8319752230 100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -36,6 +36,7 @@ #include "llviewerassetstorage.h" #include "llsimplestat.h" #include "llsd.h" +#include "llvoavatar.h" /** * @class LLViewerAssetStats @@ -181,6 +182,9 @@ public: // 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 @@ -252,6 +256,10 @@ protected: // Time of last reset duration_t mResetTimestamp; + + // Nearby avatar stats + std::vector<S32> mAvatarRezStates; + LLViewerStats::phase_stats_t mPhaseStats; }; @@ -310,6 +318,7 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t void record_fps_main(F32 fps); +void record_avatar_stats(); /** * Region context, event and duration loggers for Thread 1. diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index bef24dd69b..0d361a2646 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -87,7 +87,6 @@ std::string gLastRunVersion; extern BOOL gResizeScreenTexture; extern BOOL gDebugGL; -extern BOOL gAuditTexture; //////////////////////////////////////////////////////////////////////////// // Listeners @@ -411,12 +410,6 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue) return true; } -static bool handleAuditTextureChanged(const LLSD& newvalue) -{ - gAuditTexture = newvalue.asBoolean(); - return true; -} - static bool handleRenderDebugGLChanged(const LLSD& newvalue) { gDebugGL = newvalue.asBoolean() || gDebugSession; @@ -618,7 +611,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); - gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2)); gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 7fdaac68c8..d0e0d0d826 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -103,6 +103,7 @@ #include "llfloatertelehub.h" #include "llfloatertestinspectors.h" #include "llfloatertestlistview.h" +#include "llfloatertexturefetchdebugger.h" #include "llfloatertools.h" #include "llfloatertos.h" #include "llfloatertopobjects.h" @@ -227,6 +228,11 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>); LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); + + if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) + { + LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>); + } LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>); LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 45ca23cdfe..b47a41c44c 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -342,8 +342,8 @@ void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& ne void LLViewerInventoryItem::removeFromServer() { - llinfos << "Removing inventory item " << mUUID << " from server." - << llendl; + lldebugs << "Removing inventory item " << mUUID << " from server." + << llendl; LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1); gInventory.accountForUpdate(up); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index e052e37393..f029ae5302 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -576,7 +576,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { old_mode = mTexture->getAddressMode(); } - gGL.getTexUnit(diffuse_channel)->bind(mTexture.get()); gGL.getTexUnit(diffuse_channel)->bind(mTexture); gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 0191f0cae8..dd5dae1dc1 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -61,6 +61,7 @@ public: //----------------------------------------------------------------------------- class LLViewerJointMesh : public LLViewerJoint { + friend class LLVOAvatar; protected: LLColor4 mColor; // color value // LLColor4 mSpecular; // specular color (always white for now) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 03a12f7c4e..34e916fec0 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -517,14 +517,6 @@ class LLAdvancedToggleConsole : public view_listener_t { toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep)); } - else if (gTextureSizeView && "texture size" == console_type) - { - toggle_visibility( (void*)gTextureSizeView ); - } - else if (gTextureCategoryView && "texture category" == console_type) - { - toggle_visibility( (void*)gTextureCategoryView ); - } else if ("fast timers" == console_type) { LLFloaterReg::toggleInstance("fast_timers"); @@ -557,14 +549,6 @@ class LLAdvancedCheckConsole : public view_listener_t { new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) ); } - else if (gTextureSizeView && "texture size" == console_type) - { - new_value = get_visibility( (void*)gTextureSizeView ); - } - else if (gTextureCategoryView && "texture category" == console_type) - { - new_value = get_visibility( (void*)gTextureCategoryView ); - } else if ("fast timers" == console_type) { new_value = LLFloaterReg::instanceVisible("fast_timers"); @@ -867,6 +851,73 @@ class LLAdvancedCheckFeature : public view_listener_t } }; +class LLAdvancedCheckDisplayTextureDensity : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string mode = userdata.asString(); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) + { + return mode == "none"; + } + if (mode == "current") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT; + } + else if (mode == "desired") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED; + } + else if (mode == "full") + { + return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL; + } + return false; + } +}; + +class LLAdvancedSetDisplayTextureDensity : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string mode = userdata.asString(); + if (mode == "none") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; + } + else if (mode == "current") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT; + } + else if (mode == "desired") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true); + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED; + } + else if (mode == "full") + { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE) + { + gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); + } + LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL; + } + return true; + } +}; + ////////////////// // INFO DISPLAY // @@ -981,6 +1032,10 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_WIND_VECTORS; } + else if ("texel density" == info_display) + { + return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY; + } else { return 0; @@ -2247,6 +2302,14 @@ class LLDevelopSetLoggingLevel : public view_listener_t } }; +class LLDevelopTextureFetchDebugger : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); + } +}; + ////////////////// // ADMIN MENU // ////////////////// @@ -8169,6 +8232,10 @@ void initialize_menus() //// Advanced > Render > Features view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature"); view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature"); + + view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity"); + view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity"); + // Advanced > Render > Info Displays view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay"); view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay"); @@ -8300,6 +8367,9 @@ void initialize_menus() // Develop >Set logging level view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel"); view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); + + //Develop (Texture Fetch Debug Console) + view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); // Admin >Object view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index bf7e84e2c8..d790fbc31d 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6009,16 +6009,21 @@ void process_script_question(LLMessageSystem *msg, void **user_data) args["OBJECTNAME"] = object_name; args["NAME"] = LLCacheName::cleanFullName(owner_name); + BOOL has_not_only_debit = questions ^ LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_DEBIT]; // check the received permission flags against each permission for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) { if (questions & LSCRIPTRunTimePermissionBits[i]) { count++; - script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; // check whether permission question should cause special caution dialog caution |= (SCRIPT_QUESTION_IS_CAUTION[i]); + + if (("ScriptTakeMoney" == SCRIPT_QUESTIONS[i]) && has_not_only_debit) + continue; + + script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; } } args["QUESTIONS"] = script_question; @@ -6034,6 +6039,10 @@ void process_script_question(LLMessageSystem *msg, void **user_data) // check whether cautions are even enabled or not if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) { + if (caution) + { + args["FOOTERTEXT"] = (count > 1) ? LLTrans::getString("AdditionalPermissionsRequestHeader") + "\n\n" + script_question : ""; + } // display the caution permissions prompt LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload); } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 383d4a7955..2fd8c87fc2 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -91,8 +91,9 @@ extern LLPipeline gPipeline; // Statics for object lookup tables. U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. -std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex; +std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex; std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID; +LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128); LLViewerObjectList::LLViewerObjectList() { @@ -542,6 +543,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } justCreated = TRUE; mNumNewObjects++; + sCacheHitRate.addValue(cached ? 100.f : 0.f); + } diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 336fc3cf20..9936432a71 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -194,6 +194,8 @@ protected: std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; + static LLStat sCacheHitRate; + typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t; vobj_list_t mObjects; diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index f738b84bb9..6c8a827ba3 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -57,6 +57,8 @@ #include "lldeleteutils.h" #include "imageids.h" #include "indra_constants.h" +#include "llinitparam.h" + //#include "linden_common.h" //#include "llpreprocessor.h" #include "llallocator.h" @@ -124,7 +126,5 @@ // Library includes from llmessage project #include "llcachename.h" -// Library includes from llxuixml -#include "llinitparam.h" #endif diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 28dea8aa04..28f4ec72f3 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -878,3 +878,110 @@ void send_stats() LLHTTPClient::post(url, body, new ViewerStatsResponder()); } +LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) +{ + phase_map_t::iterator iter = mPhaseMap.find(phase_name); + if (iter == mPhaseMap.end()) + { + LLFrameTimer timer; + mPhaseMap[phase_name] = timer; + } + LLFrameTimer& timer = mPhaseMap[phase_name]; + return timer; +} + +void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name) +{ + LLFrameTimer& timer = getPhaseTimer(phase_name); + lldebugs << "startPhase " << phase_name << llendl; + timer.unpause(); +} + +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 paused state - record stats. + recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); + } + lldebugs << "stopPhase " << phase_name << llendl; + iter->second.pause(); + } + else + { + lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl; + } +} + +void LLViewerStats::PhaseMap::stopAllPhases() +{ + for (phase_map_t::iterator iter = mPhaseMap.begin(); + iter != mPhaseMap.end(); ++iter) + { + const std::string& phase_name = iter->first; + if (iter->second.getStarted()) + { + // Going from started to paused state - record stats. + recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); + } + lldebugs << "stopPhase (all) " << phase_name << llendl; + iter->second.pause(); + } +} + +void LLViewerStats::PhaseMap::clearPhases() +{ + lldebugs << "clearPhases" << llendl; + + mPhaseMap.clear(); +} + +LLSD LLViewerStats::PhaseMap::dumpPhases() +{ + 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"] = !(iter->second.getStarted()); + result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); +#if 0 // global stats for each phase seem like overkill here + phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name); + if (stats_iter != sPhaseStats.end()) + { + result[phase_name]["stats"] = stats_iter->second.getData(); + } +#endif + } + return result; +} + +// static initializer +//static +LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats; + +LLViewerStats::PhaseMap::PhaseMap() +{ +} + +// 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); +} + diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index f91a1241fe..750d963f69 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -244,7 +244,7 @@ public: inline F32 getStdDev() const { const F32 mean = getMean(); - return (mCount == 0) ? 0.f : sqrt( mSumOfSquares/mCount - (mean * mean) ); + return (mCount < 2) ? 0.f : sqrt(llmax(0.f,mSumOfSquares/mCount - (mean * mean))); } inline U32 getCount() const @@ -274,7 +274,28 @@ 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; + typedef std::map<std::string,StatsAccumulator> phase_stats_t; + class PhaseMap + { + private: + phase_map_t mPhaseMap; + static phase_stats_t sStats; + public: + PhaseMap(); + LLFrameTimer& getPhaseTimer(const std::string& phase_name); + void startPhase(const std::string& phase_name); + void stopPhase(const std::string& phase_name); + void stopAllPhases(); + void clearPhases(); + LLSD dumpPhases(); + static StatsAccumulator& getPhaseStats(const std::string& phase_name); + static void recordPhaseStat(const std::string& phase_name, F32 value); + }; + private: F64 mStats[ST_COUNT]; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index a0782c1852..7f638a24bf 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -67,6 +67,7 @@ // statics LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL; LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL; +LLPointer<LLViewerTexture> LLViewerTexture::sCheckerBoardImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL; @@ -87,6 +88,7 @@ S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ; +F32 LLViewerTexture::sCameraMovingBias = 0.0f ; S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ; const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ; @@ -96,6 +98,9 @@ S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ; BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ; F32 LLViewerTexture::sCurrentTime = 0.0f ; BOOL LLViewerTexture::sUseTextureAtlas = FALSE ; +F32 LLViewerTexture::sTexelPixelRatio = 1.0f; + +LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by @@ -175,7 +180,12 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id) } return tex ; } - + +LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id) +{ + return gTextureList.findImage(id); +} + LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id) { return LLViewerMediaTexture::findMediaTexture(media_id) ; @@ -347,6 +357,21 @@ void LLViewerTextureManager::init() LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI); LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; + image_raw = new LLImageRaw(32,32,3); + data = image_raw->getData(); + + for (S32 i = 0; i < (32*32*3); i+=3) + { + S32 x = (i % (32*3)) / (3*16); + S32 y = i / (32*3*16); + U8 color = ((x + y) % 2) * 255; + data[i] = color; + data[i+1] = color; + data[i+2] = color; + } + + LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); + LLViewerTexture::initClass() ; if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) @@ -367,6 +392,7 @@ void LLViewerTextureManager::cleanup() LLImageGL::sDefaultGLTexture = NULL ; LLViewerTexture::sNullImagep = NULL; LLViewerTexture::sBlackImagep = NULL; + LLViewerTexture::sCheckerBoardImagep = NULL; LLViewerFetchedTexture::sDefaultImagep = NULL; LLViewerFetchedTexture::sSmokeImagep = NULL; LLViewerFetchedTexture::sMissingAssetImagep = NULL; @@ -383,11 +409,7 @@ void LLViewerTextureManager::cleanup() void LLViewerTexture::initClass() { LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; - - if(gAuditTexture) - { - LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ; - } + sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); } // static @@ -534,7 +556,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; + 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) ; @@ -655,10 +678,6 @@ void LLViewerTexture::setBoostLevel(S32 level) { setNoDelete() ; } - if(gAuditTexture) - { - setCategory(mBoostLevel); - } } } @@ -712,6 +731,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co mNeedsGLTexture = TRUE ; } + virtual_size *= sTexelPixelRatio; if(!mMaxVirtualSizeResetCounter) { //flag to reset the values because the old values are used. @@ -1287,6 +1307,7 @@ void LLViewerFetchedTexture::cleanup() mCachedRawDiscardLevel = -1 ; mCachedRawImageReady = FALSE ; mSavedRawImage = NULL ; + mSavedRawDiscardLevel = -1; } void LLViewerFetchedTexture::setForSculpt() @@ -1880,6 +1901,8 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching() bool LLViewerFetchedTexture::updateFetch() { static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); + static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold"); + static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost"); if(textures_decode_disabled) { return false ; @@ -2042,18 +2065,24 @@ bool LLViewerFetchedTexture::updateFetch() // make_request = false; //} - if(make_request) + if (make_request) { - //load the texture progressively. + // Load the texture progressively: we try not to rush to the desired discard too fast. + // If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps + // This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ; - if(current_discard < 0) + if (current_discard < 0) { desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level); } - else + else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold) { - desired_discard = llmax(desired_discard, current_discard - delta_level); + desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost); } + else + { + desired_discard = llmax(desired_discard, current_discard - delta_level); + } if (mIsFetching) { @@ -2121,6 +2150,30 @@ bool LLViewerFetchedTexture::updateFetch() return mIsFetching ? true : false; } +void LLViewerFetchedTexture::clearFetchedResults() +{ + llassert_always(!mNeedsCreateTexture && !mIsFetching); + + cleanup(); + destroyGLTexture(); + + if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate + { + mGLTexturep->forceToInvalidateGLTexture(); + } +} + +void LLViewerFetchedTexture::forceToDeleteRequest() +{ + if (mHasFetcher) + { + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + mHasFetcher = FALSE; + mIsFetching = FALSE ; + resetTextureStats(); + } +} + void LLViewerFetchedTexture::setIsMissingAsset() { if (mUrl.empty()) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index af8afef203..f1105c3705 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -139,6 +139,7 @@ public: OTHER, MAX_GL_IMAGE_CATEGORY }; + static S32 getTotalNumOfCategories() ; static S32 getIndexFromCategory(S32 category) ; static S32 getCategoryFromIndex(S32 index) ; @@ -312,6 +313,7 @@ protected: } LLGLTextureState; LLGLTextureState mTextureState ; + static F32 sTexelPixelRatio; public: static const U32 sCurrentFileVersion; static S32 sImageCount; @@ -326,6 +328,7 @@ public: static S32 sMaxTotalTextureMemInMegaBytes; static S32 sMaxDesiredTextureMemInBytes ; static S8 sCameraMovingDiscardBias; + static F32 sCameraMovingBias; static S32 sMaxSculptRez ; static S32 sMinLargeImageSize ; static S32 sMaxSmallImageSize ; @@ -333,8 +336,19 @@ public: static F32 sCurrentTime ; static BOOL sUseTextureAtlas ; + enum EDebugTexels + { + DEBUG_TEXELS_OFF, + DEBUG_TEXELS_CURRENT, + DEBUG_TEXELS_DESIRED, + DEBUG_TEXELS_FULL + }; + + static EDebugTexels sDebugTexelsMode; + static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects. static LLPointer<LLViewerTexture> sBlackImagep; // Texture to show NOTHING (pure black) + static LLPointer<LLViewerTexture> sCheckerBoardImagep; // Texture to show NOTHING (pure black) }; @@ -423,6 +437,8 @@ public: bool updateFetch(); + void clearFetchedResults(); //clear all fetched results, for debug use. + // Override the computation of discard levels if we know the exact output // size of the image. Used for UI textures to not decode, even if we have // more data. @@ -481,6 +497,7 @@ public: BOOL hasFetcher() const { return mHasFetcher;} void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} + void forceToDeleteRequest(); protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; @@ -690,6 +707,7 @@ public: //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. // static LLViewerTexture* findTexture(const LLUUID& id) ; + static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id) ; static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index c463b85913..9a6c0569a9 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,6 +58,7 @@ #include "pipeline.h" #include "llappviewer.h" #include "llxuiparser.h" +#include "llagent.h" //////////////////////////////////////////////////////////////////////////// @@ -597,6 +598,12 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats"); void LLViewerTextureList::updateImages(F32 max_time) { + if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) + { + clearFetchingRequests(); + return; + } + LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); @@ -659,6 +666,24 @@ void LLViewerTextureList::updateImages(F32 max_time) } } +void LLViewerTextureList::clearFetchingRequests() +{ + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + return; + } + + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ++iter) + { + LLViewerFetchedTexture* image = *iter; + if(image->hasFetcher()) + { + image->forceToDeleteRequest() ; + } + } +} + void LLViewerTextureList::updateImagesDecodePriorities() { // Update the decode priority for N images each frame @@ -1030,7 +1055,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage { raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C(); - compressedImage->setRate(0.f); if (gSavedSettings.getBOOL("LosslessJ2CUpload") && (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index b386c73d2a..e89997fe28 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -110,6 +110,8 @@ public: void doPreloadImages(); void doPrefetchImages(); + void clearFetchingRequests(); + static S32 getMinVideoRamSetting(); static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -164,7 +166,7 @@ private: // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) - { return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } + { return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } public: typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ade21ff30e..28a25f744b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -101,6 +101,8 @@ #include "llvoicevisualizer.h" // Ventrella #include "lldebugmessagebox.h" +#include "llsdutil.h" + extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; extern F32 ANIM_SPEED_MAX; @@ -627,7 +629,6 @@ F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; BOOL LLVOAvatar::sJointDebug = FALSE; - F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; @@ -683,13 +684,16 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mNeedsSkin(FALSE), mLastSkinTime(0.f), mUpdatePeriod(1), + mFirstFullyVisible(TRUE), mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), mSupportsAlphaLayers(FALSE), mLoadedCallbacksPaused(FALSE), mHasPelvisOffset( FALSE ), - mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")) + mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), + mLastRezzedStatus(-1) + { LLMemType mt(LLMemType::MTYPE_AVATAR); //VTResume(); // VTune @@ -770,32 +774,46 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastPelvisFixup = 0.0f; } +std::string LLVOAvatar::avString() const +{ + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + return " Avatar '" + getFullname() + "' " + viz_string + " "; +} + +void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment) +{ + LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " Notification " << notification_name + << " : " << comment + << llendl; + + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); + args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); + args["NAME"] = getFullname(); + LLNotificationsUtil::add(notification_name,args); + } +} + //------------------------------------------------------------------------ // LLVOAvatar::~LLVOAvatar() //------------------------------------------------------------------------ LLVOAvatar::~LLVOAvatar() { - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + if (!mFullyLoaded) { - if (!mFullyLoaded) - { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left after " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds as cloud." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftCloudNotification",args); - } - else - { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftNotification",args); - } - + debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); } + else + { + debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); + } + lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; mRoot.removeAllChildren(); @@ -845,6 +863,8 @@ LLVOAvatar::~LLVOAvatar() mAnimationSources.clear(); LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; + getPhases().clearPhases(); + lldebugs << "LLVOAvatar Destructor end" << llendl; } @@ -878,6 +898,55 @@ BOOL LLVOAvatar::isFullyBaked() return TRUE; } +BOOL LLVOAvatar::isFullyTextured() const +{ + for (S32 i = 0; i < mMeshLOD.size(); i++) + { + LLViewerJoint* joint = (LLViewerJoint*) mMeshLOD[i]; + if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) + { + continue; // don't care about skirt textures if we're not wearing one. + } + if (!joint) + { + continue; // nonexistent LOD OK. + } + std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin(); + if (meshIter != joint->mMeshParts.end()) + { + LLViewerJointMesh *mesh = (LLViewerJointMesh *) *meshIter; + if (!mesh) + { + continue; // nonexistent mesh OK + } + if (mesh->mTexture.notNull() && mesh->mTexture->hasGLTexture()) + { + continue; // Mesh exists and has a baked texture. + } + if (mesh->mLayerSet && mesh->mLayerSet->hasComposite()) + { + continue; // Mesh exists and has a composite texture. + } + // Fail + return FALSE; + } + } + return TRUE; +} + +BOOL LLVOAvatar::hasGray() const +{ + return !getIsCloud() && !isFullyTextured(); +} + +S32 LLVOAvatar::getRezzedStatus() const +{ + if (getIsCloud()) return 0; + if (isFullyTextured()) return 2; + llassert(hasGray()); + return 1; // gray +} + void LLVOAvatar::deleteLayerSetCaches(bool clearAll) { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -925,6 +994,31 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars) } // static +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ + counts.clear(); + counts.resize(3); + for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if (!inst) + continue; + S32 rez_status = inst->getRezzedStatus(); + counts[rez_status]++; + } +} + +// 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 void LLVOAvatar::dumpBakedStatus() { LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); @@ -2259,18 +2353,12 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); // Print out arrival information once we have name of avatar. - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + if (has_name && getNVPair("FirstName")) { - if (has_name && getNVPair("FirstName")) - { - mDebugExistenceTimer.reset(); - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezArrivedNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' arrived." << llendl; - } + mDebugExistenceTimer.reset(); + debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); } + if(retval & LLViewerObject::INVALID_UPDATE) { if (isSelf()) @@ -2776,16 +2864,16 @@ void LLVOAvatar::idleUpdateLoadingEffect() // update visibility when avatar is partially loaded if (updateIsFullyLoaded()) // changed? { - if (isFullyLoaded() && isSelf()) + if (isFullyLoaded() && mFirstFullyVisible && isSelf()) { - static bool first_fully_visible = true; - if (first_fully_visible) - { - llinfos << "self isFullyLoaded, first_fully_visible" << llendl; - - first_fully_visible = false; - LLAppearanceMgr::instance().onFirstFullyVisible(); - } + LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL; + mFirstFullyVisible = FALSE; + LLAppearanceMgr::instance().onFirstFullyVisible(); + } + if (isFullyLoaded() && mFirstFullyVisible && !isSelf()) + { + LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL; + mFirstFullyVisible = FALSE; } if (isFullyLoaded()) { @@ -2929,43 +3017,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - BOOL new_name = FALSE; - if (visible_chat != mVisibleChat) + BOOL new_name = FALSE; + if (visible_chat != mVisibleChat) + { + mVisibleChat = visible_chat; + new_name = TRUE; + } + + if (sRenderGroupTitles != mRenderGroupTitles) + { + mRenderGroupTitles = sRenderGroupTitles; + new_name = TRUE; + } + + // First Calculate Alpha + // If alpha > 0, create mNameText if necessary, otherwise delete it + F32 alpha = 0.f; + if (mAppAngle > 5.f) + { + const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; + if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) { - mVisibleChat = visible_chat; - new_name = TRUE; + alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; } - - if (sRenderGroupTitles != mRenderGroupTitles) + else { - mRenderGroupTitles = sRenderGroupTitles; - new_name = TRUE; + // ...not fading, full alpha + alpha = 1.f; } - - // First Calculate Alpha - // If alpha > 0, create mNameText if necessary, otherwise delete it - F32 alpha = 0.f; - if (mAppAngle > 5.f) - { - const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; - if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) - { - alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; - } - else - { - // ...not fading, full alpha - alpha = 1.f; - } - } - else if (mAppAngle > 2.f) - { - // far away is faded out also - alpha = (mAppAngle-2.f)/3.f; - } + } + else if (mAppAngle > 2.f) + { + // far away is faded out also + alpha = (mAppAngle-2.f)/3.f; + } if (alpha <= 0.f) - { + { if (mNameText) { mNameText->markDead(); @@ -2975,19 +3063,19 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - if (!mNameText) - { + if (!mNameText) + { mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject( - LLHUDObject::LL_HUD_NAME_TAG) ); + LLHUDObject::LL_HUD_NAME_TAG) ); //mNameText->setMass(10.f); - mNameText->setSourceObject(this); + mNameText->setSourceObject(this); mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); - mNameText->setVisibleOffScreen(TRUE); - mNameText->setMaxLines(11); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - sNumVisibleChatBubbles++; - new_name = TRUE; - } + mNameText->setVisibleOffScreen(TRUE); + mNameText->setMaxLines(11); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + sNumVisibleChatBubbles++; + new_name = TRUE; + } LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); mNameText->setPositionAgent(name_position); @@ -2996,10 +3084,10 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) - { - LLNameValue *title = getNVPair("Title"); - LLNameValue* firstname = getNVPair("FirstName"); - LLNameValue* lastname = getNVPair("LastName"); +{ + LLNameValue *title = getNVPair("Title"); + LLNameValue* firstname = getNVPair("FirstName"); + LLNameValue* lastname = getNVPair("LastName"); // Avatars must have a first and last name if (!firstname || !lastname) return; @@ -3013,34 +3101,23 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) is_muted = false; } else - { + { is_muted = LLMuteList::getInstance()->isMuted(getID()); } bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); bool is_cloud = getIsCloud(); - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - if (is_appearance != mNameAppearance) - { - if (is_appearance) - { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; - } - else - { - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; - } - } - } + if (is_appearance != mNameAppearance) + { + if (is_appearance) + { + debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode"); + } + else + { + debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode"); + } + } // Rebuild name tag if state change detected if (mNameString.empty() @@ -3050,56 +3127,56 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) || is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute - || is_appearance != mNameAppearance + || is_appearance != mNameAppearance || is_friend != mNameFriend || is_cloud != mNameCloud) - { + { LLColor4 name_tag_color = getNameTagColor(is_friend); clearNameTag(); if (is_away || is_muted || is_busy || is_appearance) - { + { std::string line; - if (is_away) - { - line += LLTrans::getString("AvatarAway"); + if (is_away) + { + line += LLTrans::getString("AvatarAway"); line += ", "; - } - if (is_busy) - { + } + if (is_busy) + { line += LLTrans::getString("AvatarBusy"); line += ", "; } if (is_muted) - { + { line += LLTrans::getString("AvatarMuted"); - line += ", "; - } + line += ", "; + } if (is_appearance) { line += LLTrans::getString("AvatarEditingAppearance"); line += ", "; - } + } if (is_cloud) - { + { line += LLTrans::getString("LoadingData"); line += ", "; } // trim last ", " line.resize( line.length() - 2 ); addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall()); + LLFontGL::getFontSansSerifSmall()); } if (sRenderGroupTitles && title && title->getString() && title->getString()[0] != '\0') - { + { std::string title_str = title->getString(); LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall()); - } + LLFontGL::getFontSansSerifSmall()); + } static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames"); static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); @@ -3112,120 +3189,120 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // ...call this function back when the name arrives // and force a rebuild LLAvatarNameCache::get(getID(), - boost::bind(&LLVOAvatar::clearNameTag, this)); - } + boost::bind(&LLVOAvatar::clearNameTag, this)); + } // Might be blank if name not available yet, that's OK if (show_display_names) { addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerif()); - } + LLFontGL::getFontSansSerif()); + } // Suppress SLID display if display name matches exactly (ugh) if (show_usernames && !av_name.mIsDisplayNameDefault) - { + { // *HACK: Desaturate the color LLColor4 username_color = name_tag_color * 0.83f; addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall()); + LLFontGL::getFontSansSerifSmall()); } - } + } else - { + { const LLFontGL* font = LLFontGL::getFontSansSerif(); std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); - } + } - mNameAway = is_away; - mNameBusy = is_busy; - mNameMute = is_muted; - mNameAppearance = is_appearance; + mNameAway = is_away; + mNameBusy = is_busy; + mNameMute = is_muted; + mNameAppearance = is_appearance; mNameFriend = is_friend; - mNameCloud = is_cloud; - mTitle = title ? title->getString() : ""; - LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); - new_name = TRUE; - } + mNameCloud = is_cloud; + mTitle = title ? title->getString() : ""; + LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); + new_name = TRUE; + } if (mVisibleChat) - { - mNameText->setFont(LLFontGL::getFontSansSerif()); + { + mNameText->setFont(LLFontGL::getFontSansSerif()); mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - char line[MAX_STRING]; /* Flawfinder: ignore */ - line[0] = '\0'; - std::deque<LLChat>::iterator chat_iter = mChats.begin(); - mNameText->clearString(); - - LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); - LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); - LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); - if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) - { - ++chat_iter; - } - - for(; chat_iter != mChats.end(); ++chat_iter) - { - F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); - LLFontGL::StyleFlags style; - switch(chat_iter->mChatType) - { - case CHAT_TYPE_WHISPER: - style = LLFontGL::ITALIC; - break; - case CHAT_TYPE_SHOUT: - style = LLFontGL::BOLD; - break; - default: - style = LLFontGL::NORMAL; - break; - } - if (chat_fade_amt < 1.f) - { - F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); - mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); - } - else if (chat_fade_amt < 2.f) - { - F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); - mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); - } - else if (chat_fade_amt < 3.f) - { - // *NOTE: only remove lines down to minimum number - mNameText->addLine(chat_iter->mText, old_chat, style); - } - } - mNameText->setVisibleOffScreen(TRUE); + char line[MAX_STRING]; /* Flawfinder: ignore */ + line[0] = '\0'; + std::deque<LLChat>::iterator chat_iter = mChats.begin(); + mNameText->clearString(); - if (mTyping) - { - S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; - switch(dot_count) - { - case 1: - mNameText->addLine(".", new_chat); - break; - case 2: - mNameText->addLine("..", new_chat); - break; - case 3: - mNameText->addLine("...", new_chat); - break; - } + LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); + LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); + LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); + if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) + { + ++chat_iter; + } - } + for(; chat_iter != mChats.end(); ++chat_iter) + { + F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); + LLFontGL::StyleFlags style; + switch(chat_iter->mChatType) + { + case CHAT_TYPE_WHISPER: + style = LLFontGL::ITALIC; + break; + case CHAT_TYPE_SHOUT: + style = LLFontGL::BOLD; + break; + default: + style = LLFontGL::NORMAL; + break; } - else + if (chat_fade_amt < 1.f) + { + F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); + mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); + } + else if (chat_fade_amt < 2.f) + { + F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); + mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); + } + else if (chat_fade_amt < 3.f) + { + // *NOTE: only remove lines down to minimum number + mNameText->addLine(chat_iter->mText, old_chat, style); + } + } + mNameText->setVisibleOffScreen(TRUE); + + if (mTyping) + { + S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; + switch(dot_count) { + case 1: + mNameText->addLine(".", new_chat); + break; + case 2: + mNameText->addLine("..", new_chat); + break; + case 3: + mNameText->addLine("...", new_chat); + break; + } + + } + } + else + { // ...not using chat bubbles, just names mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - mNameText->setVisibleOffScreen(FALSE); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + mNameText->setVisibleOffScreen(FALSE); } } @@ -3248,8 +3325,8 @@ void LLVOAvatar::clearNameTag() { mNameString.clear(); if (mNameText) - { - mNameText->setLabel(""); + { + mNameText->setLabel(""); mNameText->setString( "" ); } } @@ -3975,7 +4052,7 @@ void LLVOAvatar::updateVisibility() LLNameValue* firstname = getNVPair("FirstName"); if (firstname) { - llinfos << "Avatar " << firstname->getString() << " updating visiblity" << llendl; + LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL; } else { @@ -4191,7 +4268,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLNameValue* firstname = getNVPair("FirstName"); if (firstname) { - llinfos << "Avatar " << firstname->getString() << " in render" << llendl; + LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL; } else { @@ -6421,10 +6498,10 @@ BOOL LLVOAvatar::isVisible() const } // Determine if we have enough avatar data to render -BOOL LLVOAvatar::getIsCloud() +BOOL LLVOAvatar::getIsCloud() const { // Do we have a shape? - if (visualParamWeightsAreDefault()) + if ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault()) { return TRUE; } @@ -6443,11 +6520,53 @@ BOOL LLVOAvatar::getIsCloud() return FALSE; } +void LLVOAvatar::updateRezzedStatusTimers() +{ + // State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured. + // Purpose is to collect time data for each period of cloud or cloud+gray. + S32 rez_status = getRezzedStatus(); + if (rez_status != mLastRezzedStatus) + { + LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; + bool is_cloud_or_gray = (rez_status==0 || rez_status==1); + bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1); + bool is_cloud = (rez_status==0); + bool was_cloud = (mLastRezzedStatus==0); + + // Non-cloud to cloud + if (is_cloud && !was_cloud) + { + // start cloud timer. + getPhases().startPhase("cloud"); + } + else if (was_cloud && !is_cloud) + { + // stop cloud timer, which will capture stats. + getPhases().stopPhase("cloud"); + } + + // Non-cloud-or-gray to cloud-or-gray + if (is_cloud_or_gray && !was_cloud_or_gray) + { + // start cloud-or-gray timer. + getPhases().startPhase("cloud-or-gray"); + } + else if (was_cloud_or_gray && !is_cloud_or_gray) + { + // stop cloud-or-gray timer, which will capture stats. + getPhases().stopPhase("cloud-or-gray"); + } + + mLastRezzedStatus = rez_status; + } +} + // call periodically to keep isFullyLoaded up to date. // returns true if the value has changed. BOOL LLVOAvatar::updateIsFullyLoaded() { const BOOL loading = getIsCloud(); + updateRezzedStatusTimers(); updateRuthTimer(loading); return processFullyLoadedChange(loading); } @@ -6462,27 +6581,19 @@ void LLVOAvatar::updateRuthTimer(bool loading) if (mPreviousFullyLoaded) { mRuthTimer.reset(); - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) - { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' became cloud." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezCloudNotification",args); - } - mRuthDebugTimer.reset(); + debugAvatarRezTime("AvatarRezCloudNotification","became cloud"); } const F32 LOADING_TIMEOUT__SECONDS = 120.f; if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS) { - llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " + LL_DEBUGS("Avatar") << avString() + << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) " << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) " << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) " << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." - << llendl; + << LL_ENDL; LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); mRuthTimer.reset(); @@ -6499,20 +6610,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); - if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + if (!mPreviousFullyLoaded && !loading && mFullyLoaded) { - if (!mPreviousFullyLoaded && !loading && mFullyLoaded) - { - llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' resolved in " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl; - LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); - args["NAME"] = getFullname(); - LLNotificationsUtil::add("AvatarRezNotification",args); - } + debugAvatarRezTime("AvatarRezNotification","fully loaded"); } // did our loading state "change" from last call? + // runway - why are we updating every 30 calls even if nothing has changed? const S32 UPDATE_RATE = 30; BOOL changed = ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call @@ -6952,7 +7056,7 @@ LLColor4 LLVOAvatar::getDummyColor() void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const { - llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl; + LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL; for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); ++iter) @@ -6962,23 +7066,23 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const const LLViewerTexture* te_image = getImage(iter->first,0); if( !te_image ) { - llinfos << " " << texture_dict->mName << ": null ptr" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL; } else if( te_image->getID().isNull() ) { - llinfos << " " << texture_dict->mName << ": null UUID" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL; } else if( te_image->getID() == IMG_DEFAULT ) { - llinfos << " " << texture_dict->mName << ": IMG_DEFAULT" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL; } else if( te_image->getID() == IMG_DEFAULT_AVATAR ) { - llinfos << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL; } else { - llinfos << " " << texture_dict->mName << ": " << te_image->getID() << llendl; + LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL; } } } @@ -7109,6 +7213,7 @@ void LLVOAvatar::rebuildHUD() //----------------------------------------------------------------------------- void LLVOAvatar::onFirstTEMessageReceived() { + LL_INFOS("Avatar") << avString() << LL_ENDL; if( !mFirstTEMessageReceived ) { mFirstTEMessageReceived = TRUE; @@ -7137,6 +7242,7 @@ void LLVOAvatar::onFirstTEMessageReceived() image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), src_callback_list, paused); } + LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL; image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ), src_callback_list, paused ); } @@ -7195,14 +7301,16 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) LLMemType mt(LLMemType::MTYPE_AVATAR); -// llinfos << "processAvatarAppearance start " << mID << llendl; BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; - mFirstAppearanceMessageReceived = TRUE; + LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID + << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + + if( isSelf() ) { - llwarns << "Received AvatarAppearance for self" << llendl; + llwarns << avString() << "Received AvatarAppearance for self" << llendl; if( mFirstTEMessageReceived ) { // llinfos << "processAvatarAppearance end " << mID << llendl; @@ -7230,7 +7338,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } - if( !is_first_appearance_message ) + // runway - was + // if (!is_first_appearance_message ) + // which means it would be called on second appearance message - probably wrong. + if (is_first_appearance_message ) { onFirstTEMessageReceived(); } @@ -7251,6 +7362,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) 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 if( num_blocks > 1 && !drop_visual_params_debug) { + LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; BOOL params_changed = FALSE; BOOL interp_params = FALSE; @@ -7323,6 +7435,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) else { // AvatarAppearance message arrived without visual params + LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL; if (drop_visual_params_debug) { llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl; @@ -7475,8 +7588,15 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture // static void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { + + 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; + } if (!success && selfp) { @@ -7488,13 +7608,20 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu } } -void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +// Static +void LLVOAvatar::onBakedTextureLoaded(BOOL success, + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, + S32 discard_level, BOOL final, void* userdata) { //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl; LLUUID id = src_vi->getID(); 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 << " id " << src_vi->getID() << LL_ENDL; + } if (selfp && !success) { @@ -7516,6 +7643,8 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_ // Called when baked texture is loaded and also when we start up with a baked texture void LLVOAvatar::useBakedTexture( const LLUUID& id ) { + + /* if(id == head_baked->getID()) mHeadBakedLoaded = TRUE; mLastHeadBakedID = id; @@ -7526,6 +7655,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); if (id == image_baked->getID()) { + LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL; mBakedTextureDatas[i].mIsLoaded = true; mBakedTextureDatas[i].mLastTextureIndex = id; mBakedTextureDatas[i].mIsUsed = true; @@ -7700,6 +7830,9 @@ void LLVOAvatar::cullAvatarsByPixelArea() } } + // runway - this doesn't detect gray/grey state. + // think we just need to be checking self av since it's the only + // one with lltexlayer stuff. S32 grey_avatars = 0; if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) { @@ -8503,7 +8636,9 @@ void LLVOAvatar::idleUpdateRenderCost() } } - setDebugText(llformat("%d", cost)); + + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + setDebugText(llformat("%s %d", viz_string.c_str(), cost)); mVisualComplexity = cost; F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index d106086c88..fab15c200d 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -48,6 +48,7 @@ #include "lltexglobalcolor.h" #include "lldriverparam.h" #include "material_codes.h" // LL_MCODE_END +#include "llviewerstats.h" extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -277,14 +278,27 @@ public: public: BOOL isFullyLoaded() const; bool isTooComplex() const; - bool visualParamWeightsAreDefault(); + bool visualParamWeightsAreDefault(); + virtual BOOL getIsCloud() const; + BOOL isFullyTextured() const; + BOOL hasGray() const; + S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured. + void updateRezzedStatusTimers(); + + S32 mLastRezzedStatus; + + LLViewerStats::PhaseMap& getPhases() + { + return mPhases; + } + protected: - virtual BOOL getIsCloud(); BOOL updateIsFullyLoaded(); BOOL processFullyLoadedChange(bool loading); void updateRuthTimer(bool loading); F32 calcMorphAmount(); private: + BOOL mFirstFullyVisible; BOOL mFullyLoaded; BOOL mPreviousFullyLoaded; BOOL mFullyLoadedInitialized; @@ -292,6 +306,28 @@ private: S32 mVisualComplexity; LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; + +public: + class ScopedPhaseSetter + { + public: + ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name): + mAvatar(avatarp), mPhaseName(phase_name) + { + if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); } + } + ~ScopedPhaseSetter() + { + if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); } + } + private: + std::string mPhaseName; + LLVOAvatar* mAvatar; + }; + +private: + LLViewerStats::PhaseMap mPhases; + protected: LLFrameTimer mInvisibleTimer; @@ -522,9 +558,10 @@ public: virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const; -protected: BOOL isFullyBaked(); static BOOL areAllNearbyInstancesBaked(S32& grey_avatars); + static void getNearbyRezzedStats(std::vector<S32>& counts); + static std::string rezStatusToString(S32 status); //-------------------------------------------------------------------- // Baked textures @@ -886,6 +923,7 @@ private: public: std::string getFullname() const; // Returns "FirstName LastName" + std::string avString() const; // Frequently used string in log messages "Avatar '<full name'" protected: static void getAnimLabels(LLDynamicArray<std::string>* labels); static void getAnimNames(LLDynamicArray<std::string>* names); @@ -987,7 +1025,9 @@ private: // Avatar Rez Metrics //-------------------------------------------------------------------- public: + void debugAvatarRezTime(std::string notification_name, std::string comment = ""); F32 debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); } + protected: LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez LLFrameTimer mDebugExistenceTimer; // Debugging for how long the avatar has been in memory. diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index c99e94e60c..98f7245f8d 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -58,6 +58,8 @@ #include "llappearancemgr.h" #include "llmeshrepository.h" #include "llvovolume.h" +#include "llsdutil.h" +#include "llstartup.h" #if LL_MSVC // disable boost::lexical_cast warning @@ -75,6 +77,39 @@ BOOL isAgentAvatarValid() (!gAgentAvatarp->isDead())); } +void selfStartPhase(const std::string& phase_name) +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().startPhase(phase_name); + } +} + +void selfStopPhase(const std::string& phase_name) +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().stopPhase(phase_name); + } +} + +void selfClearPhases() +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().clearPhases(); + gAgentAvatarp->mLastRezzedStatus = -1; + } +} + +void selfStopAllPhases() +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->getPhases().stopAllPhases(); + } +} + using namespace LLVOAvatarDefines; /********************************************************************************* @@ -131,7 +166,8 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, LLVOAvatar(id, pcode, regionp), mScreenp(NULL), mLastRegionHandle(0), - mRegionCrossingCount(0) + mRegionCrossingCount(0), + mInitialBakesLoaded(false) { gAgentWearables.setAvatarObject(this); @@ -164,6 +200,7 @@ void LLVOAvatarSelf::initInstance() { mDebugBakedTextureTimes[i][0] = -1.0f; mDebugBakedTextureTimes[i][1] = -1.0f; + mInitialBakeIDs[i] = LLUUID::null; } status &= buildMenus(); @@ -762,6 +799,41 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) } } +//virtual +U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp) +{ + U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp); + + if (mInitialBakesLoaded == false && retval == 0x0) + { + // call update textures to force the images to be created + updateMeshTextures(); + + // unpack the texture UUIDs to the texture slots + retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); + + // need to trigger a few operations to get the avatar to use the new bakes + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex; + LLUUID texture_id = getTEImage(te)->getID(); + setNewBakedTexture(te, texture_id); + mInitialBakeIDs[i] = texture_id; + } + + onFirstTEMessageReceived(); + + mInitialBakesLoaded = true; + } + + return retval; +} + + void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index) { if (te >= TEX_NUM_INDICES) @@ -1889,7 +1961,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl; } -BOOL LLVOAvatarSelf::getIsCloud() +BOOL LLVOAvatarSelf::getIsCloud() const { // do we have our body parts? if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 || @@ -2055,6 +2127,80 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const return text; } +// Dump avatar metrics data. +LLSD LLVOAvatarSelf::metricsData() +{ + // runway - add region info + LLSD result; + result["id"] = getID(); + result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); + result["is_self"] = isSelf(); + std::vector<S32> rez_counts; + LLVOAvatar::getNearbyRezzedStats(rez_counts); + result["nearby"] = LLSD::emptyMap(); + for (S32 i=0; i<rez_counts.size(); ++i) + { + std::string rez_status_name = LLVOAvatar::rezStatusToString(i); + result["nearby"][rez_status_name] = rez_counts[i]; + } + result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32(); + result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32(); + result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); + result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32(); + result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); + result["phases"] = getPhases().dumpPhases(); + result["startup"] = LLStartUp::getPhases().dumpPhases(); + + return result; +} + +class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder +{ +public: + ViewerAppearanceChangeMetricsResponder() + { + } + + virtual void completed(U32 status, + const std::string& reason, + const LLSD& content) + { + if (isGoodStatus(status)) + { + LL_DEBUGS("Avatar") << "OK" << LL_ENDL; + result(content); + } + else + { + LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL; + error(status,reason); + } + } +}; + +void LLVOAvatarSelf::sendAppearanceChangeMetrics() +{ + // gAgentAvatarp->stopAllPhases(); + + LLSD msg = metricsData(); + msg["message"] = "ViewerAppearanceChangeMetrics"; + + LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL; + std::string caps_url; + if (getRegion()) + { + // runway - change here to activate. + caps_url = getRegion()->getCapability("ViewerMetrics"); + } + if (!caps_url.empty()) + { + LLCurlRequest::headers_t headers; + LLHTTPClient::post(caps_url, + msg, + new ViewerAppearanceChangeMetricsResponder); + } +} + const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const { if (canGrabBakedTexture(baked_index)) @@ -2253,11 +2399,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) if (isAllLocalTextureDataFinal()) { LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedDoneNotification" + << llendl; } else { args["STATUS"] = debugDumpAllLocalTextureDataInfo(); LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedUpdateNotification" + << llendl; } } @@ -2265,7 +2425,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) } } -// FIXME: This is never called. Something may be broken. +// FIXME: This is not called consistently. Something may be broken. void LLVOAvatarSelf::outputRezDiagnostics() const { if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) @@ -2274,11 +2434,11 @@ void LLVOAvatarSelf::outputRezDiagnostics() const } const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); - llinfos << "REZTIME: Myself rez stats:" << llendl; - llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; - llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; - llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; - llinfos << "\t Load time for each texture: " << llendl; + LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; + LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl; for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) { std::stringstream out; @@ -2302,12 +2462,14 @@ void LLVOAvatarSelf::outputRezDiagnostics() const // Don't print out non-existent textures. if (j != 0) - llinfos << out.str() << llendl; + { + LL_DEBUGS("Avatar") << out.str() << LL_ENDL; + } } - llinfos << "\t Time points for each upload (start / finish)" << llendl; + LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl; for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i) { - llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; + LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; } for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); @@ -2319,15 +2481,16 @@ void LLVOAvatarSelf::outputRezDiagnostics() const if (!layerset) continue; const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); if (!layerset_buffer) continue; - llinfos << layerset_buffer->dumpTextureInfo() << llendl; + LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl; } } void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const { - LL_DEBUGS("Avatar Rez") + LL_INFOS("Avatar") + << avString() << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) - << llendl; + << LL_ENDL; } void LLVOAvatarSelf::reportAvatarRezTime() const @@ -2351,6 +2514,18 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid { if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet) { + if (mInitialBakeIDs[i] != LLUUID::null) + { + if (mInitialBakeIDs[i] == uuid) + { + llinfos << "baked texture correctly loaded at login! " << i << llendl; + } + else + { + llwarns << "baked texture does not match id loaded at login!" << i << llendl; + } + mInitialBakeIDs[i] = LLUUID::null; + } mBakedTextureDatas[i].mTexLayerSet->cancelUpload(); } } @@ -2478,6 +2653,20 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const return NULL; } +LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const +{ + /* switch(index) + case TEX_HEAD_BAKED: + case TEX_HEAD_BODYPAINT: + return mHeadLayerSet; */ + if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES) + { + return mBakedTextureDatas[baked_index].mTexLayerSet; + } + return NULL; +} + + // static void LLVOAvatarSelf::onCustomizeStart() { @@ -2558,49 +2747,6 @@ BOOL LLVOAvatarSelf::needsRenderBeam() // static void LLVOAvatarSelf::deleteScratchTextures() { - if(gAuditTexture) - { - S32 total_tex_size = sScratchTexBytes ; - S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; - - if( sScratchTexNames.checkData( GL_LUMINANCE ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( sScratchTexNames.checkData( GL_ALPHA ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( sScratchTexNames.checkData( GL_COLOR_INDEX ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( sScratchTexNames.checkData( LLRender::sGLCoreProfile ? GL_RG : GL_LUMINANCE_ALPHA ) ) - { - LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 2 * tex_size ; - } - if( sScratchTexNames.checkData( GL_RGB ) ) - { - LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 3 * tex_size ; - } - if( sScratchTexNames.checkData( GL_RGBA ) ) - { - LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 4 * tex_size ; - } - //others - while(total_tex_size > 0) - { - LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 4 * tex_size ; - } - } - for( LLGLuint* namep = sScratchTexNames.getFirstData(); namep; namep = sScratchTexNames.getNextData() ) diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 655fb3a012..543891ca63 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -93,15 +93,27 @@ public: /*virtual*/ void updateVisualParams(); /*virtual*/ void idleUpdateAppearanceAnimation(); + /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys, + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp); + private: // helper function. Passed in param is assumed to be in avatar's parameter list. BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); + /** Initialization ** ** *******************************************************************************/ +private: + LLUUID mInitialBakeIDs[6]; + bool mInitialBakesLoaded; + + /******************************************************************************** ** ** ** STATE @@ -121,7 +133,7 @@ public: // Loading state //-------------------------------------------------------------------- public: - /*virtual*/ BOOL getIsCloud(); + /*virtual*/ BOOL getIsCloud() const; //-------------------------------------------------------------------- // Region state @@ -229,6 +241,7 @@ public: void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i); void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; + LLTexLayerSet* getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; //-------------------------------------------------------------------- // Composites @@ -369,6 +382,8 @@ public: const LLTexLayerSet* debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; } const std::string debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD + LLSD metricsData(); + void sendAppearanceChangeMetrics(); // send data associated with completing a change. private: LLFrameTimer mDebugSelfLoadTimer; F32 mDebugTimeWearablesLoaded; @@ -387,4 +402,9 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp; BOOL isAgentAvatarValid(); +void selfStartPhase(const std::string& phase_name); +void selfStopPhase(const std::string& phase_name); +void selfStopAllPhases(); +void selfClearPhases(); + #endif // LL_VO_AVATARSELF_H diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index df1d3f2955..820d1d73e1 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -27,8 +27,6 @@ #include "llviewerprecompiledheaders.h" #include "llvoicevivox.h" -#include <boost/tokenizer.hpp> - #include "llsdutil.h" // Linden library includes @@ -47,6 +45,7 @@ #include "llbase64.h" #include "llviewercontrol.h" #include "llappviewer.h" // for gDisconnected, gDisableVoice +#include "llprocess.h" // Viewer includes #include "llmutelist.h" // to check for muted avatars @@ -242,59 +241,21 @@ void LLVivoxVoiceClientCapResponder::result(const LLSD& content) } } - - -#if LL_WINDOWS -static HANDLE sGatewayHandle = 0; +static LLProcessPtr sGatewayPtr; static bool isGatewayRunning() { - bool result = false; - if(sGatewayHandle != 0) - { - DWORD waitresult = WaitForSingleObject(sGatewayHandle, 0); - if(waitresult != WAIT_OBJECT_0) - { - result = true; - } - } - return result; -} -static void killGateway() -{ - if(sGatewayHandle != 0) - { - TerminateProcess(sGatewayHandle,0); - } -} - -#else // Mac and linux - -static pid_t sGatewayPID = 0; -static bool isGatewayRunning() -{ - bool result = false; - if(sGatewayPID != 0) - { - // A kill with signal number 0 has no effect, just does error checking. It should return an error if the process no longer exists. - if(kill(sGatewayPID, 0) == 0) - { - result = true; - } - } - return result; + return sGatewayPtr && sGatewayPtr->isRunning(); } static void killGateway() { - if(sGatewayPID != 0) + if (sGatewayPtr) { - kill(sGatewayPID, SIGTERM); + sGatewayPtr->kill(); } } -#endif - /////////////////////////////////////////////////////////////////////////////////////////////// LLVivoxVoiceClient::LLVivoxVoiceClient() : @@ -790,7 +751,7 @@ void LLVivoxVoiceClient::stateMachine() } else if(!isGatewayRunning()) { - if(true) + if (true) // production build, not test { // Launch the voice daemon @@ -809,102 +770,33 @@ void LLVivoxVoiceClient::stateMachine() #endif // See if the vivox executable exists llstat s; - if(!LLFile::stat(exe_path, &s)) + if (!LLFile::stat(exe_path, &s)) { // vivox executable exists. Build the command line and launch the daemon. + LLProcess::Params params; + params.executable = exe_path; // SLIM SDK: these arguments are no longer necessary. // std::string args = " -p tcp -h -c"; - std::string args; - std::string cmd; std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); - if(loglevel.empty()) { loglevel = "-1"; // turn logging off completely } - - args += " -ll "; - args += loglevel; - - LL_DEBUGS("Voice") << "Args for SLVoice: " << args << LL_ENDL; - -#if LL_WINDOWS - PROCESS_INFORMATION pinfo; - STARTUPINFOA sinfo; - - memset(&sinfo, 0, sizeof(sinfo)); - - std::string exe_dir = gDirUtilp->getAppRODataDir(); - cmd = "SLVoice.exe"; - cmd += args; - - // So retarded. Windows requires that the second parameter to CreateProcessA be writable (non-const) string... - char *args2 = new char[args.size() + 1]; - strcpy(args2, args.c_str()); - if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo)) - { -// DWORD dwErr = GetLastError(); - } - else - { - // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on - // CloseHandle(pinfo.hProcess); // stops leaks - nothing else - sGatewayHandle = pinfo.hProcess; - CloseHandle(pinfo.hThread); // stops leaks - nothing else - } - - delete[] args2; -#else // LL_WINDOWS - // This should be the same for mac and linux - { - std::vector<std::string> arglist; - arglist.push_back(exe_path); - - // Split the argument string into separate strings for each argument - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep(" "); - tokenizer tokens(args, sep); - tokenizer::iterator token_iter; - for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) - { - arglist.push_back(*token_iter); - } - - // create an argv vector for the child process - char **fakeargv = new char*[arglist.size() + 1]; - int i; - for(i=0; i < arglist.size(); i++) - fakeargv[i] = const_cast<char*>(arglist[i].c_str()); + params.args.add("-ll"); + params.args.add(loglevel); + params.cwd = gDirUtilp->getAppRODataDir(); + sGatewayPtr = LLProcess::create(params); - fakeargv[i] = NULL; - - fflush(NULL); // flush all buffers before the child inherits them - pid_t id = vfork(); - if(id == 0) - { - // child - execv(exe_path.c_str(), fakeargv); - - // If we reach this point, the exec failed. - // Use _exit() instead of exit() per the vfork man page. - _exit(0); - } - - // parent - delete[] fakeargv; - sGatewayPID = id; - } -#endif // LL_WINDOWS mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort")); - } + } else { LL_INFOS("Voice") << exe_path << " not found." << LL_ENDL; - } + } } else - { + { // SLIM SDK: port changed from 44124 to 44125. // We can connect to a client gateway running on another host. This is useful for testing. // To do this, launch the gateway on a nearby host like this: diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c195f0ea14..cfa47b3ba3 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -873,9 +873,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (shadow_detail > 0) { //allocate 4 sun shadow maps + U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur for (U32 i = 0; i < 4; i++) { - if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false; + if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false; } } else @@ -891,9 +892,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (shadow_detail > 1) { //allocate two spot shadow maps + U32 spot_shadow_map_width = width; for (U32 i = 4; i < 6; i++) { - if (!mShadow[i].allocate(width, height, 0, TRUE, FALSE)) return false; + if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false; } } else @@ -8442,7 +8444,7 @@ static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows"); static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow"); static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow"); -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion) +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width) { LLFastTimer t(FTM_SHADOW_RENDER); @@ -8530,7 +8532,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLFastTimer ftm(FTM_SHADOW_ALPHA); gDeferredShadowAlphaMaskProgram.bind(); gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); - + gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | @@ -9387,11 +9390,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[j].getViewport(gGLViewport); mShadow[j].clear(); + U32 target_width = mShadow[j].getWidth(); + { static LLCullResult result[4]; //LLGLEnable enable(GL_DEPTH_CLAMP_NV); - renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE); + renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width); } mShadow[j].flush(); @@ -9530,11 +9535,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[i+4].getViewport(gGLViewport); mShadow[i+4].clear(); + U32 target_width = mShadow[i+4].getWidth(); + static LLCullResult result[2]; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); mShadow[i+4].flush(); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index ed707551ec..efc94315d7 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -265,7 +265,7 @@ public: void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } - void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader = TRUE, BOOL use_occlusion = TRUE); + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader, BOOL use_occlusion, U32 target_width); void renderHighlights(); void renderDebug(); void renderPhysicsDisplay(); @@ -465,6 +465,7 @@ public: RENDER_DEBUG_LOD_INFO = 0x04000000, RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000, RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000, + RENDER_DEBUG_TEXEL_DENSITY = 0x20000000 }; public: diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index 2fd932786b..9400f7b94f 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -149,13 +149,52 @@ show_per_sec="true" show_bar="false"> </stat_bar> + <stat_bar + name="object_cache_hits" + label="Object Cache Hit Rate" + stat="object_cache_hits" + bar_min="0" + 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> <!--Texture Stats--> <stat_view name="texture" label="Texture" show_label="true"> - <stat_bar + <stat_bar + name="texture_cache_hits" + label="Cache Hit Rate" + stat="texture_cache_hits" + bar_min="0.f" + 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 + name="texture_cache_read_latency" + label="Cache Read Latency" + unit_label="msec" + stat="texture_cache_read_latency" + 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 name="numimagesstat" label="Count" stat="numimagesstat" diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..44b6a63bca --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -0,0 +1,341 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ height="550"
+ layout="topleft"
+ name="TexFetchDebugger"
+ help_topic="texfetchdebugger"
+ title="Texture Fetching Debugger"
+ width="540">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left="10"
+ name="total_num_fetched_label"
+ top="30"
+ width="400">
+ 1, Total number of fetched textures: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_fetching_requests_label"
+ top_delta="25"
+ width="400">
+ 2, Total number of fetching requests: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_cache_hits_label"
+ top_delta="25"
+ width="400">
+ 3, Total number of cache hits: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_visible_tex_label"
+ top_delta="25"
+ width="400">
+ 4, Total number of visible textures: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_visible_tex_fetch_req_label"
+ top_delta="25"
+ width="450">
+ 5, Total number of visible texture fetching requests: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_fetched_data_label"
+ top_delta="25"
+ width="530">
+ 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_fetched_vis_data_label"
+ top_delta="25"
+ width="480">
+ 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_fetched_rendered_data_label"
+ top_delta="25"
+ width="530">
+ 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_cache_read_label"
+ top_delta="25"
+ width="400">
+ 9, Total time on cache readings: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_cache_write_label"
+ top_delta="25"
+ width="400">
+ 10, Total time on cache writings: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_decode_label"
+ top_delta="25"
+ width="400">
+ 11, Total time on decodings: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_gl_label"
+ top_delta="25"
+ width="400">
+ 12, Total time on gl texture creation: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_http_label"
+ top_delta="25"
+ width="400">
+ 13, Total time on HTTP fetching: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_fetch_label"
+ top_delta="25"
+ width="400">
+ 14, Total time on entire fetching: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_refetch_vis_cache_label"
+ top_delta="25"
+ width="540">
+ 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_refetch_vis_http_label"
+ top_delta="25"
+ width="540">
+ 16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="20"
+ increment="0.01"
+ initial_value="1.0"
+ label="17, Ratio of Texel/Pixel:"
+ label_width="130"
+ layout="topleft"
+ left_delta="0"
+ max_val="10.0"
+ min_val="0.01"
+ name="texel_pixel_ratio"
+ top_delta="30"
+ width="200">
+ <spinner.commit_callback
+ function="TexFetchDebugger.ChangeTexelPixelRatio" />
+ </spinner>
+ <button
+ follows="left|top"
+ height="20"
+ label="Start"
+ layout="topleft"
+ left_delta="0"
+ name="start_btn"
+ top_delta="30"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Start" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Reset"
+ layout="topleft"
+ left_pad="7"
+ name="clear_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Clear" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Close"
+ layout="topleft"
+ left_pad="7"
+ name="close_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Close" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Cache Read"
+ layout="topleft"
+ left="10"
+ name="cacheread_btn"
+ top_delta="30"
+ width="80">
+ <button.commit_callback
+ function="TexFetchDebugger.CacheRead" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Cache Write"
+ layout="topleft"
+ left_pad="7"
+ name="cachewrite_btn"
+ top_delta="0"
+ width="80">
+ <button.commit_callback
+ function="TexFetchDebugger.CacheWrite" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="HTTP"
+ layout="topleft"
+ left_pad="7"
+ name="http_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.HTTPLoad" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Decode"
+ layout="topleft"
+ left_pad="7"
+ name="decode_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Decode" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="GL Texture"
+ layout="topleft"
+ left_pad="7"
+ name="gl_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.GLTexture" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refetch Vis Cache"
+ layout="topleft"
+ left="10"
+ name="refetchviscache_btn"
+ top_delta="30"
+ width="120">
+ <button.commit_callback
+ function="TexFetchDebugger.RefetchVisCache" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refetch Vis HTTP"
+ layout="topleft"
+ left_pad="7"
+ name="refetchvishttp_btn"
+ top_delta="0"
+ width="120">
+ <button.commit_callback
+ function="TexFetchDebugger.RefetchVisHTTP" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 5ba566b175..a6898c554f 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1876,7 +1876,7 @@ <menu_item_check.on_click function="Advanced.ToggleConsole" parameter="texture" /> - </menu_item_check> + </menu_item_check> <menu_item_check label="Debug Console" name="Debug Console" @@ -1898,28 +1898,6 @@ parameter="notifications_console" /> </menu_item_call> <menu_item_check - label="Texture Size Console" - name="Texture Size" - shortcut="control|shift|6"> - <menu_item_check.on_check - function="Advanced.CheckConsole" - parameter="texture size" /> - <menu_item_check.on_click - function="Advanced.ToggleConsole" - parameter="texture size" /> - </menu_item_check> - <menu_item_check - label="Texture Category Console" - name="Texture Category" - shortcut="control|shift|7"> - <menu_item_check.on_check - function="Advanced.CheckConsole" - parameter="texture category" /> - <menu_item_check.on_click - function="Advanced.ToggleConsole" - parameter="texture category" /> - </menu_item_check> - <menu_item_check label="Fast Timers" name="Fast Timers" shortcut="control|shift|9" @@ -1953,7 +1931,20 @@ function="Advanced.ToggleConsole" parameter="scene view" /> </menu_item_check> - + <menu_item_call + enabled="false" + visible="false" + label="Texture Fetch Debug Console" + name="Texture Fetch Debug Console"> + <menu_item_call.on_click + function="Floater.Show" + parameter="tex_fetch_debugger" /> + <on_enable + function="Develop.SetTexFetchDebugger" /> + <on_visible + function="Develop.SetTexFetchDebugger" /> + </menu_item_call> + <menu_item_separator/> <menu_item_call @@ -2439,6 +2430,52 @@ function="Advanced.ToggleInfoDisplay" parameter="sculpt" /> </menu_item_check> + <menu + create_jump_keys="true" + label="Texture Density" + name="Texture Density" + tear_off="true"> + <menu_item_check + label="None" + name="None"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="none" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="none" /> + </menu_item_check> + <menu_item_check + label="Current" + name="Current"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="current" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="current" /> + </menu_item_check> + <menu_item_check + label="Desired" + name="Desired"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="desired" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="desired" /> + </menu_item_check> + <menu_item_check + label="Full" + name="Full"> + <menu_item_check.on_check + function="Advanced.CheckDisplayTextureDensity" + parameter="full" /> + <menu_item_check.on_click + function="Advanced.SetDisplayTextureDensity" + parameter="full" /> + </menu_item_check> + </menu> </menu> <menu create_jump_keys="true" @@ -2606,16 +2643,6 @@ parameter="TextureLoadFullRes" /> </menu_item_check> <menu_item_check - label="Audit Textures" - name="Audit Textures"> - <menu_item_check.on_check - function="CheckControl" - parameter="AuditTexture" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="AuditTexture" /> - </menu_item_check> - <menu_item_check label="Texture Atlas (experimental)" name="Texture Atlas"> <menu_item_check.on_check diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d956a7225d..e806a40951 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6392,31 +6392,28 @@ Is this OK? <notification icon="notify.tga" name="ScriptQuestionCaution" - priority="high" + priority="critical" persist="true" type="notify"> -An object named '<nolink>[OBJECTNAME]</nolink>', owned by '[NAME]' would like to: - -[QUESTIONS] -If you do not trust this object and its creator, you should deny the request. +Warning: The object '<nolink>[OBJECTNAME]</nolink>' wants total access to your Linden Dollars account. If you allow access, it can remove funds from your account at any time, or empty your account completely, on an ongoing basis with no additional warnings. + +It is rare that such a request is legitimate. Do not allow access if you do not fully understand why it wants access to your account. -Grant this request? <tag>confirm</tag> <form name="form"> <button index="0" name="Grant" - text="Grant"/> + text="Allow total access"/> <button default="true" index="1" name="Deny" text="Deny"/> - <button - index="2" - name="Details" - text="Details..."/> </form> + <footer> +[FOOTERTEXT] + </footer> </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_script_question_toast.xml b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml new file mode 100644 index 0000000000..b0436bb6dc --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel + background_opaque="false" + border_visible="false" + background_visible="true" + bg_alpha_color="PanelNotificationBackground" + bg_opaque_color="PanelNotificationBackground" + chrome="true" + height="270" + label="script_question_panel" + layout="topleft" + left="0" + name="panel_script_question_toast" + top="0" + width="305"> + <text + follows="left|right|top" + font="SansSerifBold" + height="160" + layout="topleft" + left="10" + mouse_opaque="false" + name="top_info_message" + parse_highlights="true" + parse_urls="true" + text_color="NotifyCautionBoxColor" + top="10" + value="" + width="285" + wrap="true"/> + <panel + background_visible="false" + follows="left|right|top" + height="30" + label="buttons_panel" + layout="topleft" + name="buttons_panel" + top_pad="10" + width="285"> + </panel> + <text + follows="all" + font="SansSerifBold" + height="55" + layout="topleft" + mouse_opaque="false" + name="bottom_info_message" + parse_highlights="true" + parse_urls="true" + text_color="NotifyCautionBoxColor" + top_pad="5" + value="" + width="285" + wrap="true"/> +</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 4ccec4838a..866ea296c3 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -393,6 +393,7 @@ Please try logging in again in a minute.</string> <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string> <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string> <string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string> + <string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string> <string name="ScriptTakeMoney">Take Linden dollars (L$) from you</string> <string name="ActOnControlInputs">Act on your control inputs</string> <string name="RemapControlInputs">Remap your control inputs</string> diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml index 6f8885487a..49af1a87e1 100644 --- a/indra/newview/skins/default/xui/fr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml @@ -439,7 +439,7 @@ musique : <text name="Sound:"> Son : </text> - <check_box label="Limiter les gestes et sons d'objet à cette parcelle" name="check sound local"/> + <check_box label="Limiter les sons des gestes et des objets à cette parcelle" name="check sound local"/> <text name="Avatar Sounds:"> Sons d'avatar : </text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 3eebed450f..8b410128da 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -4509,7 +4509,7 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles Backsp </string> <string name="Shift"> - Shift + Maj </string> <string name="Ctrl"> Ctrl diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 54031ccf12..7bf8a7b8be 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -2895,6 +2895,18 @@ M キーを押して変更します。 [RESIDENTS] <usetemplate name="okcancelbuttons" notext="取り消し" yestext="Ok"/> </notification> + <notification name="ShareFolderConfirmation"> + フォルダは一度に 1 つしか共有できません。 + +次のアイテムを共有しますか? + +<nolink>[ITEMS]</nolink> + +次の住人と共有: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="取り消し" yestext="Ok"/> + </notification> <notification name="ItemsShared"> アイテムが共有されました。 </notification> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index d7d5d59a33..fd973bf3c2 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -118,7 +118,7 @@ <menu_item_call label="Devolver objeto" name="Return Object back to Owner"/> </menu> <menu label="Scripts" name="Scripts"> - <menu_item_call label="Recompilar scripts (LSL)" name="Mono"/> + <menu_item_call label="Recompilar scripts (Mono)" name="Mono"/> <menu_item_call label="Recompilar scripts (LSL)" name="LSL"/> <menu_item_call label="Resetar scripts" name="Reset Scripts"/> <menu_item_call label="Scripts em modo execução" name="Set Scripts to Running"/> @@ -163,7 +163,7 @@ <menu_item_check label="Limitar distância da seleção" name="Limit Select Distance"/> <menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/> <menu_item_check label="Foto de alta resolução" name="HighResSnapshot"/> - <menu_item_check label="Compactar fotos para HD" name="QuietSnapshotsToDisk"/> + <menu_item_check label="Fotos sem barulho para HD" name="QuietSnapshotsToDisk"/> <menu label="Ferramentas de desempenho" name="Performance Tools"> <menu_item_call label="Medidor de lag" name="Lag Meter"/> <menu_item_check label="Barra de estatísticas" name="Statistics Bar"/> diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp index 2ad08dc1f3..e1cbd28f92 100644 --- a/indra/newview/tests/llcapabilitylistener_test.cpp +++ b/indra/newview/tests/llcapabilitylistener_test.cpp @@ -156,7 +156,7 @@ namespace tut regionPump.post(request); ensure("got response", netio.pump()); ensure("success response", success); - ensure_equals(result.asString(), "success"); + ensure_equals(result["reply"].asString(), "success"); body["status"] = 499; body["reason"] = "custom error message"; diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index 3faddc13c1..f8923b9868 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -35,6 +35,31 @@ #include "lluuid.h" #include "llsdutil.h" #include "llregionhandle.h" +#include "../llvoavatar.h" + +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[] = { @@ -104,18 +129,25 @@ is_single_key_map(const LLSD & sd, const std::string & key) { return sd.isMap() && 1 == sd.size() && sd.has(key); } -#endif static bool is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2) { return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2); } +#endif + +static bool +is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3) +{ + return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3); +} + static bool is_no_stats_map(const LLSD & sd) { - return is_double_key_map(sd, "duration", "regions"); + return is_triple_key_map(sd, "duration", "regions", "avatar"); } static bool @@ -226,7 +258,7 @@ namespace tut // Once the region is set, we will get a response even with no data collection it->setRegion(region1_handle); sd_full = it->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle)); LLSD sd = sd_full["regions"][0]; @@ -267,7 +299,7 @@ namespace tut it->setRegion(region1_handle); LLSD sd = it->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[0]; @@ -292,7 +324,7 @@ namespace tut LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); 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]; @@ -332,7 +364,7 @@ namespace tut 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")); + 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]; @@ -382,7 +414,7 @@ namespace tut // std::cout << sd << std::endl; - ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); LLSD sd1 = get_region(sd, region1_handle); LLSD sd2 = get_region(sd, region2_handle); @@ -405,7 +437,7 @@ namespace tut // Reset leaves current region in place gViewerAssetStatsMain->reset(); 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 (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = sd["regions"][0]; @@ -454,7 +486,7 @@ namespace tut LLSD sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); LLSD sd1 = get_region(sd, region1_handle); LLSD sd2 = get_region(sd, region2_handle); @@ -477,7 +509,7 @@ namespace tut // Reset leaves current region in place gViewerAssetStatsMain->reset(); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = get_region(sd, region2_handle); ensure("Region2 is present in results", sd2.isMap()); @@ -523,7 +555,7 @@ namespace tut 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")); + ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = get_region(sd, region1_handle); ensure("Region1 is present in results", sd.isMap()); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 9bf755c8f8..36267803e3 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1025,45 +1025,47 @@ class Linux_i686Manifest(LinuxManifest): super(Linux_i686Manifest, self).construct() if self.prefix("../packages/lib/release", dst="lib"): - self.path("libapr-1.so") - self.path("libapr-1.so.0") - self.path("libapr-1.so.0.4.2") - self.path("libaprutil-1.so") - self.path("libaprutil-1.so.0") - self.path("libaprutil-1.so.0.3.10") - self.path("libbreakpad_client.so.0.0.0") - self.path("libbreakpad_client.so.0") - self.path("libbreakpad_client.so") + self.path("libapr-1.so*") + self.path("libaprutil-1.so*") + self.path("libbreakpad_client.so*") self.path("libcollada14dom.so") - self.path("libdb-5.1.so") - self.path("libdb-5.so") - self.path("libdb.so") - self.path("libcrypto.so.1.0.0") - self.path("libexpat.so.1.5.2") + self.path("libdb*.so") + self.path("libcrypto.so.*") + self.path("libexpat.so.*") self.path("libssl.so.1.0.0") self.path("libglod.so") self.path("libminizip.so") - self.path("libuuid.so") - self.path("libuuid.so.16") - self.path("libuuid.so.16.0.22") - self.path("libSDL-1.2.so.0.11.3") - self.path("libSDL-1.2.so.0") - self.path("libdirectfb-1.4.so.5.0.4") + self.path("libuuid.so*") + self.path("libSDL-1.2.so.*") + self.path("libdirectfb-1.*.so.*") + self.path("libfusion-1.*.so.*") + self.path("libdirect-1.*.so.*") + self.path("libopenjpeg.so*") self.path("libdirectfb-1.4.so.5") - self.path("libfusion-1.4.so.5.0.4") self.path("libfusion-1.4.so.5") - self.path("libdirect-1.4.so.5.0.4") self.path("libdirect-1.4.so.5") - self.path("libopenjpeg.so.1.4.0") - self.path("libopenjpeg.so.1") - self.path("libopenjpeg.so") self.path("libalut.so") self.path("libopenal.so", "libopenal.so.1") self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname - self.path("libfontconfig.so.1.4.4") - self.path("libtcmalloc.so", "libtcmalloc.so") #formerly called google perf tools - self.path("libtcmalloc.so.0", "libtcmalloc.so.0") #formerly called google perf tools - self.path("libtcmalloc.so.0.1.0", "libtcmalloc.so.0.1.0") #formerly called google perf tools + # KLUDGE: As of 2012-04-11, the 'fontconfig' package installs + # libfontconfig.so.1.4.4, along with symlinks libfontconfig.so.1 + # and libfontconfig.so. Before we added support for library-file + # wildcards, though, this self.path() call specifically named + # libfontconfig.so.1.4.4 WITHOUT also copying the symlinks. When I + # (nat) changed the call to self.path("libfontconfig.so.*"), we + # ended up with the libfontconfig.so.1 symlink in the target + # directory as well. But guess what! At least on Ubuntu 10.04, + # certain viewer fonts look terrible with libfontconfig.so.1 + # present in the target directory. Removing that symlink suffices + # to improve them. I suspect that means we actually do better when + # the viewer fails to find our packaged libfontconfig.so*, falling + # back on the system one instead -- but diagnosing and fixing that + # is a bit out of scope for the present project. Meanwhile, this + # particular wildcard specification gets us exactly what the + # previous call did, without having to explicitly state the + # version number. + self.path("libfontconfig.so.*.*") + self.path("libtcmalloc.so*") #formerly called google perf tools try: self.path("libfmod-3.75.so") pass |