diff options
Diffstat (limited to 'indra/newview')
98 files changed, 2471 insertions, 1043 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 6e0bb161af..42d010c6f5 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -123,6 +123,7 @@ set(viewer_SOURCE_FILES llavatariconctrl.cpp llavatarlist.cpp llavatarlistitem.cpp + llavatarrenderinfoaccountant.cpp llavatarpropertiesprocessor.cpp llblockedlistitem.cpp llblocklist.cpp @@ -705,6 +706,7 @@ set(viewer_HEADER_FILES llavatarlist.h llavatarlistitem.h llavatarpropertiesprocessor.h + llavatarrenderinfoaccountant.h llblockedlistitem.h llblocklist.h llbox.h diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index a87310955f..02adbc7af4 100755 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -132,6 +132,7 @@ PSYS_PART_FOLLOW_VELOCITY_MASK PSYS_PART_TARGET_POS_MASK PSYS_PART_EMISSIVE_MASK PSYS_PART_TARGET_LINEAR_MASK +PSYS_PART_RIBBON_MASK PSYS_SRC_PATTERN PSYS_SRC_INNERANGLE Deprecated -- Use PSYS_SRC_ANGLE_BEGIN @@ -148,12 +149,24 @@ PSYS_SRC_ACCEL PSYS_SRC_TEXTURE PSYS_SRC_TARGET_KEY PSYS_SRC_OMEGA +PSYS_PART_BLEND_FUNC_SOURCE +PSYS_PART_BLEND_FUNC_DEST +PSYS_PART_START_GLOW +PSYS_PART_END_GLOW PSYS_SRC_PATTERN_DROP PSYS_SRC_PATTERN_EXPLODE PSYS_SRC_PATTERN_ANGLE PSYS_SRC_PATTERN_ANGLE_CONE PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY +PSYS_PART_BF_ONE +PSYS_PART_BF_ZERO +PSYS_PART_BF_DEST_COLOR +PSYS_PART_BF_SOURCE_COLOR +PSYS_PART_BF_ONE_MINUS_DEST_COLOR +PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR +PSYS_PART_BF_SOURCE_ALPHA +PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA OBJECT_UNKNOWN_DETAIL Returned by llGetObjectDetails when passed an invalid object parameter type OBJECT_NAME Used with llGetObjectDetails to get an object's name diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f8638a479d..676ba57726 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2147,6 +2147,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugShowAvatarRenderInfo</key> + <map> + <key>Comment</key> + <string>Show avatar render cost information</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DebugShowColor</key> <map> <key>Comment</key> @@ -9477,10 +9488,21 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderAutoMuteRenderCostLimit</key> + <map> + <key>Comment</key> + <string>Maximum render weight before an avatar is automatically visually muted (0 to not use this limit).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderAutoMuteSurfaceAreaLimit</key> <map> <key>Comment</key> - <string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string> + <string>Maximum surface area of attachments before an avatar is automatically visually muted (0 to not use this limit).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -9488,6 +9510,39 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderAutoMuteEnabled</key> + <map> + <key>Comment</key> + <string>Apply visual muting to high cost, non-friends, not in IM, or somewhat distant avatars</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderAutoMuteLogging</key> + <map> + <key>Comment</key> + <string>Show extra information in viewer logs about avatar rendering costs</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderAutoMuteVisibilityRank</key> + <map> + <key>Comment</key> + <string>Number of avatars to show normally for visual muting mode.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderAutoHideSurfaceAreaLimit</key> <map> @@ -14514,5 +14569,18 @@ <key>Value</key> <integer>7000</integer> </map> + + <key>VersionChannelName</key> + <map> + <key>Comment</key> + <string>Version information generated by running the viewer</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> + </map> </map> </llsd> + diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index bfd9b9b3eb..29a6d842d2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -31,6 +31,8 @@ out vec4 frag_data[3]; uniform sampler2D diffuseMap; +uniform float minimum_alpha; + VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; @@ -38,7 +40,7 @@ void main() { vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy); - if (diff.a < 0.2) + if (diff.a < minimum_alpha) { discard; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl deleted file mode 100755 index da1b234240..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @file giF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2D noiseMap; - -uniform sampler2D diffuseGIMap; -uniform sampler2D normalGIMap; -uniform sampler2D depthGIMap; - -uniform sampler2D lightFunc; - -// Inputs -VARYING vec2 vary_fragcoord; - -uniform vec2 screen_res; - -uniform mat4 inv_proj; -uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space -uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space -uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix -uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space -uniform float gi_radius; -uniform float gi_intensity; -uniform int gi_samples; -uniform vec2 gi_kern[25]; -uniform vec2 gi_scale; -uniform vec3 gi_quad; -uniform vec3 gi_spec; -uniform float gi_direction_weight; -uniform float gi_light_offset; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -vec4 getGIPosition(vec2 gi_tc) -{ - float depth = texture2D(depthGIMap, gi_tc).a; - vec2 sc = gi_tc*2.0; - sc -= vec2(1.0, 1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = gi_inv_proj*ndc; - pos.xyz /= pos.w; - pos.w = 1.0; - return pos; -} - -vec3 giAmbient(vec3 pos, vec3 norm) -{ - vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); - gi_c.xyz /= gi_c.w; - - vec4 gi_pos = gi_mat*vec4(pos,1.0); - vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; - gi_norm = normalize(gi_norm); - - vec2 tcx = gi_norm.xy; - vec2 tcy = gi_norm.yx; - - vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); - - vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); - - //vec3 eye_dir = vec3(0,0,-1); - //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; - //eye_dir = normalize(eye_dir); - - //float round_x = gi_scale.x; - //float round_y = gi_scale.y; - - vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; - debug.xz = vec2(0.0,0.0); - //debug = fract(debug); - - float round_x = 1.0/64.0; - float round_y = 1.0/64.0; - - //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; - //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; - - float fda = 0.0; - vec3 fdiff = vec3(0,0,0); - - vec3 rcol = vec3(0,0,0); - - float fsa = 0.0; - - for (int i = -1; i < 2; i+=2 ) - { - for (int j = -1; j < 2; j+=2) - { - vec2 tc = vec2(i, j)*0.75; - vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; - //tc += gi_norm.xy*nz.z; - tc += nz.xy*2.0; - tc /= gi_samples; - tc += gi_c.xy; - - vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); - vec3 lpos = getGIPosition(tc.xy).xyz; - - vec3 at = lpos-gi_pos.xyz; - float dist = dot(at,at); - float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); - - if (da > 0.0) - { - //add angular attenuation - vec3 ldir = at; - float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); - - float ld = -dot(ldir, lnorm); - - if (ang_atten > 0.0 && ld < 0.0) - { - vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; - da = da*ang_atten; - fda += da; - fdiff += diff*da; - } - } - } - } - - fdiff /= max(gi_spec.y*fda, gi_quad.z); - fdiff = clamp(fdiff, vec3(0), vec3(1)); - - vec3 ret = fda*fdiff; - //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; - - //fda *= nz.z; - - //rcol.rgb *= gi_intensity; - //return rcol.rgb+vary_AmblitColor.rgb*0.25; - //return vec4(debug, 0.0); - //return vec4(fda*fdiff, 0.0); - return clamp(ret,vec3(0.0), vec3(1.0)); - //return debug.xyz; -} - -void main() -{ - vec2 pos_screen = vary_fragcoord.xy; - vec4 pos = getPosition(pos_screen); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - - frag_color.xyz = giAmbient(pos, norm); -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 1ae006bc8a..7dbb28bf3a 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -53,13 +53,11 @@ uniform vec3 specular; uniform float lightExp; uniform float refScale; uniform float kd; -uniform vec2 screenRes; uniform vec3 normScale; uniform float fresnelScale; uniform float fresnelOffset; uniform float blurMultiplier; -uniform vec2 screen_res; -uniform mat4 norm_mat; //region space to screen space +uniform mat3 normal_matrix; //bigWave is (refCoord.w, view.w); VARYING vec4 refCoord; @@ -157,7 +155,7 @@ void main() //wavef.z *= 0.1f; //wavef = normalize(wavef); - vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; + vec3 screenspacewavef = normal_matrix*wavef; frag_data[0] = vec4(color.rgb, 0.5); // diffuse frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index 0d8dab0a41..485e48537c 100755 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -43,13 +43,11 @@ uniform vec2 fbScale; uniform float refScale; uniform float znear; uniform float zfar; -uniform float kd; uniform vec4 waterPlane; uniform vec3 eyeVec; uniform vec4 waterFogColor; uniform float waterFogDensity; uniform float waterFogKS; -uniform vec2 screenRes; //bigWave is (refCoord.w, view.w); VARYING vec4 refCoord; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 79bffab745..1fd7bdaa5c 100755 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -42,8 +42,6 @@ uniform vec3 lightDir; uniform vec3 specular; uniform float lightExp; uniform float refScale; -uniform float kd; -uniform vec2 screenRes; uniform vec3 normScale; uniform float fresnelScale; uniform float fresnelOffset; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8c42defa73..bd1929b0c0 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3048,6 +3048,30 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request) sendReliableMessage(); } +// Send a message to the region to stop the NULL animation state +// This will reset animation state overrides for the agent. +void LLAgent::sendAnimationStateReset() +{ + if (gAgentID.isNull() || !mRegionp) + { + return; + } + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentAnimation); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + + msg->nextBlockFast(_PREHASH_AnimationList); + msg->addUUIDFast(_PREHASH_AnimID, LLUUID::null ); + msg->addBOOLFast(_PREHASH_StartAnim, FALSE); + + msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList); + msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0); + sendReliableMessage(); +} + void LLAgent::sendWalkRun(bool running) { LLMessageSystem* msgsys = gMessageSystem; @@ -4126,6 +4150,8 @@ void LLAgent::stopCurrentAnimations() // avatar, propagating this change back to the server. if (isAgentAvatarValid()) { + LLDynamicArray<LLUUID> anim_ids; + for ( LLVOAvatar::AnimIterator anim_it = gAgentAvatarp->mPlayingAnimations.begin(); anim_it != gAgentAvatarp->mPlayingAnimations.end(); @@ -4143,10 +4169,15 @@ void LLAgent::stopCurrentAnimations() // stop this animation locally gAgentAvatarp->stopMotion(anim_it->first, TRUE); // ...and tell the server to tell everyone. - sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP); + anim_ids.push_back(anim_it->first); } } + sendAnimationRequests(anim_ids, ANIM_REQUEST_STOP); + + // Tell the region to clear any animation state overrides. + sendAnimationStateReset(); + // re-assert at least the default standing animation, because // viewers get confused by avs with no associated anims. sendAnimationRequest(ANIM_AGENT_STAND, diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index f5f26f69d8..c5b4476318 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -431,6 +431,8 @@ public: void onAnimStop(const LLUUID& id); void sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request); void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request); + void sendAnimationStateReset(); + void endAnimationUpdateUI(); void unpauseAnimation() { mPauseRequest = NULL; } BOOL getCustomAnim() const { return mCustomAnim; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 550f6bd607..7fecfae734 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -96,6 +96,7 @@ #include "llupdaterservice.h" #include "llfloatertexturefetchdebugger.h" #include "llspellcheck.h" +#include "llavatarrenderinfoaccountant.h" // Linden library includes #include "llavatarnamecache.h" @@ -569,7 +570,7 @@ static void settings_to_globals() LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); - + LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor"); @@ -4775,6 +4776,9 @@ void LLAppViewer::idle() gObjectList.updateApparentAngles(gAgent); } + // Update AV render info + LLAvatarRenderInfoAccountant::idle(); + { LLFastTimer t(FTM_AUDIO_UPDATE); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp new file mode 100644 index 0000000000..da4b6cf806 --- /dev/null +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -0,0 +1,371 @@ +/** + * @file llavatarrenderinfoaccountant.cpp + * @author Dave Simmons + * @date 2013-02-28 + * @brief + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" +// associated header +#include "llavatarrenderinfoaccountant.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llcharacter.h" +#include "llhttpclient.h" +#include "lltimer.h" +#include "llviewercontrol.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llvoavatar.h" +#include "llworld.h" + + +static const std::string KEY_AGENTS = "agents"; // map +static const std::string KEY_WEIGHT = "weight"; // integer +static const std::string KEY_GEOMETRY = "geometry"; // integer +static const std::string KEY_SURFACE = "surface"; // float + +static const std::string KEY_IDENTIFIER = "identifier"; +static const std::string KEY_MESSAGE = "message"; +static const std::string KEY_ERROR = "error"; + + +// Send data updates about once per minute, only need per-frame resolution +LLFrameTimer LLAvatarRenderInfoAccountant::sRenderInfoReportTimer; + + +// HTTP responder class for GET request for avatar render weight information +class LLAvatarRenderInfoGetResponder : public LLHTTPClient::Responder +{ +public: + LLAvatarRenderInfoGetResponder(U64 region_handle) : mRegionHandle(region_handle) + { + } + + virtual void error(U32 statusNum, const std::string& reason) + { + LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); + if (regionp) + { + llwarns << "HTTP error result for avatar weight GET: " << statusNum + << ", " << reason + << " returned by region " << regionp->getName() + << llendl; + } + else + { + llwarns << "Avatar render weight GET error recieved but region not found for " + << mRegionHandle + << ", error " << statusNum + << ", " << reason + << llendl; + } + + } + + virtual void result(const LLSD& content) + { + LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); + if (regionp) + { + if (LLAvatarRenderInfoAccountant::logRenderInfo()) + { + llinfos << "Result for avatar weights request for region " << regionp->getName() << ":" << llendl; + } + + if (content.isMap()) + { + if (content.has(KEY_AGENTS)) + { + const LLSD & agents = content[KEY_AGENTS]; + if (agents.isMap()) + { + LLSD::map_const_iterator report_iter = agents.beginMap(); + while (report_iter != agents.endMap()) + { + LLUUID target_agent_id = LLUUID(report_iter->first); + const LLSD & agent_info_map = report_iter->second; + LLViewerObject* avatarp = gObjectList.findObject(target_agent_id); + if (avatarp && + avatarp->isAvatar() && + agent_info_map.isMap()) + { // Extract the data for this avatar + + if (LLAvatarRenderInfoAccountant::logRenderInfo()) + { + llinfos << " Agent " << target_agent_id + << ": " << agent_info_map << llendl; + } + + if (agent_info_map.has(KEY_WEIGHT)) + { + ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger()); + } + if (agent_info_map.has(KEY_GEOMETRY)) + { + ((LLVOAvatar *) avatarp)->setReportedAttachmentGeometryBytes(agent_info_map[KEY_GEOMETRY].asInteger()); + } + if (agent_info_map.has(KEY_SURFACE)) + { + ((LLVOAvatar *) avatarp)->setReportedAttachmentSurfaceArea((F32) agent_info_map[KEY_SURFACE].asReal()); + } + } + report_iter++; + } + } + } // has "agents" + else if (content.has(KEY_ERROR)) + { + const LLSD & error = content[KEY_ERROR]; + llwarns << "Avatar render info GET error: " + << error[KEY_IDENTIFIER] + << ": " << error[KEY_MESSAGE] + << " from region " << regionp->getName() + << llendl; + } + } + } + else + { + llinfos << "Avatar render weight info recieved but region not found for " + << mRegionHandle << llendl; + } + } + +private: + U64 mRegionHandle; +}; + + +// HTTP responder class for POST request for avatar render weight information +class LLAvatarRenderInfoPostResponder : public LLHTTPClient::Responder +{ +public: + LLAvatarRenderInfoPostResponder(U64 region_handle) : mRegionHandle(region_handle) + { + } + + virtual void error(U32 statusNum, const std::string& reason) + { + LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); + if (regionp) + { + llwarns << "HTTP error result for avatar weight POST: " << statusNum + << ", " << reason + << " returned by region " << regionp->getName() + << llendl; + } + else + { + llwarns << "Avatar render weight POST error recieved but region not found for " + << mRegionHandle + << ", error " << statusNum + << ", " << reason + << llendl; + } + } + + virtual void result(const LLSD& content) + { + LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); + if (regionp) + { + if (LLAvatarRenderInfoAccountant::logRenderInfo()) + { + llinfos << "Result for avatar weights POST for region " << regionp->getName() + << ": " << content << llendl; + } + + if (content.isMap()) + { + if (content.has(KEY_ERROR)) + { + const LLSD & error = content[KEY_ERROR]; + llwarns << "Avatar render info POST error: " + << error[KEY_IDENTIFIER] + << ": " << error[KEY_MESSAGE] + << " from region " << regionp->getName() + << llendl; + } + } + } + else + { + llinfos << "Avatar render weight POST result recieved but region not found for " + << mRegionHandle << llendl; + } + } + +private: + U64 mRegionHandle; +}; + + +// static +// Send request for one region, no timer checks +void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regionp) +{ + std::string url = regionp->getCapability("AvatarRenderInfo"); + if (!url.empty()) + { + if (logRenderInfo()) + { + llinfos << "Sending avatar render info to region " + << regionp->getName() + << " from " << url + << llendl; + } + + // Build the render info to POST to the region + LLSD report = LLSD::emptyMap(); + LLSD agents = LLSD::emptyMap(); + + std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + while( iter != LLCharacter::sInstances.end() ) + { + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter); + if (avatar && + avatar->getRezzedStatus() >= 2 && // Mostly rezzed (maybe without baked textures downloaded) + !avatar->isDead() && // Not dead yet + avatar->getObjectHost() == regionp->getHost()) // Ensure it's on the same region + { + avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date + + LLSD info = LLSD::emptyMap(); + if (avatar->getVisualComplexity() > 0) + { + info[KEY_WEIGHT] = avatar->getVisualComplexity(); + } + if (avatar->getAttachmentGeometryBytes() > 0) + { + info[KEY_GEOMETRY] = (S32) avatar->getAttachmentGeometryBytes(); + } + if (avatar->getAttachmentSurfaceArea() > 0.f) + { + info[KEY_SURFACE] = avatar->getAttachmentSurfaceArea(); + } + if (info.size() > 0) + { + agents[avatar->getID().asString()] = info; + } + + if (logRenderInfo()) + { + llinfos << "Sending avatar render info for " << avatar->getID() + << ": " << info << llendl; + } + } + iter++; + } + + report[KEY_AGENTS] = agents; + if (agents.size() > 0) + { + LLHTTPClient::post(url, report, new LLAvatarRenderInfoPostResponder(regionp->getHandle())); + } + } +} + + + + +// static +// Send request for one region, no timer checks +void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regionp) +{ + std::string url = regionp->getCapability("AvatarRenderInfo"); + if (!url.empty()) + { + if (logRenderInfo()) + { + llinfos << "Requesting avatar render info for region " + << regionp->getName() + << " from " << url + << llendl; + } + + // First send a request to get the latest data + LLHTTPClient::get(url, new LLAvatarRenderInfoGetResponder(regionp->getHandle())); + } +} + + +// static +// Called every frame - send render weight requests to every region +void LLAvatarRenderInfoAccountant::idle() +{ + if (sRenderInfoReportTimer.hasExpired()) + { + const F32 SECS_BETWEEN_REGION_SCANS = 5.f; // Scan the region list every 5 seconds + const F32 SECS_BETWEEN_REGION_REQUEST = 60.0; // Update each region every 60 seconds + + S32 num_avs = LLCharacter::sInstances.size(); + + // Check all regions and see if it's time to fetch/send data + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* regionp = *iter; + if (regionp && + regionp->isAlive() && + regionp->capabilitiesReceived() && // Region has capability URLs available + regionp->getRenderInfoRequestTimer().hasExpired()) // Time to make request + { + sendRenderInfoToRegion(regionp); + getRenderInfoFromRegion(regionp); + + // Reset this regions timer, moving to longer intervals if there are lots of avatars around + regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST + (2.f * num_avs)); + } + } + + // We scanned all the regions, reset the request timer. + sRenderInfoReportTimer.resetWithExpiry(SECS_BETWEEN_REGION_SCANS); + } +} + + +// static +// Make sRenderInfoReportTimer expire so the next call to idle() will scan and query a new region +// called via LLViewerRegion::setCapabilitiesReceived() boost signals when the capabilities +// are returned for a new LLViewerRegion, and is the earliest time to get render info +void LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer() +{ + if (logRenderInfo()) + { + llinfos << "Viewer has new region capabilities" << llendl; + } + + sRenderInfoReportTimer.resetWithExpiry(0.f); +} + +// static +bool LLAvatarRenderInfoAccountant::logRenderInfo() +{ + static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging"); + return render_mute_logging_enabled; +} diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h new file mode 100644 index 0000000000..97dd9f0ad3 --- /dev/null +++ b/indra/newview/llavatarrenderinfoaccountant.h @@ -0,0 +1,56 @@ +/** + * @file llavatarrenderinfoaccountant.h + * @author Dave Simmons + * @date 2013-02-28 + * @brief + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#if ! defined(LL_llavatarrenderinfoaccountant_H) +#define LL_llavatarrenderinfoaccountant_H + +class LLViewerRegion; + +// Class to gather avatar rendering information +// that is sent to or fetched from regions. +class LLAvatarRenderInfoAccountant +{ +public: + LLAvatarRenderInfoAccountant() {}; + ~LLAvatarRenderInfoAccountant() {}; + + static void sendRenderInfoToRegion(LLViewerRegion * regionp); + static void getRenderInfoFromRegion(LLViewerRegion * regionp); + + static void expireRenderInfoReportTimer(); + + static void idle(); + + static bool logRenderInfo(); + +private: + // Send data updates about once per minute, only need per-frame resolution + static LLFrameTimer sRenderInfoReportTimer; +}; + +#endif /* ! defined(LL_llavatarrenderinfoaccountant_H) */ diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 8766585049..8766585049 100755..100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index b6c53e5e30..b6c53e5e30 100755..100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 3eb2e63792..3eb2e63792 100755..100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index bb1d263670..2e3a9119b8 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -254,7 +254,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep) return count; } -static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true); +static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face"); LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 94dd927d26..d8f293cc62 100755 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -472,6 +472,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba { params.mGroup->rebuildMesh(); } + params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..6fa16825df 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -394,10 +394,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { - bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. - // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress. - group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && - group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; + static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); + LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP); + + bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow. + + bool disable_cull = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE || + group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; + + LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0); LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; @@ -498,32 +503,31 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); + { + LLFastTimer t(FTM_RENDER_ALPHA_PUSH); + gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); + params.mVertexBuffer->setBuffer(mask); + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + } // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. if (current_shader && draw_glow_for_this_partition && params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) { + static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GLOW("Alpha Glow"); + LLFastTimer t(FTM_RENDER_ALPHA_GLOW); // install glow-accumulating blend mode gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) - emissive_shader->bind(); - - // glow doesn't use vertex colors from the mesh data - params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); + params.mVertexBuffer->setBuffer(mask | LLVertexBuffer::MAP_EMISSIVE); // do the actual drawing, again params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); - - // restore our alpha blend mode - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - - current_shader->bind(); } if (tex_setup) @@ -536,6 +540,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } + gGL.setSceneBlendType(LLRender::BT_ALPHA); + LLVertexBuffer::unbind(); if (!light_enabled) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 38268b102b..91394f0767 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -59,6 +59,7 @@ LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL; BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE; BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE; S32 LLDrawPoolAvatar::sDiffuseChannel = 0; +F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f; static bool is_deferred_render = false; @@ -272,7 +273,7 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() gPipeline.bindDeferredShader(*sVertexProgram); - sVertexProgram->setMinimumAlpha(0.2f); + sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } @@ -620,7 +621,7 @@ void LLDrawPoolAvatar::beginRigid() if (sVertexProgram != NULL) { //eyeballs render with the specular shader sVertexProgram->bind(); - sVertexProgram->setMinimumAlpha(0.2f); + sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); } } else @@ -671,7 +672,7 @@ void LLDrawPoolAvatar::beginDeferredRigid() sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); - sVertexProgram->setMinimumAlpha(0.2f); + sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); } void LLDrawPoolAvatar::endDeferredRigid() @@ -729,7 +730,7 @@ void LLDrawPoolAvatar::beginSkinned() if (LLGLSLShader::sNoFixedFunction) { - sVertexProgram->setMinimumAlpha(0.2f); + sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); } } @@ -1027,7 +1028,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned() sRenderingSkinned = TRUE; sVertexProgram->bind(); - sVertexProgram->setMinimumAlpha(0.2f); + sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); gGL.getTexUnit(0)->activate(); @@ -1138,7 +1139,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (impostor) { - if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) + if (LLPipeline::sRenderDeferred && //rendering a deferred impostor + !LLPipeline::sReflectionRender && + avatarp->mImpostor.isComplete() && //impostor has required data channels + avatarp->mImpostor.getNumTextures() >= 3) { if (normal_channel > -1) { @@ -1151,115 +1155,93 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel); } - return; } - - llassert(LLPipeline::sImpostorRender || !avatarp->isVisuallyMuted()); - - /*if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview, 3=morph view - { - gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); - }*/ - - if (pass == 1) + else if (pass == 1) { // render rigid meshes (eyeballs) first avatarp->renderRigid(); - return; } - - if (pass == 3) - { - if (is_deferred_render) - { - renderDeferredRiggedSimple(avatarp); - } - else - { - renderRiggedSimple(avatarp); - } - return; - } - - if (pass == 4) - { - if (is_deferred_render) - { - renderDeferredRiggedBump(avatarp); - } - else + else if (pass >= 3 && pass <= 9) + { //render rigged attachments + if (!avatarp->isVisuallyMuted()) // These details are skipped for visually muted (plain imposter) avatars { - renderRiggedFullbright(avatarp); + if (pass == 3) // To do - use switch statement + { + if (is_deferred_render) + { + renderDeferredRiggedSimple(avatarp); + } + else + { + renderRiggedSimple(avatarp); + } + } + else if (pass == 4) + { + if (is_deferred_render) + { + renderDeferredRiggedBump(avatarp); + } + else + { + renderRiggedFullbright(avatarp); + } + } + else if (pass == 5) + { + renderRiggedShinySimple(avatarp); + } + else if (pass == 6) + { + renderRiggedFullbrightShiny(avatarp); + } + else if (pass == 7) + { + renderRiggedAlpha(avatarp); + } + else if (pass == 8) + { + renderRiggedFullbrightAlpha(avatarp); + } + else if (pass == 9) + { + renderRiggedGlow(avatarp); + } } - - return; - } - - if (pass == 5) - { - renderRiggedShinySimple(avatarp); - return; } - - if (pass == 6) - { - renderRiggedFullbrightShiny(avatarp); - return; - } - - if (pass >= 7 && pass < 9) + else { - if (pass == 7) + if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) { - renderRiggedAlpha(avatarp); - return; + LLMatrix4 rot_mat; + LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + rot_mat *= cfr; + + LLVector4 wind; + wind.setVec(avatarp->mWindVec); + wind.mV[VW] = 0; + wind = wind * rot_mat; + wind.mV[VW] = avatarp->mWindVec.mV[VW]; + + sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); + F32 phase = -1.f * (avatarp->mRipplePhase); + + F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); + LLVector4 sin_params(freq, freq, freq, phase); + sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); + + LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); + gravity = gravity * rot_mat; + sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); } - if (pass == 8) + if( !single_avatar || (avatarp == single_avatar) ) { - renderRiggedFullbrightAlpha(avatarp); - return; + avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } } - - if (pass == 9) - { - renderRiggedGlow(avatarp); - - return; - } - - if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) - { - LLMatrix4 rot_mat; - LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); - rot_mat *= cfr; - - LLVector4 wind; - wind.setVec(avatarp->mWindVec); - wind.mV[VW] = 0; - wind = wind * rot_mat; - wind.mV[VW] = avatarp->mWindVec.mV[VW]; - - sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); - F32 phase = -1.f * (avatarp->mRipplePhase); - - F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); - LLVector4 sin_params(freq, freq, freq, phase); - sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); - - LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); - gravity = gravity * rot_mat; - sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); - } - - if( !single_avatar || (avatarp == single_avatar) ) - { - avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); - } } - void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) { face->setGeomIndex(0); @@ -1519,7 +1501,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) stop_glerror(); - LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette", + LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(LLViewerShaderMgr::AVATAR_MATRIX, skin->mJointNames.size(), FALSE, (GLfloat*) mat[0].mMatrix); @@ -1547,7 +1529,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) LLDrawPoolBump::bindBumpMap(face, normal_channel); } - if (face->mTextureMatrix) + if (face->mTextureMatrix && vobj->mTexAnimMode) { gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix); @@ -1561,6 +1543,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) buff->setBuffer(data_mask); buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); } + + gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES); } } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 5551d8f6d8..544969001d 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -209,6 +209,7 @@ public: static BOOL sSkipOpaque; static BOOL sSkipTransparent; static S32 sDiffuseChannel; + static F32 sMinimumAlpha; static LLGLSLShader* sVertexProgram; }; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index e8d43c8631..49051e74a9 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -449,9 +449,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - cube_map->disable(); - cube_map->restoreMatrix(); - if (!invisible && shader_level > 1) { shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -464,6 +461,10 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& } } } + // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0 + // MAINT-755 + cube_map->disable(); + cube_map->restoreMatrix(); } if (!LLGLSLShader::sNoFixedFunction) @@ -1369,9 +1370,14 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI LLGLDisable blend(GL_BLEND); gGL.setColorMask(TRUE, TRUE); gNormalMapGenProgram.bind(); - gNormalMapGenProgram.uniform1f("norm_scale", gSavedSettings.getF32("RenderNormalMapScale")); - gNormalMapGenProgram.uniform1f("stepX", 1.f/bump->getWidth()); - gNormalMapGenProgram.uniform1f("stepY", 1.f/bump->getHeight()); + + static LLStaticHashedString sNormScale("norm_scale"); + static LLStaticHashedString sStepX("stepX"); + static LLStaticHashedString sStepY("stepY"); + + gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale")); + gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth()); + gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight()); LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(), (F32) bump->getHeight()/gPipeline.mScreen.getHeight()); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 0adb42428d..c3ec234223 100755 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -354,8 +354,8 @@ void LLDrawPoolTerrain::renderFullShader() LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; llassert(shader); - shader->uniform4fv("object_plane_s", 1, tp0.mV); - shader->uniform4fv("object_plane_t", 1, tp1.mV); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); @@ -864,8 +864,8 @@ void LLDrawPoolTerrain::renderSimple() if (LLGLSLShader::sNoFixedFunction) { - sShader->uniform4fv("object_plane_s", 1, tp0.mV); - sShader->uniform4fv("object_plane_t", 1, tp1.mV); + sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); } else { diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5ddc15df42..0d79631182 100755 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -407,8 +407,8 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() } else { - shader->uniform4fv("object_plane_s", 1, tp0); - shader->uniform4fv("object_plane_t", 1, tp1); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1); } gGL.diffuseColor3f(1.f, 1.f, 1.f); @@ -546,7 +546,7 @@ void LLDrawPoolWater::shade() sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; - S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); + S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); if (reftex > -1) { @@ -577,12 +577,12 @@ void LLDrawPoolWater::shade() mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); } - S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); + S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); if (screentex > -1) { - shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); - shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, param_mgr->getFogDensity()); gPipeline.mWaterDis.bindTexture(0, screentex); } @@ -594,15 +594,9 @@ void LLDrawPoolWater::shade() if (mVertexShaderLevel == 1) { sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; - shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); } - F32 screenRes[] = - { - 1.f/gGLViewport[2], - 1.f/gGLViewport[3] - }; - shader->uniform2fv("screenRes", 1, screenRes); stop_glerror(); S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -614,26 +608,26 @@ void LLDrawPoolWater::shade() light_diffuse *= 6.f; //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); - shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth); - shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime); - shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); - shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); - shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp); - shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); - shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); - shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); - - shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV); - shader->uniform1f("fresnelScale", param_mgr->getFresnelScale()); - shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset()); - shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier()); + shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); + shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); + shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); + shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); + shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + + shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); + shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier()); F32 sunAngle = llmax(0.f, light_dir.mV[2]); F32 scaledAngle = 1.f - sunAngle; - shader->uniform1f("sunAngle", sunAngle); - shader->uniform1f("scaledAngle", scaledAngle); - shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle); + shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); + shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); + shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle); LLColor4 water_color; LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); @@ -641,12 +635,12 @@ void LLDrawPoolWater::shade() if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_color.setVec(1.f, 1.f, 1.f, 0.4f); - shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); } else { water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); - shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); } if (water_color.mV[3] > 0.9f) @@ -690,11 +684,11 @@ void LLDrawPoolWater::shade() } shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX); + shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); shader->disableTexture(LLViewerShaderMgr::BUMP_MAP); shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX); - shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH); + shader->disableTexture(LLShaderMgr::WATER_REFTEX); + shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); if (deferred_render) { diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index b5faff7968..b0e69aa9b5 100755 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -152,7 +152,8 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons gGL.translatef(0.f,-camHeightLocal, 0.f); // Draw WL Sky - shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f); + static LLStaticHashedString sCamPosLocal("camPosLocal"); + shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); gSky.mVOWLSkyp->drawDome(); @@ -207,7 +208,8 @@ void LLDrawPoolWLSky::renderStars(void) const if (LLGLSLShader::sNoFixedFunction) { gCustomAlphaProgram.bind(); - gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]); + static LLStaticHashedString sCustomAlpha("custom_alpha"); + gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]); } else { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 281f852b0a..e4c5590c5c 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -51,10 +51,21 @@ #include "llviewerregion.h" #include "llviewerwindow.h" #include "llviewershadermgr.h" +#include "llvoavatar.h" +#if LL_LINUX +// Work-around spurious used before init warning on Vector4a +// +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + +extern BOOL gGLDebugLoggingEnabled; #define LL_MAX_INDICES_COUNT 1000000 +static LLStaticHashedString sTextureIndexIn("texture_index_in"); +static LLStaticHashedString sColorIn("color_in"); + BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) @@ -325,6 +336,12 @@ void LLFace::dirtyTexture() if (vobj) { vobj->mLODChanged = TRUE; + + LLVOAvatar* avatar = vobj->getAvatar(); + if (avatar) + { //avatar render cost may have changed + avatar->updateVisualComplexity(); + } } gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE); } @@ -1159,6 +1176,15 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); + +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK("Face Feedback"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_NORMAL("Feedback Normal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_TEXTURE("Feedback Texture"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_COLOR("Feedback Color"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_EMISSIVE("Feedback Emissive"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_BINORMAL("Feedback Binormal"); + static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail"); static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); @@ -1382,12 +1408,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, #ifdef GL_TRANSFORM_FEEDBACK_BUFFER if (use_transform_feedback && + mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB && gTransformPositionProgram.mProgramObject && //transform shaders are loaded mVertexBuffer->useVBOs() && //target buffer is in VRAM !rebuild_weights && //TODO: add support for weights !volume.isUnique()) //source volume is NOT flexi { //use transform feedback to pack vertex buffer - + //gGLDebugLoggingEnabled = TRUE; + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK); + LLGLEnable discard(GL_RASTERIZER_DISCARD); LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) @@ -1404,7 +1433,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_pos) { - LLFastTimer t(FTM_FACE_GEOM_POSITION); + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_POSITION); gTransformPositionProgram.bind(); mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); @@ -1418,7 +1447,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, vp[2] = 0; vp[3] = 0; - gTransformPositionProgram.uniform1i("texture_index_in", val); + gTransformPositionProgram.uniform1i(sTextureIndexIn, val); glBeginTransformFeedback(GL_POINTS); buff->setBuffer(LLVertexBuffer::MAP_VERTEX); @@ -1429,14 +1458,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_color) { - LLFastTimer t(FTM_FACE_GEOM_COLOR); + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_COLOR); gTransformColorProgram.bind(); mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); S32 val = *((S32*) color.mV); - gTransformColorProgram.uniform1i("color_in", val); + gTransformColorProgram.uniform1i(sColorIn, val); glBeginTransformFeedback(GL_POINTS); buff->setBuffer(LLVertexBuffer::MAP_VERTEX); push_for_transform(buff, vf.mNumVertices, mGeomCount); @@ -1445,7 +1474,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_emissive) { - LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_EMISSIVE); gTransformColorProgram.bind(); mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); @@ -1457,7 +1486,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, (glow << 16) | (glow << 24); - gTransformColorProgram.uniform1i("color_in", glow32); + gTransformColorProgram.uniform1i(sColorIn, glow32); glBeginTransformFeedback(GL_POINTS); buff->setBuffer(LLVertexBuffer::MAP_VERTEX); push_for_transform(buff, vf.mNumVertices, mGeomCount); @@ -1466,7 +1495,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_normal) { - LLFastTimer t(FTM_FACE_GEOM_NORMAL); + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_NORMAL); gTransformNormalProgram.bind(); mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); @@ -1479,7 +1508,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_binormal) { - LLFastTimer t(FTM_FACE_GEOM_BINORMAL); + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_BINORMAL); gTransformBinormalProgram.bind(); mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); @@ -1492,7 +1521,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_tcoord) { - LLFastTimer t(FTM_FACE_GEOM_TEXTURE); + LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_TEXTURE); gTransformTexCoordProgram.bind(); mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); @@ -1515,13 +1544,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0); - gGL.popMatrix(); if (cur_shader) { cur_shader->bind(); } + //gGLDebugLoggingEnabled = FALSE; } else #endif @@ -1936,21 +1965,32 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_pos) { - LLFastTimer t(FTM_FACE_GEOM_POSITION); + LLVector4a* src = vf.mPositions; + + //_mm_prefetch((char*)src, _MM_HINT_T0); + + LLVector4a* end = src+num_vertices; + //LLVector4a* end_64 = end-4; + + //LLFastTimer t(FTM_FACE_GEOM_POSITION); llassert(num_vertices > 0); mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); - LLMatrix4a mat_vert; mat_vert.loadu(mat_vert_in); + + F32* dst = (F32*) vert.get(); + F32* end_f32 = dst+mGeomCount*4; - LLVector4a* src = vf.mPositions; - volatile F32* dst = (volatile F32*) vert.get(); + //_mm_prefetch((char*)dst, _MM_HINT_NTA); + //_mm_prefetch((char*)src, _MM_HINT_NTA); + + //_mm_prefetch((char*)dst, _MM_HINT_NTA); - volatile F32* end = dst+num_vertices*4; - LLVector4a res; + LLVector4a res0; //,res1,res2,res3; + LLVector4a texIdx; S32 index = mTextureIndex < 255 ? mTextureIndex : 0; @@ -1967,29 +2007,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, texIdx.set(0,0,0,val); + LLVector4a tmp; + { - LLFastTimer t(FTM_FACE_POSITION_STORE); - LLVector4a tmp; + //LLFastTimer t2(FTM_FACE_POSITION_STORE); - do - { - mat_vert.affineTransform(*src++, res); - tmp.setSelectWithMask(mask, texIdx, res); + /*if (num_vertices > 4) + { //more than 64 bytes + while (src < end_64) + { + _mm_prefetch((char*)src + 64, _MM_HINT_T0); + _mm_prefetch((char*)dst + 64, _MM_HINT_T0); + + mat_vert.affineTransform(*src, res0); + tmp.setSelectWithMask(mask, texIdx, res0); + tmp.store4a((F32*) dst); + + mat_vert.affineTransform(*(src+1), res1); + tmp.setSelectWithMask(mask, texIdx, res1); + tmp.store4a((F32*) dst+4); + + mat_vert.affineTransform(*(src+2), res2); + tmp.setSelectWithMask(mask, texIdx, res2); + tmp.store4a((F32*) dst+8); + + mat_vert.affineTransform(*(src+3), res3); + tmp.setSelectWithMask(mask, texIdx, res3); + tmp.store4a((F32*) dst+12); + + dst += 16; + src += 4; + } + }*/ + + while (src < end) + { + mat_vert.affineTransform(*src++, res0); + tmp.setSelectWithMask(mask, texIdx, res0); tmp.store4a((F32*) dst); dst += 4; } - while(dst < end); } - + { - LLFastTimer t(FTM_FACE_POSITION_PAD); - S32 aligned_pad_vertices = mGeomCount - num_vertices; - res.set(res[0], res[1], res[2], 0.f); - - while (aligned_pad_vertices > 0) + //LLFastTimer t(FTM_FACE_POSITION_PAD); + while (dst < end_f32) { - --aligned_pad_vertices; - res.store4a((F32*) dst); + res0.store4a((F32*) dst); dst += 4; } } @@ -2003,15 +2067,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_normal) { - LLFastTimer t(FTM_FACE_GEOM_NORMAL); + //LLFastTimer t(FTM_FACE_GEOM_NORMAL); mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); F32* normals = (F32*) norm.get(); - for (S32 i = 0; i < num_vertices; i++) - { + LLVector4a* src = vf.mNormals; + LLVector4a* end = src+num_vertices; + + while (src < end) + { LLVector4a normal; - mat_normal.rotate(vf.mNormals[i], normal); - normal.normalize3fast(); + mat_normal.rotate(*src++, normal); normal.store4a(normals); normals += 4; } @@ -2028,11 +2094,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); F32* binormals = (F32*) binorm.get(); - for (S32 i = 0; i < num_vertices; i++) + LLVector4a* src = vf.mBinormals; + LLVector4a* end = vf.mBinormals+num_vertices; + + while (src < end) { LLVector4a binormal; - mat_normal.rotate(vf.mBinormals[i], binormal); - binormal.normalize3fast(); + mat_normal.rotate(*src++, binormal); binormal.store4a(binormals); binormals += 4; } diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index fbf72b1a85..8e1a1df211 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -345,7 +345,7 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } -static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true); +static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers"); static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index caad0afec0..98c0c0bf51 100755 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -294,6 +294,9 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons void LLVolumeImplFlexible::updateRenderRes() { + if (!mAttributes) + return; + LLDrawable* drawablep = mVO->mDrawable; S32 new_res = mAttributes->getSimulateLOD(); @@ -435,7 +438,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() } } - if(!mInitialized) + if(!mInitialized || !mAttributes) { //the object is not visible return ; @@ -689,30 +692,36 @@ void LLVolumeImplFlexible::doFlexibleUpdate() LLVector4(z_axis, 0.f), LLVector4(delta_pos, 1.f)); + LL_CHECK_MEMORY for (i=0; i<=num_render_sections; ++i) { new_point = &path->mPath[i]; LLVector3 pos = newSection[i].mPosition * rel_xform; LLQuaternion rot = mSection[i].mAxisRotation * newSection[i].mRotation * delta_rot; - - if (!mUpdated || (new_point->mPos-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f) + + LLVector3 np(new_point->mPos.getF32ptr()); + + if (!mUpdated || (np-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f) { - new_point->mPos = newSection[i].mPosition * rel_xform; + new_point->mPos.load3((newSection[i].mPosition * rel_xform).mV); mUpdated = FALSE; } - new_point->mRot = rot; - new_point->mScale = newSection[i].mScale; + new_point->mRot.loadu(LLMatrix3(rot)); + new_point->mScale.set(newSection[i].mScale.mV[0], newSection[i].mScale.mV[1], 0,1); new_point->mTexT = ((F32)i)/(num_render_sections); } - + LL_CHECK_MEMORY mLastSegmentRotation = parentSegmentRotation; } +static LLFastTimer::DeclareTimer FTM_FLEXI_PREBUILD("Flexi Prebuild"); + void LLVolumeImplFlexible::preRebuild() { if (!mUpdated) { + LLFastTimer t(FTM_FLEXI_PREBUILD); doFlexibleRebuild(); } } diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 116bd241c4..664f7d4fd6 100755 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -89,8 +89,10 @@ void LLFloaterHardwareSettings::refresh() void LLFloaterHardwareSettings::refreshEnabledState() { + F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); + S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); - S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); + S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem); getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem); diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 9ce5e12897..c4d7bbb7f6 100755 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -187,14 +187,11 @@ void LLFloaterIMNearbyChatScreenChannel::deactivateToast(LLToast* toast) { toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle()); - if (pos == m_active_toasts.end()) + if (pos != m_active_toasts.end()) { - llassert(pos == m_active_toasts.end()); - return; + LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl; + m_active_toasts.erase(pos); } - - LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl; - m_active_toasts.erase(pos); } void LLFloaterIMNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer) @@ -210,8 +207,8 @@ void LLFloaterIMNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool a { // Viewer is quitting. // Immediately stop processing chat messages (EXT-1419). - mStopProcessing = true; -} + mStopProcessing = true; + } else { // The toast is being closed by user (STORM-192). diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index d4355007c1..6ef4d8717d 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2027,6 +2027,10 @@ void LLPanelLandOptions::refresh() mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID()); mSnapshotCtrl->setEnabled( can_change_identity ); + // find out where we're looking and convert that to an angle in degrees on a regular compass (not the internal representation) + LLVector3 user_look_at = parcel->getUserLookAt(); + U32 user_look_at_angle = ( (U32)( ( atan2(user_look_at[1], -user_look_at[0]) + F_PI * 2 ) * RAD_TO_DEG + 0.5) - 90) % 360; + LLVector3 pos = parcel->getUserLocation(); if (pos.isExactlyZero()) { @@ -2034,10 +2038,11 @@ void LLPanelLandOptions::refresh() } else { - mLocationText->setTextArg("[LANDING]",llformat("%d, %d, %d", + mLocationText->setTextArg("[LANDING]",llformat("%d, %d, %d (%d\xC2\xB0)", llround(pos.mV[VX]), llround(pos.mV[VY]), - llround(pos.mV[VZ]))); + llround(pos.mV[VZ]), + user_look_at_angle)); } mSetBtn->setEnabled( can_change_landing_point ); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 100f1d580b..19cec55837 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -290,6 +290,22 @@ bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a bool validate_face(const LLVolumeFace& face) { + + for (U32 v = 0; v < face.mNumVertices; v++) + { + if(face.mPositions && !face.mPositions[v].isFinite3()) + { + llwarns << "NaN position data in face found!" << llendl; + return false; + } + + if(face.mNormals && !face.mNormals[v].isFinite3()) + { + llwarns << "NaN normal data in face found!" << llendl; + return false; + } + } + for (U32 i = 0; i < face.mNumIndices; ++i) { if (face.mIndices[i] >= face.mNumVertices) @@ -305,8 +321,10 @@ bool validate_face(const LLVolumeFace& face) return false; } + /*const LLVector4a scale(0.5f); + for (U32 i = 0; i < face.mNumIndices; i+=3) { U16 idx1 = face.mIndices[i]; @@ -323,7 +341,6 @@ bool validate_face(const LLVolumeFace& face) return false; } }*/ - return true; } @@ -5921,3 +5938,5 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::stri LLNotificationsUtil::add("MeshUploadPermError"); } + + diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index bbf88060c1..515d96e0e7 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -337,7 +337,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this)); mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreference::onVertexShaderEnable, this)); mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this)); - mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::onUpdateSliderText,this, _1,_2)); + mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::refreshUI,this)); mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2)); mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2)); mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2)); @@ -1147,6 +1147,8 @@ void LLFloaterPreference::refreshEnabledState() //Deferred/SSAO/Shadows LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); + LLCheckBoxCtrl* ctrl_deferred2 = getChild<LLCheckBoxCtrl>("UseLightShaders2"); + BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && shaders && @@ -1155,11 +1157,13 @@ void LLFloaterPreference::refreshEnabledState() (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); - + ctrl_deferred2->setEnabled(enabled); + LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); + // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); ctrl_ssao->setEnabled(enabled); @@ -1185,6 +1189,7 @@ void LLFloaterPreference::disableUnavailableSettings() LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders"); LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors"); LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); + LLCheckBoxCtrl* ctrl_deferred2 = getChild<LLCheckBoxCtrl>("UseLightShaders2"); LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); @@ -1218,6 +1223,8 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); + ctrl_deferred2->setEnabled(FALSE); + ctrl_deferred2->setValue(FALSE); } // disabled windlight @@ -1238,6 +1245,8 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); + ctrl_deferred2->setEnabled(FALSE); + ctrl_deferred2->setValue(FALSE); } // disabled deferred @@ -1255,6 +1264,8 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); + ctrl_deferred2->setEnabled(FALSE); + ctrl_deferred2->setValue(FALSE); } // disabled deferred SSAO @@ -1299,6 +1310,8 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); + ctrl_deferred2->setEnabled(FALSE); + ctrl_deferred2->setValue(FALSE); } // disabled cloth @@ -1327,6 +1340,7 @@ void LLFloaterPreference::refresh() updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail", true), getChild<LLTextBox>("FlexibleMeshDetailText", true)); updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail", true), getChild<LLTextBox>("TreeMeshDetailText", true)); updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail", true), getChild<LLTextBox>("AvatarMeshDetailText", true)); + updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail2", true), getChild<LLTextBox>("AvatarMeshDetailText2", true)); updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail", true), getChild<LLTextBox>("AvatarPhysicsDetailText", true)); updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail", true), getChild<LLTextBox>("TerrainMeshDetailText", true)); updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess", true), getChild<LLTextBox>("PostProcessText", true)); @@ -1578,16 +1592,9 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im getChildView("chat_font_size")->setEnabled(TRUE); } -void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name) +void LLFloaterPreference::refreshUI() { - std::string ctrl_name = name.asString(); - - if ((ctrl_name =="" )|| !hasChild(ctrl_name, TRUE)) - return; - - LLTextBox* text_box = getChild<LLTextBox>(name.asString()); - LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl); - updateSliderText(slider, text_box); + refresh(); } void LLFloaterPreference::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box) diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 22e80a21cb..cb180f6f1e 100755 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -154,8 +154,7 @@ public: void onChangeQuality(const LLSD& data); void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box); - void onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name); -// void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator); + void refreshUI(); void onCommitParcelMediaAutoPlayEnable(); void onCommitMediaEnabled(); diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h index cfc87e9015..86b5a5e00b 100755 --- a/indra/newview/llfloaterwebcontent.h +++ b/indra/newview/llfloaterwebcontent.h @@ -43,6 +43,7 @@ class LLFloaterWebContent : public LLInstanceTracker<LLFloaterWebContent, std::string> { public: + typedef LLInstanceTracker<LLFloaterWebContent, std::string> instance_tracker_t; LOG_CLASS(LLFloaterWebContent); diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index b62db70ec8..06bf294417 100755 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1681,7 +1681,8 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane); - gClipProgram.uniform4fv("clip_plane", 1, plane.v); + static LLStaticHashedString sClipPlane("clip_plane"); + gClipProgram.uniform4fv(sClipPlane, 1, plane.v); BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS); diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 7f2a5e1642..6c38c1fb56 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -46,6 +46,7 @@ class LLMediaCtrl : { LOG_CLASS(LLMediaCtrl); public: + struct Params : public LLInitParam::Block<Params, LLPanel::Params> { Optional<std::string> start_url; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 17311dd75e..83b7cae347 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -288,7 +288,14 @@ public: ~LLMeshSkinInfoResponder() { - llassert(mProcessed); + if (!LLApp::isQuitting() && + !mProcessed && + mMeshID.notNull()) + { // Something went wrong, retry + llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); + } } virtual void completedRaw(U32 status, const std::string& reason, @@ -313,7 +320,14 @@ public: ~LLMeshDecompositionResponder() { - llassert(mProcessed); + if (!LLApp::isQuitting() && + !mProcessed && + mMeshID.notNull()) + { // Something went wrong, retry + llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshDecomposition(mMeshID); + } } virtual void completedRaw(U32 status, const std::string& reason, @@ -338,7 +352,14 @@ public: ~LLMeshPhysicsShapeResponder() { - llassert(mProcessed); + if (!LLApp::isQuitting() && + !mProcessed && + mMeshID.notNull()) + { // Something went wrong, retry + llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl; + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); + } } virtual void completedRaw(U32 status, const std::string& reason, @@ -588,7 +609,7 @@ void LLMeshRepoThread::run() if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit { mMutex->lock(); - mLODReqQ.push(req) ; + mLODReqQ.push(req); mMutex->unlock(); } } @@ -1200,8 +1221,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat LLMutexLock lock(mHeaderMutex); mMeshHeaderSize[mesh_id] = header_size; mMeshHeader[mesh_id] = header; - } - + } LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. @@ -1215,8 +1235,8 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat mLODReqQ.push(req); LLMeshRepository::sLODProcessing++; } + mPendingLOD.erase(iter); } - mPendingLOD.erase(iter); } return true; @@ -1919,7 +1939,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, if (data_size < mRequestedBytes) { - if (status == 499 || status == 503) + if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; @@ -1927,7 +1947,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, } else { - llassert(status == 499 || status == 503); //intentionally trigger a breakpoint + llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -1983,15 +2003,15 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason if (data_size < mRequestedBytes) { - if (status == 499 || status == 503) + if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again - llwarns << "Timeout or service unavailable, retrying." << llendl; + llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); } else { - llassert(status == 499 || status == 503); //intentionally trigger a breakpoint + llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -2046,15 +2066,15 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r if (data_size < mRequestedBytes) { - if (status == 499 || status == 503) + if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again - llwarns << "Timeout or service unavailable, retrying." << llendl; + llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshDecomposition(mMeshID); } else { - llassert(status == 499 || status == 503); //intentionally trigger a breakpoint + llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -2110,15 +2130,15 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re if (data_size < mRequestedBytes) { - if (status == 499 || status == 503) + if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again - llwarns << "Timeout or service unavailable, retrying." << llendl; + llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); } else { - llassert(status == 499 || status == 503); //intentionally trigger a breakpoint + llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint llwarns << "Unhandled status " << status << llendl; } return; @@ -2171,16 +2191,16 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, // << "Header responder failed with status: " // << status << ": " << reason << llendl; - // 503 (service unavailable) or 499 (timeout) + // 503 (service unavailable) or 499 (internal Linden-generated error) // can be due to server load and can be retried // TODO*: Add maximum retry logic, exponential backoff // and (somewhat more optional than the others) retries // again after some set period of time - llassert(status == 503 || status == 499); + llassert(status == HTTP_NOT_FOUND || status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || status == HTTP_INTERNAL_ERROR); - if (status == 503 || status == 499) + if (status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || status == HTTP_INTERNAL_ERROR) { //retry llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; @@ -2192,7 +2212,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, } else { - llwarns << "Unhandled status." << llendl; + llwarns << "Unhandled status: " << status << llendl; } } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 5aa1e1c458..92e82b672d 100755 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -67,6 +67,7 @@ class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl> { public: + typedef enum e_name_type { INDIVIDUAL, diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index e4c2e94230..9e07cedf18 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1404,7 +1404,9 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) if (bridge->mAvatar.notNull()) { bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes; + bridge->mAvatar->mAttachmentGeometryBytes = llmax(bridge->mAvatar->mAttachmentGeometryBytes, 0); bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea; + bridge->mAvatar->mAttachmentSurfaceArea = llmax(bridge->mAvatar->mAttachmentSurfaceArea, 0.f); } } @@ -4648,7 +4650,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mGroup(NULL), mFace(NULL), mDistance(0.f), - mDrawMode(LLRender::TRIANGLES) + mDrawMode(LLRender::TRIANGLES), + mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA), + mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA) { mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b1706d9d35..08e77855c4 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -119,6 +119,8 @@ public: LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; + U32 mBlendFuncSrc; + U32 mBlendFuncDst; struct CompareTexture { @@ -739,7 +741,7 @@ class LLVolumeGeometryManager: public LLGeometryManager virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); - void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); + void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); }; diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 9dfb29b905..d876c9a3f4 100755 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -173,8 +173,20 @@ void LLToast::setHideButtonEnabled(bool enabled) //-------------------------------------------------------------------------- LLToast::~LLToast() -{ - mOnToastDestroyedSignal(this); +{ + if(LLApp::isQuitting()) + { + mOnFadeSignal.disconnect_all_slots(); + mOnDeleteToastSignal.disconnect_all_slots(); + mOnToastDestroyedSignal.disconnect_all_slots(); + mOnToastHoverSignal.disconnect_all_slots(); + mToastMouseEnterSignal.disconnect_all_slots(); + mToastMouseLeaveSignal.disconnect_all_slots(); + } + else + { + mOnToastDestroyedSignal(this); + } } //-------------------------------------------------------------------------- @@ -572,10 +584,34 @@ S32 LLToast::notifyParent(const LLSD& info) //static void LLToast::updateClass() { - for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances(); iter != LLInstanceTracker<LLToast>::endInstances(); ) + for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances(); + iter != LLInstanceTracker<LLToast>::endInstances(); ) { LLToast& toast = *iter++; toast.updateHoveredState(); } } + +// static +void LLToast::cleanupToasts() +{ + LLToast * toastp = NULL; + + while (LLInstanceTracker<LLToast>::instanceCount() > 0) + { + { // Need to scope iter to allow deletion + LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances(); + toastp = &(*iter); + } + + //llinfos << "Cleaning up toast id " << toastp->getNotificationID() << llendl; + + // LLToast destructor will remove it from the LLInstanceTracker. + if (!toastp) + break; // Don't get stuck in the loop if a null pointer somehow got on the list + + delete toastp; + } +} + diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index ea62f758f8..f02d7c2a1a 100755 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -73,6 +73,7 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast> { friend class LLToastLifeTimer; public: + typedef boost::function<void (LLToast* toast)> toast_callback_t; typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t; typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t; @@ -105,6 +106,7 @@ public: }; static void updateClass(); + static void cleanupToasts(); LLToast(const LLToast::Params& p); virtual ~LLToast(); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 8bfde2bcf1..94d07b37ef 100755 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -60,7 +60,7 @@ LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, co LLInstanceTracker<LLToastNotifyPanel, LLUUID>(notification->getID()) { init(rect, show_images); - } +} void LLToastNotifyPanel::addDefaultButton() { LLSD form_element; diff --git a/indra/newview/lltoolselect.h b/indra/newview/lltoolselect.h index baa27f6071..74dababe8c 100755 --- a/indra/newview/lltoolselect.h +++ b/indra/newview/lltoolselect.h @@ -34,7 +34,7 @@ class LLObjectSelection; -class LLToolSelect : public LLTool, public LLSingleton<LLToolSelect> +class LLToolSelect : public LLTool { public: LLToolSelect( LLToolComposite* composite ); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index cf59e67955..0f273a8241 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -212,13 +212,13 @@ void display_stats() } static LLFastTimer::DeclareTimer FTM_PICK("Picking"); -static LLFastTimer::DeclareTimer FTM_RENDER("Render", true); +static LLFastTimer::DeclareTimer FTM_RENDER("Render"); static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky"); static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump"); -static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List"); +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List", true); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete"); static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window"); static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update"); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index a179b61cff..a179b61cff 100755..100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c96764e892..ae38dc2fe9 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2949,6 +2949,63 @@ bool enable_object_unmute() } } + +// 0 = normal, 1 = always, 2 = never +class LLAvatarCheckImposterMode : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; + + LLVOAvatar* avatar = find_avatar_from_object(object); + if (!avatar) return false; + + U32 mode = userdata.asInteger(); + switch (mode) + { + case 0: + return (avatar->getVisualMuteSettings() == LLVOAvatar::VISUAL_MUTE_NOT_SET); + case 1: + return (avatar->getVisualMuteSettings() == LLVOAvatar::ALWAYS_VISUAL_MUTE); + case 2: + return (avatar->getVisualMuteSettings() == LLVOAvatar::NEVER_VISUAL_MUTE); + default: + return false; + } + } // handleEvent() +}; + +// 0 = normal, 1 = always, 2 = never +class LLAvatarSetImposterMode : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; + + LLVOAvatar* avatar = find_avatar_from_object(object); + if (!avatar) return false; + + U32 mode = userdata.asInteger(); + switch (mode) + { + case 0: + avatar->setVisualMuteSettings(LLVOAvatar::VISUAL_MUTE_NOT_SET); + return true; + case 1: + avatar->setVisualMuteSettings(LLVOAvatar::ALWAYS_VISUAL_MUTE); + return true; + case 2: + avatar->setVisualMuteSettings(LLVOAvatar::NEVER_VISUAL_MUTE); + return true; + default: + return false; + } + } // handleEvent() +}; + + class LLObjectMute : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -8651,6 +8708,8 @@ void initialize_menus() view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab"); // Avatar pie menu + view_listener_t::addMenu(new LLAvatarCheckImposterMode(), "Avatar.CheckImposterMode"); + view_listener_t::addMenu(new LLAvatarSetImposterMode(), "Avatar.SetImposterMode"); view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute"); view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend"); view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0db118835c..9894ec7c07 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4129,7 +4129,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) { LLTracker::stopTracking(NULL); } - else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() ) + else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() && look_at.isExactlyZero()) { //look at the beacon LLVector3 global_agent_pos = agent_pos; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 670272e7be..9dc9932c86 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1553,6 +1553,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, dp->setPassFlags(value); dp->unpackUUID(owner_id, "Owner"); + mOwnerID = owner_id; + if (value & 0x80) { dp->unpackVector3(new_angv, "Omega"); @@ -1626,13 +1628,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, retval |= checkMediaURL(media_url); // - // Unpack particle system data + // Unpack particle system data (legacy) // if (value & 0x8) { - unpackParticleSource(*dp, owner_id); + unpackParticleSource(*dp, owner_id, true); } - else + else if (!(value & 0x400)) { deleteParticleSource(); } @@ -1697,7 +1699,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // keep local flags and overwrite remote-controlled flags mFlags = (mFlags & FLAGS_LOCAL) | flags; - // ...new objects that should come in selected need to be added to the selected list + // ...new objects that should come in selected need to be added to the selected list mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); } break; @@ -4618,7 +4620,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own } } -void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id) +void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy) { if (!mPartSourcep.isNull() && mPartSourcep->isDead()) { @@ -4627,7 +4629,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_ if (mPartSourcep) { // If we've got one already, just update the existing source (or remove it) - if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp)) + if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy)) { mPartSourcep->setDead(); mPartSourcep = NULL; @@ -4635,7 +4637,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_ } else { - LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp); + LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy); //If the owner is muted, don't create the system if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; // We need to be able to deal with a particle source that hasn't changed, but still got an update! @@ -5481,6 +5483,11 @@ F32 LLAlphaObject::getPartSize(S32 idx) return 0.f; } +void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst) +{ + +} + // virtual void LLStaticViewerObject::updateDrawable(BOOL force_damped) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 316dbce7d0..9996c916a4 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -112,14 +112,6 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate protected: ~LLViewerObject(); // use unref() - // TomY: Provide for a list of extra parameter structures, mapped by structure name - struct ExtraParameter - { - BOOL in_use; - LLNetworkData *data; - }; - std::map<U16, ExtraParameter*> mExtraParameterList; - public: typedef std::list<LLPointer<LLViewerObject> > child_list_t; typedef std::list<LLPointer<LLViewerObject> > vobj_list_t; @@ -545,6 +537,8 @@ public: std::vector<LLVector3> mUnselectedChildrenPositions ; private: + // TomY: Provide for a list of extra parameter structures, mapped by structure name + struct ExtraParameter; ExtraParameter* createNewParameterEntry(U16 param_type); ExtraParameter* getExtraParameterEntry(U16 param_type) const; ExtraParameter* getExtraParameterEntryCreate(U16 param_type); @@ -584,6 +578,7 @@ public: } EPhysicsShapeType; LLUUID mID; + LLUUID mOwnerID; //null if unknown // unique within region, not unique across regions // Local ID = 0 is not used @@ -662,7 +657,7 @@ protected: BOOL isOnMap(); void unpackParticleSource(const S32 block_num, const LLUUID& owner_id); - void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id); + void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy); void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); @@ -781,6 +776,14 @@ private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. EObjectUpdateType mLastUpdateType; BOOL mLastUpdateCached; + + // TomY: Provide for a list of extra parameter structures, mapped by structure name + struct ExtraParameter + { + BOOL in_use; + LLNetworkData *data; + }; + std::map<U16, ExtraParameter*> mExtraParameterList; }; /////////////////// @@ -826,9 +829,12 @@ public: LLStrider<LLVector4a>& verticesp, LLStrider<LLVector3>& normalsp, LLStrider<LLVector2>& texcoordsp, - LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& emissivep, LLStrider<U16>& indicesp) = 0; + virtual void getBlendFunc(S32 face, U32& src, U32& dst); + F32 mDepth; }; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 61cdfd7818..21f1d2619c 100755 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -80,12 +80,31 @@ LLViewerPart::LLViewerPart() : mImagep(NULL) { mPartSourcep = NULL; - + mParent = NULL; + mChild = NULL; ++LLViewerPartSim::sParticleCount2 ; } LLViewerPart::~LLViewerPart() { + if (mPartSourcep.notNull() && mPartSourcep->mLastPart == this) + { + mPartSourcep->mLastPart = NULL; + } + + //patch up holes in the ribbon + if (mParent) + { + llassert(mParent->mChild == this); + mParent->mChild = mChild; + } + + if (mChild) + { + llassert (mChild->mParent == this); + mChild->mParent = mParent; + } + mPartSourcep = NULL; --LLViewerPartSim::sParticleCount2 ; @@ -367,6 +386,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) part->mScale += frac*part->mEndScale; } + // Do glow interpolation + part->mGlow.mV[3] = (U8) (lerp(part->mStartGlow, part->mEndGlow, frac)*255.f); + // Set the last update time to now. part->mLastUpdateTime = cur_time; @@ -623,6 +645,9 @@ void LLViewerPartSim::updateSimulation() { static LLFrameTimer update_timer; + //reset VBO cursor + LLVOPartGroup::sVBSlotCursor = 0; + const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f); if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index c91fcf0691..095de2060c 100755 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -65,15 +65,22 @@ public: LLVPCallback mVPCallback; // Callback function for more complicated behaviors LLPointer<LLViewerPartSource> mPartSourcep; // Particle source used for this object - + + LLViewerPart* mParent; // particle to connect to if this is part of a particle ribbon + LLViewerPart* mChild; // child particle for clean reference destruction // Current particle state (possibly used for rendering) LLPointer<LLViewerTexture> mImagep; LLVector3 mPosAgent; LLVector3 mVelocity; LLVector3 mAccel; + LLVector3 mAxis; LLColor4 mColor; LLVector2 mScale; + F32 mStartGlow; + F32 mEndGlow; + LLColor4U mGlow; + static U32 sNextPartID; }; diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index b311f659fb..8c49ce646d 100755 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -52,6 +52,8 @@ LLViewerPartSource::LLViewerPartSource(const U32 type) : static U32 id_seed = 0; mID = ++id_seed; + mLastPart = NULL; + mDelay = 0 ; } @@ -279,6 +281,22 @@ void LLViewerPartSourceScript::update(const F32 dt) { part->mFlags |= LLPartData::LL_PART_HUD; } + + if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK && mLastPart) + { //set previous particle's parent to this particle to chain ribbon together + mLastPart->mParent = part; + part->mChild = mLastPart; + part->mAxis = LLVector3(0,0,1); + + if (mSourceObjectp.notNull()) + { + LLQuaternion rot = mSourceObjectp->getRenderRotation(); + part->mAxis *= rot; + } + } + + mLastPart = part; + part->mMaxAge = mPartSysData.mPartData.mMaxAge; part->mStartColor = mPartSysData.mPartData.mStartColor; part->mEndColor = mPartSysData.mPartData.mEndColor; @@ -290,6 +308,13 @@ void LLViewerPartSourceScript::update(const F32 dt) part->mAccel = mPartSysData.mPartAccel; + part->mBlendFuncDest = mPartSysData.mPartData.mBlendFuncDest; + part->mBlendFuncSource = mPartSysData.mPartData.mBlendFuncSource; + + part->mStartGlow = mPartSysData.mPartData.mStartGlow; + part->mEndGlow = mPartSysData.mPartData.mEndGlow; + part->mGlow = LLColor4U(0, 0, 0, (U8) (part->mStartGlow*255.f)); + if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP) { part->mPosAgent = mPosAgent; @@ -430,28 +455,51 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer } -LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp) +LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy) { if (!pssp) { LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp); - if (!new_pssp->mPartSysData.unpack(dp)) + if (legacy) { - return NULL; + if (!new_pssp->mPartSysData.unpackLegacy(dp)) + { + return NULL; + } + } + else + { + if (!new_pssp->mPartSysData.unpack(dp)) + { + return NULL; + } } + if (new_pssp->mPartSysData.mTargetUUID.notNull()) { LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID); new_pssp->setTargetObject(target_objp); } + return new_pssp; } else { - if (!pssp->mPartSysData.unpack(dp)) + if (legacy) { - return NULL; + if (!pssp->mPartSysData.unpackLegacy(dp)) + { + return NULL; + } } + else + { + if (!pssp->mPartSysData.unpack(dp)) + { + return NULL; + } + } + if (pssp->mPartSysData.mTargetUUID.notNull()) { LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID); @@ -569,6 +617,11 @@ void LLViewerPartSourceSpiral::update(const F32 dt) part->mScale.mV[0] = 0.25f; part->mScale.mV[1] = 0.25f; part->mParameter = ll_frand(F_TWO_PI); + part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA; + part->mStartGlow = 0.f; + part->mEndGlow = 0.f; + part->mGlow = LLColor4U(0, 0, 0, 0); LLViewerPartSim::getInstance()->addPart(part); } @@ -721,6 +774,12 @@ void LLViewerPartSourceBeam::update(const F32 dt) part->mPosAgent = mPosAgent; part->mVelocity = mTargetPosAgent - mPosAgent; + part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA; + part->mStartGlow = 0.f; + part->mEndGlow = 0.f; + part->mGlow = LLColor4U(0, 0, 0, 0); + LLViewerPartSim::getInstance()->addPart(part); } } @@ -825,6 +884,12 @@ void LLViewerPartSourceChat::update(const F32 dt) part->mScale.mV[0] = 0.25f; part->mScale.mV[1] = 0.25f; part->mParameter = ll_frand(F_TWO_PI); + part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA; + part->mStartGlow = 0.f; + part->mEndGlow = 0.f; + part->mGlow = LLColor4U(0, 0, 0, 0); + LLViewerPartSim::getInstance()->addPart(part); } diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h index 28702d36a2..12e926173b 100755 --- a/indra/newview/llviewerpartsource.h +++ b/indra/newview/llviewerpartsource.h @@ -76,6 +76,7 @@ public: LLVector3 mLastUpdatePosAgent; LLPointer<LLViewerObject> mSourceObjectp; U32 mID; + LLViewerPart* mLastPart; //last particle emitted (for making particle ribbons) protected: U32 mType; @@ -85,7 +86,6 @@ protected: F32 mLastPartTime; LLUUID mOwnerUUID; LLPointer<LLViewerTexture> mImagep; - // Particle information U32 mPartFlags; // Flags for the particle U32 mDelay ; //delay to start particles @@ -114,7 +114,7 @@ public: // Returns a new particle source to attach to an object... static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num); - static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp); + static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy); static LLPointer<LLViewerPartSourceScript> createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters); LLViewerTexture *getImage() const { return mImagep; } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b8b53aa6e4..62fb0ed8c1 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -44,6 +44,7 @@ #include "llagent.h" #include "llagentcamera.h" +#include "llavatarrenderinfoaccountant.h" #include "llcallingcard.h" #include "llcaphttpsender.h" #include "llcapabilitylistener.h" @@ -300,12 +301,16 @@ public: if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() ) { - llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl; + llinfos << "BaseCapabilitiesCompleteTracker " << "sim " << regionp->getName() + << " sent duplicate seed caps that differs in size - most likely content. " + << (S32) regionp->getRegionImpl()->mCapabilities.size() << " vs " << regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() + << llendl; //todo#add cap debug versus original check? - /*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin(); + /* + CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin(); while (iter!=regionp->getRegionImpl()->mCapabilities.end() ) { - llinfos<<"BaseCapabilitiesCompleteTracker Original "<<iter->first<<" "<< iter->second<<llendl; + llinfos << "BaseCapabilitiesCompleteTracker Original " << iter->first << " is " << iter->second << llendl; ++iter; } */ @@ -393,6 +398,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE + + mRenderInfoRequestTimer.resetWithExpiry(0.f); // Set timer to be expired + setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer)); } @@ -1577,6 +1585,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("AgentState"); capabilityNames.append("AttachmentResources"); capabilityNames.append("AvatarPickerSearch"); + capabilityNames.append("AvatarRenderInfo"); capabilityNames.append("CharacterProperties"); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b5fe4677b7..c442b47f6e 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -376,6 +376,8 @@ public: LLDynamicArray<U32> mMapAvatars; LLDynamicArray<LLUUID> mMapAvatarIDs; + LLFrameTimer & getRenderInfoRequestTimer() { return mRenderInfoRequestTimer; }; + private: LLViewerRegionImpl * mImpl; @@ -434,6 +436,8 @@ private: BOOL mReleaseNotesRequested; LLSD mSimulatorFeatures; + + LLFrameTimer mRenderInfoRequestTimer; }; inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ba9818946c..7d7889845d 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -52,6 +52,13 @@ #define UNIFORM_ERRS LL_ERRS("Shader") #endif +static LLStaticHashedString sTexture0("texture0"); +static LLStaticHashedString sTexture1("texture1"); +static LLStaticHashedString sTex0("tex0"); +static LLStaticHashedString sTex1("tex1"); +static LLStaticHashedString sGlowMap("glowMap"); +static LLStaticHashedString sScreenMap("screenMap"); + // Lots of STL stuff in here, using namespace std to keep things more readable using std::vector; using std::pair; @@ -304,47 +311,6 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) if (mReservedAttribs.empty()) { LLShaderMgr::initAttribsAndUniforms(); - - mAvatarUniforms.push_back("matrixPalette"); - mAvatarUniforms.push_back("gWindDir"); - mAvatarUniforms.push_back("gSinWaveParams"); - mAvatarUniforms.push_back("gGravity"); - - mWLUniforms.push_back("camPosLocal"); - - mTerrainUniforms.reserve(5); - mTerrainUniforms.push_back("detail_0"); - mTerrainUniforms.push_back("detail_1"); - mTerrainUniforms.push_back("detail_2"); - mTerrainUniforms.push_back("detail_3"); - mTerrainUniforms.push_back("alpha_ramp"); - - mGlowUniforms.push_back("glowDelta"); - mGlowUniforms.push_back("glowStrength"); - - mGlowExtractUniforms.push_back("minLuminance"); - mGlowExtractUniforms.push_back("maxExtractAlpha"); - mGlowExtractUniforms.push_back("lumWeights"); - mGlowExtractUniforms.push_back("warmthWeights"); - mGlowExtractUniforms.push_back("warmthAmount"); - - mShinyUniforms.push_back("origin"); - - mWaterUniforms.reserve(12); - mWaterUniforms.push_back("screenTex"); - mWaterUniforms.push_back("screenDepth"); - mWaterUniforms.push_back("refTex"); - mWaterUniforms.push_back("eyeVec"); - mWaterUniforms.push_back("time"); - mWaterUniforms.push_back("d1"); - mWaterUniforms.push_back("d2"); - mWaterUniforms.push_back("lightDir"); - mWaterUniforms.push_back("specular"); - mWaterUniforms.push_back("lightExp"); - mWaterUniforms.push_back("fogCol"); - mWaterUniforms.push_back("kd"); - mWaterUniforms.push_back("refScale"); - mWaterUniforms.push_back("waterHeight"); } } @@ -915,7 +881,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment() gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); gTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; - success = gTerrainProgram.createShader(NULL, &mTerrainUniforms); + success = gTerrainProgram.createShader(NULL, NULL); } if (!success) @@ -953,7 +919,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); gWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER]; - success = gWaterProgram.createShader(NULL, &mWaterUniforms); + success = gWaterProgram.createShader(NULL, NULL); } if (success) @@ -967,7 +933,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER]; gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gUnderWaterProgram.createShader(NULL, &mWaterUniforms); + success = gUnderWaterProgram.createShader(NULL, NULL); } if (success) @@ -985,7 +951,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gTerrainWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &mTerrainUniforms); + terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL); } /// Keep track of water shader levels @@ -1034,7 +1000,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; - success = gGlowProgram.createShader(NULL, &mGlowUniforms); + success = gGlowProgram.createShader(NULL, NULL); if (!success) { LLPipeline::sRenderGlow = FALSE; @@ -1048,7 +1014,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; - success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms); + success = gGlowExtractProgram.createShader(NULL, NULL); if (!success) { LLPipeline::sRenderGlow = FALSE; @@ -1408,7 +1374,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredWaterProgram.createShader(NULL, &mWaterUniforms); + success = gDeferredWaterProgram.createShader(NULL, NULL); } if (success) @@ -1467,7 +1433,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms); + success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); } if (success) @@ -1488,7 +1454,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredTerrainProgram.createShader(NULL, &mTerrainUniforms); + success = gDeferredTerrainProgram.createShader(NULL, NULL); } if (success) @@ -1499,7 +1465,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarProgram.createShader(NULL, &mAvatarUniforms); + success = gDeferredAvatarProgram.createShader(NULL, NULL); } if (success) @@ -1519,7 +1485,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); + success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL); gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; @@ -1584,7 +1550,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms); + success = gDeferredWLSkyProgram.createShader(NULL, NULL); } if (success) @@ -1595,7 +1561,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms); + success = gDeferredWLCloudProgram.createShader(NULL, NULL); } if (success) @@ -1606,7 +1572,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); + success = gDeferredStarProgram.createShader(NULL, NULL); } if (success) @@ -1957,7 +1923,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); + success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL); } if (success) @@ -1974,7 +1940,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); + success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL); } if (success) @@ -1990,7 +1956,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); + success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL); } if (success) @@ -2008,7 +1974,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); + success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL); } if (success) @@ -2087,12 +2053,11 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; success = gObjectBumpProgram.createShader(NULL, NULL); - if (success) { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1 gObjectBumpProgram.bind(); - gObjectBumpProgram.uniform1i("texture0", 0); - gObjectBumpProgram.uniform1i("texture1", 1); + gObjectBumpProgram.uniform1i(sTexture0, 0); + gObjectBumpProgram.uniform1i(sTexture1, 1); gObjectBumpProgram.unbind(); } } @@ -2241,7 +2206,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gObjectShinyProgram.createShader(NULL, &mShinyUniforms); + success = gObjectShinyProgram.createShader(NULL, NULL); } if (success) @@ -2258,7 +2223,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyWaterProgram.createShader(NULL, &mShinyUniforms); + success = gObjectShinyWaterProgram.createShader(NULL, NULL); } if (success) @@ -2274,7 +2239,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); + success = gObjectFullbrightShinyProgram.createShader(NULL, NULL); } if (success) @@ -2292,7 +2257,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); + success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); } if (mVertexShaderLevel[SHADER_AVATAR] > 0) @@ -2377,7 +2342,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); + success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL); } if (success) @@ -2394,7 +2359,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms); + success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL); } if (success) @@ -2451,7 +2416,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); + success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); } if (success) @@ -2470,7 +2435,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, &mShinyUniforms); + success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL); } } @@ -2511,7 +2476,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); gAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarProgram.createShader(NULL, &mAvatarUniforms); + success = gAvatarProgram.createShader(NULL, NULL); if (success) { @@ -2530,7 +2495,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() // Note: no cloth under water: gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1); gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gAvatarWaterProgram.createShader(NULL, &mAvatarUniforms); + success = gAvatarWaterProgram.createShader(NULL, NULL); } /// Keep track of avatar levels @@ -2549,7 +2514,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarPickProgram.createShader(NULL, &mAvatarUniforms); + success = gAvatarPickProgram.createShader(NULL, NULL); } if (success) @@ -2651,7 +2616,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { gSplatTextureRectProgram.bind(); - gSplatTextureRectProgram.uniform1i("screenMap", 0); + gSplatTextureRectProgram.uniform1i(sScreenMap, 0); gSplatTextureRectProgram.unbind(); } } @@ -2667,8 +2632,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { gGlowCombineProgram.bind(); - gGlowCombineProgram.uniform1i("glowMap", 0); - gGlowCombineProgram.uniform1i("screenMap", 1); + gGlowCombineProgram.uniform1i(sGlowMap, 0); + gGlowCombineProgram.uniform1i(sScreenMap, 1); gGlowCombineProgram.unbind(); } } @@ -2684,8 +2649,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { gGlowCombineFXAAProgram.bind(); - gGlowCombineFXAAProgram.uniform1i("glowMap", 0); - gGlowCombineFXAAProgram.uniform1i("screenMap", 1); + gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0); + gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1); gGlowCombineFXAAProgram.unbind(); } } @@ -2702,8 +2667,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { gTwoTextureAddProgram.bind(); - gTwoTextureAddProgram.uniform1i("tex0", 0); - gTwoTextureAddProgram.uniform1i("tex1", 1); + gTwoTextureAddProgram.uniform1i(sTex0, 0); + gTwoTextureAddProgram.uniform1i(sTex1, 1); } } @@ -2718,7 +2683,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { gOneTextureNoColorProgram.bind(); - gOneTextureNoColorProgram.uniform1i("tex0", 0); + gOneTextureNoColorProgram.uniform1i(sTex0, 0); } } @@ -2733,7 +2698,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { gSolidColorProgram.bind(); - gSolidColorProgram.uniform1i("tex0", 0); + gSolidColorProgram.uniform1i(sTex0, 0); gSolidColorProgram.unbind(); } } @@ -2817,7 +2782,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); gWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gWLSkyProgram.createShader(NULL, &mWLUniforms); + success = gWLSkyProgram.createShader(NULL, NULL); } if (success) @@ -2829,7 +2794,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); gWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gWLCloudProgram.createShader(NULL, &mWLUniforms); + success = gWLCloudProgram.createShader(NULL, NULL); } return success; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e3d28f2f5c..75173653e6 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -74,56 +74,7 @@ public: SHADER_COUNT }; - typedef enum - { - SHINY_ORIGIN = END_RESERVED_UNIFORMS - } eShinyUniforms; - - typedef enum - { - WATER_SCREENTEX = END_RESERVED_UNIFORMS, - WATER_SCREENDEPTH, - WATER_REFTEX, - WATER_EYEVEC, - WATER_TIME, - WATER_WAVE_DIR1, - WATER_WAVE_DIR2, - WATER_LIGHT_DIR, - WATER_SPECULAR, - WATER_SPECULAR_EXP, - WATER_FOGCOLOR, - WATER_FOGDENSITY, - WATER_REFSCALE, - WATER_WATERHEIGHT, - } eWaterUniforms; - - typedef enum - { - WL_CAMPOSLOCAL = END_RESERVED_UNIFORMS, - WL_WATERHEIGHT - } eWLUniforms; - - typedef enum - { - TERRAIN_DETAIL0 = END_RESERVED_UNIFORMS, - TERRAIN_DETAIL1, - TERRAIN_DETAIL2, - TERRAIN_DETAIL3, - TERRAIN_ALPHARAMP - } eTerrainUniforms; - - typedef enum - { - GLOW_DELTA = END_RESERVED_UNIFORMS - } eGlowUniforms; - - typedef enum - { - AVATAR_MATRIX = END_RESERVED_UNIFORMS, - AVATAR_WIND, - AVATAR_SINWAVE, - AVATAR_GRAVITY, - } eAvatarUniforms; + // simple model of forward iterator // http://www.sgi.com/tech/stl/ForwardIterator.html @@ -176,23 +127,6 @@ public: /* virtual */ void updateShaderUniforms(LLGLSLShader * shader); private: - - std::vector<std::string> mShinyUniforms; - - //water parameters - std::vector<std::string> mWaterUniforms; - - std::vector<std::string> mWLUniforms; - - //terrain parameters - std::vector<std::string> mTerrainUniforms; - - //glow parameters - std::vector<std::string> mGlowUniforms; - - std::vector<std::string> mGlowExtractUniforms; - - std::vector<std::string> mAvatarUniforms; // the list of shaders we need to propagate parameters to. std::vector<LLGLSLShader *> mShaderList; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d2af48f528..b70eae791c 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -558,15 +558,17 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) llassert_always(mInitialized) ; llassert(image); if (image->isInImageList()) - { - llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl; + { // Flag is already set? + llwarns << "LLViewerTextureList::addImageToList - image " << image->getID() << " already in list" << llendl; } - if((mImageList.insert(image)).second != true) + else { - llerrs << "Error happens when insert image to mImageList!" << llendl ; + if((mImageList.insert(image)).second != true) + { + llwarns << "Error happens when insert image " << image->getID() << " into mImageList!" << llendl ; + } + image->setInImageList(TRUE) ; } - - image->setInImageList(TRUE) ; } void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) @@ -574,24 +576,46 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) assert_main_thread(); llassert_always(mInitialized) ; llassert(image); - if (!image->isInImageList()) + + S32 count = 0; + if (image->isInImageList()) { - llinfos << "RefCount: " << image->getNumRefs() << llendl ; + count = mImageList.erase(image) ; + if(count != 1) + { + llwarns << "Image " << image->getID() + << " had mInImageList set but mImageList.erase() returned " << count + << llendl; + } + } + else + { // Something is wrong, image is expected in list or callers should check first + llwarns << "Calling removeImageFromList() for " << image->getID() + << " but doesn't have mInImageList set" + << " ref count is " << image->getNumRefs() + << llendl; uuid_map_t::iterator iter = mUUIDMap.find(image->getID()); - if(iter == mUUIDMap.end() || iter->second != image) + if(iter == mUUIDMap.end()) { - llinfos << "Image is not in mUUIDMap!" << llendl ; + llwarns << "Image " << image->getID() << " is also not in mUUIDMap!" << llendl ; + } + else if (iter->second != image) + { + llwarns << "Image " << image->getID() << " was in mUUIDMap but with different pointer" << llendl ; + } + else + { + llwarns << "Image " << image->getID() << " was in mUUIDMap with same pointer" << llendl ; + } + count = mImageList.erase(image) ; + if(count != 0) + { // it was in the list already? + llwarns << "Image " << image->getID() + << " had mInImageList false but mImageList.erase() returned " << count + << llendl; } - llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; } - S32 count = mImageList.erase(image) ; - if(count != 1) - { - llinfos << image->getID() << llendl ; - llerrs << "Error happens when remove image from mImageList: " << count << llendl ; - } - image->setInImageList(FALSE) ; } @@ -1234,7 +1258,7 @@ S32 LLViewerTextureList::getMinVideoRamSetting() //static // Returns max setting for TextureMemory (in MB) -S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) +S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) { S32 max_texmem; if (gGLManager.mVRAM != 0) @@ -1278,7 +1302,10 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) max_texmem = llmin(max_texmem, (S32)(system_ram/2)); else max_texmem = llmin(max_texmem, (S32)(system_ram)); - + + // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise + max_texmem = llmin(max_texmem, (S32) (mem_multiplier * (F32) max_texmem)); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); return max_texmem; @@ -1291,7 +1318,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) // Initialize the image pipeline VRAM settings S32 cur_mem = gSavedSettings.getS32("TextureMemory"); F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); - S32 default_mem = getMaxVideoRamSetting(true); // recommended default + S32 default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default if (mem == 0) { mem = cur_mem > 0 ? cur_mem : default_mem; @@ -1301,10 +1328,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) mem = default_mem; } - // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise - mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem)); - - mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier)); if (mem != cur_mem) { gSavedSettings.setS32("TextureMemory", mem); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 136042620d..26dc6dcbe2 100755 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -114,7 +114,7 @@ public: void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); static S32 getMinVideoRamSetting(); - static S32 getMaxVideoRamSetting(bool get_recommended = false); + static S32 getMaxVideoRamSetting(bool get_recommended, float mem_multiplier); private: void updateImagesDecodePriorities(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index dff56be5e2..4da570960f 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -151,6 +151,7 @@ #include "lltexturecache.h" #include "lltexturefetch.h" #include "lltextureview.h" +#include "lltoast.h" #include "lltool.h" #include "lltoolbarview.h" #include "lltoolcomp.h" @@ -333,9 +334,10 @@ public: mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f ); // Draw stuff growing up from right lower corner of screen - U32 xpos = mWindow->getWorldViewWidthScaled() - 350; - U32 ypos = 64; - const U32 y_inc = 20; + S32 xpos = mWindow->getWorldViewWidthScaled() - 400; + xpos = llmax(xpos, 0); + S32 ypos = 64; + const S32 y_inc = 20; clearText(); @@ -635,6 +637,42 @@ public: LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; } + if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo")) + { + std::map<std::string, LLVOAvatar*> sorted_avs; + + std::vector<LLCharacter*>::iterator sort_iter = LLCharacter::sInstances.begin(); + while (sort_iter != LLCharacter::sInstances.end()) + { + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*sort_iter); + if (avatar && + !avatar->isDead()) // Not dead yet + { + // Stuff into a sorted map so the display is ordered + sorted_avs[avatar->getFullname()] = avatar; + } + sort_iter++; + } + + std::string trunc_name; + std::map<std::string, LLVOAvatar*>::reverse_iterator av_iter = sorted_avs.rbegin(); // Put "A" at the top + while (av_iter != sorted_avs.rend()) + { + LLVOAvatar* avatar = av_iter->second; + + avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date + + trunc_name = utf8str_truncate(avatar->getFullname(), 16); + addText(xpos, ypos, llformat("%s : rez %d, weight %d, bytes %d area %.2f", + trunc_name.c_str(), + avatar->getRezzedStatus(), + avatar->getVisualComplexity(), + avatar->getAttachmentGeometryBytes(), + avatar->getAttachmentSurfaceArea())); + ypos += y_inc; + av_iter++; + } + } if (gSavedSettings.getBOOL("DebugShowRenderMatrices")) { addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15])); @@ -1999,6 +2037,9 @@ void LLViewerWindow::shutdownViews() } llinfos << "Global views cleaned." << llendl ; + LLNotificationsUI::LLToast::cleanupToasts(); + llinfos << "Leftover toast cleaned up." << llendl; + // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open // will crump with LL_ERRS. LLModalDialog::shutdownModals(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 06fb23b84b..3c25339037 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -58,6 +58,7 @@ #include "llhudmanager.h" #include "llhudnametag.h" #include "llhudtext.h" // for mText/mDebugText +#include "llimview.h" #include "llinitparam.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" @@ -668,6 +669,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mSpecialRenderMode(0), mAttachmentGeometryBytes(0), mAttachmentSurfaceArea(0.f), + mReportedVisualComplexity(-1), + mReportedAttachmentGeometryBytes(-1), + mReportedAttachmentSurfaceArea(-1.f), mTurning(FALSE), mLastSkeletonSerialNum( 0 ), mIsSitting(FALSE), @@ -701,6 +705,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), + mVisualComplexity(0), + mVisualComplexityStale(TRUE), mLoadedCallbacksPaused(FALSE), mHasPelvisOffset( FALSE ), mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), @@ -769,6 +775,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastPelvisToFoot = 0.0f; mPelvisFixup = 0.0f; mLastPelvisFixup = 0.0f; + + mCachedVisualMute = !isSelf(); + mCachedVisualMuteUpdateTime = LLFrameTimer::getTotalSeconds() + 5.0; + mVisuallyMuteSetting = VISUAL_MUTE_NOT_SET; + + F32 color_value = (F32) (getID().mData[0]); + mMutedAVColor = calcMutedAVColor(color_value, 0, 256); } std::string LLVOAvatar::avString() const @@ -2971,14 +2984,82 @@ void LLVOAvatar::slamPosition() mRoot->updateWorldMatrixChildren(); } -bool LLVOAvatar::isVisuallyMuted() const +bool LLVOAvatar::isVisuallyMuted() { - static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); - static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); - - return LLMuteList::getInstance()->isMuted(getID()) - || (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) - || (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); + bool muted = false; + + // Priority order (highest priority first) + // * own avatar is never visually muted + // * if on the "always draw normally" list, draw them normally + // * if on the "always visually mute" list, mute them + // * draw them normally if they meet the following criteria: + // - within the closest N avatars OR on friends list OR in an IM chat + // - AND aren't over the thresholds + // * otherwise visually mute all other avatars + + if (!isSelf()) + { + static LLCachedControl<bool> render_mute_enabled(gSavedSettings, "RenderAutoMuteEnabled"); + static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); + static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); + static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderCostLimit"); + static LLCachedControl<U32> visibility_rank(gSavedSettings, "RenderAutoMuteVisibilityRank"); + + if (mVisuallyMuteSetting == ALWAYS_VISUAL_MUTE) + { // Always want to see this AV as an imposter + muted = true; + } + else if (mVisuallyMuteSetting == NEVER_VISUAL_MUTE) + { // Never show as imposter + muted = false; + } + else if (render_mute_enabled) + { + F64 now = LLFrameTimer::getTotalSeconds(); + + if (now < mCachedVisualMuteUpdateTime) + { // Use cached mute value + muted = mCachedVisualMute; + } + else + { // Determine if visually muted or not + + U32 max_cost = (U32) (max_render_cost*(LLVOAvatar::sLODFactor+0.5)); + + muted = LLMuteList::getInstance()->isMuted(getID()) || + (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || + (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) || + (mVisualComplexity > max_cost && max_render_cost > 0); + + // Could be part of the grand || collection above, but yanked out to make the logic visible + if (!muted) + { + if (visibility_rank > 0) + { // They are above the visibilty rank - mute them + muted = (mVisibilityRank > visibility_rank); + } + + if (muted || // Don't mute friends or IMs + visibility_rank == 0) + { + muted = !(LLAvatarTracker::instance().isBuddy(getID())); + if (muted) + { // Not a friend, so they are muted ... are they in an IM? + LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,getID()); + muted = !gIMMgr->hasSession(session_id); + } + } + } + + // Save visual mute state and set interval for updating + const F64 SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES = 1.5; + mCachedVisualMuteUpdateTime = now + SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES; + mCachedVisualMute = muted; + } + } + } + + return muted; } //------------------------------------------------------------------------ @@ -3076,7 +3157,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // the rest should only be done occasionally for far away avatars //-------------------------------------------------------------------- - if (visible && (!isSelf() || isVisuallyMuted()) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) + bool visually_muted = isVisuallyMuted(); + if (visible && (!isSelf() || visually_muted) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; @@ -3085,8 +3167,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); - if (isVisuallyMuted()) - { // muted avatars update at 16 hz + if (visually_muted) + { // visually muted avatars update at 16 hz mUpdatePeriod = 16; } else if (mVisibilityRank <= LLVOAvatar::sMaxVisible || @@ -3886,9 +3968,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) BOOL first_pass = TRUE; if (!LLDrawPoolAvatar::sSkipOpaque) { + bool visually_muted = isVisuallyMuted(); + if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { - if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) + if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy || visually_muted) { LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); if (head_mesh) @@ -3898,7 +3982,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) first_pass = FALSE; } } - if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) + if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy || visually_muted) { LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); if (upper_mesh) @@ -3908,7 +3992,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) first_pass = FALSE; } - if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) + if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy || visually_muted) { LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); if (lower_mesh) @@ -5480,6 +5564,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o return 0; } + mVisualComplexityStale = TRUE; + if (viewer_object->isSelected()) { LLSelectMgr::getInstance()->updateSelectionCenter(); @@ -5627,6 +5713,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) if (attachment->isObjectAttached(viewer_object)) { + mVisualComplexityStale = TRUE; cleanupAttachedMesh( viewer_object ); attachment->removeObject(viewer_object); lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; @@ -7728,9 +7815,9 @@ void LLVOAvatar::updateImpostors() LLCharacter::sAllowInstancesChange = TRUE ; } -BOOL LLVOAvatar::isImpostor() const +BOOL LLVOAvatar::isImpostor() { - return (isVisuallyMuted() || (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; + return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; } @@ -7773,135 +7860,224 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d angle.mV[2] = da; } + void LLVOAvatar::idleUpdateRenderCost() { - static const U32 ARC_BODY_PART_COST = 200; - static const U32 ARC_LIMIT = 20000; + static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderCostLimit"); - static std::set<LLUUID> all_textures; + static const U32 ARC_LIMIT = 20000; if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES)) { //set debug text to attachment geometry bytes here so render cost will override setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea)); } - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME) && max_render_cost == 0) { return; } - U32 cost = 0; - LLVOVolume::texture_cost_t textures; + calculateUpdateRenderCost(); // Update mVisualComplexity if needed + + doRenderCostNagging(max_render_cost); // Remind the user their AV is too complex - for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) + { + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + setDebugText(llformat("%s %d", viz_string.c_str(), mVisualComplexity)); + F32 green = 1.f-llclamp(((F32) mVisualComplexity-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); + F32 red = llmin((F32) mVisualComplexity/(F32)ARC_LIMIT, 1.f); + mText->setColor(LLColor4(red,green,0,1)); + } +} + + +// Remind the user about their expensive avatar +void LLVOAvatar::doRenderCostNagging(U32 max_render_cost) +{ + if (isSelf()) { - const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); - ETextureIndex tex_index = baked_dict->mTextureIndex; - if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) + static S32 sOldComplexity = 0; + static F64 sLastRenderCostNagTime = 0.0; + + const F64 RENDER_NAG_INTERVAL = 60.0; + + F64 now = LLFrameTimer::getTotalSeconds(); + if (sLastRenderCostNagTime > 0.0 && + (now - sLastRenderCostNagTime) > RENDER_NAG_INTERVAL && + sOldComplexity != mVisualComplexity) { - if (isTextureVisible(tex_index)) - { - cost +=ARC_BODY_PART_COST; + sOldComplexity = mVisualComplexity; + + if (max_render_cost > 0) + { //pop up notification that you have exceeded a render cost limit + if (mVisualComplexity > max_render_cost+max_render_cost/2) + { + LLNotificationsUtil::add("ExceededHighDetailRenderCost"); + sLastRenderCostNagTime = now; + } + else if (mVisualComplexity > max_render_cost) + { + LLNotificationsUtil::add("ExceededMidDetailRenderCost"); + sLastRenderCostNagTime = now; + } + else if (mVisualComplexity > max_render_cost/2) + { + LLNotificationsUtil::add("ExceededLowDetailRenderCost"); + sLastRenderCostNagTime = now; + } } } } +} - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) +// Calculations for mVisualComplexity value +void LLVOAvatar::calculateUpdateRenderCost() +{ + static const U32 ARC_BODY_PART_COST = 200; + + // Diagnostic list of all textures on our avatar + static std::set<LLUUID> all_textures; + + if (mVisualComplexityStale) { - LLViewerJointAttachment* attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + mVisualComplexityStale = FALSE; + U32 cost = 0; + LLVOVolume::texture_cost_t textures; + + for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) + const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); + ETextureIndex tex_index = baked_dict->mTextureIndex; + if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) { - textures.clear(); - const LLDrawable* drawable = attached_object->mDrawable; - if (drawable) + if (isTextureVisible(tex_index)) { - const LLVOVolume* volume = drawable->getVOVolume(); - if (volume) - { - cost += volume->getRenderCost(textures); + cost +=ARC_BODY_PART_COST; + } + } + } + - const_child_list_t children = volume->getChildren(); - for (const_child_list_t::const_iterator child_iter = children.begin(); - child_iter != children.end(); - ++child_iter) + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) + { + textures.clear(); + const LLDrawable* drawable = attached_object->mDrawable; + if (drawable) + { + const LLVOVolume* volume = drawable->getVOVolume(); + if (volume) { - LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); - if (child) + cost += volume->getRenderCost(textures); + + const_child_list_t children = volume->getChildren(); + for (const_child_list_t::const_iterator child_iter = children.begin(); + child_iter != children.end(); + ++child_iter) { - cost += child->getRenderCost(textures); + LLViewerObject* child_obj = *child_iter; + LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); + if (child) + { + cost += child->getRenderCost(textures); + } } - } - for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) - { - // add the cost of each individual texture in the linkset - cost += iter->second; + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += iter->second; + } } } } } - } - - } - + } - // Diagnostic output to identify all avatar-related textures. - // Does not affect rendering cost calculation. - // Could be wrapped in a debug option if output becomes problematic. - if (isSelf()) - { - // print any attachment textures we didn't already know about. - for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) + // Diagnostic output to identify all avatar-related textures. + // Does not affect rendering cost calculation. + // Could be wrapped in a debug option if output becomes problematic. + if (isSelf()) { - LLUUID image_id = it->first; - if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - continue; - if (all_textures.find(image_id) == all_textures.end()) + // print any attachment textures we didn't already know about. + for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) { - // attachment texture not previously seen. - llinfos << "attachment_texture: " << image_id.asString() << llendl; - all_textures.insert(image_id); + LLUUID image_id = it->first; + if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + continue; + if (all_textures.find(image_id) == all_textures.end()) + { + // attachment texture not previously seen. + llinfos << "attachment_texture: " << image_id.asString() << llendl; + all_textures.insert(image_id); + } } - } - // print any avatar textures we didn't already know about - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); + // print any avatar textures we didn't already know about + for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); - ++iter) - { - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - // TODO: MULTI-WEARABLE: handle multiple textures for self - const LLViewerTexture* te_image = getImage(iter->first,0); - if (!te_image) - continue; - LLUUID image_id = te_image->getID(); - if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - continue; - if (all_textures.find(image_id) == all_textures.end()) + ++iter) { - llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; - all_textures.insert(image_id); + const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; + // TODO: MULTI-WEARABLE: handle multiple textures for self + const LLViewerTexture* te_image = getImage(iter->first,0); + if (!te_image) + continue; + LLUUID image_id = te_image->getID(); + if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + continue; + if (all_textures.find(image_id) == all_textures.end()) + { + llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; + all_textures.insert(image_id); + } } } + + mVisualComplexity = 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); - mText->setColor(LLColor4(red,green,0,1)); + +// static +LLColor4 LLVOAvatar::calcMutedAVColor(F32 value, S32 range_low, S32 range_high) +{ + F32 clamped_value = llmin(value, (F32) range_high); + clamped_value = llmax(value, (F32) range_low); + F32 spectrum = (clamped_value / range_high); // spectrum is between 0 and 1.f + + // Array of colors. These are arranged so only one RGB color changes between each step, + // and it loops back to red so there is an even distribution. It is not a heat map + const S32 NUM_SPECTRUM_COLORS = 7; + static LLColor4 * spectrum_color[NUM_SPECTRUM_COLORS] = { &LLColor4::red, &LLColor4::magenta, &LLColor4::blue, &LLColor4::cyan, &LLColor4::green, &LLColor4::yellow, &LLColor4::red }; + + spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1); // Scale to range of number of colors + S32 spectrum_index_1 = floor(spectrum); // Desired color will be after this index + S32 spectrum_index_2 = spectrum_index_1 + 1; // and before this index (inclusive) + F32 fractBetween = spectrum - (F32)(spectrum_index_1); // distance between the two indexes (0-1) + + LLColor4 new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween); + new_color.normalize(); + new_color *= 0.9f; + + //llinfos << "From value " << std::setprecision(3) << value << " returning color " << new_color + // << " using indexes " << spectrum_index_1 << ", " << spectrum_index_2 + // << " and fractBetween " << fractBetween + // << llendl; + + return new_color; } // static diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 85f6f25009..8862056066 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -250,6 +250,25 @@ public: static void invalidateNameTags(); void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); void idleUpdateRenderCost(); + void doRenderCostNagging(U32 max_render_cost); + void calculateUpdateRenderCost(); + void updateVisualComplexity() { mVisualComplexityStale = TRUE; } + + S32 getVisualComplexity() { return mVisualComplexity; }; // Numbers calculated here by rendering AV + S32 getAttachmentGeometryBytes() { return mAttachmentGeometryBytes; }; // number of bytes in attached geometry + F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; }; // estimated surface area of attachments + + S32 getReportedVisualComplexity() { return mReportedVisualComplexity; }; // Numbers as reported by the SL server + void setReportedVisualComplexity(S32 value) { mReportedVisualComplexity = value; }; + S32 getReportedAttachmentGeometryBytes() { return mReportedAttachmentGeometryBytes; }; //number of bytes in attached geometry + void setReportedAttachmentGeometryBytes(S32 value) { mReportedAttachmentGeometryBytes = value; }; + F32 getReportedAttachmentSurfaceArea() { return mReportedAttachmentSurfaceArea; }; //estimated surface area of attachments + void setReportedAttachmentSurfaceArea(F32 value) { mReportedAttachmentSurfaceArea = value; }; + + S32 getUpdatePeriod() { return mUpdatePeriod; }; + const LLColor4 & getMutedAVColor() { return mMutedAVColor; }; + + void idleUpdateBelowWater(); //-------------------------------------------------------------------- @@ -303,12 +322,15 @@ public: static void logPendingPhasesAllAvatars(); void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed); + static LLColor4 calcMutedAVColor(F32 value, S32 range_low, S32 range_high); + protected: LLViewerStats::PhaseMap& getPhases() { return mPhases; } BOOL updateIsFullyLoaded(); BOOL processFullyLoadedChange(bool loading); void updateRuthTimer(bool loading); F32 calcMorphAmount(); + private: BOOL mFirstFullyVisible; BOOL mFullyLoaded; @@ -316,6 +338,8 @@ private: BOOL mFullyLoadedInitialized; S32 mFullyLoadedFrameCounter; S32 mVisualComplexity; + BOOL mVisualComplexityStale; + LLColor4 mMutedAVColor; LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; @@ -369,7 +393,16 @@ public: public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); - bool isVisuallyMuted() const; + bool isVisuallyMuted(); + + enum VisualMuteSettings + { + VISUAL_MUTE_NOT_SET = 0, + ALWAYS_VISUAL_MUTE = 1, + NEVER_VISUAL_MUTE = 2 + }; + void setVisualMuteSettings(VisualMuteSettings set) { mVisuallyMuteSetting = set; }; + VisualMuteSettings getVisualMuteSettings() { return mVisuallyMuteSetting; }; U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); @@ -380,9 +413,13 @@ public: static void destroyGL(); static void restoreGL(); S32 mSpecialRenderMode; // special lighting - U32 mAttachmentGeometryBytes; //number of bytes in attached geometry + S32 mAttachmentGeometryBytes; //number of bytes in attached geometry F32 mAttachmentSurfaceArea; //estimated surface area of attachments + S32 mReportedVisualComplexity; // Numbers as reported by the SL server + S32 mReportedAttachmentGeometryBytes; //number of bytes in attached geometry + F32 mReportedAttachmentSurfaceArea; //estimated surface area of attachments + private: bool shouldAlphaMask(); @@ -392,6 +429,11 @@ private: S32 mUpdatePeriod; S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer. + bool mCachedVisualMute; // cached return value for isVisuallyMuted() + F64 mCachedVisualMuteUpdateTime; // Time to update mCachedVisualMute + + VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV + //-------------------------------------------------------------------- // Morph masks //-------------------------------------------------------------------- @@ -430,7 +472,7 @@ private: // Impostors //-------------------------------------------------------------------- public: - BOOL isImpostor() const; + BOOL isImpostor(); BOOL needsImpostorUpdate() const; const LLVector3& getImpostorOffset() const; const LLVector2& getImpostorDim() const; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 6a25b765cf..f40d55161f 100755 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -476,6 +476,7 @@ void LLVOGrass::getGeometry(S32 idx, LLStrider<LLVector3>& normalsp, LLStrider<LLVector2>& texcoordsp, LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& emissivep, LLStrider<U16>& indicesp) { if(!mNumBlades)//stop rendering grass @@ -708,7 +709,11 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) facep->setIndicesIndex(index_count); facep->setVertexBuffer(buffer); facep->setPoolType(LLDrawPool::POOL_ALPHA); - object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); + + //dummy parameter (unused by this implementation) + LLStrider<LLColor4U> emissivep; + + object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, emissivep, indicesp); vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index b9835b8802..1fe9990cea 100755 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -63,6 +63,7 @@ public: LLStrider<LLVector3>& normalsp, LLStrider<LLVector2>& texcoordsp, LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& emissivep, LLStrider<U16>& indicesp); void updateFaceSize(S32 idx) { } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 9b5d981aa5..abead02174 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -532,25 +532,25 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries) { LLViewerRegion *region = gAgent.getRegion(); - if ( region && (mVoiceEnabled || !mIsInitialized)) + // If we've not received the capability yet, return. + // the password will remain empty, so we'll remain in + // stateIdle + if ( region && + region->capabilitiesReceived() && + (mVoiceEnabled || !mIsInitialized)) { std::string url = region->getCapability("ProvisionVoiceAccountRequest"); - if ( url.empty() ) + if ( !url.empty() ) { - // we've not received the capability yet, so return. - // the password will remain empty, so we'll remain in - // stateIdle - return; - } - - LLHTTPClient::post( - url, - LLSD(), - new LLVivoxVoiceAccountProvisionResponder(retries)); + LLHTTPClient::post( + url, + LLSD(), + new LLVivoxVoiceAccountProvisionResponder(retries)); - setState(stateConnectorStart); + setState(stateConnectorStart); + } } } @@ -7660,6 +7660,9 @@ void LLVivoxProtocolParser::processResponse(std::string tag) */ // We don't need to process this, but we also shouldn't warn on it, since that confuses people. } + else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent")) + { // Yet another ignored event + } else { LL_WARNS("VivoxProtocolParser") << "Unknown event type " << eventTypeString << LL_ENDL; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index e67e2ab7f4..99b3accda8 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -49,17 +49,11 @@ const F32 MAX_PART_LIFETIME = 120.f; extern U64 gFrameTime; LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL; -S32 LLVOPartGroup::sVBSlotFree[]; -S32* LLVOPartGroup::sVBSlotCursor = NULL; +S32 LLVOPartGroup::sVBSlotCursor = 0; void LLVOPartGroup::initClass() { - for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i) - { - sVBSlotFree[i] = i; - } - - sVBSlotCursor = sVBSlotFree; + } //static @@ -122,36 +116,33 @@ void LLVOPartGroup::destroyGL() //static S32 LLVOPartGroup::findAvailableVBSlot() { - if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT) + if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT) { //no more available slots return -1; } - S32 ret = *sVBSlotCursor; - sVBSlotCursor++; - - return ret; + return sVBSlotCursor++; } bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) { - while (start < end) + /*while (start < end) { if (*start == idx) { //not allocated (in free list) return false; } ++start; - } + }*/ //allocated (not in free list) - return true; + return false; } //static void LLVOPartGroup::freeVBSlot(S32 idx) { - llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); + /*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); //llassert(sVBSlotCursor > sVBSlotFree); //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); @@ -159,7 +150,7 @@ void LLVOPartGroup::freeVBSlot(S32 idx) { sVBSlotCursor--; *sVBSlotCursor = idx; - } + }*/ } LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -189,6 +180,7 @@ F32 LLVOPartGroup::getBinRadius() void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { const LLVector3& pos_agent = getPositionAgent(); + newMin.load3( (pos_agent - mScale).mV); newMax.load3( (pos_agent + mScale).mV); LLVector4a pos; @@ -273,6 +265,16 @@ F32 LLVOPartGroup::getPartSize(S32 idx) return 0.f; } +void LLVOPartGroup::getBlendFunc(S32 idx, U32& src, U32& dst) +{ + if (idx < (S32) mViewerPartGroupp->mParticles.size()) + { + LLViewerPart* part = mViewerPartGroupp->mParticles[idx]; + src = part->mBlendFuncSource; + dst = part->mBlendFuncDest; + } +} + LLVector3 LLVOPartGroup::getCameraPosition() const { return gAgentCamera.getCameraPositionAgent(); @@ -332,13 +334,42 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) mDepth = 0.f; S32 i = 0 ; LLVector3 camera_agent = getCameraPosition(); + + F32 max_scale = 0.f; + + for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; + + //remember the largest particle + max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]); + + if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK) + { //include ribbon segment length in scale + const LLVector3* pos_agent = NULL; + if (part->mParent) + { + pos_agent = &(part->mParent->mPosAgent); + } + else if (part->mPartSourcep.notNull()) + { + pos_agent = &(part->mPartSourcep->mPosAgent); + } + + if (pos_agent) + { + F32 dist = (*pos_agent-part->mPosAgent).length(); + + max_scale = llmax(max_scale, dist); + } + } + LLVector3 part_pos_agent(part->mPosAgent); LLVector3 at(part_pos_agent - camera_agent); + F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; if (camera_dist_squared > 1.f) @@ -411,6 +442,9 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) facep->setSize(0, 0); } + //record max scale (used to stretch bounding box for visibility culling) + mScale.set(max_scale, max_scale, max_scale); + mDrawable->movePartition(); LLPipeline::sCompiles++; return TRUE; @@ -478,74 +512,129 @@ BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector3& start, const LLVector3 void LLVOPartGroup::getGeometry(const LLViewerPart& part, LLStrider<LLVector4a>& verticesp) { - LLVector4a part_pos_agent; - part_pos_agent.load3(part.mPosAgent.mV); - LLVector4a camera_agent; - camera_agent.load3(getCameraPosition().mV); - LLVector4a at; - at.setSub(part_pos_agent, camera_agent); - LLVector4a up(0, 0, 1); - LLVector4a right; - - right.setCross3(at, up); - right.normalize3fast(); - up.setCross3(right, at); - up.normalize3fast(); - - if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK) + if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK) { - LLVector4a normvel; - normvel.load3(part.mVelocity.mV); - normvel.normalize3fast(); - LLVector2 up_fracs; - up_fracs.mV[0] = normvel.dot3(right).getF32(); - up_fracs.mV[1] = normvel.dot3(up).getF32(); - up_fracs.normalize(); - LLVector4a new_up; - LLVector4a new_right; - - //new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up; - LLVector4a t = right; - t.mul(up_fracs.mV[0]); - new_up = up; - new_up.mul(up_fracs.mV[1]); - new_up.add(t); - - //new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up; - t = right; - t.mul(up_fracs.mV[1]); - new_right = up; - new_right.mul(up_fracs.mV[0]); - t.sub(new_right); - - up = new_up; - right = t; - up.normalize3fast(); - right.normalize3fast(); + LLVector4a axis, pos, paxis, ppos; + F32 scale, pscale; + + pos.load3(part.mPosAgent.mV); + axis.load3(part.mAxis.mV); + scale = part.mScale.mV[0]; + + if (part.mParent) + { + ppos.load3(part.mParent->mPosAgent.mV); + paxis.load3(part.mParent->mAxis.mV); + pscale = part.mParent->mScale.mV[0]; + } + else + { //use source object as position + + if (part.mPartSourcep->mSourceObjectp.notNull()) + { + LLVector3 v = LLVector3(0,0,1); + v *= part.mPartSourcep->mSourceObjectp->getRenderRotation(); + paxis.load3(v.mV); + ppos.load3(part.mPartSourcep->mPosAgent.mV); + pscale = part.mStartScale.mV[0]; + } + else + { //no source object, no parent, nothing to draw + ppos = pos; + pscale = scale; + paxis = axis; + } + } + + LLVector4a p0, p1, p2, p3; + + scale *= 0.5f; + pscale *= 0.5f; + + axis.mul(scale); + paxis.mul(pscale); + + p0.setAdd(pos, axis); + p1.setSub(pos,axis); + p2.setAdd(ppos, paxis); + p3.setSub(ppos, paxis); + + (*verticesp++) = p2; + (*verticesp++) = p3; + (*verticesp++) = p0; + (*verticesp++) = p1; } + else + { + LLVector4a part_pos_agent; + part_pos_agent.load3(part.mPosAgent.mV); + LLVector4a camera_agent; + camera_agent.load3(getCameraPosition().mV); + LLVector4a at; + at.setSub(part_pos_agent, camera_agent); + LLVector4a up(0, 0, 1); + LLVector4a right; + + right.setCross3(at, up); + right.normalize3fast(); + up.setCross3(right, at); + up.normalize3fast(); - right.mul(0.5f*part.mScale.mV[0]); - up.mul(0.5f*part.mScale.mV[1]); + if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK) + { + LLVector4a normvel; + normvel.load3(part.mVelocity.mV); + normvel.normalize3fast(); + LLVector2 up_fracs; + up_fracs.mV[0] = normvel.dot3(right).getF32(); + up_fracs.mV[1] = normvel.dot3(up).getF32(); + up_fracs.normalize(); + LLVector4a new_up; + LLVector4a new_right; + + //new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up; + LLVector4a t = right; + t.mul(up_fracs.mV[0]); + new_up = up; + new_up.mul(up_fracs.mV[1]); + new_up.add(t); + + //new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up; + t = right; + t.mul(up_fracs.mV[1]); + new_right = up; + new_right.mul(up_fracs.mV[0]); + t.sub(new_right); + + up = new_up; + right = t; + up.normalize3fast(); + right.normalize3fast(); + } + right.mul(0.5f*part.mScale.mV[0]); + up.mul(0.5f*part.mScale.mV[1]); - //HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) - // this works because there is actually a 4th float stored after the vertex position which is used as a texture index - // also, somebody please VECTORIZE THIS - LLVector4a ppapu; - LLVector4a ppamu; + //HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) + // this works because there is actually a 4th float stored after the vertex position which is used as a texture index + // also, somebody please VECTORIZE THIS - ppapu.setAdd(part_pos_agent, up); - ppamu.setSub(part_pos_agent, up); + LLVector4a ppapu; + LLVector4a ppamu; - verticesp->setSub(ppapu, right); - (*verticesp++).getF32ptr()[3] = 0.f; - verticesp->setSub(ppamu, right); - (*verticesp++).getF32ptr()[3] = 0.f; - verticesp->setAdd(ppapu, right); - (*verticesp++).getF32ptr()[3] = 0.f; - verticesp->setAdd(ppamu, right); - (*verticesp++).getF32ptr()[3] = 0.f; + ppapu.setAdd(part_pos_agent, up); + ppamu.setSub(part_pos_agent, up); + + verticesp->setSub(ppapu, right); + (*verticesp++).getF32ptr()[3] = 0.f; + verticesp->setSub(ppamu, right); + (*verticesp++).getF32ptr()[3] = 0.f; + verticesp->setAdd(ppapu, right); + (*verticesp++).getF32ptr()[3] = 0.f; + verticesp->setAdd(ppamu, right); + (*verticesp++).getF32ptr()[3] = 0.f; + } } @@ -555,6 +644,7 @@ void LLVOPartGroup::getGeometry(S32 idx, LLStrider<LLVector3>& normalsp, LLStrider<LLVector2>& texcoordsp, LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& emissivep, LLStrider<U16>& indicesp) { if (idx >= (S32) mViewerPartGroupp->mParticles.size()) @@ -566,10 +656,40 @@ void LLVOPartGroup::getGeometry(S32 idx, getGeometry(part, verticesp); - *colorsp++ = part.mColor; - *colorsp++ = part.mColor; - *colorsp++ = part.mColor; - *colorsp++ = part.mColor; + LLColor4U pcolor; + LLColor4U color = part.mColor; + + LLColor4U pglow; + + if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK) + { //make sure color blends properly + if (part.mParent) + { + pglow = part.mParent->mGlow; + pcolor = part.mParent->mColor; + } + else + { + pglow = LLColor4U(0, 0, 0, (U8) (255.f*part.mStartGlow)); + pcolor = part.mStartColor; + } + } + else + { + pglow = part.mGlow; + pcolor = color; + } + + *colorsp++ = pcolor; + *colorsp++ = pcolor; + *colorsp++ = color; + *colorsp++ = color; + + *emissivep++ = pglow; + *emissivep++ = pglow; + *emissivep++ = part.mGlow; + *emissivep++ = part.mGlow; + if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)) { //not fullbright, needs normal @@ -712,10 +832,13 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLStrider<LLVector3> normalsp; LLStrider<LLVector2> texcoordsp; LLStrider<LLColor4U> colorsp; + LLStrider<LLColor4U> emissivep; buffer->getVertexStrider(verticesp); buffer->getNormalStrider(normalsp); buffer->getColorStrider(colorsp); + buffer->getEmissiveStrider(emissivep); + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; @@ -724,7 +847,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLFace* facep = *i; LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); - if (!facep->isState(LLFace::PARTICLE)) + //if (!facep->isState(LLFace::PARTICLE)) { //set the indices of this face S32 idx = LLVOPartGroup::findAvailableVBSlot(); if (idx >= 0) @@ -733,7 +856,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) facep->setIndicesIndex(idx*6); facep->setVertexBuffer(LLVOPartGroup::sVB); facep->setPoolType(LLDrawPool::POOL_ALPHA); - facep->setState(LLFace::PARTICLE); + //facep->setState(LLFace::PARTICLE); } else { @@ -748,8 +871,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLStrider<LLVector3> cur_norm = normalsp + geom_idx; LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx; LLStrider<LLColor4U> cur_col = colorsp + geom_idx; + LLStrider<LLColor4U> cur_glow = emissivep + geom_idx; - object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx); + object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx); llassert(facep->getGeomCount() == 4); llassert(facep->getIndicesCount() == 6); @@ -765,9 +889,16 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) bool batched = false; + U32 bf_src = LLRender::BF_SOURCE_ALPHA; + U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + + object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst); + if (idx >= 0 && draw_vec[idx]->mTexture == facep->getTexture() && - draw_vec[idx]->mFullbright == fullbright) + draw_vec[idx]->mFullbright == fullbright && + draw_vec[idx]->mBlendFuncDst == bf_dst && + draw_vec[idx]->mBlendFuncSrc == bf_src) { if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1) { @@ -799,6 +930,8 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) info->mExtents[0] = group->mObjectExtents[0]; info->mExtents[1] = group->mObjectExtents[1]; info->mVSize = vsize; + info->mBlendFuncDst = bf_dst; + info->mBlendFuncSrc = bf_src; draw_vec.push_back(info); //for alpha sorting facep->setDrawInfo(info); diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index ce05a0282e..3c2e0344a2 100755 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -42,8 +42,7 @@ public: //vertex buffer for holding all particles static LLPointer<LLVertexBuffer> sVB; - static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT]; - static S32* sVBSlotCursor; + static S32 sVBSlotCursor; static void initClass(); static void restoreGL(); @@ -57,6 +56,7 @@ public: LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_EMISSIVE | LLVertexBuffer::MAP_TEXTURE_INDEX }; @@ -91,10 +91,12 @@ public: LLStrider<LLVector3>& normalsp, LLStrider<LLVector2>& texcoordsp, LLStrider<LLColor4U>& colorsp, + LLStrider<LLColor4U>& emissivep, LLStrider<U16>& indicesp); void updateFaceSize(S32 idx) { } F32 getPartSize(S32 idx); + void getBlendFunc(S32 idx, U32& src, U32& dst); LLUUID getPartOwner(S32 idx); LLUUID getPartSource(S32 idx); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cac6d4939b..00a109546e 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -99,6 +99,8 @@ static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles"); static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes"); static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures"); +extern BOOL gGLDebugLoggingEnabled; + // Implementation class of LLMediaDataClientObject. See llmediadataclient.h class LLMediaDataClientObjectImpl : public LLMediaDataClientObject { @@ -382,7 +384,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } else { - // CORY TO DO: Figure out how to get the value here if (update_type != OUT_TERSE_IMPROVED) { LLVolumeParams volume_params; @@ -451,6 +452,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, mFaceMappingChanged = TRUE; mTexAnimMode = 0; } + + if (value & 0x400) + { //particle system (new) + unpackParticleSource(*dp, mOwnerID, false); + } } else { @@ -1049,8 +1055,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } } - - + static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && @@ -1067,7 +1072,9 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo break; } volume->genBinormals(i); + //gGLDebugLoggingEnabled = TRUE; LLFace::cacheFaceInVRAM(face); + //gGLDebugLoggingEnabled = FALSE; } } @@ -1116,6 +1123,12 @@ void LLVOVolume::notifyMeshLoaded() { mSculptChanged = TRUE; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE); + + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + avatar->updateVisualComplexity(); + } } // sculpt replaces generate() for sculpted surfaces @@ -1144,28 +1157,38 @@ void LLVOVolume::sculpt() S32 current_discard = getVolume()->getSculptLevel() ; if(current_discard < -2) { - static S32 low_sculpty_discard_warning_count = 100; - if (++low_sculpty_discard_warning_count >= 100) - { // Log first time, then every 100 afterwards otherwise this can flood the logs + static S32 low_sculpty_discard_warning_count = 1; + S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) )); + S32 interval = pow(10.0, exponent); + if ( low_sculpty_discard_warning_count < 10 || + (low_sculpty_discard_warning_count % interval) == 0) + { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() << " at " << current_discard - << " is less than -2." << llendl; - low_sculpty_discard_warning_count = 0; + << " is less than -2." + << " Hit this " << low_sculpty_discard_warning_count << " times" + << llendl; } + low_sculpty_discard_warning_count++; // corrupted volume... don't update the sculpty return; } else if (current_discard > MAX_DISCARD_LEVEL) { - static S32 high_sculpty_discard_warning_count = 100; - if (++high_sculpty_discard_warning_count >= 100) - { // Log first time, then every 100 afterwards otherwise this can flood the logs + static S32 high_sculpty_discard_warning_count = 1; + S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) )); + S32 interval = pow(10.0, exponent); + if ( high_sculpty_discard_warning_count < 10 || + (high_sculpty_discard_warning_count % interval) == 0) + { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() << " at " << current_discard - << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; - high_sculpty_discard_warning_count = 0; + << " is more than than allowed max of " << MAX_DISCARD_LEVEL + << ". Hit this " << high_sculpty_discard_warning_count << " times" + << llendl; } + high_sculpty_discard_warning_count++; // corrupted volume... don't update the sculpty return; @@ -1258,7 +1281,7 @@ BOOL LLVOVolume::calcLOD() else { distance = mDrawable->mDistanceWRTCamera; - radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length(); + radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); } //hold onto unmodified distance for debugging @@ -1288,7 +1311,7 @@ BOOL LLVOVolume::calcLOD() { //setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); - setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex())); + //setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex())); } if (cur_detail != mLOD) @@ -2980,7 +3003,7 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p //transform view vector into volume space view_vector -= getRenderPosition(); - mDrawable->mDistanceWRTCamera = view_vector.length(); + //mDrawable->mDistanceWRTCamera = view_vector.length(); LLQuaternion worldRot = getRenderRotation(); view_vector = view_vector * ~worldRot; if (!isVolumeGlobal()) @@ -3836,10 +3859,13 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //build matrix palette - LLMatrix4a mp[64]; + static const size_t kMaxJoints = 64; + + LLMatrix4a mp[kMaxJoints]; LLMatrix4* mat = (LLMatrix4*) mp; - for (U32 j = 0; j < skin->mJointNames.size(); ++j) + U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints); + for (U32 j = 0; j < maxJoints; ++j) { LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); if (joint) @@ -3894,8 +3920,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons F32 w = wght[k]; LLMatrix4a src; - src.setMul(mp[idx[k]], w); - + // Insure ref'd bone is in our clamped array of mats + llassert(idx[k] < kMaxJoints); + // clamp k to kMaxJoints to avoid reading garbage off stack in release + src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w); final_mat.add(src); } @@ -4214,7 +4242,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (pAvatarVO) { pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes; + pAvatarVO->mAttachmentGeometryBytes = llmax(pAvatarVO->mAttachmentGeometryBytes, 0); pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea; + pAvatarVO->mAttachmentSurfaceArea = llmax(pAvatarVO->mAttachmentSurfaceArea, 0.f); } group->mGeometryBytes = 0; @@ -4227,11 +4257,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) mFaceList.clear(); - std::vector<LLFace*> fullbright_faces; - std::vector<LLFace*> bump_faces; - std::vector<LLFace*> simple_faces; + const U32 MAX_FACE_COUNT = 4096; + + static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); + static LLFace** bump_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); + static LLFace** simple_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); + static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); + + U32 fullbright_count = 0; + U32 bump_count = 0; + U32 simple_count = 0; + U32 alpha_count = 0; - std::vector<LLFace*> alpha_faces; + + U32 useage = group->mSpatialPartition->mBufferUsage; U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); @@ -4242,6 +4281,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool emissive = false; + + { LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); @@ -4543,7 +4584,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (facep->canRenderAsMask()) { //can be treated as alpha mask - simple_faces.push_back(facep); + if (simple_count < MAX_FACE_COUNT) + { + simple_faces[simple_count++] = facep; + } } else { @@ -4551,7 +4595,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //only treat as alpha in the pipeline if < 100% transparent drawablep->setState(LLDrawable::HAS_ALPHA); } - alpha_faces.push_back(facep); + if (alpha_count < MAX_FACE_COUNT) + { + alpha_faces[alpha_count++] = facep; + } } } else @@ -4566,33 +4613,51 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (te->getBumpmap()) { //needs normal + binormal - bump_faces.push_back(facep); + if (bump_count < MAX_FACE_COUNT) + { + bump_faces[bump_count++] = facep; + } } else if (te->getShiny() || !te->getFullbright()) { //needs normal - simple_faces.push_back(facep); + if (simple_count < MAX_FACE_COUNT) + { + simple_faces[simple_count++] = facep; + } } else { //doesn't need normal facep->setState(LLFace::FULLBRIGHT); - fullbright_faces.push_back(facep); + if (fullbright_count < MAX_FACE_COUNT) + { + fullbright_faces[fullbright_count++] = facep; + } } } else { if (te->getBumpmap() && LLPipeline::sRenderBump) { //needs normal + binormal - bump_faces.push_back(facep); + if (bump_count < MAX_FACE_COUNT) + { + bump_faces[bump_count++] = facep; + } } else if ((te->getShiny() && LLPipeline::sRenderBump) || !(te->getFullbright() || bake_sunlight)) { //needs normal - simple_faces.push_back(facep); + if (simple_count < MAX_FACE_COUNT) + { + simple_faces[simple_count++] = facep; + } } else { //doesn't need normal facep->setState(LLFace::FULLBRIGHT); - fullbright_faces.push_back(facep); + if (fullbright_count < MAX_FACE_COUNT) + { + fullbright_faces[fullbright_count++] = facep; + } } } } @@ -4642,17 +4707,17 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (batch_textures) { bump_mask |= LLVertexBuffer::MAP_BINORMAL; - genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); - genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); - genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); - genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE); + genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, TRUE); + genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, TRUE); + genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE); + genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, TRUE); } else { - genDrawInfo(group, simple_mask, simple_faces); - genDrawInfo(group, fullbright_mask, fullbright_faces); - genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE); - genDrawInfo(group, alpha_mask, alpha_faces, TRUE); + genDrawInfo(group, simple_mask, simple_faces, simple_count); + genDrawInfo(group, fullbright_mask, fullbright_faces, fullbright_count); + genDrawInfo(group, bump_mask, bump_faces, bump_count, FALSE, FALSE); + genDrawInfo(group, alpha_mask, alpha_faces, alpha_count, TRUE); } @@ -4684,6 +4749,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } +static LLFastTimer::DeclareTimer FTM_REBUILD_MESH_FLUSH("Flush Mesh"); void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { @@ -4693,11 +4759,14 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers - S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; - group->mBuilt = 1.f; - std::set<LLVertexBuffer*> mapped_buffers; + S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; + + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; + + U32 buffer_count = 0; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { @@ -4707,7 +4776,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); - + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { vobj->updateRelativeXform(true); @@ -4732,9 +4801,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } - if (buff->isLocked()) + if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) { - mapped_buffers.insert(buff); + locked_buffer[buffer_count++] = buff; } } } @@ -4750,21 +4819,24 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } - for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter) - { - (*iter)->flush(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull() && - group->mVertexBuffer->isLocked()) { - group->mVertexBuffer->flush(); + LLFastTimer t(FTM_REBUILD_MESH_FLUSH); + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) + { + (*iter)->flush(); + } + + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull() && + group->mVertexBuffer->isLocked()) + { + group->mVertexBuffer->flush(); + } } //if not all buffers are unmapped - if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount) + if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) { llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) @@ -4824,12 +4896,22 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures) { LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); U32 buffer_usage = group->mBufferUsage; + static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + + if (use_transform_feedback && + gTransformPositionProgram.mProgramObject && //transform shaders are loaded + buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM + !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights + { + buffer_usage = GL_DYNAMIC_COPY_ARB; + } + #if LL_DARWIN // HACK from Leslie: // Disable VBO usage for alpha on Mac OS X because it kills the framerate @@ -4850,17 +4932,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!distance_sort) { //sort faces by things that break batches - std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); + std::sort(faces, faces+face_count, CompareBatchBreakerModified()); } else { //sort faces by distance - std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); + std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater()); } } bool hud_group = group->isHUDGroup() ; - std::vector<LLFace*>::iterator face_iter = faces.begin(); + LLFace** face_iter = faces; + LLFace** end_faces = faces+face_count; LLSpatialGroup::buffer_map_t buffer_map; @@ -4889,7 +4972,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: //NEVER use more than 16 texture index channels (workaround for prevalent driver bug) texture_index_channels = llmin(texture_index_channels, 16); - while (face_iter != faces.end()) + bool flexi = false; + + while (face_iter != end_faces) { //pull off next face LLFace* facep = *face_iter; @@ -4915,11 +5000,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U32 index_count = facep->getIndicesCount(); U32 geom_count = facep->getGeomCount(); + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + //sum up vertices needed for this render batch - std::vector<LLFace*>::iterator i = face_iter; + LLFace** i = face_iter; ++i; - std::vector<LLViewerTexture*> texture_list; + const U32 MAX_TEXTURE_COUNT = 32; + LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; + + U32 texture_count = 0; { LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); @@ -4927,12 +5017,15 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { U8 cur_tex = 0; facep->setTextureIndex(cur_tex); - texture_list.push_back(tex); - + if (texture_count < MAX_TEXTURE_COUNT) + { + texture_list[texture_count++] = tex; + } + if (can_batch_texture(facep)) { //populate texture_list with any textures that can be batched //move i to the next unbatchable face - while (i != faces.end()) + while (i != end_faces) { facep = *i; @@ -4947,7 +5040,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (distance_sort) { //textures might be out of order, see if texture exists in current batch bool found = false; - for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) + for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx) { if (facep->getTexture() == texture_list[tex_idx]) { @@ -4959,7 +5052,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!found) { - cur_tex = texture_list.size(); + cur_tex = texture_count; } } else @@ -4974,7 +5067,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: tex = facep->getTexture(); - texture_list.push_back(tex); + if (texture_count < MAX_TEXTURE_COUNT) + { + texture_list[texture_count++] = tex; + } } if (geom_count + facep->getGeomCount() > max_vertices) @@ -4983,6 +5079,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } ++i; + + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + index_count += facep->getIndicesCount(); geom_count += facep->getGeomCount(); @@ -4994,7 +5093,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - while (i != faces.end() && + while (i != end_faces && (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) { facep = *i; @@ -5012,8 +5111,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: ++i; index_count += facep->getIndicesCount(); geom_count += facep->getGeomCount(); + + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + } } } + + + if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB) + { + buffer_usage = GL_STREAM_DRAW_ARB; } //create vertex buffer diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 4f52ff9778..548890b5b5 100755 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -188,13 +188,11 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) if (shader->mShaderGroup == LLGLSLShader::SG_WATER) { shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV); - shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV); - shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV); - shader->uniform1f("waterFogEnd", LLDrawPoolWater::sWaterFogEnd); - shader->uniform4fv("waterPlane", 1, mWaterPlane.mV); - shader->uniform1f("waterFogDensity", getFogDensity()); - shader->uniform1f("waterFogKS", mWaterFogKS); - shader->uniform1f("distance_multiplier", 0); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, LLDrawPoolWater::sWaterFogColor.mV); + shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, mWaterPlane.mV); + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, getFogDensity()); + shader->uniform1f(LLShaderMgr::WATER_FOGKS, mWaterFogKS); + shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); } } diff --git a/indra/newview/llwaterparamset.h b/indra/newview/llwaterparamset.h index b28585af59..368cb0ccba 100755 --- a/indra/newview/llwaterparamset.h +++ b/indra/newview/llwaterparamset.h @@ -33,6 +33,7 @@ #include "v4math.h" #include "v4color.h" #include "llviewershadermgr.h" +#include "llstringtable.h" class LLWaterParamSet; @@ -47,6 +48,9 @@ public: private: LLSD mParamValues; + std::vector<LLStaticHashedString> mParamHashedNames; + + void updateHashedNames(); public: @@ -140,6 +144,17 @@ inline void LLWaterParamSet::setAll(const LLSD& val) mParamValues[mIt->first] = mIt->second; } } + updateHashedNames(); +} + +inline void LLWaterParamSet::updateHashedNames() +{ + mParamHashedNames.clear(); + // Iterate through values + for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) + { + mParamHashedNames.push_back(LLStaticHashedString(iter->first)); + } } inline const LLSD& LLWaterParamSet::getAll() diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h index 5223b45343..810f4cf7e5 100755 --- a/indra/newview/llwlanimator.h +++ b/indra/newview/llwlanimator.h @@ -137,3 +137,4 @@ private: }; #endif // LL_WL_ANIMATOR_H + diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 6077208799..04d41a2512 100755 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -352,7 +352,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) { shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV); - shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); } else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) @@ -360,7 +360,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV); } - shader->uniform1f("scene_light_strength", mSceneLightStrength); + shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength); } diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index 72422500fc..e13aed98ed 100755 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -412,3 +412,4 @@ inline LLVector4 LLWLParamManager::getRotatedLightDir(void) const } #endif + diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index b04d30db55..b307f19e8a 100755 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -38,6 +38,22 @@ #include <sstream> +static LLStaticHashedString sStarBrightness("star_brightness"); +static LLStaticHashedString sPresetNum("preset_num"); +static LLStaticHashedString sSunAngle("sun_angle"); +static LLStaticHashedString sEastAngle("east_angle"); +static LLStaticHashedString sEnableCloudScroll("enable_cloud_scroll"); +static LLStaticHashedString sCloudScrollRate("cloud_scroll_rate"); +static LLStaticHashedString sLightNorm("lightnorm"); +static LLStaticHashedString sCloudDensity("cloud_pos_density1"); +static LLStaticHashedString sCloudScale("cloud_scale"); +static LLStaticHashedString sCloudShadow("cloud_shadow"); +static LLStaticHashedString sDensityMultiplier("density_multiplier"); +static LLStaticHashedString sDistanceMultiplier("distance_multiplier"); +static LLStaticHashedString sHazeDensity("haze_density"); +static LLStaticHashedString sHazeHorizon("haze_horizon"); +static LLStaticHashedString sMaxY("max_y"); + LLWLParamSet::LLWLParamSet(void) : mName("Unnamed Preset"), mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f) @@ -48,21 +64,24 @@ static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update"); void LLWLParamSet::update(LLGLSLShader * shader) const { LLFastTimer t(FTM_WL_PARAM_UPDATE); - - for(LLSD::map_const_iterator i = mParamValues.beginMap(); - i != mParamValues.endMap(); - ++i) + LLSD::map_const_iterator i = mParamValues.beginMap(); + std::vector<LLStaticHashedString>::const_iterator n = mParamHashedNames.begin(); + for(;(i != mParamValues.endMap()) && (n != mParamHashedNames.end());++i, n++) { - const std::string& param = i->first; + const LLStaticHashedString& param = *n; - if (param == "star_brightness" || param == "preset_num" || param == "sun_angle" || - param == "east_angle" || param == "enable_cloud_scroll" || - param == "cloud_scroll_rate" || param == "lightnorm" ) + // check that our pre-hashed names are still tracking the mParamValues map correctly + // + llassert(param.String() == i->first); + + if (param == sStarBrightness || param == sPresetNum || param == sSunAngle || + param == sEastAngle || param == sEnableCloudScroll || + param == sCloudScrollRate || param == sLightNorm ) { continue; } - if (param == "cloud_pos_density1") + if (param == sCloudDensity) { LLVector4 val; val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset; @@ -74,10 +93,10 @@ void LLWLParamSet::update(LLGLSLShader * shader) const shader->uniform4fv(param, 1, val.mV); stop_glerror(); } - else if (param == "cloud_scale" || param == "cloud_shadow" || - param == "density_multiplier" || param == "distance_multiplier" || - param == "haze_density" || param == "haze_horizon" || - param == "max_y" ) + else if (param == sCloudScale || param == sCloudShadow || + param == sDensityMultiplier || param == sDistanceMultiplier || + param == sHazeDensity || param == sHazeHorizon || + param == sMaxY ) { F32 val = (F32) i->second[0].asReal(); @@ -378,3 +397,14 @@ void LLWLParamSet::updateCloudScrolling(void) mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f); } } + +void LLWLParamSet::updateHashedNames() +{ + mParamHashedNames.clear(); + // Iterate through values + for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) + { + mParamHashedNames.push_back(LLStaticHashedString(iter->first)); + } +} + diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h index b087119dd5..6e5f1d3a4b 100755 --- a/indra/newview/llwlparamset.h +++ b/indra/newview/llwlparamset.h @@ -29,9 +29,11 @@ #include <string> #include <map> +#include <vector> #include "v4math.h" #include "v4color.h" +#include "llstaticstringtable.h" class LLWLParamSet; class LLGLSLShader; @@ -47,9 +49,12 @@ public: private: LLSD mParamValues; - + std::vector<LLStaticHashedString> mParamHashedNames; + float mCloudScrollXOffset, mCloudScrollYOffset; + void updateHashedNames(); + public: LLWLParamSet(); @@ -177,6 +182,8 @@ inline void LLWLParamSet::setAll(const LLSD& val) if(val.isMap()) { mParamValues = val; } + + updateHashedNames(); } inline const LLSD& LLWLParamSet::getAll() @@ -236,3 +243,4 @@ inline F32 LLWLParamSet::getCloudScrollY() { #endif // LL_WLPARAM_SET_H + diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 1940cf541e..ae334d4bd2 100755 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -1792,3 +1792,5 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) } return FALSE; } + + diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 340291159c..442c3ef124 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -254,6 +254,17 @@ LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading"); static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables"); static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort"); +static LLStaticHashedString sTint("tint"); +static LLStaticHashedString sAmbiance("ambiance"); +static LLStaticHashedString sAlphaScale("alpha_scale"); +static LLStaticHashedString sNormMat("norm_mat"); +static LLStaticHashedString sOffset("offset"); +static LLStaticHashedString sScreenRes("screenRes"); +static LLStaticHashedString sDelta("delta"); +static LLStaticHashedString sDistFactor("dist_factor"); +static LLStaticHashedString sKern("kern"); +static LLStaticHashedString sKernScale("kern_scale"); + //---------------------------------------- std::string gPoolNames[] = { @@ -2864,7 +2875,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) llassert(vobj); // trying to catch a bad assumption if (vobj) // this test may not be needed, see above { - const LLVOAvatar* av = vobj->asAvatar(); + LLVOAvatar* av = vobj->asAvatar(); if (av && av->isImpostor()) { return; @@ -4634,9 +4645,9 @@ void LLPipeline::renderDebug() if (LLGLSLShader::sNoFixedFunction) { gPathfindingProgram.bind(); - gPathfindingProgram.uniform1f("tint", 1.f); - gPathfindingProgram.uniform1f("ambiance", 1.f); - gPathfindingProgram.uniform1f("alpha_scale", 1.f); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); } //Requried character physics capsule render parameters @@ -4653,7 +4664,7 @@ void LLPipeline::renderDebug() llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); gGL.setColorMask(true, false); LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f("alpha_scale", 0.90f); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); gPathfindingProgram.bind(); } @@ -4680,9 +4691,9 @@ void LLPipeline::renderDebug() { gPathfindingProgram.bind(); - gPathfindingProgram.uniform1f("tint", 1.f); - gPathfindingProgram.uniform1f("ambiance", ambiance); - gPathfindingProgram.uniform1f("alpha_scale", 1.f); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); } if ( !pathfindingConsole->isRenderWorld() ) @@ -4706,7 +4717,7 @@ void LLPipeline::renderDebug() if ( pathfindingConsole->isRenderWorld() ) { LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f("alpha_scale", 0.66f); + gPathfindingProgram.uniform1f(sAlphaScale, 0.66f); llPathingLibInstance->renderNavMesh(); } else @@ -4718,8 +4729,8 @@ void LLPipeline::renderDebug() if (LLGLSLShader::sNoFixedFunction) { gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f("tint", 1.f); - gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 1.f); + gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); llPathingLibInstance->renderNavMeshEdges(); gPathfindingProgram.bind(); } @@ -4759,7 +4770,7 @@ void LLPipeline::renderDebug() gGL.setColorMask(true, false); //render the bookends LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f("alpha_scale", 0.90f); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); gPathfindingProgram.bind(); @@ -4777,7 +4788,7 @@ void LLPipeline::renderDebug() if (LLGLSLShader::sNoFixedFunction) { LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f("alpha_scale", 0.90f); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); } else @@ -4825,7 +4836,7 @@ void LLPipeline::renderDebug() LLGLEnable blend(GL_BLEND); { - gPathfindingProgram.uniform1f("ambiance", ambiance); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); { //draw solid overlay LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL); @@ -4840,8 +4851,8 @@ void LLPipeline::renderDebug() if (pathfindingConsole->isRenderXRay()) { - gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity")); + gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); LLGLEnable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); @@ -4849,13 +4860,13 @@ void LLPipeline::renderDebug() if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) { //draw hidden wireframe as darker and less opaque - gPathfindingProgram.uniform1f("ambiance", 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); } else { glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - gPathfindingProgram.uniform1f("ambiance", ambiance); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } @@ -4863,9 +4874,9 @@ void LLPipeline::renderDebug() { //draw visible wireframe as brighter, thicker and more opaque glPolygonOffset(offset, offset); - gPathfindingProgram.uniform1f("ambiance", 1.f); - gPathfindingProgram.uniform1f("tint", 1.f); - gPathfindingProgram.uniform1f("alpha_scale", 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); glLineWidth(gSavedSettings.getF32("PathfindingLineWidth")); LLGLDisable blendOut(GL_BLEND); @@ -4897,19 +4908,19 @@ void LLPipeline::renderDebug() glLineWidth(2.0f); LLGLEnable cull(GL_CULL_FACE); - gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity")); + gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) { //draw hidden wireframe as darker and less opaque glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - gPathfindingProgram.uniform1f("ambiance", 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); llPathingLibInstance->renderNavMesh(); glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); } else { - gPathfindingProgram.uniform1f("ambiance", ambiance); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); llPathingLibInstance->renderNavMesh(); } @@ -4917,8 +4928,8 @@ void LLPipeline::renderDebug() if (LLGLSLShader::sNoFixedFunction) { gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingNoNormalsProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity")); + gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); llPathingLibInstance->renderNavMeshEdges(); gPathfindingProgram.bind(); } @@ -7273,7 +7284,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) else { //focus on alt-zoom target - focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); + } } } @@ -7880,13 +7895,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight()); shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); - - - if (shader.getUniformLocation("norm_mat") >= 0) - { - glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); - shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m); - } } static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace"); @@ -7995,9 +8003,8 @@ void LLPipeline::renderDeferredLighting() } } - gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight()); - + gDeferredSunProgram.uniform3fv(sOffset, slice, offset); + { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); @@ -8040,10 +8047,10 @@ void LLPipeline::renderDeferredLighting() x += 1.f; } - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); + gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f)); { LLGLDisable blend(GL_BLEND); @@ -8060,7 +8067,7 @@ void LLPipeline::renderDeferredLighting() mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); mDeferredLight.bindTarget(); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); { LLGLDisable blend(GL_BLEND); @@ -10121,11 +10128,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - bool muted = avatar->isVisuallyMuted(); + bool visually_muted = avatar->isVisuallyMuted(); pushRenderTypeMask(); - if (muted) + if (visually_muted) { andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); } @@ -10267,6 +10274,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) avatar->mImpostor.bindTarget(); } + F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; + + if (visually_muted) + { //disable alpha masking for muted avatars (get whole skin silhouette) + LLDrawPoolAvatar::sMinimumAlpha = 0.f; + } + if (LLPipeline::sRenderDeferred) { avatar->mImpostor.clear(); @@ -10281,6 +10295,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) renderGeom(camera); } + LLDrawPoolAvatar::sMinimumAlpha = old_alpha; + { //create alpha mask based on depth buffer (grey out if muted) LLFastTimer t(FTM_IMPOSTOR_BACKGROUND); if (LLPipeline::sRenderDeferred) @@ -10291,9 +10307,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLGLDisable blend(GL_BLEND); - if (muted) + if (visually_muted) { gGL.setColorMask(true, true); + } else { @@ -10312,14 +10329,24 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.pushMatrix(); gGL.loadIdentity(); - static const F32 clip_plane = 0.99999f; + static const F32 clip_plane = 0.999f; if (LLGLSLShader::sNoFixedFunction) { - gUIProgram.bind(); + gDebugProgram.bind(); } - gGL.color4ub(64,64,64,255); + + if (LLMuteList::getInstance()->isMuted(avatar->getID())) + { //grey muted avatar + gGL.diffuseColor4ub(64,64,64,255); + } + else + { // Visually muted avatar + gGL.diffuseColor4fv( avatar->getMutedAVColor().mV ); + } + + { gGL.begin(LLRender::QUADS); gGL.vertex3f(-1, -1, clip_plane); gGL.vertex3f(1, -1, clip_plane); @@ -10327,10 +10354,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.vertex3f(-1, 1, clip_plane); gGL.end(); gGL.flush(); + } if (LLGLSLShader::sNoFixedFunction) { - gUIProgram.unbind(); + gDebugProgram.unbind(); } gGL.popMatrix(); diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png Binary files differindex 0631f16f3b..0631f16f3b 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png Binary files differindex 578482f5ed..578482f5ed 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png Binary files differindex 7676131790..7676131790 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png Binary files differindex 2880eb766a..2880eb766a 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png Binary files differindex d009c8f446..d009c8f446 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png Binary files differindex 8d82960e28..8d82960e28 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png Binary files differindex f718d3fc60..f718d3fc60 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png Binary files differindex 315e2c581a..315e2c581a 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png Binary files differindex 732ab02a20..732ab02a20 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png Binary files differindex 25a32cb2ba..25a32cb2ba 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png Binary files differindex 08debeb91f..08debeb91f 100755..100644 --- a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png +++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index a8012656c2..a73ea0cc05 100755 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -112,8 +112,43 @@ <menu_item_call.on_enable function="Object.EnableInspect" /> </menu_item_call> + + <menu_item_separator /> + + <menu_item_check + name="Normal" + label="Normal"> + <menu_item_check.on_check + function="Avatar.CheckImposterMode" + parameter="0" /> + <menu_item_check.on_click + function="Avatar.SetImposterMode" + parameter="0" /> + </menu_item_check> + <menu_item_check + name="Always use imposter" + label="Always use imposter"> + <menu_item_check.on_check + function="Avatar.CheckImposterMode" + parameter="1" /> + <menu_item_check.on_click + function="Avatar.SetImposterMode" + parameter="1" /> + </menu_item_check> + <menu_item_check + name="Never use imposter" + label="Never use imposter"> + <menu_item_check.on_check + function="Avatar.CheckImposterMode" + parameter="2" /> + <menu_item_check.on_click + function="Avatar.SetImposterMode" + parameter="2" /> + </menu_item_check> + <menu_item_separator layout="topleft" /> + <menu_item_call enabled="false" label="Mute Particle Owner" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index bca9ba5a56..2ef18dbf90 100755 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -39,8 +39,10 @@ <menu_item_call.on_click function="Avatar.InviteToGroup" /> </menu_item_call> + <menu_item_separator /> - <menu_item_call + + <menu_item_call enabled="false" label="Block" name="Avatar Mute"> @@ -103,8 +105,43 @@ <menu_item_call.on_enable function="EnablePayAvatar" /> </menu_item_call> + + <menu_item_separator /> + + <menu_item_check + name="Normal" + label="Normal"> + <menu_item_check.on_check + function="Avatar.CheckImposterMode" + parameter="0" /> + <menu_item_check.on_click + function="Avatar.SetImposterMode" + parameter="0" /> + </menu_item_check> + <menu_item_check + name="Always use imposter" + label="Always use imposter"> + <menu_item_check.on_check + function="Avatar.CheckImposterMode" + parameter="1" /> + <menu_item_check.on_click + function="Avatar.SetImposterMode" + parameter="1" /> + </menu_item_check> + <menu_item_check + name="Never use imposter" + label="Never use imposter"> + <menu_item_check.on_check + function="Avatar.CheckImposterMode" + parameter="2" /> + <menu_item_check.on_click + function="Avatar.SetImposterMode" + parameter="2" /> + </menu_item_check> + <menu_item_separator layout="topleft" /> + <menu_item_call enabled="false" label="Mute Particle Owner" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index a11cd13fdb..f66272aa2e 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -547,6 +547,15 @@ <menu_item_check.on_check control="NavBarShowParcelProperties" /> </menu_item_check> + <menu_item_check + label="Simple Imposters" + name="RenderAutoMuteEnabled"> + <menu_item_check.on_check + control="RenderAutoMuteEnabled" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="RenderAutoMuteEnabled" /> + </menu_item_check> <menu_item_separator /> <menu_item_check label="Advanced Menu" @@ -2197,6 +2206,16 @@ function="ToggleControl" parameter="DebugShowRenderInfo" /> </menu_item_check> + <menu_item_check + label="Show Avatar Render Info" + name="Show Avatar Render Info"> + <menu_item_check.on_check + function="CheckControl" + parameter="DebugShowAvatarRenderInfo" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="DebugShowAvatarRenderInfo" /> + </menu_item_check> <menu_item_check label="Show Texture Info" name="Show Texture Info"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index b89e25809c..5bf33da14a 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -203,6 +203,45 @@ Message Template [PATH] not found. </notification> <notification + icon="notify.tga" + name="ExceededHighDetailRenderCost" + persist="false" + type="alertmodal"> + Your avatar has become too complex to be rendered by even high performance computers. Almost all Residents will see a low detail stand in instead of your actual avatar. + <unique/> + <usetemplate + ignoretext="Avatar exceeded high detail complexity." + name="okignore" + yestext="Close"/> + </notification> + + <notification + icon="notify.tga" + name="ExceededMidDetailRenderCost" + persist="false" + type="alertmodal"> + Your avatar has become too complex to be rendered by most computers. Many Residents will see a low detail stand in instead of your actual avatar. + <unique/> + <usetemplate + ignoretext="Avatar exceeded mid detail complexity." + name="okignore" + yestext="Close"/> +</notification> + + <notification + icon="notify.tga" + name="ExceededLowDetailRenderCost" + persist="false" + type="alertmodal"> + Your avatar has become too complex to be rendered by some computers. Some Residents will see a low detail stand in instead of your actual avatar. + <unique/> + <usetemplate + ignoretext="Avatar exceeded low detail complexity." + name="okignore" + yestext="Close"/> + </notification> + + <notification icon="alertmodal.tga" name="WearableSave" type="alertmodal"> @@ -10073,7 +10112,7 @@ An internal error prevented us from properly updating your viewer. The L$ balan <tag>fail</tag> Cannot create large prims that intersect other players. Please re-try when other players have moved. </notification> - + <notification icon="alertmodal.tga" name="PreferenceChatClearLog" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 4ed95f0758..7abc67494f 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -177,10 +177,86 @@ width="80"> Ultra </text> + <slider + control_name="RenderAvatarLODFactor" + invisiblity_control="ShowAdvancedGraphicsSettings" + follows="left|top" + height="16" + increment="0.125" + initial_value="160" + label="Avatar detail:" + label_width="90" + layout="topleft" + left="30" + name="AvatarMeshDetail2" + show_text="false" + top="72" + width="300"> + <slider.commit_callback + function="Pref.UpdateSliderText" + parameter="AvatarMeshDetailText2" /> + </slider> + <text + type="string" + invisiblity_control="ShowAdvancedGraphicsSettings" + length="1" + follows="left|top" + height="12" + layout="topleft" + name="AvatarMeshDetailText2" + top_delta="0" + left_delta="304" + width="128"> + Low + </text> + <slider + control_name="RenderFarClip" + invisiblity_control="ShowAdvancedGraphicsSettings" + decimal_digits="0" + follows="left|top" + height="16" + increment="8" + initial_value="160" + label="Draw distance:" + label_width="90" + layout="topleft" + left="30" + max_val="512" + min_val="64" + name="DrawDistance" + top="110" + width="330" /> + <text + type="string" + invisiblity_control="ShowAdvancedGraphicsSettings" + length="1" + follows="left|top" + height="12" + layout="topleft" + left_delta="330" + name="DrawDistanceMeterText2" + top_delta="0" + width="128"> + m + </text> + <check_box + control_name="RenderDeferred" + invisiblity_control="ShowAdvancedGraphicsSettings" + height="16" + initial_value="true" + label="Lighting and Shadows" + layout="topleft" + left="30" + name="UseLightShaders2" + top="148" + width="256"> + <check_box.commit_callback + function="Pref.VertexShaderEnable" /> + </check_box> <panel - visiblity_control="ShowAdvancedGraphicsSettings" + visiblity_control="ShowAdvancedGraphicsSettings" border="false" - follows="top|left" + follows="top|left" height="300" label="CustomGraphics" layout="topleft" @@ -219,15 +295,15 @@ left_delta="0" name="BumpShiny" top_pad="1" - width="256" /> + width="256" /> <check_box - control_name="RenderLocalLights" - height="16" - initial_value="true" - label="Local Lights" - layout="topleft" - left_delta="0" - name="LocalLights" + control_name="RenderLocalLights" + height="16" + initial_value="true" + label="Local Lights" + layout="topleft" + left_delta="0" + name="LocalLights" top_pad="1" width="256" /> <check_box diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index c6ad9fc264..f821fa7619 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -407,10 +407,13 @@ Please try logging in again in a minute.</string> <string name="AddAndRemoveJoints">Add and remove joints with other objects</string> <string name="ChangePermissions">Change its permissions</string> <string name="TrackYourCamera">Track your camera</string> - <string name="ControlYourCamera">Control your camera</string> + <string name="ControlYourCamera">Control your camera</string> + <string name="TeleportYourAgent">Teleport you</string> + <string name="ManageEstateSilently">Manage your estates silently</string> + <string name="ChangeYourDefaultAnimations">Change your default animations</string> + <string name="NotConnected">Not Connected</string> <string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name --> - <string name="TeleportYourAgent">Teleport you</string> <string name="JoinAnExperience">Join an experience</string> <!-- not used --> <string name="SilentlyManageEstateAccess">Suppress alerts when managing estate access lists</string> <string name="OverrideYourAnimations">Replace your default animations</string> diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml index b83d9122f7..b83d9122f7 100755..100644 --- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml +++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp index 3ba25f3c10..05289f0309 100755 --- a/indra/newview/tests/llagentaccess_test.cpp +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -40,7 +40,7 @@ static U32 test_preferred_maturity = SIM_ACCESS_PG; LLControlGroup::LLControlGroup(const std::string& name) - : LLInstanceTracker<LLControlGroup, std::string>(name) +: LLInstanceTracker<LLControlGroup, std::string>(name) { } |