From e8ec81bf04e11e47bcf4af2542cacf6fba277bed Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 14 Oct 2012 04:00:02 -0500 Subject: [PATCH 001/213] Experimentation with normalpacking and component precision. --- indra/llrender/llshadermgr.cpp | 4 ++++ indra/newview/app_settings/settings_sh.xml | 22 +++++++++++++++++++ .../shaders/class1/deferred/avatarF.glsl | 13 ++++++++++- .../shaders/class1/deferred/blurLightF.glsl | 18 +++++++++++++-- .../shaders/class1/deferred/bumpF.glsl | 13 ++++++++++- .../shaders/class1/deferred/cloudsF.glsl | 7 +++++- .../class1/deferred/diffuseAlphaMaskF.glsl | 13 ++++++++++- .../deferred/diffuseAlphaMaskIndexedF.glsl | 13 ++++++++++- .../deferred/diffuseAlphaMaskNoColorF.glsl | 13 ++++++++++- .../shaders/class1/deferred/diffuseF.glsl | 13 ++++++++++- .../class1/deferred/diffuseIndexedF.glsl | 13 ++++++++++- .../class1/deferred/multiPointLightF.glsl | 19 +++++++++++++--- .../class1/deferred/multiSpotLightF.glsl | 19 +++++++++++++--- .../shaders/class1/deferred/pointLightF.glsl | 19 +++++++++++++--- .../shaders/class1/deferred/skyF.glsl | 7 +++++- .../shaders/class1/deferred/softenLightF.glsl | 17 ++++++++++++-- .../shaders/class1/deferred/spotLightF.glsl | 19 +++++++++++++--- .../shaders/class1/deferred/starsF.glsl | 7 +++++- .../class1/deferred/sunLightSSAOF.glsl | 16 ++++++++++++-- .../shaders/class1/deferred/terrainF.glsl | 13 ++++++++++- .../shaders/class1/deferred/treeF.glsl | 13 ++++++++++- .../shaders/class1/deferred/waterF.glsl | 13 ++++++++++- .../class2/deferred/multiSpotLightF.glsl | 19 +++++++++++++--- .../shaders/class2/deferred/softenLightF.glsl | 17 ++++++++++++-- .../shaders/class2/deferred/spotLightF.glsl | 19 +++++++++++++--- .../shaders/class2/deferred/sunLightF.glsl | 19 +++++++++++++--- .../class2/deferred/sunLightSSAOF.glsl | 19 +++++++++++++--- indra/newview/pipeline.cpp | 3 ++- 28 files changed, 354 insertions(+), 46 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 234d2e141..ceead02cd 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -660,6 +660,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade } } + static const LLCachedControl SHPackDeferredNormals("SHPackDeferredNormals",false); + if(SHPackDeferredNormals) + text[count++] = strdup("#define PACK_NORMALS\n"); + //copy preprocessor definitions into buffer for (std::map::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) { diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 81659467c..3deb249fa 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -174,5 +174,27 @@ Value 0 + SHPackDeferredNormals + + Comment + Pack deferred normals into two components. + Persist + 1 + Type + Boolean + Value + 0 + + SHPrecisionDeferredNormals + + Comment + Enable usage of RGB10A2 for the deferred normalMap format. Reduces normalmapping artifacts. + Persist + 1 + Type + Boolean + Value + 0 + diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 46d2aa487..cf57a33d9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -34,6 +34,17 @@ uniform sampler2D diffuseMap; VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy); @@ -46,6 +57,6 @@ void main() frag_data[0] = vec4(diff.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn), 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index f400eb7a5..6f752f89e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -64,11 +64,25 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 tc = vary_fragcoord.xy; - vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(tc); // unpack norm + vec3 pos = getPosition(tc).xyz; vec4 ccol = texture2DRect(lightMap, tc).rgba; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 680eadb85..db80a8e87 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -39,6 +39,17 @@ VARYING vec3 vary_mat2; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -52,5 +63,5 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(tnorm); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn), 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index 1d8ca04cc..9f6b1ea1f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -102,6 +102,11 @@ void main() /// Gamma correct for WL (soft clip effect). frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1); frag_data[1] = vec4(0.0,0.0,0.0,0.0); - frag_data[2] = vec4(0,0,1,0); +//#define PACK_NORMALS +#ifdef PACK_NORMALS + frag_data[2] = vec4(0.5,0.5,0.0,0.0); +#else + frag_data[2] = vec4(0.0,0.0,1.0,0.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index b2027d3a5..d31cbfa28 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -37,6 +37,17 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color; @@ -49,6 +60,6 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index ead384b07..c65539d43 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -36,6 +36,17 @@ uniform float minimum_alpha; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; @@ -48,5 +59,5 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn), 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index f73fa6f23..252975aad 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -37,6 +37,17 @@ uniform sampler2D diffuseMap; VARYING vec3 vary_normal; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -49,6 +60,6 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 227aa2aae..ac33fd261 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -35,6 +35,17 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -42,6 +53,6 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index d442e5403..b97cd060d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -33,6 +33,17 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; @@ -41,5 +52,5 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 4d01eeb64..26aa34107 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -69,6 +69,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; @@ -78,9 +92,8 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - norm = normalize(norm); + vec3 norm = unpack(frag.xy); // unpack norm + //norm = normalize(norm); // may be superfluous vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; float noise = texture2D(noiseMap, frag.xy/128.0).b; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index bff87cb6a..a82ba899a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -125,6 +125,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -141,10 +155,9 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0, norm.z); + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index f671d5b75..6c1ff1660 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -67,6 +67,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -83,15 +97,14 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(frag.xy); // unpack norm float da = dot(norm, lv); if (da < 0.0) { discard; } - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous lv = normalize(lv); da = dot(norm, lv); diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index faa54a316..46b34c6d3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -61,6 +61,11 @@ void main() /// Gamma correct for WL (soft clip effect). frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0); frag_data[1] = vec4(0.0,0.0,0.0,0.0); - frag_data[2] = vec4(0,0,1,0); +//#define PACK_NORMALS +#ifdef PACK_NORMALS + frag_data[2] = vec4(0.5,0.5,0.0,0.0); +#else + frag_data[2] = vec4(0.0,0.0,1.0,0.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 66e3cf6d1..61f592d77 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -271,13 +271,26 @@ vec3 scaleSoftClip(vec3 light) return light; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 tc = vary_fragcoord.xy; float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; - vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(tc); // unpack norm float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index cca63872d..ae64d8937 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -127,6 +127,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -143,10 +157,9 @@ void main() discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0, norm.z); + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl index 821058804..71486156f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -40,5 +40,10 @@ void main() frag_data[0] = col; frag_data[1] = vec4(0,0,0,0); - frag_data[2] = vec4(0,0,1,0); +//#define PACK_NORMALS +#ifdef PACK_NORMALS + frag_data[2] = vec4(0.5,0.5,0.0,0.0); +#else + frag_data[2] = vec4(0.0,0.0,1.0,0.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 2422d73a3..605063805 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -114,6 +114,19 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) return min(ret, 1.0); } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} void main() { vec2 pos_screen = vary_fragcoord.xy; @@ -122,8 +135,7 @@ void main() vec4 pos = getPosition(pos_screen); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(pos_screen); // unpack norm frag_color[0] = 1.0; frag_color[1] = calcAmbientOcclusion(pos, norm); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 8a5e482e8..3e4c5fc9c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -39,6 +39,17 @@ VARYING vec3 vary_normal; VARYING vec4 vary_texcoord0; VARYING vec4 vary_texcoord1; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { /// Note: This should duplicate the blending functionality currently used for the terrain rendering. @@ -56,6 +67,6 @@ void main() frag_data[0] = vec4(outColor.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 6cf6106b5..6cd309fdb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -37,6 +37,17 @@ VARYING vec2 vary_texcoord0; uniform float minimum_alpha; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -48,5 +59,5 @@ void main() frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(pack(nvn),0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 42dc7c098..9b64b3d3f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,17 @@ VARYING vec4 littleWave; VARYING vec4 view; VARYING vec4 vary_position; +vec3 pack(vec3 norm) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + float p = sqrt(8.0*norm.z+8.0); + return vec3(norm.xy/p + 0.5, 0.0); +#else + return norm.xyz*0.5+0.5; +#endif +} + void main() { vec4 color; @@ -161,5 +172,5 @@ void main() frag_data[0] = vec4(color.rgb, 0.5); // diffuse frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec - frag_data[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace + frag_data[2] = vec4(pack(screenspacewavef), 0.5); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index f7f1f649c..7f6a31ef7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -126,6 +126,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -153,10 +167,9 @@ void main() shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index a137bea30..7e005d335 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -273,13 +273,26 @@ vec3 scaleSoftClip(vec3 light) return light; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec2 tc = vary_fragcoord.xy; float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; - vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(tc); // unpack norm float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index ab077d9e0..3a556e913 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -126,6 +126,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } +vec3 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec2 enc = texture2DRect(normalMap, tc).xy; + enc = enc*4.0-2.0; + float prod = dot(enc,enc); + return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5); +#else + vec3 norm = texture2DRect(normalMap, tc).xyz; + return norm*2.0-1.0; +#endif +} + void main() { vec4 frag = vary_fragcoord; @@ -153,10 +167,9 @@ void main() shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 norm = unpack(frag.xy); // unpack norm - norm = normalize(norm); + //norm = normalize(norm); // may be superfluous float l_dist = -dot(lv, proj_n); vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index db3d76035..9b5d37965 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -116,6 +116,20 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) return shadow*0.2; } +vec4 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec4 enc = texture2DRect(normalMap, tc).xyzw; + enc = vec4((enc.xy*4.0)-2.0,0.0,enc.w); + float prod = dot(enc.xy,enc.xy); + return vec4(enc.xy*sqrt(1.0-prod*.25),1.0-prod*.5,enc.w); +#else + vec4 norm = texture2DRect(normalMap, tc).xyz; + return vec4(norm.xyz*2.0-1.0,norm.w); +#endif +} + void main() { vec2 pos_screen = vary_fragcoord.xy; @@ -124,9 +138,8 @@ void main() vec4 pos = getPosition(pos_screen); - vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm - float displace = nmap4.w; + vec4 nmap4 = unpack(pos_screen) // unpack norm + float displace = nmap4.w*norm.z; vec3 norm = nmap4.xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 32b206e63..1e3691720 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -177,6 +177,20 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) return shadow*0.2; } +vec4 unpack(vec2 tc) +{ +//#define PACK_NORMALS +#ifdef PACK_NORMALS + vec4 enc = texture2DRect(normalMap, tc).xyzw; + enc = vec4((enc.xy*4.0)-2.0,0.0,enc.w); + float prod = dot(enc.xy,enc.xy); + return vec4(enc.xy*sqrt(1.0-prod*.25),1.0-prod*.5,enc.w); +#else + vec4 norm = texture2DRect(normalMap, tc).xyz; + return vec4(norm.xyz*2.0-1.0,norm.w); +#endif +} + void main() { vec2 pos_screen = vary_fragcoord.xy; @@ -185,9 +199,8 @@ void main() vec4 pos = getPosition(pos_screen); - vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm - float displace = nmap4.w; + vec4 nmap4 = unpack(pos_screen); // unpack norm + float displace = nmap4.w*norm.z; vec3 norm = nmap4.xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d2004a187..aa5d9ab2b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -340,8 +340,9 @@ void validate_framebuffer_object(); bool addDeferredAttachments(LLRenderTarget& target) { + static const LLCachedControl SHPrecisionDeferredNormals("SHPrecisionDeferredNormals",false); return target.addColorAttachment(GL_RGBA) && //specular - target.addColorAttachment(GL_RGBA); //normal+z + target.addColorAttachment(SHPrecisionDeferredNormals ? GL_RGB10_A2 : GL_RGBA); //normal+z } LLPipeline::LLPipeline() : From 1b89e5c9732a03289e21ca11d7f012784e55095e Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 16 Oct 2012 02:33:05 -0500 Subject: [PATCH 002/213] Dragged in a bunch of alignment fixes from LL. Should allow disabling of tcmalloc on windows/linux32 if such is ever implemented. --- indra/llcommon/llallocator.cpp | 2 +- indra/llcommon/llevents.cpp | 4 +- indra/llcommon/llmemory.cpp | 40 +++++++--------- indra/llcommon/llmemory.h | 60 +++++++++++++++++------ indra/llmath/llcamera.h | 12 ++--- indra/llmath/llmatrix3a.h | 2 +- indra/llmath/llmatrix4a.h | 2 +- indra/llmath/lloctree.h | 5 +- indra/llmath/llplane.h | 4 +- indra/llmath/llsimdmath.h | 3 +- indra/llmath/llvector4a.cpp | 8 +++- indra/llmath/llvector4a.h | 5 +- indra/llmath/llvector4logical.h | 2 + indra/llmath/llvolume.cpp | 32 ++++++++----- indra/llmath/llvolumeoctree.h | 25 ++++++++-- indra/llprimitive/llmodel.cpp | 3 +- indra/llrender/llrender.cpp | 18 ++++--- indra/newview/lldrawable.h | 17 +++++-- indra/newview/lldriverparam.h | 10 ++++ indra/newview/lldynamictexture.h | 12 ++++- indra/newview/llface.h | 11 +++++ indra/newview/llpolymesh.cpp | 48 +++++++++---------- indra/newview/llpolymesh.h | 10 ++++ indra/newview/llpolymorph.cpp | 72 ++++++++++++++++++++-------- indra/newview/llpolymorph.h | 13 +++++ indra/newview/llspatialpartition.cpp | 3 ++ indra/newview/llspatialpartition.h | 36 ++++++++++---- indra/newview/lltexlayerparams.h | 20 ++++++++ indra/newview/llviewercamera.h | 14 +++++- indra/newview/llvoavatar.cpp | 2 +- indra/newview/llvoavatar.h | 12 ++++- indra/newview/llvoavatarself.h | 10 ++++ 32 files changed, 381 insertions(+), 136 deletions(-) diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp index 6f6abefc6..87654b5b9 100644 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include "llallocator.h" -#if LL_USE_TCMALLOC +#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER) #include "google/heap-profiler.h" #include "google/commandlineflags_public.h" diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 9bc61ccb5..480e94e43 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -444,13 +444,13 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL { // The new node isn't last. Place it between the previous node and // the successor. - newNode = (myprev + mydmi->second)/2.0; + newNode = (myprev + mydmi->second)/2.f; } else { // The new node is last. Bump myprev up to the next integer, add // 1.0 and use that. - newNode = std::ceil(myprev) + 1.0; + newNode = std::ceil(myprev) + 1.f; } // Now that newNode has a value that places it appropriately in mSignal, // connect it. diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 446946ac4..52d0917d7 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -67,6 +67,17 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker; #endif +void ll_assert_aligned_func(uintptr_t ptr,U32 alignment) +{ +#ifdef SHOW_ASSERT + // Redundant, place to set breakpoints. + if (ptr%alignment!=0) + { + llwarns << "alignment check failed" << llendl; + } + llassert(ptr%alignment==0); +#endif +} //static void LLMemory::initClass() { @@ -246,21 +257,6 @@ U32 LLMemory::getAllocatedMemKB() return sAllocatedMemInKB ; } -void* ll_allocate (size_t size) -{ - if (size == 0) - { - llwarns << "Null allocation" << llendl; - } - void *p = malloc(size); - if (p == NULL) - { - LLMemory::freeReserve(); - llerrs << "Out of memory Error" << llendl; - } - return p; -} - //---------------------------------------------------------------------------- #if defined(LL_WINDOWS) @@ -1415,7 +1411,7 @@ char* LLPrivateMemoryPool::allocate(U32 size) to_log = false ; } - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } return p ; @@ -1434,7 +1430,7 @@ void LLPrivateMemoryPool::freeMem(void* addr) if(!chunk) { - free(addr) ; //release from heap + ll_aligned_free_16(addr) ; //release from heap } else { @@ -1558,7 +1554,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde mReservedPoolSize += preferred_size + overhead ; - char* buffer = (char*)malloc(preferred_size + overhead) ; + char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ; if(!buffer) { return NULL ; @@ -1626,7 +1622,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk) mReservedPoolSize -= chunk->getBufferSize() ; //release memory - free(chunk->getBuffer()) ; + ll_aligned_free_16(chunk->getBuffer()) ; } U16 LLPrivateMemoryPool::findHashKey(const char* addr) @@ -1970,7 +1966,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size, if(!poolp) { - p = (char*)malloc(size) ; + p = (char*)ll_aligned_malloc_16(size) ; } else { @@ -1999,7 +1995,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size) } else { - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } } #endif @@ -2024,7 +2020,7 @@ void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr { if(!sPrivatePoolEnabled) { - free(addr) ; //private pool is disabled. + ll_aligned_free_16(addr) ; //private pool is disabled. } else if(!sInstance) //the private memory manager is destroyed, try the dangling list { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 19cc720b0..a28be0adb 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -39,9 +39,14 @@ #include // uintptr_t #endif -#include "llerror.h" #include "llmemtype.h" -#if LL_DEBUG + +#if LL_WINDOWS && LL_DEBUG +#define LL_CHECK_MEMORY llassert(_CrtCheckMemory()); +#else +#define LL_CHECK_MEMORY +#endif + inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -57,10 +62,11 @@ inline void ll_aligned_free( void* ptr ) free( ((void**)ptr)[-1] ); } +#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { #if defined(LL_WINDOWS) - return _mm_malloc(size, 16); + return _aligned_malloc(size, 16); #elif defined(LL_DARWIN) return malloc(size); // default osx malloc is 16 byte aligned. #else @@ -75,7 +81,7 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_16(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) return free(p); #else @@ -83,10 +89,35 @@ inline void ll_aligned_free_16(void *p) #endif } +inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16(). +{ +#if defined(LL_WINDOWS) + return _aligned_realloc(ptr, size, 16); +#elif defined(LL_DARWIN) + return realloc(ptr,size); // default osx malloc is 16 byte aligned. +#else + //FIXME: memcpy is SLOW + void* ret = ll_aligned_malloc_16(size); + if (ptr) + { + memcpy(ret, ptr, old_size); + ll_aligned_free_16(ptr); + } + return ret; +#endif +} + +#else // USE_TCMALLOC +// ll_aligned_foo_16 are not needed with tcmalloc +#define ll_aligned_malloc_16 malloc +#define ll_aligned_realloc_16(a,b,c) realloc(a,b) +#define ll_aligned_free_16 free +#endif // USE_TCMALLOC + inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). { #if defined(LL_WINDOWS) - return _mm_malloc(size, 32); + return _aligned_malloc(size, 32); #elif defined(LL_DARWIN) return ll_aligned_malloc( size, 32 ); #else @@ -101,22 +132,13 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_32(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) ll_aligned_free( p ); #else free(p); // posix_memalign() is compatible with heap deallocator #endif } -#else // LL_DEBUG -// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals) -#define ll_aligned_malloc( size, align ) malloc(size) -#define ll_aligned_free( ptr ) free(ptr) -#define ll_aligned_malloc_16 malloc -#define ll_aligned_free_16 free -#define ll_aligned_malloc_32 malloc -#define ll_aligned_free_32 free -#endif // LL_DEBUG #ifndef __DEBUG_PRIVATE_MEM__ #define __DEBUG_PRIVATE_MEM__ 0 @@ -521,6 +543,14 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) #endif #endif +LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); + +#ifdef SHOW_ASSERT +#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast(ptr),((U32)alignment)) +#else +#define ll_assert_aligned(ptr,alignment) +#endif + //EVENTUALLY REMOVE THESE: #include "llpointer.h" #include "llsingleton.h" diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 0459f797c..97e56b2a2 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -66,7 +66,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; // roll(), pitch(), yaw() // etc... - +LL_ALIGN_PREFIX(16) class LLCamera : public LLCoordFrame { @@ -114,7 +114,7 @@ public: }; private: - LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP U8 mPlaneMask[8]; // 8 for alignment F32 mView; // angle between top and bottom frustum planes in radians. @@ -122,13 +122,13 @@ private: S32 mViewHeightInPixels; // for ViewHeightInPixels() only F32 mNearPlane; F32 mFarPlane; - LLPlane mLocalPlanes[4]; + LL_ALIGN_16(LLPlane mLocalPlanes[4]); F32 mFixedDistance; // Always return this distance, unless < 0 LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test F32 mFrustRadiusSquared; - LLPlane mWorldPlanes[PLANE_NUM]; - LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; + LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]); + LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]); U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in @@ -214,7 +214,7 @@ protected: void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom); void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2); void calculateWorldFrustumPlanes(); -}; +} LL_ALIGN_POSTFIX(16); #endif diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h index adb7e3389..9916cfd2d 100644 --- a/indra/llmath/llmatrix3a.h +++ b/indra/llmath/llmatrix3a.h @@ -111,7 +111,7 @@ public: protected: - LLVector4a mColumns[3]; + LL_ALIGN_16(LLVector4a mColumns[3]); }; diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 0c61fc96f..94e5e54af 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -34,7 +34,7 @@ class LLMatrix4a { public: - LLVector4a mMatrix[4]; + LL_ALIGN_16(LLVector4a mMatrix[4]); inline void clear() { diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 6e5e51b7e..fcc0c2807 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -121,11 +121,12 @@ public: typedef typename std::vector*>::iterator tree_listener_iter; typedef LLOctreeNode** child_list; typedef LLOctreeNode** child_iter; + typedef LLTreeNode BaseType; typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - /*void* operator new(size_t size) + void* operator new(size_t size) { return ll_aligned_malloc_16(size); } @@ -133,7 +134,7 @@ public: void operator delete(void* ptr) { ll_aligned_free_16(ptr); - }*/ + } LLOctreeNode( const LLVector4a& center, const LLVector4a& size, diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index a18f63a0d..44c8327f5 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -42,6 +42,8 @@ // The plane normal = [A, B, C] // The closest approach = D / sqrt(A*A + B*B + C*C) + +LL_ALIGN_PREFIX(16) class LLPlane { public: @@ -100,7 +102,7 @@ public: private: LLVector4a mV; -}; +} LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index c7cdf7b32..01458521e 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -67,11 +67,10 @@ template T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) - - #include #include +#include "llmemory.h" #include "llsimdtypes.h" #include "llsimdtypes.inl" diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index b66b7a707..6edeb0fef 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -24,6 +24,7 @@ * $/LicenseInfo$ */ +#include "llmemory.h" #include "llmath.h" #include "llquantize.h" @@ -44,7 +45,10 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F assert(dst != NULL); assert(bytes > 0); assert((bytes % sizeof(F32))== 0); - + ll_assert_aligned(src,16); + ll_assert_aligned(dst,16); + assert(bytes%16==0); + F32* end = dst + (bytes / sizeof(F32) ); if (bytes > 64) @@ -189,6 +193,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high ) LLVector4a oneOverDelta; { static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; + ll_assert_aligned(F_TWO_4A,16); + LLVector4a two; two.load4a( F_TWO_4A ); // Here we use _mm_rcp_ps plus one round of newton-raphson diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 596082509..9de0e6677 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -32,6 +32,7 @@ class LLRotation; #include #include "llpreprocessor.h" +#include "llmemory.h" /////////////////////////////////// // FIRST TIME USERS PLEASE READ @@ -46,6 +47,7 @@ class LLRotation; // LLVector3/LLVector4. ///////////////////////////////// +LL_ALIGN_PREFIX(16) class LLVector4a { public: @@ -90,6 +92,7 @@ public: LLVector4a() { //DO NOT INITIALIZE -- The overhead is completely unnecessary + ll_assert_aligned(this,16); } LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f) @@ -313,7 +316,7 @@ public: private: LLQuad mQ; -}; +} LL_ALIGN_POSTFIX(16); inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p) { diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h index dd66b09d4..c5698f7ce 100644 --- a/indra/llmath/llvector4logical.h +++ b/indra/llmath/llvector4logical.h @@ -27,6 +27,7 @@ #ifndef LL_VECTOR4LOGICAL_H #define LL_VECTOR4LOGICAL_H +#include "llmemory.h" //////////////////////////// // LLVector4Logical @@ -77,6 +78,7 @@ public: inline LLVector4Logical& invert() { static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + ll_assert_aligned(allOnes,16); mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); return *this; } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 54a88a570..ebf049591 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -29,6 +29,10 @@ #include "llmath.h" #include +#if !LL_WINDOWS +#include +#endif +#include #include "llerror.h" #include "llmemtype.h" @@ -6991,17 +6995,21 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con { S32 new_verts = mNumVertices+1; S32 new_size = new_verts*16; -// S32 old_size = mNumVertices*16; + S32 old_size = mNumVertices*16; //positions - mPositions = (LLVector4a*) realloc(mPositions, new_size); + mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size); + ll_assert_aligned(mPositions,16); //normals - mNormals = (LLVector4a*) realloc(mNormals, new_size); - + mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size); + ll_assert_aligned(mNormals,16); + //tex coords new_size = ((new_verts*8)+0xF) & ~0xF; - mTexCoords = (LLVector2*) realloc(mTexCoords, new_size); + old_size = ((mNumVertices*8)+0xF) & ~0xF; + mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size); + ll_assert_aligned(mTexCoords,16); //just clear binormals @@ -7095,12 +7103,12 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } //allocate new buffer space - mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a)); - assert_aligned(mPositions, 16); - mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a)); - assert_aligned(mNormals, 16); - mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF); - assert_aligned(mTexCoords, 16); + mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); + ll_assert_aligned(mPositions, 16); + mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); + ll_assert_aligned(mNormals, 16); + mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF); + ll_assert_aligned(mTexCoords, 16); mNumVertices = new_count; @@ -7146,7 +7154,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; //allocate new index buffer - mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF); + mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF, (mNumIndices*sizeof(U16)+0xF) & ~0xF); //get destination address into new index buffer U16* dst_idx = mIndices+mNumIndices; diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index c25e37f1a..03f10814e 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -37,6 +37,15 @@ class LLVolumeTriangle : public LLRefCount { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } LLVolumeTriangle() { mBinIndex = -1; @@ -58,7 +67,7 @@ public: } - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mPositionGroup); const LLVector4a* mV[3]; U16 mIndex[3]; @@ -78,6 +87,16 @@ class LLVolumeOctreeListener : public LLOctreeListener { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); @@ -104,8 +123,8 @@ public: public: - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; class LLOctreeTriangleRayIntersect : public LLOctreeTraveler diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 7d4b34ead..b3b5145c5 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1027,7 +1027,8 @@ void LLModel::setVolumeFaceData( if (tc.get()) { - LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF; + LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size); } else { diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 366f506a7..6c985fbb4 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1510,20 +1510,26 @@ void LLRender::pushUIMatrix() { if (mUIOffset.empty()) { - mUIOffset.push_back(new LLVector4a(0.f)); + mUIOffset.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + mUIOffset.back()->splat(0.f); } else { - mUIOffset.push_back(new LLVector4a(*mUIOffset.back())); + const LLVector4a* last_entry = mUIOffset.back(); + mUIOffset.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + *mUIOffset.back() = *last_entry; } if (mUIScale.empty()) { - mUIScale.push_back(new LLVector4a(1.f)); + mUIScale.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + mUIScale.back()->splat(1.f); } else { - mUIScale.push_back(new LLVector4a(*mUIScale.back())); + const LLVector4a* last_entry = mUIScale.back(); + mUIScale.push_back(static_cast(ll_aligned_malloc_16(sizeof(LLVector4a)))); + *mUIScale.back() = *last_entry; } } @@ -1533,9 +1539,9 @@ void LLRender::popUIMatrix() { llerrs << "UI offset stack blown." << llendl; } - delete mUIOffset.back(); + ll_aligned_free_16(mUIOffset.back()); mUIOffset.pop_back(); - delete mUIScale.back(); + ll_aligned_free_16(mUIScale.back()); mUIScale.pop_back(); } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index bd2d23c5f..ff6023597 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -65,6 +65,7 @@ class LLViewerTexture; const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. +LL_ALIGN_PREFIX(16) class LLDrawable : public LLRefCount { public: @@ -81,6 +82,16 @@ public: static void initClass(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawable() { init(); } MEM_TYPE_NEW(LLMemType::MTYPE_DRAWABLE); @@ -290,8 +301,8 @@ public: } EDrawableFlags; private: //aligned members - LLVector4a mExtents[2]; - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mExtents[2]); + LL_ALIGN_16(LLVector4a mPositionGroup); public: LLXformMatrix mXform; @@ -333,7 +344,7 @@ private: static U32 sNumZombieDrawables; static LLDynamicArrayPtr > sDeadList; -}; +} LL_ALIGN_POSTFIX(16); inline LLFace* LLDrawable::getFace(const S32 i) const diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h index 7a4d711d4..c0976d1d4 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/newview/lldriverparam.h @@ -83,6 +83,16 @@ public: LLDriverParam(LLWearable *wearablep); ~LLDriverParam(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // Special: These functions are overridden by child classes LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; } // This sets mInfo and calls initialization functions diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 398a41cef..33287ae1a 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -36,6 +36,16 @@ class LLViewerDynamicTexture : public LLViewerTexture { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + enum { LL_VIEWER_DYNAMIC_TEXTURE = LLViewerTexture::DYNAMIC_TEXTURE, @@ -85,7 +95,7 @@ protected: protected: BOOL mClamp; LLCoordGL mOrigin; - LLCamera mCamera; + LL_ALIGN_16(LLCamera mCamera); typedef std::set instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 4cab49205..b59dff8f0 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -64,6 +64,17 @@ class LLFace { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLFace(const LLFace& rhs) { *this = rhs; diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index d7b342b25..04ccafcb9 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -125,28 +125,28 @@ void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data) //----------------------------------------------------------------------------- void LLPolyMeshSharedData::freeMeshData() { - if (!mReferenceData) - { - mNumVertices = 0; + if (!mReferenceData) + { + mNumVertices = 0; - delete [] mBaseCoords; - mBaseCoords = NULL; + ll_aligned_free_16(mBaseCoords); + mBaseCoords = NULL; - delete [] mBaseNormals; - mBaseNormals = NULL; + ll_aligned_free_16(mBaseNormals); + mBaseNormals = NULL; - delete [] mBaseBinormals; - mBaseBinormals = NULL; + ll_aligned_free_16(mBaseBinormals); + mBaseBinormals = NULL; - delete [] mTexCoords; - mTexCoords = NULL; + ll_aligned_free_16(mTexCoords); + mTexCoords = NULL; - delete [] mDetailTexCoords; - mDetailTexCoords = NULL; + ll_aligned_free_16(mDetailTexCoords); + mDetailTexCoords = NULL; - delete [] mWeights; - mWeights = NULL; - } + ll_aligned_free_16(mWeights); + mWeights = NULL; + } mNumFaces = 0; delete [] mFaces; @@ -228,14 +228,14 @@ U32 LLPolyMeshSharedData::getNumKB() //----------------------------------------------------------------------------- BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) { - U32 i; - mBaseCoords = new LLVector4a[ numVertices ]; - mBaseNormals = new LLVector4a[ numVertices ]; - mBaseBinormals = new LLVector4a[ numVertices ]; - mTexCoords = new LLVector2[ numVertices ]; - mDetailTexCoords = new LLVector2[ numVertices ]; - mWeights = new F32[ numVertices ]; - for (i = 0; i < numVertices; i++) + U32 i; + mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); + mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32)); + for (i = 0; i < numVertices; i++) { mBaseCoords[i].clear(); mBaseNormals[i].clear(); diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index d09909309..184372a95 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -428,6 +428,16 @@ public: LLPolySkeletalDistortion(LLVOAvatar *avatarp); ~LLPolySkeletalDistortion(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // Special: These functions are overridden by child classes LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; } // This sets mInfo and calls initialization functions diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index b43837e89..c05d1c1f1 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -74,9 +74,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : { const S32 numVertices = mNumIndices; - mCoords = new LLVector4a[numVertices]; - mNormals = new LLVector4a[numVertices]; - mBinormals = new LLVector4a[numVertices]; + mCoords = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mNormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mBinormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); mTexCoords = new LLVector2[numVertices]; mVertexIndices = new U32[numVertices]; @@ -90,17 +90,12 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : } } - //----------------------------------------------------------------------------- // ~LLPolyMorphData() //----------------------------------------------------------------------------- LLPolyMorphData::~LLPolyMorphData() { - delete [] mVertexIndices; - delete [] mCoords; - delete [] mNormals; - delete [] mBinormals; - delete [] mTexCoords; + freeData(); } //----------------------------------------------------------------------------- @@ -119,12 +114,17 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) return FALSE; } + //------------------------------------------------------------------------- + // free any existing data + //------------------------------------------------------------------------- + freeData(); + //------------------------------------------------------------------------- // allocate vertices //------------------------------------------------------------------------- - mCoords = new LLVector4a[numVertices]; - mNormals = new LLVector4a[numVertices]; - mBinormals = new LLVector4a[numVertices]; + mCoords = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mNormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + mBinormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); mTexCoords = new LLVector2[numVertices]; // Actually, we are allocating more space than we need for the skiplist mVertexIndices = new U32[numVertices]; @@ -207,6 +207,42 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) return TRUE; } +//----------------------------------------------------------------------------- +// freeData() +//----------------------------------------------------------------------------- +void LLPolyMorphData::freeData() +{ + if (mCoords != NULL) + { + ll_aligned_free_16(mCoords); + mCoords = NULL; + } + + if (mNormals != NULL) + { + ll_aligned_free_16(mNormals); + mNormals = NULL; + } + + if (mBinormals != NULL) + { + ll_aligned_free_16(mBinormals); + mBinormals = NULL; + } + + if (mTexCoords != NULL) + { + delete [] mTexCoords; + mTexCoords = NULL; + } + + if (mVertexIndices != NULL) + { + delete [] mVertexIndices; + mVertexIndices = NULL; + } +} + //----------------------------------------------------------------------------- // LLPolyMesh::saveLLM() //----------------------------------------------------------------------------- @@ -354,9 +390,9 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) if (num_significant == 0) nindices = 1; - LLVector4a* new_coords = new LLVector4a[nindices]; - LLVector4a* new_normals = new LLVector4a[nindices]; - LLVector4a* new_binormals = new LLVector4a[nindices]; + LLVector4a* new_coords = static_cast(ll_aligned_malloc_16(nindices * sizeof(LLVector4a))); + LLVector4a* new_normals = static_cast(ll_aligned_malloc_16(nindices * sizeof(LLVector4a))); + LLVector4a* new_binormals = static_cast(ll_aligned_malloc_16(nindices * sizeof(LLVector4a))); LLVector2* new_tex_coords = new LLVector2[nindices]; U32* new_vertex_indices = new U32[nindices]; @@ -490,11 +526,7 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) //------------------------------------------------------------------------- // reallocate vertices //------------------------------------------------------------------------- - delete [] mVertexIndices; - delete [] mCoords; - delete [] mNormals; - delete [] mBinormals; - delete [] mTexCoords; + freeData(); mVertexIndices = new_vertex_indices; mCoords = new_coords; diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h index dac698437..02f5be42f 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/newview/llpolymorph.h @@ -54,6 +54,16 @@ public: ~LLPolyMorphData(); LLPolyMorphData(const LLPolyMorphData &rhs); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh); const std::string& getName() { return mName; } @@ -77,6 +87,9 @@ public: F32 mMaxDistortion; // maximum single vertex distortion in a given morph LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph LLPolyMeshSharedData* mMesh; + +private: + void freeData(); }; //----------------------------------------------------------------------------- diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index dbc2a1961..60ad83ad2 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -412,6 +412,7 @@ void LLSpatialGroup::setVisible() void LLSpatialGroup::validate() { + ll_assert_aligned(this,64); #if LL_OCTREE_PARANOIA_CHECK sg_assert(!isState(DIRTY)); @@ -1075,6 +1076,8 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds) { + ll_assert_aligned(this,16); + sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index e6b018087..fa3ce39e8 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -73,6 +73,16 @@ protected: ~LLDrawInfo(); public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawInfo(const LLDrawInfo& rhs) { @@ -111,7 +121,7 @@ public: F32 mPartSize; F32 mVSize; LLSpatialGroup* mGroup; - LLFace* mFace; //associated face + LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; @@ -186,7 +196,7 @@ public: }; }; -LL_ALIGN_PREFIX(64) +LL_ALIGN_PREFIX(16) class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; @@ -198,6 +208,16 @@ public: *this = rhs; } + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) { llerrs << "Illegal operation!" << llendl; @@ -359,12 +379,12 @@ public: V4_COUNT = 10 } eV4Index; - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children - LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node - LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node - LLVector4a mViewAngle; - LLVector4a mLastUpdateViewAngle; + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node + LL_ALIGN_16(LLVector4a mViewAngle); + LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 2c0da60b4..fffe20208 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -67,6 +67,16 @@ public: /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const; + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex avatar_sex ) {} @@ -143,6 +153,16 @@ public: LLTexLayerParamColor( LLVOAvatar* avatar ); /* virtual */ ~LLTexLayerParamColor(); + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const; // LLVisualParam Virtual functions diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index a4a05fca8..82d88bc3d 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -52,9 +52,20 @@ const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X const BOOL FOR_SELECTION = TRUE; const BOOL NOT_FOR_SELECTION = FALSE; + +LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } typedef enum { @@ -138,6 +149,7 @@ protected: S16 mZoomSubregion; public: -}; +} LL_ALIGN_POSTFIX(16); + #endif // LL_LLVIEWERCAMERA_H diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 4b27f6a2a..1b26891c8 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3139,7 +3139,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (isImpostor() && !mNeedsImpostorUpdate) { - LLVector4a ext[2]; + LL_ALIGN_16(LLVector4a ext[2]); F32 distance; LLVector3 angle; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 81529a2f3..39937c9db 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -140,6 +140,16 @@ protected: **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. @@ -261,7 +271,7 @@ public: bool isBuilt() const { return mIsBuilt; } private: //aligned members - LLVector4a mImpostorExtents[2]; + LL_ALIGN_16(LLVector4a mImpostorExtents[2]); private: BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 0105315ff..03c3b9b75 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -49,6 +49,16 @@ class LLVOAvatarSelf : **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual ~LLVOAvatarSelf(); virtual void markDead(); From 7533b475beca4988443e3bd12d5e99e160c78dad Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 16 Oct 2012 17:15:23 -0500 Subject: [PATCH 003/213] TCMalloc can now be manually disabled via develop.py -DDISABLE_TCMALLOC:BOOL=ON --- indra/cmake/GooglePerfTools.cmake | 4 ++-- indra/cmake/Variables.cmake | 1 + indra/develop.py | 15 ++++++++------- indra/newview/sgmemstat.cpp | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index c102542e0..3ad669c94 100644 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -11,10 +11,10 @@ else (STANDALONE) if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64) use_prebuilt_binary(gperftools) endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64) - if (WINDOWS) + if (WINDOWS AND NOT DISABLE_TCMALLOC) set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib) set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"") - endif (WINDOWS) + endif (WINDOWS AND NOT DISABLE_TCMALLOC) if (LINUX) if(USE_GOOGLE_PERFTOOLS) set(TCMALLOC_LIBRARIES tcmalloc) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index c6035597f..9e7d411a2 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -30,6 +30,7 @@ set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX}) set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX}) set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX}) set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX}) +set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)") set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)") set(VISTA_ICON OFF CACHE BOOL "Allow vista icon with pre 2008 Visual Studio IDEs. (Assumes replacement old rcdll.dll with new rcdll.dll from win sdk 7.0 or later)") diff --git a/indra/develop.py b/indra/develop.py index 5e94ca125..a38758d39 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -782,13 +782,14 @@ Commands: Command-options for "configure": We use cmake variables to change the build configuration. - -DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc - -DVIEWER:BOOL=OFF Don't configure the viewer - -DPACKAGE:BOOL=ON Create "package" target to make installers - -DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language - -DLL_TESTS:BOOL=OFF Don't generate unit test projects - -DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project - -VISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!) + -DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc + -DVIEWER:BOOL=OFF Don't configure the viewer + -DPACKAGE:BOOL=ON Create "package" target to make installers + -DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language + -DLL_TESTS:BOOL=OFF Don't generate unit test projects + -DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project + -DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc) + -DVISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!) Examples: Set up a viewer-only project for your system: diff --git a/indra/newview/sgmemstat.cpp b/indra/newview/sgmemstat.cpp index d4e22a882..d8c4a3f5a 100644 --- a/indra/newview/sgmemstat.cpp +++ b/indra/newview/sgmemstat.cpp @@ -18,7 +18,7 @@ #include "llviewerprecompiledheaders.h" #include "sgmemstat.h" -#if (!LL_WINDOWS && !LL_LINUX) +#if (!(LL_LINUX || LL_USE_TCMALLOC)) bool SGMemStat::haveStat() { return false; } From 43271f290e95f8d568d2f81a40b87e6a23e8f83f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 16 Oct 2012 20:07:04 -0500 Subject: [PATCH 004/213] A few more alignment bits and bobs. --- indra/llimage/llimage.cpp | 6 ++++++ indra/llimage/llimage.h | 2 +- indra/llmath/llsimdtypes.inl | 2 ++ indra/llmath/llvolume.cpp | 20 +++++--------------- indra/newview/llface.cpp | 3 ++- indra/newview/llviewerjointmesh.cpp | 6 ++++-- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index c3f4878ee..d436e3280 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1689,6 +1689,12 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2); } +void LLImageBase::setDataAndSize(U8 *data, S32 size) +{ + ll_assert_aligned(data, 16); + mData = data; mDataSize = size; +} + //static void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels) { diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 3782ff1cf..88fc0562e 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -134,7 +134,7 @@ public: protected: // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted - void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; } + void setDataAndSize(U8 *data, S32 size); public: static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); diff --git a/indra/llmath/llsimdtypes.inl b/indra/llmath/llsimdtypes.inl index 712239e42..e905c8495 100644 --- a/indra/llmath/llsimdtypes.inl +++ b/indra/llmath/llsimdtypes.inl @@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b) inline LLSimdScalar operator-(const LLSimdScalar& a) { static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + ll_assert_aligned(signMask,16); return _mm_xor_ps(*reinterpret_cast(signMask), a); } @@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs) inline LLSimdScalar LLSimdScalar::getAbs() const { static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; + ll_assert_aligned(F_ABS_MASK_4A,16); return _mm_and_ps( mQ, *reinterpret_cast(F_ABS_MASK_4A)); } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ebf049591..d090b8429 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -95,17 +95,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1; extern BOOL gDebugGL; -void assert_aligned(void* ptr, uintptr_t alignment) -{ -#if 0 - uintptr_t t = (uintptr_t) ptr; - if (t%alignment != 0) - { - llerrs << "Alignment check failed." << llendl; - } -#endif -} - BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -6967,14 +6956,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts) if (num_verts) { mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - assert_aligned(mPositions, 16); + ll_assert_aligned(mPositions, 16); mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - assert_aligned(mNormals, 16); + ll_assert_aligned(mNormals, 16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); - assert_aligned(mTexCoords, 16); + ll_assert_aligned(mTexCoords, 16); } else { @@ -7062,7 +7051,8 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; if (new_size != old_size) { - mIndices = (U16*) realloc(mIndices, new_size); + mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size); + ll_assert_aligned(mIndices,16); } mIndices[mNumIndices++] = idx; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index c42846b6f..d1e0e3c52 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1639,7 +1639,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (!do_xform) { LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM); - LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); } else { diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index d9e9499ce..48661cd54 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -736,8 +736,10 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w F32* vw = (F32*) vertex_weightsp.get(); F32* cw = (F32*) clothing_weightsp.get(); - LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); + S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); } From b73f4dd8e457d473bbfa063ca2d1224b91bf16b7 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 20 Oct 2012 17:02:43 -0500 Subject: [PATCH 005/213] Catch up with viewer-beta. Primarily sim transition alterations to reduce frame hitching, and some optimization in LLViewerObjectList (std::set -> std::vector and and some allocation tweakage). --- indra/newview/lldrawable.cpp | 57 +++++++++++++------- indra/newview/lldrawpool.cpp | 42 --------------- indra/newview/lldrawpool.h | 4 -- indra/newview/lldrawpoolavatar.cpp | 8 +++ indra/newview/lldrawpoolterrain.cpp | 28 ++++++++++ indra/newview/lldrawpoolterrain.h | 1 + indra/newview/lldrawpooltree.cpp | 15 ++++++ indra/newview/llspatialpartition.cpp | 13 ++++- indra/newview/llspatialpartition.h | 3 +- indra/newview/llsurface.cpp | 24 +++++++-- indra/newview/llsurface.h | 1 + indra/newview/llsurfacepatch.cpp | 14 +++-- indra/newview/llviewerdisplay.cpp | 4 ++ indra/newview/llviewermessage.cpp | 2 + indra/newview/llviewerobject.cpp | 1 + indra/newview/llviewerobject.h | 5 ++ indra/newview/llviewerobjectlist.cpp | 79 ++++++++++++++++++++++------ indra/newview/llviewerobjectlist.h | 4 +- indra/newview/llvotree.cpp | 6 +-- indra/newview/pipeline.cpp | 3 ++ 20 files changed, 218 insertions(+), 96 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 97b9764ab..98343700d 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -63,6 +63,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f; static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +extern bool gShiftFrame; + //////////////////////// // @@ -722,6 +724,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) return; } + if (gShiftFrame) + { + return; + } + //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); @@ -820,14 +827,19 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) mXform.setPosition(mVObjp->getPositionAgent()); } - mXform.setRotation(mVObjp->getRotation()); - mXform.setScale(1,1,1); mXform.updateMatrix(); if (isStatic()) { LLVOVolume* volume = getVOVolume(); - if (!volume) + + bool rebuild = (!volume && + getRenderType() != LLPipeline::RENDER_TYPE_TREE && + getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN && + getRenderType() != LLPipeline::RENDER_TYPE_SKY && + getRenderType() != LLPipeline::RENDER_TYPE_GROUND); + + if (rebuild) { gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); } @@ -841,7 +853,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) facep->mExtents[0].add(shift_vector); facep->mExtents[1].add(shift_vector); - if (!volume && facep->hasGeometry()) + if (rebuild && facep->hasGeometry()) { facep->clearVertexBuffer(); } @@ -960,6 +972,12 @@ LLSpatialGroup* LLDrawable::getSpatialGroup() const void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { + //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this + llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this)); + + //precondition: groupp MUST be null or groupp MUST contain this + llassert(!groupp || groupp->hasElement(this)); + /*if (mSpatialGroupp && (groupp != mSpatialGroupp)) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); @@ -979,9 +997,12 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) } } - mSpatialGroupp = groupp; + //postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1 + //postcondition: if next group is NOT NULL, binIndex must not be -1 + llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 : + getBinIndex() != -1); - llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); + mSpatialGroupp = groupp; } LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1416,6 +1437,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) return; } + if (gShiftFrame) + { + return; + } + if (mDrawable->getVObj()) { if (mDrawable->getVObj()->isAttachment()) @@ -1499,13 +1525,11 @@ void LLSpatialBridge::cleanupReferences() LLDrawable::cleanupReferences(); if (mDrawable) { - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->mOctreeNode->remove(mDrawable); - mDrawable->setSpatialGroup(NULL); - } + /* + DON'T DO THIS -- this should happen through octree destruction + + mDrawable->setSpatialGroup(NULL); if (mDrawable->getVObj()) { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1516,15 +1540,10 @@ void LLSpatialBridge::cleanupReferences() LLDrawable* drawable = child->mDrawable; if (drawable) { - LLSpatialGroup* group = drawable->getSpatialGroup(); - if (group) - { - group->mOctreeNode->remove(drawable); - drawable->setSpatialGroup(NULL); - } + drawable->setSpatialGroup(NULL); } } - } + }*/ LLDrawable* drawablep = mDrawable; mDrawable = NULL; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 69a3cf419..0232f7139 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -257,48 +257,6 @@ void LLFacePool::dirtyTextures(const std::set& textures { } -// static -S32 LLFacePool::drawLoop(face_array_t& face_list) -{ - S32 res = 0; - if (!face_list.empty()) - { - for (std::vector::iterator iter = face_list.begin(); - iter != face_list.end(); iter++) - { - LLFace *facep = *iter; - res += facep->renderIndexed(); - } - } - return res; -} - -// static -S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) -{ - S32 res = 0; - if (!face_list.empty()) - { - for (std::vector::iterator iter = face_list.begin(); - iter != face_list.end(); iter++) - { - LLFace *facep = *iter; - gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE); - gGL.getTexUnit(0)->activate(); - res += facep->renderIndexed(); - } - } - return res; -} - -void LLFacePool::drawLoop() -{ - if (!mDrawFace.empty()) - { - drawLoop(mDrawFace); - } -} - void LLFacePool::enqueue(LLFace* facep) { mDrawFace.push_back(facep); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 341583996..890536ba2 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -192,10 +192,6 @@ public: void buildEdges(); - static S32 drawLoop(face_array_t& face_list); - static S32 drawLoopSetTex(face_array_t& face_list, S32 stage); - void drawLoop(); - void addFaceReference(LLFace *facep); void removeFaceReference(LLFace *facep); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 3e818faa4..b12279209 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1040,9 +1040,13 @@ void LLDrawPoolAvatar::endDeferredSkinned() gGL.getTexUnit(0)->activate(); } +static LLFastTimer::DeclareTimer FTM_RENDER_AVATARS("renderAvatars"); + void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { + LLFastTimer t(FTM_RENDER_AVATARS); + if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) @@ -1546,8 +1550,12 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) renderRigged(avatar, RIGGED_DEFERRED_BUMP); } +static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO"); + void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) { + LLFastTimer t(FTM_RIGGED_VBO); + //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b98cc84e8..d1ef2c6d7 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -302,6 +302,34 @@ void LLDrawPoolTerrain::renderShadow(S32 pass) //glCullFace(GL_BACK); } + +void LLDrawPoolTerrain::drawLoop() +{ + if (!mDrawFace.empty()) + { + for (std::vector::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *facep = *iter; + + LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix); + + if (model_matrix != gGLLastMatrix) + { + gGLLastMatrix = model_matrix; + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; + } + + facep->renderIndexed(); + } + } +} + void LLDrawPoolTerrain::renderFullShader() { // Hack! Get the region that this draw pool is rendering from! diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 24ed06500..a9fb48bac 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -89,6 +89,7 @@ protected: void renderFull2TU(); void renderFull4TU(); void renderFullShader(); + void drawLoop(); }; #endif // LL_LLDRAWPOOLSIMPLE_H diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 9500f5aff..233d0a691 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -43,6 +43,7 @@ #include "llviewershadermgr.h" #include "llrender.h" #include "llviewercontrol.h" +#include "llviewerregion.h" S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; @@ -116,8 +117,22 @@ void LLDrawPoolTree::render(S32 pass) { LLFace *face = *iter; LLVertexBuffer* buff = face->getVertexBuffer(); + if(buff) { + LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); + + if (model_matrix != gGLLastMatrix) + { + gGLLastMatrix = model_matrix; + gGL.loadMatrix(gGLModelView); + if (model_matrix) + { + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); + } + gPipeline.mMatrixOpCount++; + } + buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); gPipeline.addTrianglesDrawn(buff->getNumIndices()); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 60ad83ad2..1094b3668 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -73,6 +73,7 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f; #define assert_states_valid(x) #endif +extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; @@ -806,7 +807,10 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - if (!mSpatialPartition->mRenderByGroup) + if (!mSpatialPartition->mRenderByGroup && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -1121,6 +1125,11 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) return; } + if (gShiftFrame) + { + return; + } + #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { @@ -1735,6 +1744,8 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) drawablep->setSpatialGroup(NULL); } + drawablep->setSpatialGroup(NULL); + assert_octree_valid(mOctree); return TRUE; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index fa3ce39e8..2c1624734 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -352,9 +352,10 @@ public: void dirtyMesh() { setState(MESH_DIRTY); } //octree wrappers to make code more readable - //element_list& getData() { return mOctreeNode->getData(); } + //element_list& getData() { return mOctreeNode->getData(); } //unused element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } + bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } bool isEmpty() const { return mOctreeNode->isEmpty(); } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index de0562b7f..e25fe241a 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -61,6 +61,7 @@ #include "lldrawable.h" extern LLPipeline gPipeline; +extern bool gShiftFrame; LLColor4U MAX_WATER_COLOR(0, 48, 96, 240); @@ -351,13 +352,21 @@ void LLSurface::getNeighboringRegions( std::vector& uniqueRegio } } + +void LLSurface::getNeighboringRegionsStatus( std::vector& regions ) +{ + S32 i; + for (i = 0; i < 8; i++) + { + if ( mNeighbors[i] != NULL ) + { + regions.push_back( i ); + } + } +} + void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) { - if (gNoRender) - { - return; - } - S32 i; LLSurfacePatch *patchp, *neighbor_patchp; @@ -618,6 +627,11 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta) void LLSurface::updatePatchVisibilities(LLAgent &agent) { + if (gShiftFrame) + { + return; + } + LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal()); LLSurfacePatch *patchp; diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 127bec465..b985b8568 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -148,6 +148,7 @@ public: friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); void getNeighboringRegions( std::vector& uniqueRegions ); + void getNeighboringRegionsStatus( std::vector& regions ); public: // Number of grid points on one side of a region, including +1 buffer for diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 770f6579a..0c0ccd5aa 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -49,6 +49,7 @@ #include "lldrawpool.h" #include "noise.h" +extern bool gShiftFrame; extern U64 gFrameTime; extern LLPipeline gPipeline; @@ -224,7 +225,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid(); pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid(); pos_agent.mV[VZ] = *(mDataZ + point_offset); - *vertex = pos_agent; + *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); LLVector3 tex_pos = rel_pos * (1.f/surface_stride); @@ -372,10 +373,13 @@ void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region) { if (LLPipeline::sDynamicLOD) { - LLVector3 dv = pos_region; - dv -= mCenterRegion; - mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ - llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + if (!gShiftFrame) + { + LLVector3 dv = pos_region; + dv -= mCenterRegion; + mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ + llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + } } else { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 8c932285b..66f9771f7 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -90,6 +90,8 @@ #include "rlvlocks.h" // [/RLVa:KB] +extern bool gShiftFrame; + LLPointer gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport @@ -1109,6 +1111,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo display_stats(); LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); + + gShiftFrame = false; } void render_hud_attachments() diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b8aa8571d..1da6ceb0b 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -207,6 +207,7 @@ static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT = 5; // requests static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds extern BOOL gDebugClicks; +extern bool gShiftFrame; // function prototypes bool check_offer_throttle(const std::string& from_name, bool check_only); @@ -4208,6 +4209,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**) void process_agent_movement_complete(LLMessageSystem* msg, void**) { + gShiftFrame = true; gAgentMovementCompleted = true; LLUUID agent_id; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b8833d302..0293d3f90 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -205,6 +205,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mID(id), mLocalID(0), mTotalCRC(0), + mListIndex(-1), mTEImages(NULL), mGLName(0), mbCanSelect(TRUE), diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 791393533..199027b53 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -219,6 +219,8 @@ public: const LLUUID &getID() const { return mID; } U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mTotalCRC; } + S32 getListIndex() const { return mListIndex; } + void setListIndex(S32 idx) { mListIndex = idx; } virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } @@ -603,6 +605,9 @@ public: // Last total CRC received from sim, used for caching U32 mTotalCRC; + // index into LLViewerObjectList::mActiveObjects or -1 if not in list + S32 mListIndex; + LLPointer *mTEImages; // Selection, picking and rendering variables diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 27da8f4f8..41d69425b 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -922,21 +922,32 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) LLViewerObject *objectp = NULL; // Make a copy of the list in case something in idleUpdate() messes with it - std::vector idle_list; - + static std::vector idle_list; + if(mActiveObjects.size() > idle_list.capacity()) + idle_list.reserve( mActiveObjects.size() ); + + U32 idle_count = 0; + static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); { LLFastTimer t(idle_copy); - idle_list.reserve( mActiveObjects.size() ); - for (std::set >::iterator active_iter = mActiveObjects.begin(); + for (std::vector >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { objectp = *active_iter; if (objectp) { - idle_list.push_back( objectp ); + if (idle_count >= idle_list.size()) + { + idle_list.push_back( objectp ); + } + else + { + idle_list[idle_count] = objectp; + } + ++idle_count; } else { // There shouldn't be any NULL pointers in the list, but they have caused @@ -945,12 +956,14 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } } } + + std::vector::iterator idle_end = idle_list.begin()+idle_count; static const LLCachedControl freeze_time("FreezeTime",0); if (freeze_time) { for (std::vector::iterator iter = idle_list.begin(); - iter != idle_list.end(); iter++) + iter != idle_end; iter++) { objectp = *iter; if ( @@ -966,17 +979,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) else { for (std::vector::iterator idle_iter = idle_list.begin(); - idle_iter != idle_list.end(); idle_iter++) + idle_iter != idle_end; idle_iter++) { objectp = *idle_iter; - if (!objectp->idleUpdate(agent, world, frame_time)) + if (objectp->idleUpdate(agent, world, frame_time)) { - // If Idle Update returns false, kill object! - kill_list.push_back(objectp); + num_active_objects++; } else { - num_active_objects++; + // If Idle Update returns false, kill object! + kill_list.push_back(objectp); } } for (std::vector::iterator kill_iter = kill_list.begin(); @@ -1219,7 +1232,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl; objectp->setOnActiveList(FALSE); - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); } if (objectp->isOnMap()) @@ -1409,6 +1422,26 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) mNumDeadObjects = 0; } +void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) +{ + S32 idx = objectp->getListIndex(); + if (idx != -1) + { //remove by moving last element to this object's position + llassert(mActiveObjects[idx] == objectp); + + objectp->setListIndex(-1); + + S32 last_index = mActiveObjects.size()-1; + + if (idx != last_index) + { + mActiveObjects[idx] = mActiveObjects[last_index]; + mActiveObjects[idx]->setListIndex(idx); + mActiveObjects.pop_back(); + } + } +} + void LLViewerObjectList::updateActive(LLViewerObject *objectp) { LLMemType mt(LLMemType::MTYPE_OBJECT); @@ -1423,13 +1456,29 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) if (active) { //llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl; - mActiveObjects.insert(objectp); - objectp->setOnActiveList(TRUE); + S32 idx = objectp->getListIndex(); + if (idx <= -1) + { + mActiveObjects.push_back(objectp); + objectp->setListIndex(mActiveObjects.size()-1); + objectp->setOnActiveList(TRUE); + } + else + { + llassert(idx < mActiveObjects.size()); + llassert(mActiveObjects[idx] == objectp); + + if (idx >= (S32)mActiveObjects.size() || + mActiveObjects[idx] != objectp) + { + llwarns << "Invalid object list index detected!" << llendl; + } + } } else { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl; - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); objectp->setOnActiveList(FALSE); } } diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 9266dcf2d..5a48656b7 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -128,7 +128,9 @@ public: void dirtyAllObjectInventory(); + void removeFromActiveList(LLViewerObject* objectp); void updateActive(LLViewerObject *objectp); + void updateAvatarVisibility(); // Selection related stuff @@ -206,7 +208,7 @@ public: typedef std::vector > vobj_list_t; vobj_list_t mObjects; - std::set > mActiveObjects; + std::vector > mActiveObjects; vobj_list_t mMapObjects; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index e50c11ced..cbc22781a 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -389,7 +389,7 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) // *TODO: I don't know what's so special about trees // that they don't get REBUILD_POSITION automatically // at a higher level. - const LLVector3 &this_position = getPositionAgent(); + const LLVector3 &this_position = getPositionRegion(); if (this_position != mLastPosition) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); @@ -858,10 +858,10 @@ void LLVOTree::updateMesh() LLMatrix4 matrix; // Translate to tree base HACK - adjustment in Z plants tree underground - const LLVector3 &pos_agent = getPositionAgent(); + const LLVector3 &pos_region = getPositionRegion(); //gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); LLMatrix4 trans_mat; - trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); + trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f); trans_mat *= matrix; // Rotate to tree position and bend for current trunk/wind diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index aa5d9ab2b..0e9726b04 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -142,6 +142,8 @@ void check_stack_depth(S32 stack_depth) //#define DEBUG_INDICES #endif +bool gShiftFrame = false; + const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; @@ -543,6 +545,7 @@ void LLPipeline::cleanup() mInitialized = FALSE; mDeferredVB = NULL; + mCubeVB = NULL; } //============================================================================ From 44faf3e169ea70d2d5d266675dc35aa242d7382c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 21 Oct 2012 17:14:00 -0500 Subject: [PATCH 006/213] Removed annoying attribute consumption warnings. Alpha pass was leaving shader bound, which hosed up updateCull for water reflections (updateCull only binds occlusion shader if another shader isn't currently bound) --- indra/newview/lldrawpoolalpha.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 865e89f89..aad2a8acb 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -205,7 +205,7 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass ) LLFastTimer t(FTM_RENDER_ALPHA); LLRenderPass::endRenderPass(pass); - if(gPipeline.canUseWindLightShaders()) + if(mVertexShaderLevel > 0) { LLGLSLShader::bindNoShader(); } From 5be31898f1be2edd110b3c013730371fbe34b0dc Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 21 Oct 2012 17:14:29 -0500 Subject: [PATCH 007/213] Don't compile avatar eye shader, as it isn't used anywhere. --- indra/newview/llviewershadermgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 25014b640..f427b10a7 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -2396,7 +2396,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() if (success) { - gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; + /*gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; gAvatarEyeballProgram.mFeatures.calculatesLighting = true; gAvatarEyeballProgram.mFeatures.isSpecular = true; gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; @@ -2409,7 +2409,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); gAvatarEyeballProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(NULL, NULL); + success = gAvatarEyeballProgram.createShader(NULL, NULL);*/ } if( !success ) From 413a8111c0a15191cd0373015b38bea430b3890f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 21 Oct 2012 17:16:22 -0500 Subject: [PATCH 008/213] PASS_INVISI_SHINY never issued. Commented out some unused code. --- indra/newview/lldrawpoolbump.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index dd8b4e80c..28a1acaab 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1572,16 +1572,21 @@ void LLDrawPoolInvisible::render(S32 pass) gOcclusionProgram.unbind(); } - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + /*if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) // invisible (deprecated) { beginShiny(true); renderShiny(true); endShiny(true); - } + }*/ } void LLDrawPoolInvisible::beginDeferredPass(S32 pass) { + static const LLCachedControl enable("SianaRenderDeferredInvisiprim"); + if (!enable) + { + return; + } beginRenderPass(pass); } @@ -1593,7 +1598,8 @@ void LLDrawPoolInvisible::endDeferredPass( S32 pass ) void LLDrawPoolInvisible::renderDeferred( S32 pass ) { //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff static const LLCachedControl enable("SianaRenderDeferredInvisiprim"); - if (!enable) { + if (!enable) + { return; } @@ -1610,10 +1616,10 @@ void LLDrawPoolInvisible::renderDeferred( S32 pass ) gOcclusionProgram.unbind(); - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + /*if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) // invisible (deprecated) { beginShiny(true); renderShiny(true); endShiny(true); - } + }*/ } From ed4997168b353f004e797a8dc7d46976cf450fb5 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 02:50:04 -0500 Subject: [PATCH 009/213] LLViewerObject::idleUpdate now returns void. Texture animations/flexis now have their own update queues. --- indra/newview/lldrawable.cpp | 38 ++--- indra/newview/lldrawable.h | 3 +- indra/newview/llflexibleobject.cpp | 109 +++++++++---- indra/newview/llflexibleobject.h | 46 +++--- indra/newview/llsurface.cpp | 36 ++--- indra/newview/llsurface.h | 36 ++--- indra/newview/llsurfacepatch.cpp | 36 ++--- indra/newview/llviewerobject.cpp | 41 +++-- indra/newview/llviewerobject.h | 2 +- indra/newview/llviewerobjectlist.cpp | 55 ++++--- indra/newview/llviewerregion.cpp | 3 +- indra/newview/llviewertextureanim.cpp | 26 ++- indra/newview/llviewertextureanim.h | 11 +- indra/newview/llvoavatar.cpp | 15 +- indra/newview/llvoavatar.h | 2 +- indra/newview/llvoavatarself.cpp | 21 +-- indra/newview/llvoavatarself.h | 2 +- indra/newview/llvoclouds.cpp | 6 +- indra/newview/llvoclouds.h | 2 +- indra/newview/llvograss.cpp | 13 +- indra/newview/llvograss.h | 2 +- indra/newview/llvoground.cpp | 48 ++---- indra/newview/llvoground.h | 38 ++--- indra/newview/llvopartgroup.cpp | 3 +- indra/newview/llvopartgroup.h | 2 +- indra/newview/llvosky.cpp | 3 +- indra/newview/llvosky.h | 44 +++-- indra/newview/llvotree.cpp | 6 +- indra/newview/llvotree.h | 2 +- indra/newview/llvovolume.cpp | 221 +++++++++++--------------- indra/newview/llvovolume.h | 5 +- indra/newview/llvowater.cpp | 11 +- indra/newview/llvowater.h | 2 +- indra/newview/llvowlsky.cpp | 4 +- indra/newview/llvowlsky.h | 2 +- indra/newview/pipeline.cpp | 11 +- 36 files changed, 448 insertions(+), 459 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 98343700d..f6a6a9013 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -104,7 +104,6 @@ void LLDrawable::init() mPositionGroup.clear(); mExtents[0].clear(); mExtents[1].clear(); - mQuietCount = 0; mState = 0; mVObjp = NULL; @@ -412,6 +411,8 @@ void LLDrawable::makeActive() if (!isRoot() && !mParent->isActive()) { mParent->makeActive(); + //NOTE: linked set will now NEVER become static + mParent->setState(LLDrawable::ACTIVE_CHILD); } //all child objects must also be active @@ -429,14 +430,6 @@ void LLDrawable::makeActive() } } - if (mVObjp->getPCode() == LL_PCODE_VOLUME) - { - if (mVObjp->isFlexible()) - { - return; - } - } - if (mVObjp->getPCode() == LL_PCODE_VOLUME) { gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); @@ -444,28 +437,22 @@ void LLDrawable::makeActive() updatePartition(); } - if (isRoot()) - { - mQuietCount = 0; - } - else - { - getParent()->mQuietCount = 0; - } + llassert(isAvatar() || isRoot() || mParent->isActive()); } void LLDrawable::makeStatic(BOOL warning_enabled) { - if (isState(ACTIVE)) + if (isState(ACTIVE) && + !isState(ACTIVE_CHILD) && + !mVObjp->isAttachment() && + !mVObjp->isFlexible()) { clearState(ACTIVE | ANIMATED_CHILD); - if (mParent.notNull() && mParent->isActive() && warning_enabled) - { - LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL; - } - + //drawable became static with active parent, not acceptable + llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); + LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -492,8 +479,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) mSpatialBridge->markDead(); setSpatialBridge(NULL); } + updatePartition(); } - updatePartition(); } // Returns "distance" between target destination and resulting xfrom @@ -643,8 +630,6 @@ BOOL LLDrawable::updateMove() return FALSE; } - makeActive(); - BOOL done; if (isState(MOVE_UNDAMPED)) @@ -653,6 +638,7 @@ BOOL LLDrawable::updateMove() } else { + makeActive(); done = updateMoveDamped(); } return done; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index ff6023597..e2ea0140f 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -298,6 +298,7 @@ public: RIGGED = 0x08000000, PARTITION_MOVE = 0x10000000, ANIMATED_CHILD = 0x20000000, + ACTIVE_CHILD = 0x40000000, } EDrawableFlags; private: //aligned members @@ -311,8 +312,6 @@ public: LLPointer mParent; F32 mDistanceWRTCamera; - - S32 mQuietCount; static S32 getCurrentFrame() { return sCurVisible; } static S32 getMinVisFrameRange(); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 8b0fd109f..d741beed5 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -44,6 +44,8 @@ #include "llvoavatar.h" /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; +std::vector LLVolumeImplFlexible::sInstanceList; +std::vector LLVolumeImplFlexible::sUpdateDelay; static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild"); static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update"); @@ -70,8 +72,45 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD { mVO->mDrawable->makeActive() ; } + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); + sUpdateDelay.push_back(0); }//----------------------------------------------- +LLVolumeImplFlexible::~LLVolumeImplFlexible() +{ + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx]; + } + + sInstanceList.pop_back(); + sUpdateDelay.pop_back(); +} + +//static +void LLVolumeImplFlexible::updateClass() +{ + std::vector::iterator delay_iter = sUpdateDelay.begin(); + + for (std::vector::iterator iter = sInstanceList.begin(); + iter != sInstanceList.end(); + ++iter) + { + --(*delay_iter); + if (*delay_iter <= 0) + { + (*iter)->doIdleUpdate(); + } + ++delay_iter; + } +} + LLVector3 LLVolumeImplFlexible::getFramePosition() const { return mVO->getRenderPosition(); @@ -296,22 +335,17 @@ void LLVolumeImplFlexible::updateRenderRes() // optimization similar to what Havok does for objects that are stationary. //--------------------------------------------------------------------------------- static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); -void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVolumeImplFlexible::doIdleUpdate() { LLDrawable* drawablep = mVO->mDrawable; if (drawablep) { //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - - //flexible objects never go static - drawablep->mQuietCount = 0; - if (!drawablep->isRoot()) - { - LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); - parent->mDrawable->mQuietCount = 0; - } - + + //ensure drawable is active + drawablep->makeActive(); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { bool visible = drawablep->isVisible(); @@ -321,34 +355,47 @@ void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 updateRenderRes(); gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); } - else if (visible && - !drawablep->isState(LLDrawable::IN_REBUILD_Q1) && - mVO->getPixelArea() > 256.f) + else { - U32 id; F32 pixel_area = mVO->getPixelArea(); - if (mVO->isRootEdit()) - { - id = mID; - } - else - { - LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); - id = parent->getVolumeInterfaceID(); - } - U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; - if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) + if (visible) { - updateRenderRes(); - gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) && + mVO->getPixelArea() > 256.f) + { + U32 id; + + if (mVO->isRootEdit()) + { + id = mID; + } + else + { + LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); + id = parent->getVolumeInterfaceID(); + } + + if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) + { + sUpdateDelay[mInstanceIndex] = (S32) update_period-1; + + updateRenderRes(); + + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + } + } + } + else + { + sUpdateDelay[mInstanceIndex] = (S32) update_period; } } - } - if(!mInitialized) - updateRenderRes(); + } + //if(!mInitialized) + // updateRenderRes(); } } @@ -372,7 +419,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() { BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; - doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0); + doIdleUpdate(); if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index 7d68a67da..7d0d4c83c 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -3,31 +3,25 @@ * @author JJ Ventrella, Andrew Meadows, Tom Yedwab * @brief Flexible object definition * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -76,8 +70,16 @@ struct LLFlexibleObjectSection //--------------------------------------------------------- class LLVolumeImplFlexible : public LLVolumeInterface { +private: + static std::vector sInstanceList; + static std::vector sUpdateDelay; + S32 mInstanceIndex; + public: + static void updateClass(); + LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes); + ~LLVolumeImplFlexible(); // Implements LLVolumeInterface U32 getID() const { return mID; } @@ -85,7 +87,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface LLQuaternion getFrameRotation() const; LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; } void updateRenderRes(); - void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void doIdleUpdate(); BOOL doUpdateGeometry(LLDrawable *drawable); LLVector3 getPivotPosition() const; void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index e25fe241a..39ddbcc4e 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -2,31 +2,25 @@ * @file llsurface.cpp * @brief Implementation of LLSurface class * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index b985b8568..a693f6943 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -2,31 +2,25 @@ * @file llsurface.h * @brief Description of LLSurface class * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 0c0ccd5aa..3ebea883c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -2,31 +2,25 @@ * @file llsurfacepatch.cpp * @brief LLSurfacePatch class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 0293d3f90..008a75c90 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -810,6 +810,12 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) } LLDrawable* old_parent = mDrawable->mParent; mDrawable->mParent = parentp; + + if (parentp && mDrawable->isActive()) + { + parentp->makeActive(); + parentp->setState(LLDrawable::ACTIVE_CHILD); + } gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); if( (old_parent != parentp && old_parent) @@ -2133,9 +2139,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, gPipeline.addDebugBlip(getPositionAgent(), color); } - if ((0.0f == vel_mag_sq) && - (0.0f == accel_mag_sq) && - (0.0f == getAngularVelocity().magVecSquared())) + const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO; + + llassert(vel_mag_sq >= 0.f); + llassert(accel_mag_sq >= 0.f); + llassert(getAngularVelocity().magVecSquared() >= 0.f); + + if ((MAG_CUTOFF >= vel_mag_sq) && + (MAG_CUTOFF >= accel_mag_sq) && + (MAG_CUTOFF >= getAngularVelocity().magVecSquared())) { mStatic = TRUE; // This object doesn't move! } @@ -2209,17 +2221,15 @@ BOOL LLViewerObject::isActive() const return TRUE; } -BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) + + +void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { //static LLFastTimer::DeclareTimer ftm("Viewer Object"); //LLFastTimer t(ftm); - if (mDead) + if (!mDead) { - // It's dead. Don't update it. - return TRUE; - } - // CRO - don't velocity interp linked objects! // Leviathan - but DO velocity interp joints if (!mStatic && sVelocityInterpolate && !isSelected()) @@ -2228,12 +2238,12 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) F32 dt_raw = (F32)(time - mLastInterpUpdateSecs); F32 dt = mTimeDilation * dt_raw; - applyAngularVelocity(dt); + applyAngularVelocity(dt); - if (isAttachment()) - { - mLastInterpUpdateSecs = time; - return TRUE; + if (isAttachment()) + { + mLastInterpUpdateSecs = time; + return; } else { // Move object based on it's velocity and rotation @@ -2242,8 +2252,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } updateDrawable(FALSE); - - return TRUE; +} } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 199027b53..c83b1695a 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -150,7 +150,7 @@ public: LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name // Object create and update functions - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Types of media we can associate enum { MEDIA_NONE = 0, MEDIA_SET = 1 }; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 41d69425b..69ed84d00 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -56,6 +56,8 @@ #include "llstring.h" #include "llhudnametag.h" #include "lldrawable.h" +#include "llflexibleobject.h" +#include "llviewertextureanim.h" #include "xform.h" #include "llsky.h" #include "llviewercamera.h" @@ -917,8 +919,6 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) const F64 frame_time = LLFrameTimer::getElapsedSeconds(); - std::vector kill_list; - S32 num_active_objects = 0; LLViewerObject *objectp = NULL; // Make a copy of the list in case something in idleUpdate() messes with it @@ -982,24 +982,20 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) idle_iter != idle_end; idle_iter++) { objectp = *idle_iter; - if (objectp->idleUpdate(agent, world, frame_time)) - { - num_active_objects++; - } - else - { - // If Idle Update returns false, kill object! - kill_list.push_back(objectp); - } - } - for (std::vector::iterator kill_iter = kill_list.begin(); - kill_iter != kill_list.end(); kill_iter++) - { - objectp = *kill_iter; - killObject(objectp); + llassert(objectp->isActive()); + objectp->idleUpdate(agent, world, frame_time); + } + + //update flexible objects + LLVolumeImplFlexible::updateClass(); + + //update animated textures + LLViewerTextureAnim::updateClass(); } + + fetchObjectCosts(); fetchPhysicsFlags(); @@ -1066,7 +1062,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) */ LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size() - mNumDeadObjects); - LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects); + LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); } @@ -1437,8 +1433,9 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) { mActiveObjects[idx] = mActiveObjects[last_index]; mActiveObjects[idx]->setListIndex(idx); - mActiveObjects.pop_back(); } + + mActiveObjects.pop_back(); } } @@ -1482,6 +1479,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) objectp->setOnActiveList(FALSE); } } + + llassert(objectp->isActive() || objectp->getListIndex() == -1); + } void LLViewerObjectList::updateObjectCost(LLViewerObject* object) @@ -1552,6 +1552,10 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id) mPendingPhysicsFlags.erase(object_id); } +static LLFastTimer::DeclareTimer FTM_SHIFT_OBJECTS("Shift Objects"); +static LLFastTimer::DeclareTimer FTM_PIPELINE_SHIFT("Pipeline Shift"); +static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift"); + void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { // This is called when we shift our origin when we cross region boundaries... @@ -1563,6 +1567,8 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) return; } + LLFastTimer t(FTM_SHIFT_OBJECTS); + LLViewerObject *objectp; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { @@ -1579,8 +1585,15 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) } } - gPipeline.shiftObjects(offset); - LLWorld::getInstance()->shiftRegions(offset); + { + LLFastTimer t(FTM_PIPELINE_SHIFT); + gPipeline.shiftObjects(offset); + } + + { + LLFastTimer t(FTM_REGION_SHIFT); + LLWorld::getInstance()->shiftRegions(offset); + } } void LLViewerObjectList::repartitionObjects() diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 11e47bd77..fbbe04023 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1533,7 +1533,8 @@ void LLViewerRegion::unpackRegionHandshake() // all of our terrain stuff, by if (compp->getParamsReady()) { - getLand().dirtyAllPatches(); + //this line creates frame stalls on region crossing and removing it appears to have no effect + //getLand().dirtyAllPatches(); } else { diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp index 9f1ac7c49..2b364851a 100644 --- a/indra/newview/llviewertextureanim.cpp +++ b/indra/newview/llviewertextureanim.cpp @@ -27,21 +27,37 @@ #include "llviewerprecompiledheaders.h" #include "llviewertextureanim.h" +#include "llvovolume.h" #include "llmath.h" #include "llerror.h" -LLViewerTextureAnim::LLViewerTextureAnim() : LLTextureAnim() +std::vector LLViewerTextureAnim::sInstanceList; + +LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim() { + mVObj = vobj; mLastFrame = -1.f; // Force an update initially mLastTime = 0.f; mOffS = mOffT = 0; mScaleS = mScaleT = 1; mRot = 0; + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); } LLViewerTextureAnim::~LLViewerTextureAnim() { + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + } + + sInstanceList.pop_back(); } void LLViewerTextureAnim::reset() @@ -50,6 +66,14 @@ void LLViewerTextureAnim::reset() mTimer.reset(); } +//static +void LLViewerTextureAnim::updateClass() +{ + for (std::vector::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter) + { + (*iter)->mVObj->animateTextures(); + } +} S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t, F32 &scale_s, F32 &scale_t, diff --git a/indra/newview/llviewertextureanim.h b/indra/newview/llviewertextureanim.h index dd7bd0cb9..abbfabceb 100644 --- a/indra/newview/llviewertextureanim.h +++ b/indra/newview/llviewertextureanim.h @@ -30,10 +30,18 @@ #include "lltextureanim.h" #include "llframetimer.h" +class LLVOVolume; + class LLViewerTextureAnim : public LLTextureAnim { +private: + static std::vector sInstanceList; + S32 mInstanceIndex; + public: - LLViewerTextureAnim(); + static void updateClass(); + + LLViewerTextureAnim(LLVOVolume* vobj); virtual ~LLViewerTextureAnim(); /*virtual*/ void reset(); @@ -51,6 +59,7 @@ public: F32 mRot; protected: + LLVOVolume* mVObj; LLFrameTimer mTimer; F64 mLastTime; F32 mLastFrame; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1b26891c8..96f3baa35 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2859,7 +2859,7 @@ void LLVOAvatar::dumpAnimationState() //------------------------------------------------------------------------ // idleUpdate() //------------------------------------------------------------------------ -BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLMemType mt(LLMemType::MTYPE_AVATAR); LLFastTimer t(FTM_AVATAR_UPDATE); @@ -2867,12 +2867,12 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) if (isDead()) { llinfos << "Warning! Idle on dead avatar" << llendl; - return TRUE; - } + return; + } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) { - return TRUE; + return; } checkTextureLoading() ; @@ -2941,7 +2941,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) if (gNoRender) { - return TRUE; + return; } idleUpdateVoiceVisualizer( voice_enabled ); @@ -2958,8 +2958,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateNameTag( root_pos_last ); idleUpdateRenderCost(); - - return TRUE; } void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) @@ -8828,6 +8826,9 @@ void LLVOAvatar::cullAvatarsByPixelArea() } } + // runway - this doesn't detect gray/grey state. + // think we just need to be checking self av since it's the only + // one with lltexlayer stuff. S32 grey_avatars = 0; if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars)) { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 39937c9db..2869e1670 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -181,7 +181,7 @@ public: U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual BOOL updateLOD(); BOOL updateJointLODs(); void updateLODRiggedAttachments( void ); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 2d8010c70..3381d0890 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -570,25 +570,14 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) } // virtual -BOOL LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (!isAgentAvatarValid()) + if (isAgentAvatarValid()) { - return TRUE; + LLVOAvatar::idleUpdate(agent, world, time); + if(!gNoRender) + idleUpdateTractorBeam(); } - /*if(!gNoRender) - { - //Emerald performs some force-bakes stuff here. Added it in because we noticed slow responses with client tag ident. -HgB - for(U8 i=0;iforceActive(); - } - }*/ - LLVOAvatar::idleUpdate(agent,world,time); - if(!gNoRender) - idleUpdateTractorBeam(); - return TRUE; } // virtual diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 03c3b9b75..4f261266f 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -85,7 +85,7 @@ protected: //-------------------------------------------------------------------- public: /*virtual*/ void updateRegion(LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); //-------------------------------------------------------------------- // LLCharacter interface and related diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index b63103acb..10c03ebda 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -79,11 +79,11 @@ BOOL LLVOClouds::isActive() const } -BOOL LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS))) { - return TRUE; + return; } // Set dirty flag (so renderer will rebuild primitive) @@ -91,8 +91,6 @@ BOOL LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } - - return TRUE; } diff --git a/indra/newview/llvoclouds.h b/indra/newview/llvoclouds.h index 685400f32..089f3efc1 100644 --- a/indra/newview/llvoclouds.h +++ b/indra/newview/llvoclouds.h @@ -69,7 +69,7 @@ public: /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area void updateFaceSize(S32 idx) { } - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual U32 getPartitionType() const; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 9e9b0c8a3..a124311b3 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -301,17 +301,17 @@ BOOL LLVOGrass::isActive() const return TRUE; } -BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS))) { - return TRUE; + return; } if (!mDrawable) { // So drones work. - return TRUE; + return; } if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass @@ -321,21 +321,22 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) mNumBlades = 0 ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } - return TRUE ; + return; } else if(!mNumBlades)//restart grass rendering { mNumBlades = GRASS_MAX_BLADES ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - return TRUE ; + return; } + if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } - return TRUE; + return; } diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index 4dc79c4fd..1e1c97ea5 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -79,7 +79,7 @@ public: void plantBlades(); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 3300cb697..97b7418b4 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -2,31 +2,25 @@ * @file llvoground.cpp * @brief LLVOGround class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -55,18 +49,8 @@ LLVOGround::~LLVOGround() { } -BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GROUND))) - { - return TRUE; - } - - /*if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index 0ccb0834a..290579b4d 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -2,31 +2,25 @@ * @file llvoground.h * @brief LLVOGround class header file * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -47,7 +41,7 @@ protected: public: LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class // later? diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index f8c1f84a7..210cd1452 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -202,9 +202,8 @@ void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) mDrawable->setPositionGroup(pos); } -BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index 4948ddf55..ecf149c67 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -69,7 +69,7 @@ public: LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual F32 getBinRadius(); virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 416834eee..25371d495 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1055,9 +1055,8 @@ void LLVOSky::calcAtmospherics(void) mFadeColor.setAlpha(0); } -BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } BOOL LLVOSky::updateSky() diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index c669b92d9..2a150eccb 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -2,31 +2,25 @@ * @file llvosky.h * @brief LLVOSky class header file * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -145,7 +139,7 @@ protected: ~LLSkyTex(); - static S32 getResolution() { return sResolution; } + static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; } static S32 getNext() { return ((sCurrent+1) & 1); } @@ -467,7 +461,7 @@ public: void cleanupGL(); void restoreGL(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); BOOL updateSky(); // Graphical stuff for objects - maybe broken out into render class @@ -616,8 +610,8 @@ protected: public: //by bao //fake vertex buffer updating - //to guaranttee at least updating one VBO buffer every frame - //to walk around the bug caused by ATI card --> DEV-3855 + //to guarantee at least updating one VBO buffer every frame + //to work around the bug caused by ATI card --> DEV-3855 // void createDummyVertexBuffer() ; void updateDummyVertexBuffer() ; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index cbc22781a..c5735ef37 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -354,11 +354,11 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } -BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) { - return TRUE; + return; } S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; @@ -408,8 +408,6 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } mTrunkLOD = trunk_LOD; - - return TRUE; } const F32 TREE_BLEND_MIN = 1.f; diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index c1c94563b..f90503030 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -65,7 +65,7 @@ public: void **user_data, U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c7a7c44b0..b3c6485ce 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -185,7 +185,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -274,7 +274,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -317,157 +317,118 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, void LLVOVolume::animateTextures() { - F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; - S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); - - if (result) + if (!mDead) { - if (!mTexAnimMode) + F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; + S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); + + if (result) { - mFaceMappingChanged = TRUE; - gPipeline.markTextured(mDrawable); - } - mTexAnimMode = result | mTextureAnimp->mMode; + if (!mTexAnimMode) + { + mFaceMappingChanged = TRUE; + gPipeline.markTextured(mDrawable); + } + mTexAnimMode = result | mTextureAnimp->mMode; - S32 start=0, end=mDrawable->getNumFaces()-1; - if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) - { - start = end = mTextureAnimp->mFace; - } + S32 start=0, end=mDrawable->getNumFaces()-1; + if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) + { + start = end = mTextureAnimp->mFace; + } - for (S32 i = start; i <= end; i++) - { - LLFace* facep = mDrawable->getFace(i); - if (!facep) continue; - if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; + for (S32 i = start; i <= end; i++) + { + LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - const LLTextureEntry* te = facep->getTextureEntry(); + const LLTextureEntry* te = facep->getTextureEntry(); - if (!te) - { - continue; - } + if (!te) + { + continue; + } - if (!(result & LLViewerTextureAnim::ROTATE)) - { - te->getRotation(&rot); - } - if (!(result & LLViewerTextureAnim::TRANSLATE)) - { - te->getOffset(&off_s,&off_t); - } - if (!(result & LLViewerTextureAnim::SCALE)) - { - te->getScale(&scale_s, &scale_t); - } + if (!(result & LLViewerTextureAnim::ROTATE)) + { + te->getRotation(&rot); + } + if (!(result & LLViewerTextureAnim::TRANSLATE)) + { + te->getOffset(&off_s,&off_t); + } + if (!(result & LLViewerTextureAnim::SCALE)) + { + te->getScale(&scale_s, &scale_t); + } - if (!facep->mTextureMatrix) - { - facep->mTextureMatrix = new LLMatrix4(); - } + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } - LLMatrix4& tex_mat = *facep->mTextureMatrix; - tex_mat.setIdentity(); - LLVector3 trans ; - { - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - } + LLMatrix4& tex_mat = *facep->mTextureMatrix; + tex_mat.setIdentity(); + LLVector3 trans ; + { + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + } - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); - tex_mat.rotate(quat); + tex_mat.rotate(quat); - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; + LLMatrix4 mat; + mat.initAll(scale, LLQuaternion(), LLVector3()); + tex_mat *= mat; - tex_mat.translate(trans); + tex_mat.translate(trans); + } } - } - else - { - if (mTexAnimMode && mTextureAnimp->mRate == 0) + else { - U8 start, count; - - if (mTextureAnimp->mFace == -1) + if (mTexAnimMode && mTextureAnimp->mRate == 0) { - start = 0; - count = getNumTEs(); - } - else - { - start = (U8) mTextureAnimp->mFace; - count = 1; - } + U8 start, count; - for (S32 i = start; i < start + count; i++) - { - if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + if (mTextureAnimp->mFace == -1) { - setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + start = 0; + count = getNumTEs(); } - if (mTexAnimMode & LLViewerTextureAnim::SCALE) + else { - setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + start = (U8) mTextureAnimp->mFace; + count = 1; } - if (mTexAnimMode & LLViewerTextureAnim::ROTATE) - { - setTERotation(i, mTextureAnimp->mRot); - } - } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; + for (S32 i = start; i < start + count; i++) + { + if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + { + setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + } + if (mTexAnimMode & LLViewerTextureAnim::SCALE) + { + setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + } + if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + { + setTERotation(i, mTextureAnimp->mRot); + } + } + + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } } } } -BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ - LLViewerObject::idleUpdate(agent, world, time); - - //static LLFastTimer::DeclareTimer ftm("Volume Idle"); - //LLFastTimer t(ftm); - - if (mDead || mDrawable.isNull()) - { - return TRUE; - } - - /////////////////////// - // - // Do texture animation stuff - // - - if (mTextureAnimp && gAnimateTextures) - { - animateTextures(); - } - - // Dispatch to implementation - if (mVolumeImpl) - { - mVolumeImpl->doIdleUpdate(agent, world, time); - } - - const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; - - if (mDrawable->isActive()) - { - if (mDrawable->isRoot() && - mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && - (!mDrawable->getParent() || !mDrawable->getParent()->isActive())) - { - mDrawable->makeStatic(); - } - } - - return TRUE; -} void LLVOVolume::updateTextures() { @@ -489,6 +450,7 @@ void LLVOVolume::updateTextures() } } + } } @@ -711,8 +673,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) || - (mDrawable.notNull() && mDrawable->isActive()); + return !mStatic; } BOOL LLVOVolume::setMaterial(const U8 material) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index dbf9800db..a83a33680 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -70,7 +70,7 @@ class LLVolumeInterface public: virtual ~LLVolumeInterface() { } virtual LLVolumeInterfaceType getInterfaceType() const = 0; - virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0; + virtual void doIdleUpdate() = 0; virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0; virtual LLVector3 getPivotPosition() const = 0; virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; @@ -116,8 +116,7 @@ public: void deleteFaces(); void animateTextures(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - + BOOL isVisible() const ; /*virtual*/ BOOL isActive() const; /*virtual*/ BOOL isAttachment() const; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 05e033392..bb8de38de 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -106,17 +106,8 @@ void LLVOWater::updateTextures() } // Never gets called -BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))) - { - return TRUE; - } - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index 02a577a50..1203fb2ea 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -64,7 +64,7 @@ public: static void initClass(); static void cleanupClass(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index e9a03fee8..4ce25f4f1 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -98,9 +98,9 @@ void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction, { } -BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; + } BOOL LLVOWLSky::isActive(void) const diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h index 82abe79cb..82124587d 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -59,7 +59,7 @@ public: void initSunDirection(LLVector3 const & sun_direction, LLVector3 const & sun_angular_velocity); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL isActive(void) const; /*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0e9726b04..5c6966e84 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1642,6 +1642,10 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); if (done) { + if (drawablep->isRoot()) + { + drawablep->makeStatic(); + } drawablep->clearState(LLDrawable::ON_MOVE_LIST); if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { //will likely not receive any future world matrix updates @@ -6130,9 +6134,12 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) } void LLPipeline::resetVertexBuffers() -{ mResetVertexBuffers = true; +{ + mResetVertexBuffers = true; } +static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB"); + void LLPipeline::doResetVertexBuffers() { if (!mResetVertexBuffers) @@ -6168,6 +6175,8 @@ void LLPipeline::doResetVertexBuffers() if(LLPostProcess::instanceExists()) LLPostProcess::getInstance()->destroyGL(); + LLVOPartGroup::destroyGL(); + LLVertexBuffer::cleanupClass(); //delete all name pool caches From 4fe84efafd7dd365b8a8b3af174f1220c551c4c0 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 02:51:28 -0500 Subject: [PATCH 010/213] Unbork shadow shaders by tweaking normal unpack. --- .../shaders/class2/deferred/sunLightF.glsl | 18 ++++++++++-------- .../shaders/class2/deferred/sunLightSSAOF.glsl | 16 +++++++++------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 9b5d37965..f8f57e5e7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -118,16 +118,18 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) vec4 unpack(vec2 tc) { + vec4 norm = texture2DRect(normalMap, tc).xyzw; //#define PACK_NORMALS #ifdef PACK_NORMALS - vec4 enc = texture2DRect(normalMap, tc).xyzw; - enc = vec4((enc.xy*4.0)-2.0,0.0,enc.w); - float prod = dot(enc.xy,enc.xy); - return vec4(enc.xy*sqrt(1.0-prod*.25),1.0-prod*.5,enc.w); + norm.xy = (norm.xy*4.0)-2.0; + float prod = dot(norm.xy,norm.xy); + norm.xy *= sqrt(1.0-prod*.25); + norm.z = 1.0-prod*.5; #else - vec4 norm = texture2DRect(normalMap, tc).xyz; - return vec4(norm.xyz*2.0-1.0,norm.w); + norm.xyz = norm.xyz*2.0-1.0; #endif + norm.w *= norm.z; + return norm; } void main() @@ -138,8 +140,8 @@ void main() vec4 pos = getPosition(pos_screen); - vec4 nmap4 = unpack(pos_screen) // unpack norm - float displace = nmap4.w*norm.z; + vec4 nmap4 = unpack(pos_screen); // unpack norm + float displace = nmap4.w; vec3 norm = nmap4.xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 1e3691720..738fde15b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -179,16 +179,18 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) vec4 unpack(vec2 tc) { + vec4 norm = texture2DRect(normalMap, tc).xyzw; //#define PACK_NORMALS #ifdef PACK_NORMALS - vec4 enc = texture2DRect(normalMap, tc).xyzw; - enc = vec4((enc.xy*4.0)-2.0,0.0,enc.w); - float prod = dot(enc.xy,enc.xy); - return vec4(enc.xy*sqrt(1.0-prod*.25),1.0-prod*.5,enc.w); + norm.xy = (norm.xy*4.0)-2.0; + float prod = dot(norm.xy,norm.xy); + norm.xy *= sqrt(1.0-prod*.25); + norm.z = 1.0-prod*.5; #else - vec4 norm = texture2DRect(normalMap, tc).xyz; - return vec4(norm.xyz*2.0-1.0,norm.w); + norm.xyz = norm.xyz*2.0-1.0; #endif + norm.w *= norm.z; + return norm; } void main() @@ -200,7 +202,7 @@ void main() vec4 pos = getPosition(pos_screen); vec4 nmap4 = unpack(pos_screen); // unpack norm - float displace = nmap4.w*norm.z; + float displace = nmap4.w; vec3 norm = nmap4.xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL From dff6171605aebf8625d98ac4c0a51839e91538f0 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 02:51:41 -0500 Subject: [PATCH 011/213] More alignment crap. --- indra/llcommon/llmemory.cpp | 2 +- indra/llcommon/llmemory.h | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 52d0917d7..c5dbfcb62 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -1354,7 +1354,7 @@ char* LLPrivateMemoryPool::allocate(U32 size) //if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it if(size >= CHUNK_SIZE) { - return (char*)malloc(size) ; + return (char*)ll_aligned_malloc_16(size) ; } char* p = NULL ; diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index a28be0adb..329ce0c5d 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -100,7 +100,11 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r void* ret = ll_aligned_malloc_16(size); if (ptr) { - memcpy(ret, ptr, old_size); + if (ret) + { + // Only copy the size of the smallest memory block to avoid memory corruption. + memcpy(ret, ptr, llmin(old_size, size)); + } ll_aligned_free_16(ptr); } return ret; From 19390eaec3e38a5005dac92a38386e85227277dd Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 02:55:21 -0500 Subject: [PATCH 012/213] Remove pointless framebuffer status check. glReadBuffer doesn't work with gl_depth_attachment, thus will always complain about readbuffer being absent. (it checks GL_COLOR_ATTACHMENT0, which isn't present because this check is before we attach color attachments.) --- indra/llrender/llrendertarget.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 6454f92d9..4509958a9 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -49,7 +49,7 @@ void check_framebuffer_status() case GL_FRAMEBUFFER_COMPLETE: break; default: - llwarns << "check_framebuffer_status failed -- " << std::hex << status << llendl; + llwarns << "check_framebuffer_status failed -- " << std::hex << status << std::dec << llendl; ll_fail("check_framebuffer_status failed"); break; } @@ -813,7 +813,6 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); } - check_framebuffer_status(); } stop_glerror(); From ef27cc54ddaca926c83d2b44195535908d5523ee Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 02:56:41 -0500 Subject: [PATCH 013/213] Fixed unsafe erasure from vector while iterating in llinventorybackup.cpp. --- indra/newview/llinventorybackup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llinventorybackup.cpp b/indra/newview/llinventorybackup.cpp index b3caf401f..412404944 100644 --- a/indra/newview/llinventorybackup.cpp +++ b/indra/newview/llinventorybackup.cpp @@ -106,7 +106,7 @@ void LLFloaterInventoryBackupSettings::onClickNext(void* userdata) for( ; item_iter != order->mItems.end(); ) { if(type_remove[(*item_iter)->getType()]) - order->mItems.erase(item_iter); + item_iter = order->mItems.erase(item_iter); else ++item_iter; } From d2004e88f92a6a9fe3a594bc9f0e6a81e402b2ac Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 03:05:18 -0500 Subject: [PATCH 014/213] MatrixMode sanity checks and adjustments to physics debug display (fixes a crash with that debug view, too) --- indra/newview/lldrawpool.cpp | 1 + indra/newview/lldrawpoolterrain.cpp | 2 ++ indra/newview/lldrawpooltree.cpp | 1 + indra/newview/llspatialpartition.cpp | 5 +++++ indra/newview/llsurface.cpp | 1 + 5 files changed, 10 insertions(+) diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 0232f7139..d433fe3a6 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -422,6 +422,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params) gGL.loadMatrix(gGLModelView); if (params.mModelMatrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix); } gPipeline.mMatrixOpCount++; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index d1ef2c6d7..81a3c99ea 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -316,6 +316,7 @@ void LLDrawPoolTerrain::drawLoop() if (model_matrix != gGLLastMatrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGLLastMatrix = model_matrix; gGL.loadMatrix(gGLModelView); if (model_matrix) @@ -793,6 +794,7 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.loadIdentity(); gGL.translatef(-2.f, 0.f, 0.f); gGL.matrixMode(LLRender::MM_MODELVIEW); + // Care about alpha only gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 233d0a691..d2faca835 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -128,6 +128,7 @@ void LLDrawPoolTree::render(S32 pass) gGL.loadMatrix(gGLModelView); if (model_matrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) model_matrix->mMatrix); } gPipeline.mMatrixOpCount++; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 1094b3668..b2c898530 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3043,6 +3043,8 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color) { + if(mesh.mPositions.empty() || mesh.mNormals.empty()) + return; gGL.diffuseColor4fv(color.mV); LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); LLGLEnable offset(GL_POLYGON_OFFSET_LINE); @@ -3404,6 +3406,8 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLViewerObject* object = drawable->getVObj(); if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) { + gGL.pushMatrix(); + gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); //push face vertices for terrain for (S32 i = 0; i < drawable->getNumFaces(); ++i) { @@ -3425,6 +3429,7 @@ void renderPhysicsShapes(LLSpatialGroup* group) } } } + gGL.popMatrix(); } } } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 39ddbcc4e..bd1b99911 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -42,6 +42,7 @@ #include "llappviewer.h" #include "llworld.h" #include "llviewercontrol.h" +#include "llviewertexture.h" #include "llsurfacepatch.h" #include "llvosurfacepatch.h" #include "llvowater.h" From 9ef10b16637960d78d4b82bd26ec4d916fd2a557 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 03:07:07 -0500 Subject: [PATCH 015/213] Muting an avatar now also removes their attached lights. Also cleaned up light update code(no change in behavior) --- indra/newview/llmutelist.cpp | 23 +++++++++++++ indra/newview/pipeline.cpp | 67 +++++++++++++++++++++--------------- indra/newview/pipeline.h | 2 ++ 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index efeb7c557..3ce3eb188 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -295,6 +295,23 @@ BOOL LLMuteList::isLinden(const std::string& name) const return last_name == "Linden"; } +static LLVOAvatar* find_avatar(const LLUUID& id) +{ + LLViewerObject *obj = gObjectList.findObject(id); + while (obj && obj->isAttachment()) + { + obj = (LLViewerObject *)obj->getParent(); + } + + if (obj && obj->isAvatar()) + { + return (LLVOAvatar*)obj; + } + else + { + return NULL; + } +} BOOL LLMuteList::add(const LLMute& mute, U32 flags) { @@ -391,6 +408,12 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID); } } + //mute local lights that are attached to the avatar + LLVOAvatar *avatarp = find_avatar(localmute.mID); + if (avatarp) + { + LLPipeline::removeMutedAVsLights(avatarp); + } return TRUE; } } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5c6966e84..7f80764dc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1455,6 +1455,21 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } +//static +void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) +{ + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + iter != gPipeline.mNearbyLights.end();) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + gPipeline.mNearbyLights.erase(iter++); + } + } +} + U32 LLPipeline::addObject(LLViewerObject *vobj) { llassert_always(vobj); @@ -5012,38 +5027,34 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad // UPDATE THE EXISTING NEARBY LIGHTS - if (!LLPipeline::sSkipUpdate) + light_set_t cur_nearby_lights; + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) { - light_set_t cur_nearby_lights; - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) + const Light* light = &(*iter); + LLDrawable* drawable = light->drawable; + LLVOVolume* volight = drawable->getVOVolume(); + if (!volight || !drawable->isState(LLDrawable::LIGHT)) { - const Light* light = &(*iter); - LLDrawable* drawable = light->drawable; - LLVOVolume* volight = drawable->getVOVolume(); - if (!volight || !drawable->isState(LLDrawable::LIGHT)) - { - setLight(drawable,false); //remove from mLight list - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (light->fade <= -LIGHT_FADE_TIME) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (!sRenderAttachedLights && volight && volight->isAttachment()) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - - F32 dist = calc_light_dist(volight, cam_pos, max_dist); - cur_nearby_lights.insert(Light(drawable, dist, light->fade)); + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; } - mNearbyLights = cur_nearby_lights; + if (light->fade <= -LIGHT_FADE_TIME) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + if (!sRenderAttachedLights && volight && volight->isAttachment()) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + + F32 dist = calc_light_dist(volight, cam_pos, max_dist); + cur_nearby_lights.insert(Light(drawable, dist, light->fade)); } - + mNearbyLights = cur_nearby_lights; + // FIND NEW LIGHTS THAT ARE IN RANGE light_set_t new_nearby_lights; for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 6dd80b5b1..3b527b108 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -155,6 +155,8 @@ public: void unlinkDrawable(LLDrawable*); + static void removeMutedAVsLights(LLVOAvatar*); + // Object related methods void markVisible(LLDrawable *drawablep, LLCamera& camera); void markOccluder(LLSpatialGroup* group); From 7dea357f4c1cde11dd5ca84f57f330db8480669c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 03:08:51 -0500 Subject: [PATCH 016/213] Picked up a few small changes from viewer-beta pertaining to pathfinding. --- indra/newview/llviewerobject.cpp | 4 +++- indra/newview/llviewerobjectlist.cpp | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 008a75c90..6bba93d49 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5460,9 +5460,12 @@ BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state) void LLViewerObject::setPhysicsShapeType(U8 type) { mPhysicsShapeUnknown = false; + if (type != mPhysicsShapeType) + { mPhysicsShapeType = type; mCostStale = true; } +} void LLViewerObject::setPhysicsGravity(F32 gravity) { @@ -5488,7 +5491,6 @@ U8 LLViewerObject::getPhysicsShapeType() const { if (mPhysicsShapeUnknown) { - mPhysicsShapeUnknown = false; gObjectList.updatePhysicsFlags(this); } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 69ed84d00..d8219deca 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -92,6 +92,8 @@ extern BOOL gAnimateTextures; #include "importtracker.h" extern ImportTracker gImportTracker; +#define MAX_CONCURRENT_PHYSICS_REQUESTS 256 + void dialog_refresh_all(); #define CULL_VIS @@ -1083,8 +1085,6 @@ void LLViewerObjectList::fetchObjectCosts() LLSD id_list; U32 object_index = 0; - U32 count = 0; - for ( std::set::iterator iter = mStaleObjectCost.begin(); iter != mStaleObjectCost.end(); @@ -1101,7 +1101,7 @@ void LLViewerObjectList::fetchObjectCosts() mStaleObjectCost.erase(iter++); - if (count++ >= 450) + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) { break; } @@ -1146,7 +1146,7 @@ void LLViewerObjectList::fetchPhysicsFlags() for ( std::set::iterator iter = mStalePhysicsFlags.begin(); iter != mStalePhysicsFlags.end(); - ++iter) + ) { // Check to see if a request for this object // has already been made. @@ -1156,12 +1156,14 @@ void LLViewerObjectList::fetchPhysicsFlags() mPendingPhysicsFlags.insert(*iter); id_list[object_index++] = *iter; } - } - // id_list should now contain all - // requests in mStalePhysicsFlags before, so clear - // it now - mStalePhysicsFlags.clear(); + mStalePhysicsFlags.erase(iter++); + + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) + { + break; + } + } if ( id_list.size() > 0 ) { From 5b4b9fd1690406e2e1c71d0a3caeda1e67581b42 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 03:17:33 -0500 Subject: [PATCH 017/213] Durr, missed a line when adding attached light muting. Clobbered when diffing. Incrementing in a for loop is kinda important! Our handling in this function differes from LL in the firstplace because they are performing iteration on an iterator that can be invalid after the erase. --- indra/newview/pipeline.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7f80764dc..035e51e64 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1467,6 +1467,7 @@ void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) gPipeline.mLights.erase(iter->drawable); gPipeline.mNearbyLights.erase(iter++); } + else ++iter; } } From 02f214d8a7ba66b51845ec21ad71479de2058cea Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 15:25:02 -0500 Subject: [PATCH 018/213] Clear object rebuild queues upon teleport. --- indra/newview/llviewertexturelist.cpp | 10 +++++++++- indra/newview/pipeline.cpp | 26 ++++++++++++++++++++++++++ indra/newview/pipeline.h | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d685b951e..f8ea97f66 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -623,11 +623,19 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MEDIA("Media"); void LLViewerTextureList::updateImages(F32 max_time) { + static BOOL cleared = FALSE; if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { - clearFetchingRequests(); + if(!cleared) + { + clearFetchingRequests(); + gPipeline.clearRebuildGroups(); + cleared = TRUE; + } return; } + cleared = FALSE; + LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); S32 global_raw_memory; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 035e51e64..80c202e67 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2351,6 +2351,32 @@ void LLPipeline::updateGL() }*/ } +static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); + +void LLPipeline::clearRebuildGroups() +{ + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + mGroupQ1.clear(); + mGroupQ1Locked = false; + + mGroupQ2Locked = true; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + + mGroupQ2.clear(); + mGroupQ2Locked = false; +} void LLPipeline::rebuildPriorityGroups() { LLTimer update_timer; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 3b527b108..c1de3f6de 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -229,6 +229,7 @@ public: void updateGL(); void rebuildPriorityGroups(); void rebuildGroups(); + void clearRebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); From 5c459797832d8c7a7c086d9d5de88e26089f14d7 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 15:26:53 -0500 Subject: [PATCH 019/213] Resolve issue with sculpties loading with incorrect discard levels. --- indra/newview/llviewertexture.cpp | 3 ++- indra/newview/llvovolume.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index cf54a6ce8..5a299c134 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1337,9 +1337,10 @@ void LLViewerFetchedTexture::setForSculpt() static const S32 MAX_INTERVAL = 8 ; //frames mForSculpt = TRUE ; - if(isForSculptOnly() && !getBoundRecently()) + if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) { destroyGLTexture() ; //sculpt image does not need gl texture. + mTextureState = ACTIVE; } checkCachedRawSculptImage() ; setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b3c6485ce..4025b9d59 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -617,7 +617,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) } } - S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; if (texture_discard >= 0 && //texture has some data available @@ -919,7 +919,7 @@ void LLVOVolume::sculpt() S8 sculpt_components = 0; const U8* sculpt_data = NULL; - S32 discard_level = mSculptTexture->getDiscardLevel(); + S32 discard_level = mSculptTexture->getCachedRawImageLevel(); LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); From 9e272aeef0b83d9c62a27cc8350cfc3b436c1117 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 15:32:33 -0500 Subject: [PATCH 020/213] Still need to initialize flexis upon their very first idle update, else you get an ugly polygon soup when they first appear. --- indra/newview/llflexibleobject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index d741beed5..5415c1acf 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -394,8 +394,8 @@ void LLVolumeImplFlexible::doIdleUpdate() } } } - //if(!mInitialized) - // updateRenderRes(); + if(!mInitialized) + updateRenderRes(); } } From a5ef61ac82d899bc230814e803eca53b0b5896d9 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 22 Oct 2012 15:46:12 -0500 Subject: [PATCH 021/213] Avoid std::vector::erase in particle system (erase in any sequence-independent vector is a waste as it shifts all elements to maintain element-ordering and contiguity). Replaced with swap and pop. --- indra/newview/llviewerpartsim.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 94a2968b4..947428924 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -710,7 +710,9 @@ void LLViewerPartSim::updateSimulation() if (mViewerPartSources[i]->isDead()) { - mViewerPartSources.erase(mViewerPartSources.begin() + i); + mViewerPartSources[i] = mViewerPartSources.back(); + mViewerPartSources.pop_back(); + //mViewerPartSources.erase(mViewerPartSources.begin() + i); count--; i+=deldir; } @@ -747,7 +749,9 @@ void LLViewerPartSim::updateSimulation() if (!mViewerPartGroups[i]->getCount()) { delete mViewerPartGroups[i]; - mViewerPartGroups.erase(mViewerPartGroups.begin() + i); + mViewerPartGroups[i] = mViewerPartGroups.back(); + mViewerPartGroups.pop_back(); + //mViewerPartGroups.erase(mViewerPartGroups.begin() + i); i--; count--; } @@ -838,7 +842,12 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) if ((*iter)->getRegion() == regionp) { delete *iter; - i = mViewerPartGroups.erase(iter); + *iter = mViewerPartGroups.back(); + bool done = (i == mViewerPartGroups.end()); + mViewerPartGroups.pop_back(); + if(done) + break; + //i = mViewerPartGroups.erase(iter); } } } From c901a7136f17ffc0959d65c72c8c4df6d6e6aadd Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 23 Oct 2012 17:24:08 -0500 Subject: [PATCH 022/213] I freaking swear LL breaks hud attachment lighting in some way every few months. *Grumble* --- indra/newview/llvovolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 4025b9d59..2a18720d6 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4321,7 +4321,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else if (facep->canRenderAsMask()) { - if (te->getFullbright() || LLPipeline::sNoAlpha) + if (te->getFullbright() || fullbright || LLPipeline::sNoAlpha) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } From b57f7cdc793bb01e4911d4220ef139832963442b Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 24 Oct 2012 03:19:53 -0500 Subject: [PATCH 023/213] Fixed various specular/glow effects bleeding through fullbright objects in deferred. --- indra/newview/lldrawpoolsimple.cpp | 6 +++++- indra/newview/pipeline.cpp | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 6e0ea78af..4bc06580f 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -351,16 +351,20 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) void LLDrawPoolFullbright::renderPostDeferred(S32 pass) { LLFastTimer t(FTM_RENDER_FULLBRIGHT); - + gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + + gGL.setColorMask(true, false); } void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) { gDeferredFullbrightProgram.unbind(); LLRenderPass::endRenderPass(pass); + } void LLDrawPoolFullbright::beginRenderPass(S32 pass) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 80c202e67..85863e957 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7789,10 +7789,10 @@ void LLPipeline::renderDeferredLighting() pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_VOLUME, + //LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, + /*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used. LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -7804,7 +7804,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/ LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); From 94f61ce3078bab9fa83eec3d0040b55dd5e6d005 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 24 Oct 2012 03:20:32 -0500 Subject: [PATCH 024/213] A few nullchecks in the particle system. Had a null drawable pop up. --- indra/newview/llviewerpartsim.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 947428924..e1d6af0e7 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -729,7 +729,7 @@ void LLViewerPartSim::updateSimulation() LLViewerObject* vobj = mViewerPartGroups[i]->mVOPartGroupp; S32 visirate = 1; - if (vobj) + if (vobj && vobj->mDrawable.notNull()) { LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup(); if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY)) @@ -740,7 +740,7 @@ void LLViewerPartSim::updateSimulation() if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%visirate == 0) { - if (vobj) + if (vobj && vobj->mDrawable.notNull()) { gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL, TRUE); } From 67ee544231abac8950856e23ea52a083ef9d5688 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 24 Oct 2012 03:21:51 -0500 Subject: [PATCH 025/213] Clear saved raw discard level upon texfetch cleanup. (missed this in an earlier commit) --- indra/newview/llviewertexture.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 5a299c134..748abf2bc 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1330,6 +1330,7 @@ void LLViewerFetchedTexture::cleanup() mCachedRawDiscardLevel = -1 ; mCachedRawImageReady = FALSE ; mSavedRawImage = NULL ; + mSavedRawDiscardLevel = -1; } void LLViewerFetchedTexture::setForSculpt() From 1a741b97d249b5f901cf6317482436b635cb2934 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 25 Oct 2012 20:42:58 -0500 Subject: [PATCH 026/213] Fixed LLGLState::checkStates() failing upon context re-creation: -After new context creation, immediately call LLRender::refreshState() after LLViewerWindow::initGLDefaults() in order to force states to apply. --LLRender::initGLDefaults optimizes out gl calls by caching states, but the cached values are only applicable to the old context, not the new, so this optimization must be skipped (LLRender::mDirty). -LLViewerWindow::mStatesDirty also triggered a redundant shader reload, since restoreGL also called setShaders(). Fixed somewhat annoying flicker of a single frame whilst recovering from screen resizing. -Skip frame if LLViewerWindow::checkSettings() called LLViewerWindow::reshape. (reshape will set gWindowResized to true) --True optimal fix will require some refactoring. Reworked how window position is saved in LLViewerWindow::changeDisplaySettings. Hopefully reduces chances of odd behavior (had WindowX and WindowY get stuck at massive negative values before) --- indra/llrender/llrender.cpp | 11 +++++--- indra/newview/llpaneldisplay.cpp | 4 +++ indra/newview/llviewerdisplay.cpp | 5 ++++ indra/newview/llviewerwindow.cpp | 44 +++++++++++++++++++++---------- indra/newview/llviewerwindow.h | 2 +- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 6c985fbb4..50cebbba0 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1120,6 +1120,9 @@ void LLRender::refreshState(void) setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal); + //Singu note: Also reset glBlendFunc + blendFunc(mCurrBlendColorSFactor,mCurrBlendColorDFactor,mCurrBlendAlphaSFactor,mCurrBlendAlphaDFactor); + mDirty = false; } @@ -1586,7 +1589,7 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB if (mCurrColorMask[0] != writeColorR || mCurrColorMask[1] != writeColorG || mCurrColorMask[2] != writeColorB || - mCurrColorMask[3] != writeAlpha) + mCurrColorMask[3] != writeAlpha || mDirty) { mCurrColorMask[0] = writeColorR; mCurrColorMask[1] = writeColorG; @@ -1641,7 +1644,7 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) } if (mCurrAlphaFunc != func || - mCurrAlphaFuncVal != value) + mCurrAlphaFuncVal != value || mDirty) { mCurrAlphaFunc = func; mCurrAlphaFuncVal = value; @@ -1685,7 +1688,7 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) llassert(sfactor < BF_UNDEF); llassert(dfactor < BF_UNDEF); if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || - mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor) + mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor || mDirty) { mCurrBlendColorSFactor = sfactor; mCurrBlendAlphaSFactor = sfactor; @@ -1710,7 +1713,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, return; } if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || - mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) + mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor || mDirty) { mCurrBlendColorSFactor = color_sfactor; mCurrBlendAlphaSFactor = alpha_sfactor; diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index d2f3bdd01..362675292 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -897,10 +897,14 @@ void LLPanelDisplay::apply() LLWindow* window = gViewerWindow->getWindow(); LLCoordScreen size; window->getSize(&size); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(window->getFullscreen(), size, gSavedSettings.getBOOL("DisableVerticalSync"), logged_in); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); } } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 66f9771f7..332db10c2 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -320,6 +320,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo } gViewerWindow->checkSettings(); + + if(gWindowResized) //Singu Note: gViewerWindow->checkSettings() can call LLViewerWindow::reshape(). If it has then skip this frame. + { + return; + } { LLFastTimer ftm(FTM_PICK); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1c4bdfcff..2348fb588 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1467,7 +1467,7 @@ LLViewerWindow::LLViewerWindow( mIgnoreActivate( FALSE ), mHoverPick(), mResDirty(false), - mStatesDirty(false), + //mStatesDirty(false), //Singu Note: No longer needed. State update is now in restoreGL. mIsFullscreenChecked(false), mCurrResolutionIndex(0) { @@ -4093,10 +4093,14 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync"); if (gViewerWindow->mWindow->getFullscreen()) { + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(FALSE, new_size, disable_sync, TRUE); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); } else { @@ -4879,6 +4883,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) gGLManager.mIsDisabled = FALSE; initGLDefaults(); + gGL.refreshState(); //Singu Note: Call immediately. Cached states may have prevented initGLDefaults from actually applying changes. LLGLState::restoreGL(); gTextureList.restoreGL(); @@ -4974,12 +4979,15 @@ void LLViewerWindow::requestResolutionUpdate(bool fullscreen_checked) BOOL LLViewerWindow::checkSettings() { - if (mStatesDirty) + //Singu Note: Don't do the following. + //setShaders is already called in restoreGL(), and gGL.refreshState() is too as to maintain blend states. + //This maintaining of blend states is needed for LLGLState::checkStates() to not error out. + /*if (mStatesDirty) { gGL.refreshState(); LLViewerShaderMgr::instance()->setShaders(); mStatesDirty = false; - } + }*/ // We want to update the resolution AFTER the states getting refreshed not before. if (mResDirty) @@ -5026,10 +5034,8 @@ BOOL LLViewerWindow::checkSettings() desired_screen_size, gSavedSettings.getBOOL("DisableVerticalSync"), mShowFullscreenProgress); - LLGLState::checkStates(); LLGLState::checkTextureChannels(); - mStatesDirty = true; return TRUE; } } @@ -5038,12 +5044,15 @@ BOOL LLViewerWindow::checkSettings() if(is_fullscreen) { // Changing to windowed mode. + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); changeDisplaySettings(FALSE, LLCoordScreen(gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight")), TRUE, mShowFullscreenProgress); - mStatesDirty = true; + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); return TRUE; } } @@ -5111,24 +5120,33 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mIgnoreActivate = TRUE; LLCoordScreen old_size; LLCoordScreen old_pos; + LLCoordScreen new_pos; mWindow->getSize(&old_size); BOOL got_position = mWindow->getPosition(&old_pos); - if (!old_fullscreen && fullscreen && got_position) + //Singu Note: ALWAYS Save old values if we can. + if(!old_fullscreen && !mWindow->getMaximized() && got_position) { - // switching from windowed to fullscreen, so save window position + //Always save the current position if we can gSavedSettings.setS32("WindowX", old_pos.mX); gSavedSettings.setS32("WindowY", old_pos.mY); } + + //Singu Note: Try to feed switchcontext a posp pointer right off the bat. Looks less clunky on systems that implemented it. + if (!fullscreen && !mWindow->getMaximized()) + { + new_pos.mX = gSavedSettings.getS32("WindowX"); + new_pos.mY = gSavedSettings.getS32("WindowY"); + } mWindow->setFSAASamples(fsaa); - result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync); + result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync, &new_pos); if (!result_first_try) { // try to switch back mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync); + result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync, &new_pos); if (!result_second_try) { @@ -5181,10 +5199,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, } else { - S32 windowX = gSavedSettings.getS32("WindowX"); - S32 windowY = gSavedSettings.getS32("WindowY"); - - mWindow->setPosition(LLCoordScreen ( windowX, windowY ) ); + mWindow->setPosition(new_pos); } } @@ -5193,6 +5208,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mWantFullscreen = mWindow->getFullscreen(); mShowFullscreenProgress = FALSE; + //mStatesDirty = true; //Singu Note: No longer needed. State update is now in restoreGL. return success; } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 30848b386..990b1799c 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -449,7 +449,7 @@ protected: class LLDebugText* mDebugText; // Internal class for debug text bool mResDirty; - bool mStatesDirty; + //bool mStatesDirty; //Singu Note: No longer needed. State update is now in restoreGL. bool mIsFullscreenChecked; // Did the user check the fullscreen checkbox in the display settings U32 mCurrResolutionIndex; From 8ed6b549eedfa40ad195932502fe31158d8ff7d9 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 25 Oct 2012 20:50:42 -0500 Subject: [PATCH 027/213] =?UTF-8?q?A=20few=20resolutions=20in=20the=20drop?= =?UTF-8?q?down=20in=20the=20prefrences=20panel=20were=20not=20being=20par?= =?UTF-8?q?sed=20correctly.=20Use=20standard=20'x'=20instead=20of=20'?= =?UTF-8?q?=C3=97'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xui/en-us/panel_preferences_graphics1.xml | 4 ++-- .../default/xui/es/panel_preferences_graphics1.xml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml index ce4cf97d9..bfe2e285e 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml @@ -13,10 +13,10 @@ 1280x800 1440x900 1600x900 (HD+) - 1680×1050 + 1680x1050 1440x1080 (HDV1080) 1920x1080 (Full-HD) - 2560×1440 + 2560x1440 Display Resolution: diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml index ca41c8f41..6ac2c25db 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml @@ -31,10 +31,10 @@ 1440x900 - 1600x900 (HD+) - - - 1680×1050 + 1600x900 (HD+) + + + 1680x1050 1440x1080 (HDV1080) @@ -42,8 +42,8 @@ 1920x1080 (Full-HD) - - 2560×1440 + + 2560x1440 From dca9501de7b6750ffa37128f3a3f08bb8e08de8a Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 25 Oct 2012 20:52:14 -0500 Subject: [PATCH 028/213] Attempt to break viewer window out of 'maximized' mode when not actually maximized. There are old jiras about the previous workaround causing issues, so let's attempt a different method. --- indra/llwindow/llwindowwin32.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 53ba137d0..dd9fbeb00 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -866,7 +866,9 @@ BOOL LLWindowWin32::setPosition(const LLCoordScreen position) return FALSE; } getSize(&size); + moveWindow(position, size); + return TRUE; } @@ -881,6 +883,7 @@ BOOL LLWindowWin32::setSize(const LLCoordScreen size) } moveWindow(position, size); + return TRUE; } @@ -1655,6 +1658,23 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre // THIS CAUSES DEV-15484 and DEV-15949 //ShowWindow(mWindowHandle, SW_RESTORE); + + // Singu note: Attempt at fixing this in a different way. Keep an eye out for regression. DEV-15484 showed graphical corruption, especially on impostors. + LLCoordScreen old_pos; + LLCoordScreen old_size; + getSize(&old_size); + getPosition(&old_pos); + if(position != old_pos || size != old_size) + { + WINDOWPLACEMENT placement; + placement.length = sizeof(WINDOWPLACEMENT); + if(GetWindowPlacement(mWindowHandle, &placement)) + { + placement.showCmd = SW_NORMAL; + SetWindowPlacement(mWindowHandle, &placement); + } + } + // NOW we can call MoveWindow MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE); } From 71deb8925eeff942f9e007171199b8379211daec Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 4 Nov 2012 21:16:53 -0600 Subject: [PATCH 029/213] Added some nullchecks, removed some dead code, and cleaned up a few small things. --- indra/newview/llappearancemgr.cpp | 5 ++++- indra/newview/llselectmgr.cpp | 2 -- indra/newview/llviewerpartsim.cpp | 17 +++++++---------- indra/newview/llviewertexture.cpp | 6 +++++- indra/newview/llvovolume.cpp | 8 ++++---- indra/newview/llwlhandlers.cpp | 19 +++++++++++++------ 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 4cab987ae..a3439995e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -56,7 +56,10 @@ std::string self_av_string() { - return gAgentAvatarp->avString(); + if(isAgentAvatarValid()) + return gAgentAvatarp->avString(); + else + return std::string(); } // RAII thingy to guarantee that a variable gets reset when the Setter diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 81c6bcb87..afe7c14e3 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5944,8 +5944,6 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color) gDebugProgram.bind(); } - static LLCachedControl mode("OutlineMode",0); - gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index e1d6af0e7..6a8de2595 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -835,18 +835,15 @@ void LLViewerPartSim::removeLastCreatedSource() void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) { LLMemType mt(LLMemType::MTYPE_PARTICLES); - for (group_list_t::iterator i = mViewerPartGroups.begin(); i != mViewerPartGroups.end(); ) - { - group_list_t::iterator iter = i++; - if ((*iter)->getRegion() == regionp) + group_list_t& vec = mViewerPartGroups; + for (group_list_t::size_type i = 0;igetRegion() == regionp) { - delete *iter; - *iter = mViewerPartGroups.back(); - bool done = (i == mViewerPartGroups.end()); - mViewerPartGroups.pop_back(); - if(done) - break; + delete vec[i]; + vec[i--] = vec.back(); + vec.pop_back(); //i = mViewerPartGroups.erase(iter); } } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 748abf2bc..2dd04cf80 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1448,7 +1448,11 @@ void LLViewerFetchedTexture::addToCreateTexture() for(U32 i = 0 ; i < mNumFaces ; i++) { - mFaceList[i]->dirtyTexture() ; + LLFace* facep = mFaceList[i]; + if(facep) + { + facep->dirtyTexture() ; + } } //discard the cached raw image and the saved raw image diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2a18720d6..975019a03 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1114,13 +1114,13 @@ void LLVOVolume::updateFaceFlags() { for (S32 i = 0; i < getVolume()->getNumFaces(); i++) { - if(mDrawable->getNumFaces() <= i || getNumTEs() <= i) - return; - LLFace *face = mDrawable->getFace(i); if (face) { - BOOL fullbright = getTE(i)->getFullbright(); + LLTextureEntry *entry = getTE(i); + if(!entry) + continue; + BOOL fullbright = entry->getFullbright(); face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); if (fullbright || (mMaterial == LL_MCODE_LIGHT)) diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 0495d9c51..e6eb7299c 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -108,18 +108,25 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() if (mID != sCount) { LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL; - return; } - - if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + else if (!gAgent.getRegion() || gAgent.getRegion()->getRegionID().isNull()) + { + LL_WARNS("WindlightCaps") << "Ignoring responder. Current region is invalid." << LL_ENDL; + } + else if (unvalidated_content[0]["regionID"].asUUID().isNull()) + { + LL_WARNS("WindlightCaps") << "Ignoring responder. Response from invalid region." << LL_ENDL; + } + else if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) { LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() << ") - ignoring..." << LL_ENDL; - return; } - - LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content); + else + { + LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content); + } } /*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason) { From 3ec1dbf51cdec55b8a13f167b22390feb0f4177f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 4 Nov 2012 21:48:17 -0600 Subject: [PATCH 030/213] Updated spatial partition and octrees to use std::vector. Also, added diagnostic spew to octrees. --- indra/llmath/lloctree.h | 203 ++++++++++++++++++---- indra/newview/llspatialpartition.cpp | 241 +-------------------------- indra/newview/llspatialpartition.h | 100 ++++------- indra/newview/llviewercontrol.cpp | 2 + indra/newview/llviewerdisplay.cpp | 2 + indra/newview/pipeline.cpp | 11 +- indra/newview/pipeline.h | 8 +- 7 files changed, 231 insertions(+), 336 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index fcc0c2807..f55f4459c 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -45,6 +45,7 @@ #endif extern U32 gOctreeMaxCapacity; +extern U32 gOctreeReserveCapacity; #if LL_DEBUG #define LL_OCTREE_PARANOIA_CHECK 0 #else @@ -55,6 +56,102 @@ extern U32 gOctreeMaxCapacity; template class LLOctreeNode; +#include "lltimer.h" +class OctreeStats : public LLSingleton +{ +public: + OctreeStats() : + mPeriodNodesCreated(0), + mPeriodNodesDestroyed(0), + mPeriodAllocs(0), + mPeriodFrees(0), + mPeriodLargestSize(0), + mTotalNodes(0), + mTotalAllocs(0), + mTotalFrees(0), + mLargestSize(0), + mTotalSize(0) + { + mTotalTimer.reset(); + mPeriodTimer.reset(); + } + void addNode() + { + ++mTotalNodes; + ++mPeriodNodesCreated; + } + void removeNode() + { + --mTotalNodes; + ++mPeriodNodesDestroyed; + } + void realloc(U32 old_count, U32 new_count) + { + if(new_count >= old_count) + mTotalSize+=new_count-old_count; + else + mTotalSize-=old_count-new_count; + if(mLargestSize < new_count) + mLargestSize = new_count; + if(mPeriodLargestSize < new_count) + mPeriodLargestSize = new_count; + ++mTotalAllocs; + ++mPeriodAllocs; + } + void free(U32 count) + { + mTotalSize-=count; + ++mTotalFrees; + ++mPeriodFrees; + } + void dump() + { + llinfos << llformat("Lifetime: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes: %u AccumSize: %llubytes Avg: %lf LargestSize: %u", + mTotalAllocs, + mTotalFrees, + F64(mTotalAllocs)/mTotalTimer.getElapsedTimeF64(), + F64(mTotalFrees)/mTotalTimer.getElapsedTimeF64(), + mTotalNodes, + mTotalSize*sizeof(LLPointer), + F64(mTotalSize)/F64(mTotalNodes), + mLargestSize + ) << llendl; + llinfos << llformat("Timeslice: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes:(+%u|-%u) LargestSize: %u", + mPeriodAllocs, + mPeriodFrees, + F64(mPeriodAllocs)/mPeriodTimer.getElapsedTimeF64(), + F64(mPeriodFrees)/mPeriodTimer.getElapsedTimeF64(), + mPeriodNodesCreated, + mPeriodNodesDestroyed, + mPeriodLargestSize + ) << llendl; + + mPeriodNodesCreated=0; + mPeriodNodesDestroyed=0; + mPeriodAllocs=0; + mPeriodFrees=0; + mPeriodLargestSize=0; + mPeriodTimer.reset(); + } +private: + //Accumulate per timer update + U32 mPeriodNodesCreated; + U32 mPeriodNodesDestroyed; + U32 mPeriodAllocs; + U32 mPeriodFrees; + U32 mPeriodLargestSize; + LLTimer mPeriodTimer; + + //Accumulate through entire app lifetime: + U32 mTotalNodes; + U32 mTotalAllocs; + U32 mTotalFrees; + U32 mLargestSize; + U64 mTotalSize; + LLTimer mTotalTimer; +}; + + template class LLOctreeListener: public LLTreeListener { @@ -115,9 +212,9 @@ public: typedef LLOctreeTraveler oct_traveler; typedef LLTreeTraveler tree_traveler; - typedef LLPointer* element_list; - typedef LLPointer* element_iter; - typedef const LLPointer* const_element_iter; + typedef std::vector > element_list; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; typedef LLOctreeNode** child_list; typedef LLOctreeNode** child_iter; @@ -143,8 +240,13 @@ public: : mParent((oct_node*)parent), mOctant(octant) { - mData = NULL; - mDataEnd = NULL; + OctreeStats::getInstance()->addNode(); + + if(gOctreeReserveCapacity) + mData.reserve(gOctreeReserveCapacity); + OctreeStats::getInstance()->realloc(0,mData.capacity()); + //mData = NULL; + //mDataEnd = NULL; mCenter = center; mSize = size; @@ -155,24 +257,27 @@ public: mOctant = ((oct_node*) mParent)->getOctant(mCenter); } - mElementCount = 0; + //mElementCount = 0; clearChildren(); } virtual ~LLOctreeNode() { + OctreeStats::getInstance()->removeNode(); BaseType::destroyListeners(); - for (U32 i = 0; i < mElementCount; ++i) + //for (U32 i = 0; i < mElementCount; ++i) + for (U32 i = 0; i < mData.size(); ++i) { mData[i]->setBinIndex(-1); mData[i] = NULL; } - free(mData); - mData = NULL; - mDataEnd = NULL; + OctreeStats::getInstance()->free(mData.capacity()); + //free(mData); + //mData = NULL; + //mDataEnd = NULL; for (U32 i = 0; i < getChildCount(); i++) { @@ -272,14 +377,14 @@ public: void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChildCount == 0; } - U32 getElementCount() const { return mElementCount; } - bool isEmpty() const { return mElementCount == 0; } + U32 getElementCount() const { return mData.size(); } + bool isEmpty() const { return mData.size() == 0; } //element_list& getData() { return mData; } //const element_list& getData() const { return mData; } - element_iter getDataBegin() { return mData; } - element_iter getDataEnd() { return mDataEnd; } - const_element_iter getDataBegin() const { return mData; } - const_element_iter getDataEnd() const { return mDataEnd; } + element_iter getDataBegin() { return mData.begin(); } + element_iter getDataEnd() { return mData.end(); } + const_element_iter getDataBegin() const { return mData.begin(); } + const_element_iter getDataEnd() const { return mData.end(); } U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } @@ -359,7 +464,8 @@ public: if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here - mElementCount++; + /*mElementCount++; + OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount); mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); //avoid unref on uninitialized memory @@ -367,7 +473,14 @@ public: mData[mElementCount-1] = data; mDataEnd = mData + mElementCount; - data->setBinIndex(mElementCount-1); + data->setBinIndex(mElementCount-1);*/ + + U32 old_cap = mData.capacity(); + data->setBinIndex(mData.size()); + mData.push_back(data); + if(old_cap != mData.capacity()) + OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); + BaseType::insert(data); return true; } @@ -402,7 +515,8 @@ public: if( lt == 0x7 ) { - mElementCount++; + /*mElementCount++; + OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount); mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); //avoid unref on uninitialized memory @@ -410,7 +524,13 @@ public: mData[mElementCount-1] = data; mDataEnd = mData + mElementCount; - data->setBinIndex(mElementCount-1); + data->setBinIndex(mElementCount-1);*/ + U32 old_cap = mData.capacity(); + data->setBinIndex(mData.size()); + mData.push_back(data); + if(old_cap != mData.capacity()) + OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); + BaseType::insert(data); return true; } @@ -463,10 +583,10 @@ public: void _remove(T* data, S32 i) { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) OctreeGuard::checkGuarded(this); - mElementCount--; + //mElementCount--; data->setBinIndex(-1); - - if (mElementCount > 0) + +/* if (mElementCount > 0) { if (mElementCount != i) { @@ -475,15 +595,40 @@ public: } mData[mElementCount] = NULL; //needed for unref + OctreeStats::getInstance()->realloc(mElementCount+1,mElementCount); mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); mDataEnd = mData+mElementCount; } else { mData[0] = NULL; //needed for unref + OctreeStats::getInstance()->free(1); free(mData); mData = NULL; mDataEnd = NULL; + }*/ + + if(mData.size()) + { + if((mData.size()-1)!=i) + { + mData[i] = mData[mData.size()-1]; + mData[i]->setBinIndex(i); + } + U32 old_cap = mData.capacity(); + mData.pop_back(); + if( mData.size() == gOctreeReserveCapacity || + (mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4)) + { + //Shrink to lowest possible (reserve)+4*i size.. Say reserve is 5, here are [size,capacity] pairs. [10,13],[9,9],[8,9],[7,9],[6,9],[5,5],[4,5],[3,5],[2,5],[1,5],[0,5] +#ifndef LL_DARWIN + mData.shrink_to_fit(); +#else + std::vector >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX.. +#endif + } + if(old_cap != mData.capacity()) + OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); } this->notifyRemoval(data); @@ -495,7 +640,8 @@ public: OctreeGuard::checkGuarded(this); S32 i = data->getBinIndex(); - if (i >= 0 && i < (S32)mElementCount) + //if (i >= 0 && i < mElementCount) + if (i >= 0 && i < (S32)mData.size()) { if (mData[i] == data) { //found it @@ -539,7 +685,8 @@ public: void removeByAddress(T* data) { OctreeGuard::checkGuarded(this); - for (U32 i = 0; i < mElementCount; ++i) + //for (U32 i = 0; i < mElementCount; ++i) + for (U32 i = 0; i < mData.size(); ++i) { if (mData[i] == data) { //we have data @@ -647,8 +794,6 @@ public: listener->handleChildRemoval(this, getChild(index)); } - - if (destroy) { mChild[index]->destroy(); @@ -720,8 +865,8 @@ protected: U32 mChildCount; element_list mData; - element_iter mDataEnd; - U32 mElementCount; + //element_iter mDataEnd; + //U32 mElementCount; }; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index b2c898530..2840458a3 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -83,6 +83,7 @@ U32 LLSpatialGroup::sNodeCount = 0; std::set LLSpatialGroup::sPendingQueries; U32 gOctreeMaxCapacity; +U32 gOctreeReserveCapacity; BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -4508,251 +4509,27 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) return new LLVertexBuffer(type_mask, usage); } -LLCullResult::LLCullResult() -{ - mVisibleGroupsAllocated = 0; - mAlphaGroupsAllocated = 0; - mOcclusionGroupsAllocated = 0; - mDrawableGroupsAllocated = 0; - mVisibleListAllocated = 0; - mVisibleBridgeAllocated = 0; - - mVisibleGroups = NULL; - mVisibleGroupsEnd = NULL; - mAlphaGroups = NULL; - mAlphaGroupsEnd = NULL; - mOcclusionGroups = NULL; - mOcclusionGroupsEnd = NULL; - mDrawableGroups = NULL; - mDrawableGroupsEnd = NULL; - mVisibleList = NULL; - mVisibleListEnd = NULL; - mVisibleBridge = NULL; - mVisibleBridgeEnd = NULL; - - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) - { - mRenderMap[i] = NULL; - mRenderMapEnd[i] = NULL; - mRenderMapAllocated[i] = 0; - } - - clear(); -} - -void LLCullResult::pushBack(void**& head, U32& count, void* val) -{ - count++; - head = (void**) realloc((void*) head, sizeof(void*) * count); - head[count-1] = val; -} void LLCullResult::clear() { - mVisibleGroupsSize = 0; - mVisibleGroupsEnd = mVisibleGroups; - - mAlphaGroupsSize = 0; - mAlphaGroupsEnd = mAlphaGroups; - - mOcclusionGroupsSize = 0; - mOcclusionGroupsEnd = mOcclusionGroups; - - mDrawableGroupsSize = 0; - mDrawableGroupsEnd = mDrawableGroups; - - mVisibleListSize = 0; - mVisibleListEnd = mVisibleList; - - mVisibleBridgeSize = 0; - mVisibleBridgeEnd = mVisibleBridge; - + mVisibleGroups.clear(); + mAlphaGroups.clear(); + mOcclusionGroups.clear(); + mDrawableGroups.clear(); + mVisibleList.clear(); + mVisibleBridge.clear(); for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) { - for (U32 j = 0; j < mRenderMapSize[i]; j++) - { - mRenderMap[i][j] = 0; - } - mRenderMapSize[i] = 0; - mRenderMapEnd[i] = mRenderMap[i]; + mRenderMap[i].clear(); } } -LLCullResult::sg_iterator LLCullResult::beginVisibleGroups() -{ - return mVisibleGroups; -} - -LLCullResult::sg_iterator LLCullResult::endVisibleGroups() -{ - return mVisibleGroupsEnd; -} - -LLCullResult::sg_iterator LLCullResult::beginAlphaGroups() -{ - return mAlphaGroups; -} - -LLCullResult::sg_iterator LLCullResult::endAlphaGroups() -{ - return mAlphaGroupsEnd; -} - -LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups() -{ - return mOcclusionGroups; -} - -LLCullResult::sg_iterator LLCullResult::endOcclusionGroups() -{ - return mOcclusionGroupsEnd; -} - -LLCullResult::sg_iterator LLCullResult::beginDrawableGroups() -{ - return mDrawableGroups; -} - -LLCullResult::sg_iterator LLCullResult::endDrawableGroups() -{ - return mDrawableGroupsEnd; -} - -LLCullResult::drawable_iterator LLCullResult::beginVisibleList() -{ - return mVisibleList; -} - -LLCullResult::drawable_iterator LLCullResult::endVisibleList() -{ - return mVisibleListEnd; -} - -LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge() -{ - return mVisibleBridge; -} - -LLCullResult::bridge_iterator LLCullResult::endVisibleBridge() -{ - return mVisibleBridgeEnd; -} - -LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type) -{ - return mRenderMap[type]; -} - -LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type) -{ - return mRenderMapEnd[type]; -} - -void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) -{ - if (mVisibleGroupsSize < mVisibleGroupsAllocated) - { - mVisibleGroups[mVisibleGroupsSize] = group; - } - else - { - pushBack((void**&) mVisibleGroups, mVisibleGroupsAllocated, (void*) group); - } - ++mVisibleGroupsSize; - mVisibleGroupsEnd = mVisibleGroups+mVisibleGroupsSize; -} - -void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) -{ - if (mAlphaGroupsSize < mAlphaGroupsAllocated) - { - mAlphaGroups[mAlphaGroupsSize] = group; - } - else - { - pushBack((void**&) mAlphaGroups, mAlphaGroupsAllocated, (void*) group); - } - ++mAlphaGroupsSize; - mAlphaGroupsEnd = mAlphaGroups+mAlphaGroupsSize; -} - -void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) -{ - if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) - { - mOcclusionGroups[mOcclusionGroupsSize] = group; - } - else - { - pushBack((void**&) mOcclusionGroups, mOcclusionGroupsAllocated, (void*) group); - } - ++mOcclusionGroupsSize; - mOcclusionGroupsEnd = mOcclusionGroups+mOcclusionGroupsSize; -} - -void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) -{ - if (mDrawableGroupsSize < mDrawableGroupsAllocated) - { - mDrawableGroups[mDrawableGroupsSize] = group; - } - else - { - pushBack((void**&) mDrawableGroups, mDrawableGroupsAllocated, (void*) group); - } - ++mDrawableGroupsSize; - mDrawableGroupsEnd = mDrawableGroups+mDrawableGroupsSize; -} - -void LLCullResult::pushDrawable(LLDrawable* drawable) -{ - if (mVisibleListSize < mVisibleListAllocated) - { - mVisibleList[mVisibleListSize] = drawable; - } - else - { - pushBack((void**&) mVisibleList, mVisibleListAllocated, (void*) drawable); - } - ++mVisibleListSize; - mVisibleListEnd = mVisibleList+mVisibleListSize; -} - -void LLCullResult::pushBridge(LLSpatialBridge* bridge) -{ - if (mVisibleBridgeSize < mVisibleBridgeAllocated) - { - mVisibleBridge[mVisibleBridgeSize] = bridge; - } - else - { - pushBack((void**&) mVisibleBridge, mVisibleBridgeAllocated, (void*) bridge); - } - ++mVisibleBridgeSize; - mVisibleBridgeEnd = mVisibleBridge+mVisibleBridgeSize; -} - -void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) -{ - if (mRenderMapSize[type] < mRenderMapAllocated[type]) - { - mRenderMap[type][mRenderMapSize[type]] = draw_info; - } - else - { - pushBack((void**&) mRenderMap[type], mRenderMapAllocated[type], (void*) draw_info); - } - ++mRenderMapSize[type]; - mRenderMapEnd[type] = mRenderMap[type] + mRenderMapSize[type]; -} - - void LLCullResult::assertDrawMapsEmpty() { for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) { - if (mRenderMapSize[i] != 0) + if (hasRenderMap(i)) { llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 2c1624734..9a00bc1e6 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -546,95 +546,63 @@ public: class LLCullResult { public: - LLCullResult(); + LLCullResult() {} - typedef LLSpatialGroup** sg_list_t; - typedef LLDrawable** drawable_list_t; - typedef LLSpatialBridge** bridge_list_t; - typedef LLDrawInfo** drawinfo_list_t; + typedef std::vector sg_list_t; + typedef std::vector drawable_list_t; + typedef std::vector bridge_list_t; + typedef std::vector drawinfo_list_t; - typedef LLSpatialGroup** sg_iterator; - typedef LLSpatialBridge** bridge_iterator; - typedef LLDrawInfo** drawinfo_iterator; - typedef LLDrawable** drawable_iterator; + typedef sg_list_t::const_iterator sg_iterator; + typedef bridge_list_t::const_iterator bridge_iterator; + typedef drawinfo_list_t::const_iterator drawinfo_iterator; + typedef drawable_list_t::const_iterator drawable_iterator; void clear(); - sg_iterator beginVisibleGroups(); - sg_iterator endVisibleGroups(); + const sg_iterator beginVisibleGroups() const { return mVisibleGroups.begin(); } + const sg_iterator endVisibleGroups() const { return mVisibleGroups.end(); } - sg_iterator beginAlphaGroups(); - sg_iterator endAlphaGroups(); + const sg_iterator beginAlphaGroups() const { return mAlphaGroups.begin(); } + const sg_iterator endAlphaGroups() const { return mAlphaGroups.end(); } + const sg_list_t::iterator beginAlphaGroups() { return mAlphaGroups.begin(); } + const sg_list_t::iterator endAlphaGroups() { return mAlphaGroups.end(); } - bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } - sg_iterator beginOcclusionGroups(); - sg_iterator endOcclusionGroups(); + bool hasOcclusionGroups() const { return !mOcclusionGroups.empty(); } + const sg_iterator beginOcclusionGroups() const { return mOcclusionGroups.begin(); } + const sg_iterator endOcclusionGroups() const { return mOcclusionGroups.end(); } - sg_iterator beginDrawableGroups(); - sg_iterator endDrawableGroups(); + const sg_iterator beginDrawableGroups() const { return mDrawableGroups.begin(); } + const sg_iterator endDrawableGroups() const { return mDrawableGroups.end(); } - drawable_iterator beginVisibleList(); - drawable_iterator endVisibleList(); + const drawable_iterator beginVisibleList() const { return mVisibleList.begin(); } + const drawable_iterator endVisibleList() const { return mVisibleList.end(); } - bridge_iterator beginVisibleBridge(); - bridge_iterator endVisibleBridge(); + const bridge_iterator beginVisibleBridge() const { return mVisibleBridge.begin(); } + const bridge_iterator endVisibleBridge() const { return mVisibleBridge.end(); } - drawinfo_iterator beginRenderMap(U32 type); - drawinfo_iterator endRenderMap(U32 type); + bool hasRenderMap(U32 type) const { return !mRenderMap[type].empty(); } + const drawinfo_iterator beginRenderMap(U32 type)const { return mRenderMap[type].begin(); } + const drawinfo_iterator endRenderMap(U32 type) const { return mRenderMap[type].end(); } - void pushVisibleGroup(LLSpatialGroup* group); - void pushAlphaGroup(LLSpatialGroup* group); - void pushOcclusionGroup(LLSpatialGroup* group); - void pushDrawableGroup(LLSpatialGroup* group); - void pushDrawable(LLDrawable* drawable); - void pushBridge(LLSpatialBridge* bridge); - void pushDrawInfo(U32 type, LLDrawInfo* draw_info); - - U32 getVisibleGroupsSize() { return mVisibleGroupsSize; } - U32 getAlphaGroupsSize() { return mAlphaGroupsSize; } - U32 getDrawableGroupsSize() { return mDrawableGroupsSize; } - U32 getVisibleListSize() { return mVisibleListSize; } - U32 getVisibleBridgeSize() { return mVisibleBridgeSize; } - U32 getRenderMapSize(U32 type) { return mRenderMapSize[type]; } + void pushVisibleGroup(LLSpatialGroup* group) { mVisibleGroups.push_back(group); } + void pushAlphaGroup(LLSpatialGroup* group) { mAlphaGroups.push_back(group); } + void pushOcclusionGroup(LLSpatialGroup* group) { mOcclusionGroups.push_back(group); } + void pushDrawableGroup(LLSpatialGroup* group) { mDrawableGroups.push_back(group); } + void pushDrawable(LLDrawable* drawable) { mVisibleList.push_back(drawable); } + void pushBridge(LLSpatialBridge* bridge) { mVisibleBridge.push_back(bridge); } + void pushDrawInfo(U32 type, LLDrawInfo* draw_info) { mRenderMap[type].push_back(draw_info); } void assertDrawMapsEmpty(); private: - - void pushBack(void** &head, U32& count, void* val); - - U32 mVisibleGroupsSize; - U32 mAlphaGroupsSize; - U32 mOcclusionGroupsSize; - U32 mDrawableGroupsSize; - U32 mVisibleListSize; - U32 mVisibleBridgeSize; - - U32 mVisibleGroupsAllocated; - U32 mAlphaGroupsAllocated; - U32 mOcclusionGroupsAllocated; - U32 mDrawableGroupsAllocated; - U32 mVisibleListAllocated; - U32 mVisibleBridgeAllocated; - - U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES]; - sg_list_t mVisibleGroups; - sg_iterator mVisibleGroupsEnd; sg_list_t mAlphaGroups; - sg_iterator mAlphaGroupsEnd; sg_list_t mOcclusionGroups; - sg_iterator mOcclusionGroupsEnd; sg_list_t mDrawableGroups; - sg_iterator mDrawableGroupsEnd; drawable_list_t mVisibleList; - drawable_iterator mVisibleListEnd; bridge_list_t mVisibleBridge; - bridge_iterator mVisibleBridgeEnd; drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; - U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES]; - drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; - }; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a58bd2c5d..ec8935930 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -434,6 +434,7 @@ static bool handleRepartition(const LLSD&) if (gPipeline.isInit()) { gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512)); gObjectList.repartitionObjects(); } return true; @@ -634,6 +635,7 @@ void settings_setup_listeners() gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeReserveNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 332db10c2..a9c54a108 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -51,6 +51,7 @@ #include "llhudmanager.h" #include "llimagebmp.h" #include "llimagegl.h" +#include "lloctree.h" #include "llselectmgr.h" #include "llsky.h" #include "llstartup.h" @@ -225,6 +226,7 @@ void display_stats() F32 fps = gRecentFrameCount / fps_log_freq; llinfos << llformat("FPS: %.02f", fps) << llendl; llinfos << llformat("VBO: %d glVBO: %d", LLVertexBuffer::sCount, LLVertexBuffer::sGLCount) << llendl; + OctreStats::getInstance()->dump(); gRecentFrameCount = 0; gRecentFPSTime.reset(); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 85863e957..d08b6e903 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -401,6 +401,7 @@ void LLPipeline::init() refreshCachedSettings(); gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512)); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); @@ -9680,25 +9681,25 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) BOOL LLPipeline::hasRenderBatches(const U32 type) const { - return sCull->getRenderMapSize(type) > 0; + return sCull->hasRenderMap(type); } -LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) const { return sCull->beginRenderMap(type); } -LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) const { return sCull->endRenderMap(type); } -LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() +LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() const { return sCull->beginAlphaGroups(); } -LLCullResult::sg_iterator LLPipeline::endAlphaGroups() +LLCullResult::sg_iterator LLPipeline::endAlphaGroups() const { return sCull->endAlphaGroups(); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c1de3f6de..3f2c08a05 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -299,10 +299,10 @@ public: void setLight(LLDrawable *drawablep, BOOL is_light); BOOL hasRenderBatches(const U32 type) const; - LLCullResult::drawinfo_iterator beginRenderMap(U32 type); - LLCullResult::drawinfo_iterator endRenderMap(U32 type); - LLCullResult::sg_iterator beginAlphaGroups(); - LLCullResult::sg_iterator endAlphaGroups(); + LLCullResult::drawinfo_iterator beginRenderMap(U32 type) const; + LLCullResult::drawinfo_iterator endRenderMap(U32 type) const; + LLCullResult::sg_iterator beginAlphaGroups() const; + LLCullResult::sg_iterator endAlphaGroups() const; void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); From a582b5996cdf7fbaa5c8dfb0c104ad25e60a492e Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 5 Nov 2012 14:54:48 -0600 Subject: [PATCH 031/213] Whoops. Forgot settings.xml --- indra/newview/app_settings/settings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 89ece3a96..bec8027e6 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10040,6 +10040,18 @@ 128 + OctreeReserveNodeCapacity + + Comment + Default number of elements to pre-allocate for in a single octree node + Persist + 1 + Type + U32 + Value + 4 + + OctreeStaticObjectSizeFactor Comment From 3bbb23b1bcde1ec2558c2cee52e143011e648c9d Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 5 Nov 2012 16:58:03 -0600 Subject: [PATCH 032/213] Experiments with allocating octree nodes via memory pools. --- indra/llmath/lloctree.h | 66 +++++++++++++++++++++++++++++-- indra/newview/llviewerdisplay.cpp | 4 +- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index f55f4459c..dbdf90174 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -37,6 +37,7 @@ #include "v3math.h" #include "llvector4a.h" #include +#include #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG #define OCT_ERRS LL_ERRS("OctreeErrors") @@ -57,6 +58,10 @@ extern U32 gOctreeReserveCapacity; template class LLOctreeNode; #include "lltimer.h" + +#define LL_OCTREE_STATS +#define LL_OCTREE_POOLS +#ifdef LL_OCTREE_STATS class OctreeStats : public LLSingleton { public: @@ -150,7 +155,7 @@ private: U64 mTotalSize; LLTimer mTotalTimer; }; - +#endif //LL_OCTREE_STATS template class LLOctreeListener: public LLTreeListener @@ -223,15 +228,41 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; +#ifdef LL_OCTREE_POOLS + struct octree_pool_alloc + { + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + static char * malloc(const std::size_t bytes) + { return (char *)ll_aligned_malloc_16(bytes); } + static void free(char * const block) + { ll_aligned_free_16(block); } + }; + static boost::pool& getPool(const std::size_t& size) + { + static boost::pool sPool((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size),1200); + llassert_always((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size) == sPool.get_requested_size()); + return sPool; + } + void* operator new(size_t size) + { + return getPool(size).malloc(); + } + void operator delete(void* ptr) + { + getPool(sizeof(LLOctreeNode)).free(ptr); + } +#else void* operator new(size_t size) { return ll_aligned_malloc_16(size); } - void operator delete(void* ptr) { ll_aligned_free_16(ptr); } +#endif LLOctreeNode( const LLVector4a& center, const LLVector4a& size, @@ -240,11 +271,14 @@ public: : mParent((oct_node*)parent), mOctant(octant) { +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->addNode(); - +#endif if(gOctreeReserveCapacity) mData.reserve(gOctreeReserveCapacity); +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->realloc(0,mData.capacity()); +#endif //mData = NULL; //mDataEnd = NULL; @@ -263,8 +297,10 @@ public: } virtual ~LLOctreeNode() - { + { +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->removeNode(); +#endif BaseType::destroyListeners(); //for (U32 i = 0; i < mElementCount; ++i) @@ -274,7 +310,9 @@ public: mData[i] = NULL; } +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->free(mData.capacity()); +#endif //free(mData); //mData = NULL; //mDataEnd = NULL; @@ -465,7 +503,9 @@ public: (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here /*mElementCount++; +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount); +#endif mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); //avoid unref on uninitialized memory @@ -475,11 +515,15 @@ public: mDataEnd = mData + mElementCount; data->setBinIndex(mElementCount-1);*/ +#ifdef LL_OCTREE_STATS U32 old_cap = mData.capacity(); +#endif data->setBinIndex(mData.size()); mData.push_back(data); +#ifdef LL_OCTREE_STATS if(old_cap != mData.capacity()) OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); +#endif BaseType::insert(data); return true; @@ -516,7 +560,9 @@ public: if( lt == 0x7 ) { /*mElementCount++; +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount); +#endif mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); //avoid unref on uninitialized memory @@ -525,11 +571,15 @@ public: mData[mElementCount-1] = data; mDataEnd = mData + mElementCount; data->setBinIndex(mElementCount-1);*/ +#ifdef LL_OCTREE_STATS U32 old_cap = mData.capacity(); +#endif data->setBinIndex(mData.size()); mData.push_back(data); +#ifdef LL_OCTREE_STATS if(old_cap != mData.capacity()) OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); +#endif BaseType::insert(data); return true; @@ -595,14 +645,18 @@ public: } mData[mElementCount] = NULL; //needed for unref +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->realloc(mElementCount+1,mElementCount); +#endif mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); mDataEnd = mData+mElementCount; } else { mData[0] = NULL; //needed for unref +#ifdef LL_OCTREE_STATS OctreeStats::getInstance()->free(1); +#endif free(mData); mData = NULL; mDataEnd = NULL; @@ -615,7 +669,9 @@ public: mData[i] = mData[mData.size()-1]; mData[i]->setBinIndex(i); } +#ifdef LL_OCTREE_STATS U32 old_cap = mData.capacity(); +#endif mData.pop_back(); if( mData.size() == gOctreeReserveCapacity || (mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4)) @@ -627,8 +683,10 @@ public: std::vector >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX.. #endif } +#ifdef LL_OCTREE_STATS if(old_cap != mData.capacity()) OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); +#endif } this->notifyRemoval(data); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a9c54a108..46a05bc6d 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -226,7 +226,9 @@ void display_stats() F32 fps = gRecentFrameCount / fps_log_freq; llinfos << llformat("FPS: %.02f", fps) << llendl; llinfos << llformat("VBO: %d glVBO: %d", LLVertexBuffer::sCount, LLVertexBuffer::sGLCount) << llendl; - OctreStats::getInstance()->dump(); +#ifdef LL_OCTREE_STATS + OctreeStats::getInstance()->dump(); +#endif gRecentFrameCount = 0; gRecentFPSTime.reset(); } From 0c58a42b081e7347eb180c9767d163b8a65ec251 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 16:32:26 -0600 Subject: [PATCH 033/213] Added a couple needed nullchecks of gAgentAvatarp in LLAgent. --- indra/newview/llagent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index a0798dcd8..cfe3a36ec 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1421,7 +1421,7 @@ void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) LLViewerObject *obj; LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); - F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); + F64 target_height = llmax((F64)(isAgentAvatarValid() ? gAgentAvatarp->getPelvisToFoot() : 0.0), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); // clamp z value of target to minimum height above ground mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; @@ -3674,7 +3674,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); bool calc = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); LLVector3 offset = LLVector3(0.f,0.f,0.f); - if(calc) + if(calc && isAgentAvatarValid()) offset += LLVector3(0.f,0.f,gAgentAvatarp->getScale().mV[2] / 2.0); if(regionp && info) { From d54daa19a08713dd6ff188f1ff2a285c2c43d82f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:10:39 -0600 Subject: [PATCH 034/213] Allow trial of trasform feedback (for testing/benchmark) on hardware that declares support for GL_EXT_transform_feedback. Performance is far less than satisfactory on my hd4870(ogl3.3 gpu), however. Also messes up texcoords. Don't add RenderUseTransformFeedback to settings.xml. --- indra/llrender/llgl.cpp | 2 +- indra/llrender/llvertexbuffer.cpp | 10 ++++++++++ indra/llrender/llvertexbuffer.h | 6 +++++- indra/newview/llface.cpp | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 762571adc..ea43ac5c0 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -935,7 +935,7 @@ void LLGLManager::initExtensions() mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts); - mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE; + mHasTransformFeedback = mGLVersion >= 4.f || ExtensionExists("GL_EXT_transform_feedback", gGLHExts.mSysExts); #if !LL_DARWIN mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); #endif diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bc4c201d9..3f6cd6227 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2083,6 +2083,16 @@ void LLVertexBuffer::flush() } } +// bind for transform feedback (quick 'n dirty) +void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count) +{ +#if GL_TRANSFORM_FEEDBACK_BUFFER + U32 offset = mOffsets[type] + sTypeSize[type]*index; + U32 size= (sTypeSize[type]*count); + glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size); +#endif +} + // Set for rendering void LLVertexBuffer::setBuffer(U32 data_mask) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 469acfcef..0fab69cbc 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -39,6 +39,7 @@ #include #define LL_MAX_VERTEX_ATTRIB_LOCATION 64 +#define GL_TRANSFORM_FEEDBACK_BUFFER //============================================================================ // NOTES @@ -202,16 +203,18 @@ protected: void destroyGLIndices(); void updateNumVerts(S32 nverts); void updateNumIndices(S32 nindices); - bool useVBOs() const; void unmapBuffer(); public: + LLVertexBuffer(U32 typemask, S32 usage); // map for data access volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range); + void bindForFeedback(U32 channel, U32 type, U32 index, U32 count); + // set for rendering virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 void flush(); //flush pending data to GL memory @@ -240,6 +243,7 @@ public: bool getClothWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool useVBOs() const; bool isEmpty() const { return mEmpty; } bool isLocked() const { return mVertexLocked || mIndexLocked; } S32 getNumVerts() const { return mNumVerts; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index d1e0e3c52..277f1bb34 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1374,7 +1374,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, static LLCachedControl use_transform_feedback("RenderUseTransformFeedback", false); -#if 0//#ifdef GL_TRANSFORM_FEEDBACK_BUFFER +#ifdef GL_TRANSFORM_FEEDBACK_BUFFER if (use_transform_feedback && gTransformPositionProgram.mProgramObject && //transform shaders are loaded mVertexBuffer->useVBOs() && //target buffer is in VRAM From 81c7445744626f394a9778e30a4daa4a5b9085c6 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:12:57 -0600 Subject: [PATCH 035/213] image->hasFetcher() check reundant in LLViewerTextureList::clearFetchingRequests(). LLViewerFetchedTexture::forceToDeleteRequest() checks for this too. --- indra/newview/llviewertexturelist.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index f8ea97f66..2ad1f996d 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -717,11 +717,8 @@ void LLViewerTextureList::clearFetchingRequests() for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { - LLViewerFetchedTexture* image = *iter; - if(image->hasFetcher()) - { - image->forceToDeleteRequest() ; - } + LLViewerFetchedTexture* imagep = *iter; + imagep->forceToDeleteRequest() ; } } From 9aca1f41f33c59e6e8f16a97b678f33b8b4008a3 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:20:45 -0600 Subject: [PATCH 036/213] Make occlusion boundingbox 'fudge' settings adjustable via SHOcclusionFudge saved setting. --- indra/newview/app_settings/settings_sh.xml | 11 +++++++++++ indra/newview/llspatialpartition.cpp | 18 ++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 3deb249fa..d86a22fa4 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -195,6 +195,17 @@ Boolean Value 0 + + SHOcclusionFudge + + Comment + Padding added to occlusion bounds. Larger = less aggressive occlusion/less pop-in. + Persist + 1 + Type + F32 + Value + .25 diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2840458a3..27757f70f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1567,7 +1567,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) // Don't cull hole/edge water, unless RenderWaterVoidCulling is set and we have the GL_ARB_depth_clamp extension. //if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || // earlyFail(camera, this)) - if (earlyFail(camera, this)) + if (earlyFail(camera, this)) //Returns true if camera is inside this spatial group. { LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); setOcclusionState(LLSpatialGroup::DISCARD_QUERY); @@ -1622,9 +1622,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) llassert(shader); shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); - shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, - mBounds[1][1]+SG_OCCLUSION_FUDGE, - mBounds[1][2]+SG_OCCLUSION_FUDGE); + //static LLVector4a fudge(SG_OCCLUSION_FUDGE); + static LLCachedControl vel("SHOcclusionFudge",SG_OCCLUSION_FUDGE); + LLVector4a fudge(SG_OCCLUSION_FUDGE); + static LLVector4a bounds; + bounds.setAdd(fudge,mBounds[1]); + shader->uniform3fv(LLShaderMgr::BOX_SIZE, 1, bounds.getF32ptr()); if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) { @@ -2323,12 +2326,11 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) return FALSE; } - const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector4a fudge; - fudge.splat(vel); + static LLCachedControl vel("SHOcclusionFudge",SG_OCCLUSION_FUDGE); + LLVector4a fudge(vel*2.f); const LLVector4a& c = group->mBounds[0]; - LLVector4a r; + static LLVector4a r; r.setAdd(group->mBounds[1], fudge); /*if (r.magVecSquared() > 1024.0*1024.0) From 313cce23db2944bdf2e0b809eb4346ca4f0c6ca6 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:32:57 -0600 Subject: [PATCH 037/213] Trivial. Changed LLOcclusionQueryPool::mAvailableName to std::queue, because it's being used as a queue, and it being a list makes little sense. --- indra/newview/llspatialpartition.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 27757f70f..e0e8421f1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -100,7 +100,7 @@ public: protected: - std::list mAvailableName; + std::queue mAvailableName; //Use queue, because this usage is FIFO, which queue is desgined for GLuint mCurQuery; virtual GLuint allocateName() @@ -110,7 +110,7 @@ protected: if (!mAvailableName.empty()) { ret = mAvailableName.front(); - mAvailableName.pop_front(); + mAvailableName.pop(); } else { @@ -126,7 +126,7 @@ protected: LLSpatialGroup::sPendingQueries.erase(name); #endif llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); - mAvailableName.push_back(name); + mAvailableName.push(name); } }; From 01868e46febaf54156648923424ab04e78a72257 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:33:44 -0600 Subject: [PATCH 038/213] Removed pointless redundant gGL.flush() calls from llworldmapview. --- indra/newview/llworldmapview.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index f8269833b..bdd3b6054 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -337,7 +337,6 @@ void LLWorldMapView::draw() gGL.matrixMode(LLRender::MM_MODELVIEW); // Clear the background alpha to 0 - gGL.flush(); gGL.setColorMask(false, true); gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); gGL.setSceneBlendType(LLRender::BT_REPLACE); @@ -345,8 +344,6 @@ void LLWorldMapView::draw() gl_rect_2d(0, height, width, 0); } - gGL.flush(); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -355,7 +352,6 @@ void LLWorldMapView::draw() drawMipmap(width, height); else drawTiles(width, height); - gGL.flush(); LLFontGL* font = LLFontGL::getFontSansSerifSmall(); @@ -591,6 +587,8 @@ void LLWorldMapView::draw() LLView::draw(); updateVisibleBlocks(); + + gGL.flush(); } // end draw() @@ -693,7 +691,6 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { // Draw map image into RGB //gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gGL.flush(); gGL.setColorMask(true, false); gGL.color4f(1.f, 1.f, 1.f, layer_alpha); @@ -709,7 +706,6 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.end(); // draw an alpha of 1 where the sims are visible - gGL.flush(); gGL.setColorMask(false, true); gGL.color4f(1.f, 1.f, 1.f, 1.f); @@ -725,7 +721,6 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.end(); } - gGL.flush(); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setColorMask(true, true); @@ -915,7 +910,6 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { if (true /*V3: REGION_FLAGS_NULL_LAYER doesn't exist... (info->getRegionFlags() & REGION_FLAGS_NULL_LAYER) == 0*/) { // draw an alpha of 1 where the sims are visible (except NULL sims) - gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); gGL.setColorMask(false, true); gGL.color4f(1.f, 1.f, 1.f, 1.f); @@ -928,7 +922,6 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.vertex2f(right, top); gGL.end(); - gGL.flush(); gGL.setColorMask(true, true); } } @@ -1040,7 +1033,7 @@ void LLWorldMapView::drawAgents() // Here's how we'd choose the color if info.mID were available but it's not being sent: //LLColor4 color = (agent_count == 1 && is_agent_friend(info.mID)) ? friend_color : avatar_color; drawImageStack(info.getGlobalPosition(), sAvatarSmallImage, agent_count, 3.f, avatar_color); - } + } LLWorldMap::getInstance()->mNumAgents[handle] = sim_agent_count; // override mNumAgents for this sim } else @@ -1056,8 +1049,8 @@ void LLWorldMapView::drawAgents() S32 agent_count = (S32)(((num_agents-1) * agents_scale + (num_agents-1) * 0.1f)+.1f) + 1; drawImageStack(region_center, sAvatarSmallImage, agent_count, 3.f, avatar_color); } - } } + } } From b6efc9f5835d3c7d246864051cc9df22641bb746 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:41:05 -0600 Subject: [PATCH 039/213] Fixed buggyness regarding objects moved by scripts. http://hg.secondlife.com/viewer-development/changeset/1a874cd5d0a0616b979a571e810320cd35e69baf --- indra/newview/lldrawable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index f6a6a9013..616f6b58a 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -630,6 +630,8 @@ BOOL LLDrawable::updateMove() return FALSE; } + makeActive(); + BOOL done; if (isState(MOVE_UNDAMPED)) @@ -638,7 +640,6 @@ BOOL LLDrawable::updateMove() } else { - makeActive(); done = updateMoveDamped(); } return done; From 1cb75c44718a586add2757f3b33a82001106df70 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:42:37 -0600 Subject: [PATCH 040/213] Tiny bit of code consolidation in lltexturefetch --- indra/newview/lltexturefetch.cpp | 26 +++++++++----------------- indra/newview/lltexturefetch.h | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2a4abcf1b..1bed70bf2 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2160,27 +2160,19 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) { lockQueue() ; LLTextureFetchWorker* worker = getWorkerAfterLock(id); - if (worker) - { - size_t erased_1 = mRequestMap.erase(worker->mID); - unlockQueue() ; - llassert_always(erased_1 > 0) ; - - removeFromNetworkQueue(worker, cancel); - llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; - - worker->scheduleDelete(); - } - else - { - unlockQueue() ; - } + removeRequest(worker, cancel, false); } -void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) +void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel, bool bNeedsLock) { - lockQueue() ; + if(!worker) + { + return; + } + + if(bNeedsLock) + lockQueue() ; size_t erased_1 = mRequestMap.erase(worker->mID); unlockQueue() ; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 03073d906..176ba31db 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -121,7 +121,7 @@ protected: void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); void addToHTTPQueue(const LLUUID& id); void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0); - void removeRequest(LLTextureFetchWorker* worker, bool cancel); + void removeRequest(LLTextureFetchWorker* worker, bool cancel, bool bNeedsLock = true); // Overrides from the LLThread tree bool runCondition(); From 1cdc11dae20da55f4adcf9d31a6d26a4f55027ff Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 18:45:57 -0600 Subject: [PATCH 041/213] Added LLTextureFetch::deleteAllRequests procedure. Called upon teleport. --- indra/newview/lltexturefetch.cpp | 17 +++++++++++++++++ indra/newview/lltexturefetch.h | 1 + indra/newview/llviewertexturelist.cpp | 2 ++ 3 files changed, 20 insertions(+) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 1bed70bf2..57ab3003f 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2183,6 +2183,23 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel, bo worker->scheduleDelete(); } +void LLTextureFetch::deleteAllRequests() +{ + while(1) + { + lockQueue(); + if(mRequestMap.empty()) + { + unlockQueue() ; + break; + } + + LLTextureFetchWorker* worker = mRequestMap.begin()->second; + + removeRequest(worker, true, false); + } +} + S32 LLTextureFetch::getNumRequests() { lockQueue() ; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 176ba31db..470e1feb7 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -70,6 +70,7 @@ public: bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); void deleteRequest(const LLUUID& id, bool cancel); + void deleteAllRequests(); bool getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer& raw, LLPointer& aux); bool updateRequestPriority(const LLUUID& id, F32 priority); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 2ad1f996d..81a0fa89a 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -714,6 +714,8 @@ void LLViewerTextureList::clearFetchingRequests() return; } + LLAppViewer::getTextureFetch()->deleteAllRequests(); + for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { From 0173c29630ff40f5660682614d1581b89398023c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 9 Nov 2012 23:32:57 -0600 Subject: [PATCH 042/213] Resolve compiler warning caused by silly temporary #define. --- indra/llrender/llvertexbuffer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 0fab69cbc..3762d956b 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -39,7 +39,6 @@ #include #define LL_MAX_VERTEX_ATTRIB_LOCATION 64 -#define GL_TRANSFORM_FEEDBACK_BUFFER //============================================================================ // NOTES From 0a4b3487ea73da521b2b755520a1fb5fa93db83c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 11 Nov 2012 01:01:04 -0600 Subject: [PATCH 043/213] Resolve string substitutions failing for a few 'unsuccessful' startup dialogs. --- indra/newview/llappviewer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 2fcf37fdb..0051e4b01 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -827,8 +827,10 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. + std::string msg = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"); + LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"), + msg, LLStringUtil::null, OSMB_OK); return 0; @@ -840,8 +842,10 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. + std::string msg = LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"); + LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"), + msg, LLStringUtil::null, OSMB_OK); return 0; @@ -852,8 +856,10 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. + std::string msg = LNotifications::instance().getGlobalString("UnsupportedCPUSSE2"); + LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( - LLNotifications::instance().getGlobalString("UnsupportedCPUSSE"), + msg, LLStringUtil::null, OSMB_OK); return 0; From f25ca2ac80f37fa7ab98949843c510bde55a6258 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 12 Nov 2012 00:12:39 -0600 Subject: [PATCH 044/213] Fixed small #if/#ifdef typo. Also fixed formatting error in strings.xml --- indra/llrender/llvertexbuffer.cpp | 2 +- indra/newview/skins/default/xui/en-us/strings.xml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 3f6cd6227..d10a9c6bb 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2086,7 +2086,7 @@ void LLVertexBuffer::flush() // bind for transform feedback (quick 'n dirty) void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count) { -#if GL_TRANSFORM_FEEDBACK_BUFFER +#ifdef GL_TRANSFORM_FEEDBACK_BUFFER U32 offset = mOffsets[type] + sTypeSize[type]*index; U32 size= (sTypeSize[type]*count); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size); diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index 6680ab9c1..3ef6bc38d 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -1920,14 +1920,14 @@ For AI Character: Navigate to destination. llCreateCharacter(list options) Convert linkset to AI Character which can navigate the world. - - http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer - None - Affects navmesh - Character - (Multiple) - + + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + None + Affects navmesh + Character + (Multiple) + llPursue(key target, list options) For AI Character: Chase after a target. From c2b26f6c15c32d4f0aac49763eae956c848d7c1f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 12 Nov 2012 03:04:24 -0600 Subject: [PATCH 045/213] GCC Fixes: Only use C++0x/C++11 features if compiling for windows, or if GCC is configured to support such features (v4.7 onwards: '-std=c++11'. v4.3 through v4.6: '-std=c++0x') Removed an assertion that's no longer possible to evaluate (queue doesn't support iterators). --- indra/llmath/lloctree.h | 5 ++++- indra/newview/llspatialpartition.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index dbdf90174..87153982e 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -677,7 +677,10 @@ public: (mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4)) { //Shrink to lowest possible (reserve)+4*i size.. Say reserve is 5, here are [size,capacity] pairs. [10,13],[9,9],[8,9],[7,9],[6,9],[5,5],[4,5],[3,5],[2,5],[1,5],[0,5] -#ifndef LL_DARWIN + //For Windows: We always assume vs2010 or later, which support this c++11 feature with no configuration needed. + //For GCC: __cplusplus >= 201103L indicates C++11 support. __GXX_EXPERIMENTAL_CXX0X being set indicates experimental c++0x support. C++11 support replaces C++0x support. + // std::vector::shrink_to_fit was added to GCCs C++0x implementation in version 4.5.0. +#if defined(LL_WINDOWS) || __cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X) && __GNUC_MINOR__ >= 5) mData.shrink_to_fit(); #else std::vector >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX.. diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index e0e8421f1..5c41199c3 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -125,7 +125,7 @@ protected: #if LL_TRACK_PENDING_OCCLUSION_QUERIES LLSpatialGroup::sPendingQueries.erase(name); #endif - llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); + //llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); mAvailableName.push(name); } }; From cd5aa8f074db8f94539f63b6e077ea1b238abd9a Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 12 Nov 2012 03:18:02 -0600 Subject: [PATCH 046/213] Avoid re-requesting object-inventory items that already have a pending request. --- indra/newview/llviewerobject.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6bba93d49..1c4d91cd4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2934,7 +2934,22 @@ void LLViewerObject::updateInventory( bool is_new) { LLMemType mt(LLMemType::MTYPE_OBJECT); - + + std::list::iterator begin = mPendingInventoryItemsIDs.begin(); + std::list::iterator end = mPendingInventoryItemsIDs.end(); + + bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end; + bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL; + + if (is_fetched || is_fetching) + { + return; + } + else + { + mPendingInventoryItemsIDs.push_back(item->getAssetUUID()); + } + // This slices the object into what we're concerned about on the // viewer. The simulator will take the permissions and transfer // ownership. From 4a4032f3b80bbd15552da82376ab07886a90414d Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 12 Nov 2012 03:41:53 -0600 Subject: [PATCH 047/213] Hopefully allows better behavior when loading other avatars. This is from v3, and taking a cursory glance, it's useful as onFirstTEMessageReceived is called before LLVOAvatar::idleUpdate, which means that mLoadedCallbacksPaused hasn't been updated for that particualr frame yet. Using LLVOAvatar::isVisible() is more accurate. --- indra/newview/llvoavatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 96f3baa35..162008518 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7643,7 +7643,7 @@ void LLVOAvatar::updateMeshTextures() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } std::vector is_layer_baked; @@ -8208,7 +8208,7 @@ void LLVOAvatar::onFirstTEMessageReceived() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } for (U32 i = 0; i < mBakedTextureDatas.size(); i++) From 3eebedc4c3b952823f79f32bcebdd44419af0111 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 12 Nov 2012 20:32:40 -0600 Subject: [PATCH 048/213] Revert "Avoid re-requesting object-inventory items that already have a pending request." This code was actually regression in viewer-dev and causes some issues. This reverts commit cd5aa8f074db8f94539f63b6e077ea1b238abd9a. --- indra/newview/llviewerobject.cpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1c4d91cd4..6bba93d49 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2934,22 +2934,7 @@ void LLViewerObject::updateInventory( bool is_new) { LLMemType mt(LLMemType::MTYPE_OBJECT); - - std::list::iterator begin = mPendingInventoryItemsIDs.begin(); - std::list::iterator end = mPendingInventoryItemsIDs.end(); - - bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end; - bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL; - - if (is_fetched || is_fetching) - { - return; - } - else - { - mPendingInventoryItemsIDs.push_back(item->getAssetUUID()); - } - + // This slices the object into what we're concerned about on the // viewer. The simulator will take the permissions and transfer // ownership. From fe1537104737d21a2180ba34ec77d6652356dd92 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 13 Nov 2012 17:55:52 -0600 Subject: [PATCH 049/213] Update to LLTombstone/LLHandle/LLRootHandle/LLHandleProvider. --- indra/llui/llfloater.cpp | 6 +- indra/llui/llfloater.h | 3 +- indra/llui/llhandle.h | 125 ++++++++++++++++++++-------- indra/llui/llpanel.cpp | 1 - indra/llui/llpanel.h | 3 +- indra/llui/llview.h | 7 +- indra/newview/llfasttimerview.cpp | 2 +- indra/newview/llinventorybridge.cpp | 42 +++++++--- indra/newview/llinventorybridge.h | 2 +- indra/newview/llinventorypanel.h | 2 + indra/newview/llpanelmediahud.cpp | 2 - indra/newview/llpanelmediahud.h | 4 +- 12 files changed, 130 insertions(+), 69 deletions(-) diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 114cabc0c..25370f739 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -148,7 +148,6 @@ LLFloater::LLFloater() : mResizeHandle[i] = NULL; } mDragHandle = NULL; - mHandle.bind(this); mNotificationContext = new LLFloaterNotificationContext(getHandle()); } @@ -222,7 +221,6 @@ void LLFloater::initFloater(const std::string& title, BOOL resizable, S32 min_width, S32 min_height, BOOL drag_on_left, BOOL minimizable, BOOL close_btn) { - mHandle.bind(this); mNotificationContext = new LLFloaterNotificationContext(getHandle()); // Init function can be called more than once, so clear out old data. @@ -422,7 +420,7 @@ void LLFloater::initFloater(const std::string& title, setVisible(FALSE); // add self to handle->floater map - sFloaterMap[mHandle] = this; + sFloaterMap[getHandle()] = this; if (!getParent()) { @@ -483,7 +481,7 @@ LLFloater::~LLFloater() // correct, non-minimized positions. setMinimized( FALSE ); - sFloaterMap.erase(mHandle); + sFloaterMap.erase(getHandle()); delete mDragHandle; for (S32 i = 0; i < 4; i++) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index e710fa6dc..1cfb4635a 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -227,7 +227,7 @@ public: void clearSnapTarget() { mSnappedTo.markDead(); } LLHandle getSnapTarget() const { return mSnappedTo; } - LLHandle getHandle() const { return mHandle; } + LLHandle getHandle() const { return getDerivedHandle(); } // Return a closeable floater, if any, given the current focus. static LLFloater* getClosableFloaterFromFocus(); @@ -331,7 +331,6 @@ private: S32 mPreviousMinimizedLeft; LLFloaterNotificationContext* mNotificationContext; - LLRootHandle mHandle; }; ///////////////////////////////////////////////////////////// diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h index 8c000eee4..6af5e198d 100644 --- a/indra/llui/llhandle.h +++ b/indra/llui/llhandle.h @@ -28,38 +28,67 @@ #define LLHANDLE_H #include "llpointer.h" +#include +#include -template +/** + * Helper object for LLHandle. Don't instantiate these directly, used + * exclusively by LLHandle. + */ class LLTombStone : public LLRefCount { public: - LLTombStone(T* target = NULL) : mTarget(target) {} + LLTombStone(void* target = NULL) : mTarget(target) {} - void setTarget(T* target) { mTarget = target; } - T* getTarget() const { return mTarget; } + void setTarget(void* target) { mTarget = target; } + void* getTarget() const { return mTarget; } private: - T* mTarget; + mutable void* mTarget; }; -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - +/** + * LLHandles are used to refer to objects whose lifetime you do not control or influence. + * Calling get() on a handle will return a pointer to the referenced object or NULL, + * if the object no longer exists. Note that during the lifetime of the returned pointer, + * you are assuming that the object will not be deleted by any action you perform, + * or any other thread, as normal when using pointers, so avoid using that pointer outside of + * the local code block. + * + * https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + * + * The implementation is like some "weak pointer" implementations. When we + * can't control the lifespan of the referenced object of interest, we can + * still instantiate a proxy object whose lifespan we DO control, and store in + * the proxy object a dumb pointer to the actual target. Then we just have to + * ensure that on destruction of the target object, the proxy's dumb pointer + * is set NULL. + * + * LLTombStone is our proxy object. LLHandle contains an LLPointer to the + * LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref + * count as usual. + * + * One copy of the LLHandle, specifically the LLRootHandle, must be stored in + * the referenced object. Destroying the LLRootHandle is what NULLs the + * proxy's target pointer. + * + * Minor optimization: we want LLHandle's mTombStone to always be a valid + * LLPointer, saving some conditionals in dereferencing. That's the + * getDefaultTombStone() mechanism. The default LLTombStone object's target + * pointer is always NULL, so it's semantically identical to allowing + * mTombStone to be invalid. + */ template class LLHandle { + template friend class LLHandle; + template friend class LLHandleProvider; public: LLHandle() : mTombStone(getDefaultTombStone()) {} - const LLHandle& operator =(const LLHandle& other) - { - mTombStone = other.mTombStone; - return *this; - } + + template + LLHandle(const LLHandle& other, typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) + : mTombStone(other.mTombStone) + {} bool isDead() const { @@ -73,7 +102,7 @@ public: T* get() const { - return mTombStone->getTarget(); + return reinterpret_cast(mTombStone->getTarget()); } friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) @@ -94,37 +123,49 @@ public: } protected: - LLPointer > mTombStone; + LLPointer mTombStone; private: - static LLPointer >& getDefaultTombStone() + typedef T* pointer_t; + static LLPointer& getDefaultTombStone() { - static LLPointer > sDefaultTombStone = new LLTombStone; + static LLPointer sDefaultTombStone = new LLTombStone; return sDefaultTombStone; } }; +/** + * LLRootHandle isa LLHandle which must be stored in the referenced object. + * You can either store it directly and explicitly bind(this), or derive from + * LLHandleProvider (q.v.) which automates that for you. The essential point + * is that destroying the LLRootHandle (as a consequence of destroying the + * referenced object) calls unbind(), setting the LLTombStone's target pointer + * NULL. + */ template class LLRootHandle : public LLHandle { public: + typedef LLRootHandle self_t; + typedef LLHandle base_t; + LLRootHandle(T* object) { bind(object); } LLRootHandle() {}; ~LLRootHandle() { unbind(); } - // this is redundant, since a LLRootHandle *is* an LLHandle - LLHandle getHandle() { return LLHandle(*this); } + // this is redundant, since an LLRootHandle *is* an LLHandle + //LLHandle getHandle() { return LLHandle(*this); } void bind(T* object) { // unbind existing tombstone if (LLHandle::mTombStone.notNull()) { - if (LLHandle::mTombStone->getTarget() == object) return; + if (LLHandle::mTombStone->getTarget() == (void*)object) return; LLHandle::mTombStone->setTarget(NULL); } // tombstone reference counted, so no paired delete - LLHandle::mTombStone = new LLTombStone(object); + LLHandle::mTombStone = new LLTombStone((void*)object); } void unbind() @@ -137,11 +178,22 @@ private: LLRootHandle(const LLRootHandle& other) {}; }; -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy +/** + * Use this as a mixin for simple classes that need handles and when you don't + * want handles at multiple points of the inheritance hierarchy + */ template class LLHandleProvider { +public: + LLHandle getHandle() const + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast(const_cast* >(this))); + return mHandle; + } + protected: typedef LLHandle handle_type_t; LLHandleProvider() @@ -149,16 +201,17 @@ protected: // provided here to enforce T deriving from LLHandleProvider } - LLHandle getHandle() - { - // perform lazy binding to avoid small tombstone allocations for handle - // providers whose handles are never referenced - mHandle.bind(static_cast(this)); - return mHandle; + template + LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const + { + LLHandle downcast_handle; + downcast_handle.mTombStone = getHandle().mTombStone; + return downcast_handle; } + private: - LLRootHandle mHandle; + mutable LLRootHandle mHandle; }; #endif diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 136dcf524..dc89e9a4f 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -80,7 +80,6 @@ void LLPanel::init() mDefaultBtn = NULL; setIsChrome(FALSE); //is this a decorator to a live window or a form? - mPanelHandle.bind(this); setTabStop(FALSE); mVisibleSignal = NULL; } diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index ad721cbf5..dbf17aec6 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -136,7 +136,7 @@ public: void setCtrlsEnabled(BOOL b); - LLHandle getHandle() const { return mPanelHandle; } + LLHandle getHandle() const { return getDerivedHandle(); } const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } @@ -246,7 +246,6 @@ private: LLViewBorder* mBorder; LLButton* mDefaultBtn; std::string mLabel; - LLRootHandle mPanelHandle; typedef std::map ui_string_map_t; ui_string_map_t mUIStrings; diff --git a/indra/llui/llview.h b/indra/llui/llview.h index ee2ad2d3e..c2dc57384 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -132,8 +132,8 @@ public: class LLView : public LLMouseHandler, // handles mouse events public LLFocusableElement, // handles keyboard events - public LLMortician // lazy deletion - //public LLHandleProvider // passes out weak references to self + public LLMortician, // lazy deletion + public LLHandleProvider // passes out weak references to self { public: struct Follows : public LLInitParam::ChoiceBlock @@ -344,8 +344,6 @@ public: void popVisible() { setVisible(mLastVisible); } BOOL getLastVisible() const { return mLastVisible; } - LLHandle getHandle() { mHandle.bind(this); return mHandle; } - U32 getFollows() const { return mReshapeFlags; } BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } BOOL followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; } @@ -678,7 +676,6 @@ private: BOOL mIsFocusRoot; BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements - LLRootHandle mHandle; BOOL mLastVisible; S32 mNextInsertionOrdinal; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index eeb53a98d..46d0d0740 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -971,7 +971,7 @@ void LLFastTimerView::draw() gGL.color4f(col[0], col[1], col[2], alpha); gGL.begin(LLRender::TRIANGLE_STRIP); for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex()); - j < LLFastTimer::NamedTimer::HISTORY_NUM; + j < (U32)LLFastTimer::NamedTimer::HISTORY_NUM; j++) { U64 ticks = idp->getHistoricalCount(j); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e2f6144fb..2e09a7339 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -263,7 +263,7 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, mInvType(LLInventoryType::IT_NONE), mIsLink(FALSE) { - mInventoryPanel = inventory->getHandle(); + mInventoryPanel = inventory->getInventoryPanelHandle(); const LLInventoryObject* obj = getInventoryObject(); mIsLink = obj && obj->getIsLinkType(); } @@ -973,7 +973,7 @@ LLInventoryObject* LLInvFVBridge::getInventoryObject() const LLInventoryModel* LLInvFVBridge::getInventoryModel() const { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); return panel ? panel->getModel() : NULL; } @@ -1937,7 +1937,7 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewFolder* folderp = dynamic_cast(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); if (folderp) { @@ -3200,7 +3200,7 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) // Not sure what the right thing is to do here. if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); if(panel && !panel->getFilterWorn()) if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox or outbox { @@ -3481,7 +3481,7 @@ void LLFolderBridge::createNewCategory(void* user_data) { LLFolderBridge* bridge = (LLFolderBridge*)user_data; if(!bridge) return; - LLInventoryPanel* panel = dynamic_cast(bridge->mInventoryPanel.get()); + LLInventoryPanel* panel = bridge->mInventoryPanel.get(); if (!panel) return; LLInventoryModel* model = panel->getModel(); if(!model) return; @@ -3675,7 +3675,7 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) // use callback to rearrange favorite landmarks after adding // to have new one placed before target (on which it was dropped). See EXT-4312. LLPointer cb = new AddFavoriteLandmarkCallback(); - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; if (drag_over_item && drag_over_item->getListener()) { @@ -3724,6 +3724,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; + LLInventoryPanel* destination_panel = mInventoryPanel.get(); + if (!destination_panel) return false; + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); @@ -3855,6 +3858,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from active inventory panel + if (accept && active_panel) + { + LLFolderView* active_folder_view = active_panel->getRootFolder(); + if (!active_folder_view) return false; + } + if(accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE @@ -3864,14 +3876,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } // If an item is being dragged between windows, unselect everything in the active window // so that we don't follow the selection to its new location (which is very annoying). - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel) + if (active_panel && (destination_panel != active_panel)) { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); - if (active_panel && (panel != active_panel)) - { active_panel->unSelectAll(); - } } // FAVORITES folder @@ -4034,6 +4041,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = can_move_to_landmarks(inv_item); } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from the library + if (accept && active_panel) + { + LLFolderView* active_folder_view = active_panel->getRootFolder(); + if (!active_folder_view) return false; + } + if (accept && drop) { // FAVORITES folder @@ -4436,7 +4452,7 @@ LLCallingCardBridge::~LLCallingCardBridge() void LLCallingCardBridge::refreshFolderViewItem() { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; if (itemp) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index c3c883a42..f2b5c4215 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -160,7 +160,7 @@ protected: BOOL restamp); void removeBatchNoCheck(LLDynamicArray& batch); protected: - LLHandle mInventoryPanel; + LLHandle mInventoryPanel; LLFolderView* mRoot; const LLUUID mUUID; // item id LLInventoryType::EType mInvType; diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 4a2953f7f..f7d58b79a 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -129,6 +129,8 @@ public: LLScrollableContainerView* getScrollableContainer() { return mScroller; } void onSelectionChange(const std::deque &items, BOOL user_action); + + LLHandle getInventoryPanelHandle() const { return getDerivedHandle(); } // DEBUG ONLY: static void dumpSelectionInformation(void* user_data); diff --git a/indra/newview/llpanelmediahud.cpp b/indra/newview/llpanelmediahud.cpp index 2fcee26c6..27d1473d6 100644 --- a/indra/newview/llpanelmediahud.cpp +++ b/indra/newview/llpanelmediahud.cpp @@ -78,8 +78,6 @@ LLPanelMediaHUD::LLPanelMediaHUD(viewer_media_t media_impl) mFadeTimer.stop(); mCurrentZoom = ZOOM_NONE; mScrollState = SCROLL_NONE; - - mPanelHandle.bind(this); } LLPanelMediaHUD::~LLPanelMediaHUD() { diff --git a/indra/newview/llpanelmediahud.h b/indra/newview/llpanelmediahud.h index 81d40591e..1d1f5e1be 100644 --- a/indra/newview/llpanelmediahud.h +++ b/indra/newview/llpanelmediahud.h @@ -55,7 +55,8 @@ public: void nextZoomLevel(); void resetZoomLevel() { mCurrentZoom = ZOOM_NONE; } - LLHandle getHandle() const { return mPanelHandle; } + LLHandle getHandle() const { return getDerivedHandle(); } + void setMediaImpl(viewer_media_t media_impl) { mMediaImpl = media_impl; } @@ -105,7 +106,6 @@ private: F32 mMouseInactiveTime; F32 mControlFadeTime; viewer_media_t mMediaImpl; - LLRootHandle mPanelHandle; }; #endif // LL_PANELMEDIAHUD_H From 97d2085735d7f73f00b09297c2eacdbd16941c03 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 13 Nov 2012 23:25:32 -0600 Subject: [PATCH 050/213] Nullcheck in LLTextureFetch::removeRequest was returning without unlocking LLTextureFetch::mQueueMutex if called via LLTextureFetch::deleteRequest --- indra/newview/lltexturefetch.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 57ab3003f..ac57ff03b 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2168,11 +2168,13 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel, bo { if(!worker) { + if(!bNeedsLock) + unlockQueue() ; return; } - if(bNeedsLock) lockQueue() ; + size_t erased_1 = mRequestMap.erase(worker->mID); unlockQueue() ; From d2422b03be1a14443c75890ad942b92e951e06c6 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 13 Nov 2012 23:34:48 -0600 Subject: [PATCH 051/213] Don't flush rebuild queue nor flush pending texture requests if merely performing a local teleport (eg: doubleclick teleporting within current sim.) --- indra/newview/llviewertexturelist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 81a0fa89a..77de8ed09 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -624,7 +624,7 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MEDIA("Media"); void LLViewerTextureList::updateImages(F32 max_time) { static BOOL cleared = FALSE; - if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) + if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && gAgent.getTeleportState() != LLAgent::TELEPORT_LOCAL ) { if(!cleared) { From 66664660d7276eee4c43958ca6f9d7ffa31dc32c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Thu, 15 Nov 2012 04:07:44 +0100 Subject: [PATCH 052/213] Copied llwebprofile.{h,cpp} from v-d as-is. --- indra/newview/CMakeLists.txt | 2 + indra/newview/llwebprofile.cpp | 305 +++++++++++++++++++++++++++++++++ indra/newview/llwebprofile.h | 69 ++++++++ 3 files changed, 376 insertions(+) create mode 100644 indra/newview/llwebprofile.cpp create mode 100644 indra/newview/llwebprofile.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3ef620b2b..dc0223a63 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -538,6 +538,7 @@ set(viewer_SOURCE_FILES llwearablelist.cpp llwearabletype.cpp llweb.cpp + llwebprofile.cpp llwind.cpp llwlanimator.cpp llwldaycycle.cpp @@ -1047,6 +1048,7 @@ set(viewer_HEADER_FILES llwearablelist.h llwearabletype.h llweb.h + llwebprofile.h llwind.h llwindebug.h llwlanimator.h diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp new file mode 100644 index 000000000..641f338f2 --- /dev/null +++ b/indra/newview/llwebprofile.cpp @@ -0,0 +1,305 @@ +/** + * @file llwebprofile.cpp + * @brief Web profile access. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwebprofile.h" + +// libs +#include "llbufferstream.h" +#include "llhttpclient.h" +#include "llimagepng.h" +#include "llplugincookiestore.h" + +// newview +#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions +#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals + +// third-party +#include "reader.h" // JSON + +/* + * Workflow: + * 1. LLViewerMedia::setOpenIDCookie() + * -> GET https://my-demo.secondlife.com/ via LLViewerMediaWebProfileResponder + * -> LLWebProfile::setAuthCookie() + * 2. LLWebProfile::uploadImage() + * -> GET "https://my-demo.secondlife.com/snapshots/s3_upload_config" via ConfigResponder + * 3. LLWebProfile::post() + * -> POST via PostImageResponder + * -> redirect + * -> GET via PostImageRedirectResponder + */ + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfileResponders::ConfigResponder + +class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLWebProfileResponders::ConfigResponder); + +public: + ConfigResponder(LLPointer imagep) + : mImagep(imagep) + { + } + + /*virtual*/ void completedRaw( + U32 status, + const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + + if (status != 200) + { + llwarns << "Failed to get upload config (" << status << ")" << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + Json::Value root; + Json::Reader reader; + if (!reader.parse(body, root)) + { + llwarns << "Failed to parse upload config: " << reader.getFormatedErrorMessages() << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + // *TODO: 404 = not supported by the grid + // *TODO: increase timeout or handle 499 Expired + + // Convert config to LLSD. + const Json::Value data = root["data"]; + const std::string upload_url = root["url"].asString(); + LLSD config; + config["acl"] = data["acl"].asString(); + config["AWSAccessKeyId"] = data["AWSAccessKeyId"].asString(); + config["Content-Type"] = data["Content-Type"].asString(); + config["key"] = data["key"].asString(); + config["policy"] = data["policy"].asString(); + config["success_action_redirect"] = data["success_action_redirect"].asString(); + config["signature"] = data["signature"].asString(); + config["add_loc"] = data.get("add_loc", "0").asString(); + config["caption"] = data.get("caption", "").asString(); + + // Do the actual image upload using the configuration. + LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << llendl; + LLWebProfile::post(mImagep, config, upload_url); + } + +private: + LLPointer mImagep; +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfilePostImageRedirectResponder +class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder); + +public: + /*virtual*/ void completedRaw( + U32 status, + const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + if (status != 200) + { + llwarns << "Failed to upload image: " << status << " " << reason << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + llinfos << "Image uploaded." << llendl; + LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << llendl; + LLWebProfile::reportImageUploadStatus(true); + } + +private: + LLPointer mImagep; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfileResponders::PostImageResponder +class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLWebProfileResponders::PostImageResponder); + +public: + /*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + // Viewer seems to fail to follow a 303 redirect on POST request + // (URLRequest Error: 65, Send failed since rewinding of the data stream failed). + // Handle it manually. + if (status == 303) + { + LLSD headers = LLViewerMedia::getHeaders(); + headers["Cookie"] = LLWebProfile::getAuthCookie(); + const std::string& redir_url = content["location"]; + LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl; + LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers); + } + else + { + llwarns << "Unexpected POST status: " << status << " " << reason << llendl; + LL_DEBUGS("Snapshots") << "headers: [" << content << "]" << llendl; + LLWebProfile::reportImageUploadStatus(false); + } + } + + // Override just to suppress warnings. + /*virtual*/ void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfile + +std::string LLWebProfile::sAuthCookie; +LLWebProfile::status_callback_t LLWebProfile::mStatusCallback; + +// static +void LLWebProfile::uploadImage(LLPointer image, const std::string& caption, bool add_location) +{ + // Get upload configuration data. + std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config"); + config_url += "?caption=" + LLURI::escape(caption); + config_url += "&add_loc=" + std::string(add_location ? "1" : "0"); + + LL_DEBUGS("Snapshots") << "Requesting " << config_url << llendl; + LLSD headers = LLViewerMedia::getHeaders(); + headers["Cookie"] = getAuthCookie(); + LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers); +} + +// static +void LLWebProfile::setAuthCookie(const std::string& cookie) +{ + LL_DEBUGS("Snapshots") << "Setting auth cookie: " << cookie << llendl; + sAuthCookie = cookie; +} + +// static +void LLWebProfile::post(LLPointer image, const LLSD& config, const std::string& url) +{ + if (dynamic_cast(image.get()) == 0) + { + llwarns << "Image to upload is not a PNG" << llendl; + llassert(dynamic_cast(image.get()) != 0); + return; + } + + const std::string boundary = "----------------------------0123abcdefab"; + + LLSD headers = LLViewerMedia::getHeaders(); + headers["Cookie"] = getAuthCookie(); + headers["Content-Type"] = "multipart/form-data; boundary=" + boundary; + + std::ostringstream body; + + // *NOTE: The order seems to matter. + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"key\"\r\n\r\n" + << config["key"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n" + << config["AWSAccessKeyId"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n" + << config["acl"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n" + << config["Content-Type"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n" + << config["policy"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n" + << config["signature"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n" + << config["success_action_redirect"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n" + << "Content-Type: image/png\r\n\r\n"; + + // Insert the image data. + // *FIX: Treating this as a string will probably screw it up ... + U8* image_data = image->getData(); + for (S32 i = 0; i < image->getDataSize(); ++i) + { + body << image_data[i]; + } + + body << "\r\n--" << boundary << "--\r\n"; + + // postRaw() takes ownership of the buffer and releases it later. + size_t size = body.str().size(); + U8 *data = new U8[size]; + memcpy(data, body.str().data(), size); + + // Send request, successful upload will trigger posting metadata. + LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers); +} + +// static +void LLWebProfile::reportImageUploadStatus(bool ok) +{ + if (mStatusCallback) + { + mStatusCallback(ok); + } +} + +// static +std::string LLWebProfile::getAuthCookie() +{ + // This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine). + const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE"); + return debug_cookie ? debug_cookie : sAuthCookie; +} diff --git a/indra/newview/llwebprofile.h b/indra/newview/llwebprofile.h new file mode 100644 index 000000000..10279bffa --- /dev/null +++ b/indra/newview/llwebprofile.h @@ -0,0 +1,69 @@ +/** + * @file llwebprofile.h + * @brief Web profile access. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWEBPROFILE_H +#define LL_LLWEBPROFILE_H + +#include "llimage.h" + +namespace LLWebProfileResponders +{ + class ConfigResponder; + class PostImageResponder; + class PostImageRedirectResponder; +}; + +/** + * @class LLWebProfile + * + * Manages interaction with, a web service allowing the upload of snapshot images + * taken within the viewer. + */ +class LLWebProfile +{ + LOG_CLASS(LLWebProfile); + +public: + typedef boost::function status_callback_t; + + static void uploadImage(LLPointer image, const std::string& caption, bool add_location); + static void setAuthCookie(const std::string& cookie); + static void setImageUploadResultCallback(status_callback_t cb) { mStatusCallback = cb; } + +private: + friend class LLWebProfileResponders::ConfigResponder; + friend class LLWebProfileResponders::PostImageResponder; + friend class LLWebProfileResponders::PostImageRedirectResponder; + + static void post(LLPointer image, const LLSD& config, const std::string& url); + static void reportImageUploadStatus(bool ok); + static std::string getAuthCookie(); + + static std::string sAuthCookie; + static status_callback_t mStatusCallback; +}; + +#endif // LL_LLWEBPROFILE_H From fdfe0cae879c49d9ff7e888b985a0d193ed793e5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Thu, 15 Nov 2012 13:51:16 +0100 Subject: [PATCH 053/213] More clearly state the implications of the NoVerifySSLCert debug option --- indra/newview/app_settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0ccac5736..06dfc90e4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9104,7 +9104,7 @@ Found in Advanced->Rendering->Info Displays NoVerifySSLCert Comment - Do not verify SSL peers + Do not verify SSL certificates. WARNING: Setting this to TRUE allows anyone to impersonate the server and intercept your data (man in the middle attack). Persist 1 Type From fce64f8f12f0de144cce7aee045438d822ac8bbe Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Fri, 16 Nov 2012 02:00:06 +0100 Subject: [PATCH 054/213] Add LLWebProfile and responders. Adds finding and using libjsoncpp. Note that the old cmake file found libjson, not the same thing. Adds Debug Setting WebProfileNonProductionURL (next to already existing WebProfileURL) to mimic V3's behavior and use a different URL for aditi. These Debug Settings are using by (the new) getProfileURL() (copied from V3 with just a minor fix). Adds HippoGridInfo::isInProductionGrid() next to the existing LLViewerLogin::isInProductionGrid that always returned true. The former should only be called SL grids and then only returns true for agni (and false for aditi et al). The latter was changed to now always return true except on SL when the grid isn't agni. The first is used for SL-only cases, the latter for things like colors and for godmode decision logic. V3's llwebprofile.cpp was fixed to compile on singu, with only real difference that I dropped the Content-Type headers for the GET methods. --- indra/cmake/FindJsonCpp.cmake | 61 +--- indra/cmake/JsonCpp.cmake | 2 +- indra/llmessage/aihttptimeoutpolicy.cpp | 1 + indra/newview/CMakeLists.txt | 4 +- indra/newview/app_settings/settings.xml | 13 +- indra/newview/hippogridmanager.cpp | 8 + indra/newview/hippogridmanager.h | 2 + indra/newview/llfloateravatarinfo.cpp | 10 - indra/newview/llfloatermodelpreview.cpp | 2 +- indra/newview/llmarketplacefunctions.cpp | 2 +- indra/newview/llpanelprofile.cpp | 441 +++++++++++++++++++++++ indra/newview/llpanelprofile.h | 106 ++++++ indra/newview/llviewernetwork.cpp | 3 +- indra/newview/llwebprofile.cpp | 55 ++- 14 files changed, 637 insertions(+), 73 deletions(-) create mode 100644 indra/newview/llpanelprofile.cpp create mode 100644 indra/newview/llpanelprofile.h diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake index 44ab0e769..a48c97396 100644 --- a/indra/cmake/FindJsonCpp.cmake +++ b/indra/cmake/FindJsonCpp.cmake @@ -3,16 +3,18 @@ # - Find JSONCpp # Find the JSONCpp includes and library # This module defines -# JSONCPP_INCLUDE_DIR, where to find json.h, etc. -# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. -# JSONCPP_FOUND, If false, do not try to use jsoncpp. -# also defined, but not for general use are -# JSONCPP_LIBRARY, where to find the jsoncpp library. +# JSONCPP_FOUND, System has libjsoncpp. +# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories. +# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp. +# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp. -FIND_PATH(JSONCPP_INCLUDE_DIR json/json.h -/usr/local/include -/usr/include -) +FIND_PACKAGE(PkgConfig) +PKG_CHECK_MODULES(PC_JSONCPP jsoncpp) +SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER}) + +FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h + HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS} + PATH_SUFFIXES jsoncpp) # Get the GCC compiler version EXEC_PROGRAM(${CMAKE_CXX_COMPILER} @@ -22,39 +24,16 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER} ) # Try to find a library that was compiled with the same compiler version as we currently use. -SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so) -IF (STANDALONE) - # On standalone, assume that the system installed library was compiled with the used compiler. - SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so) -ENDIF (STANDALONE) FIND_LIBRARY(JSONCPP_LIBRARY - NAMES ${JSONCPP_NAMES} - PATHS /usr/lib /usr/local/lib - ) + NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so + HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib) -IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) - SET(JSONCPP_FOUND "YES") -ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - SET(JSONCPP_FOUND "NO") -ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) +SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) +SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR}) +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG + JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR) -IF (JSONCPP_FOUND) - IF (NOT JSONCPP_FIND_QUIETLY) - MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") - ENDIF (NOT JSONCPP_FIND_QUIETLY) -ELSE (JSONCPP_FOUND) - IF (JSONCPP_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find JSONCpp library") - ENDIF (JSONCPP_FIND_REQUIRED) -ENDIF (JSONCPP_FOUND) - -# Deprecated declarations. -SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH) - -MARK_AS_ADVANCED( - JSONCPP_LIBRARY - JSONCPP_INCLUDE_DIR - ) +MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR) diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake index 241db3570..2d7c16939 100644 --- a/indra/cmake/JsonCpp.cmake +++ b/indra/cmake/JsonCpp.cmake @@ -2,7 +2,7 @@ include(Prebuilt) -set(JSONCPP_FIND_QUIETLY ON) +set(JSONCPP_FIND_QUIETLY OFF) set(JSONCPP_FIND_REQUIRED ON) if (STANDALONE) diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 4acd41267..e91ee2e6b 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -889,6 +889,7 @@ P(viewerStatsResponder); P(viewerVoiceAccountProvisionResponder); P(voiceCallCapResponder); P(voiceClientCapResponder); +P(webProfileResponders); P(wholeModelFeeResponder); P(wholeModelUploadResponder); P2(XMLRPCResponder, connect_40s); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index dc0223a63..ec97152c2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -17,7 +17,7 @@ endif(FMOD) include(OPENAL) include(FindOpenGL) include(Hunspell) -#include(JsonCpp) +include(JsonCpp) include(LLAddBuildTest) include(LLAudio) include(LLCharacter) @@ -370,6 +370,7 @@ set(viewer_SOURCE_FILES llpanelpermissions.cpp llpanelpick.cpp llpanelplace.cpp + llpanelprofile.cpp llpanelskins.cpp llpanelvolume.cpp llpanelweb.cpp @@ -875,6 +876,7 @@ set(viewer_HEADER_FILES llpanelpermissions.h llpanelpick.h llpanelplace.h + llpanelprofile.h llpanelskins.h llpanelvolume.h llpanelweb.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 06dfc90e4..9c0a13fb9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7402,7 +7402,7 @@ Found in Advanced->Rendering->Info Displays WebProfileURL Comment - URL for Web Profiles + URL for SL Web Profiles Persist 0 Type @@ -7410,6 +7410,17 @@ Found in Advanced->Rendering->Info Displays Value https://my.secondlife.com/[AGENT_NAME] + WebProfileNonProductionURL + + Comment + URL for SL Web Profiles on Non-Production grids + Persist + 0 + Type + String + Value + https://my-demo.secondlife.com/[AGENT_NAME] + HighResSnapshot Comment diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index c0ceef71d..a626baaf8 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -51,6 +51,7 @@ HippoGridInfo::HippoGridInfo(const std::string& gridName) : mGridMessage(""), mXmlState(XML_VOID), mVoiceConnector("SLVoice"), + mIsInProductionGrid(false), mRenderCompat(true), mInvLinks(false), mAutoUpdate(false), @@ -80,6 +81,12 @@ bool HippoGridInfo::isSecondLife() const return (mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE); } +bool HippoGridInfo::isInProductionGrid() const +{ + llassert(mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE); + return mIsInProductionGrid; +} + const std::string& HippoGridInfo::getGridName() const { return mGridName; @@ -211,6 +218,7 @@ void HippoGridInfo::setGridName(const std::string& gridName) { setGridNick(gridName); }*/ + mIsInProductionGrid = gridName == "secondlife"; } void HippoGridInfo::setGridNick(std::string gridNick) diff --git a/indra/newview/hippogridmanager.h b/indra/newview/hippogridmanager.h index 4f3ef634e..5d58a1b5f 100644 --- a/indra/newview/hippogridmanager.h +++ b/indra/newview/hippogridmanager.h @@ -39,6 +39,7 @@ public: Platform getPlatform(); bool isOpenSimulator() const; bool isSecondLife() const; + bool isInProductionGrid() const; // Should only be called if isSecondLife() returns true. const std::string& getGridName() const; const std::string& getGridOwner() const; const std::string& getLoginUri() const; @@ -110,6 +111,7 @@ private: std::string mPasswordUrl; std::string mSearchUrl; std::string mVoiceConnector; + bool mIsInProductionGrid; bool mRenderCompat; bool mInvLinks; bool mAutoUpdate; diff --git a/indra/newview/llfloateravatarinfo.cpp b/indra/newview/llfloateravatarinfo.cpp index f60e24623..224099794 100644 --- a/indra/newview/llfloateravatarinfo.cpp +++ b/indra/newview/llfloateravatarinfo.cpp @@ -294,13 +294,3 @@ LLPreview::EAssetStatus LLFloaterAvatarInfo::getAssetStatus() } return mAssetStatus; } - -std::string getProfileURL(const std::string& agent_name) -{ - std::string url = gSavedSettings.getString("WebProfileURL"); - LLSD subs; - subs["AGENT_NAME"] = agent_name; - url = LLWeb::expandURLSubstitutions(url,subs); - LLStringUtil::toLower(url); - return url; -} diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 89d34dea3..b85b1b3e5 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -455,7 +455,7 @@ BOOL LLFloaterModelPreview::postBuild() std::string validate_url; if (gHippoGridManager->getCurrentGrid()->isSecondLife()) { - if (LLViewerLogin::getInstance()->isInProductionGrid()) + if (gHippoGridManager->getConnectedGrid()->isInProductionGrid()) { validate_url = "http://secondlife.com/my/account/mesh.php"; } diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 545ad927b..65cb7f8b8 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -46,7 +46,7 @@ static std::string getMarketplaceDomain() std::string domain = "secondlife.com"; if (gHippoGridManager->getCurrentGrid()->isSecondLife()) { - if (!LLViewerLogin::getInstance()->isInProductionGrid()) + if (!gHippoGridManager->getConnectedGrid()->isInProductionGrid()) { domain = "secondlife.aditi.lindenlab.com"; } diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp new file mode 100644 index 000000000..42db9fdd6 --- /dev/null +++ b/indra/newview/llpanelprofile.cpp @@ -0,0 +1,441 @@ +/** +* @file llpanelprofile.cpp +* @brief Profile panel implementation +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llpanelprofile.h" + +#ifdef AI_UNUSED +#include "llagent.h" +#include "llavataractions.h" +#include "llfloaterreg.h" +#include "llcommandhandler.h" +#include "llnotificationsutil.h" +#include "llpanelpicks.h" +#include "lltabcontainer.h" +#include "llviewercontrol.h" +#include "llviewernetwork.h" + +static const std::string PANEL_PICKS = "panel_picks"; +#endif // AI_UNUSED + +#include "hippogridmanager.h" +#include "llcontrol.h" +#include "llweb.h" + +std::string getProfileURL(const std::string& agent_name) +{ + std::string url; + + if (gHippoGridManager->getConnectedGrid()->isInProductionGrid()) + { + url = gSavedSettings.getString("WebProfileURL"); + } + else + { + url = gSavedSettings.getString("WebProfileNonProductionURL"); + } + LLSD subs; + subs["AGENT_NAME"] = agent_name; + url = LLWeb::expandURLSubstitutions(url,subs); + LLStringUtil::toLower(url); + return url; +} + +#ifdef AI_UNUSED +class LLProfileHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLProfileHandler() : LLCommandHandler("profile", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 1) return false; + std::string agent_name = params[0]; + llinfos << "Profile, agent_name " << agent_name << llendl; + std::string url = getProfileURL(agent_name); + LLWeb::loadURLInternal(url); + + return true; + } +}; +LLProfileHandler gProfileHandler; + +class LLAgentHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 2) return false; + LLUUID avatar_id; + if (!avatar_id.set(params[0], FALSE)) + { + return false; + } + + const std::string verb = params[1].asString(); + if (verb == "about") + { + LLAvatarActions::showProfile(avatar_id); + return true; + } + + if (verb == "inspect") + { + LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", avatar_id)); + return true; + } + + if (verb == "im") + { + LLAvatarActions::startIM(avatar_id); + return true; + } + + if (verb == "pay") + { + if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAvatarPay")) + { + LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); + return true; + } + + LLAvatarActions::pay(avatar_id); + return true; + } + + if (verb == "offerteleport") + { + LLAvatarActions::offerTeleport(avatar_id); + return true; + } + + if (verb == "requestfriend") + { + LLAvatarActions::requestFriendshipDialog(avatar_id); + return true; + } + + if (verb == "mute") + { + if (! LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + if (verb == "unmute") + { + if (LLAvatarActions::isBlocked(avatar_id)) + { + LLAvatarActions::toggleBlock(avatar_id); + } + return true; + } + + return false; + } +}; +LLAgentHandler gAgentHandler; + + +//-- LLPanelProfile::ChildStack begins ---------------------------------------- +LLPanelProfile::ChildStack::ChildStack() +: mParent(NULL) +{ +} + +LLPanelProfile::ChildStack::~ChildStack() +{ + while (mStack.size() != 0) + { + view_list_t& top = mStack.back(); + for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) + { + LLView* viewp = *it; + if (viewp) + { + viewp->die(); + } + } + mStack.pop_back(); + } +} + +void LLPanelProfile::ChildStack::setParent(LLPanel* parent) +{ + llassert_always(parent != NULL); + mParent = parent; +} + +/// Save current parent's child views and remove them from the child list. +bool LLPanelProfile::ChildStack::push() +{ + view_list_t vlist = *mParent->getChildList(); + + for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it) + { + LLView* viewp = *it; + mParent->removeChild(viewp); + } + + mStack.push_back(vlist); + dump(); + return true; +} + +/// Restore saved children (adding them back to the child list). +bool LLPanelProfile::ChildStack::pop() +{ + if (mStack.size() == 0) + { + llwarns << "Empty stack" << llendl; + llassert(mStack.size() == 0); + return false; + } + + view_list_t& top = mStack.back(); + for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it) + { + LLView* viewp = *it; + mParent->addChild(viewp); + } + + mStack.pop_back(); + dump(); + return true; +} + +/// Temporarily add all saved children back. +void LLPanelProfile::ChildStack::preParentReshape() +{ + mSavedStack = mStack; + while(mStack.size() > 0) + { + pop(); + } +} + +/// Add the temporarily saved children back. +void LLPanelProfile::ChildStack::postParentReshape() +{ + mStack = mSavedStack; + mSavedStack = stack_t(); + + for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it) + { + const view_list_t& vlist = (*stack_it); + for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) + { + LLView* viewp = *list_it; + lldebugs << "removing " << viewp->getName() << llendl; + mParent->removeChild(viewp); + } + } +} + +void LLPanelProfile::ChildStack::dump() +{ + unsigned lvl = 0; + lldebugs << "child stack dump:" << llendl; + for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl) + { + std::ostringstream dbg_line; + dbg_line << "lvl #" << lvl << ":"; + const view_list_t& vlist = (*stack_it); + for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it) + { + dbg_line << " " << (*list_it)->getName(); + } + lldebugs << dbg_line.str() << llendl; + } +} + +//-- LLPanelProfile::ChildStack ends ------------------------------------------ + +LLPanelProfile::LLPanelProfile() + : LLPanel() + , mAvatarId(LLUUID::null) +{ + mChildStack.setParent(this); +} + +BOOL LLPanelProfile::postBuild() +{ + LLPanelPicks* panel_picks = findChild(PANEL_PICKS); + panel_picks->setProfilePanel(this); + + getTabContainer()[PANEL_PICKS] = panel_picks; + + return TRUE; +} + +// virtual +void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + // Temporarily add saved children back and reshape them. + mChildStack.preParentReshape(); + LLPanel::reshape(width, height, called_from_parent); + mChildStack.postParentReshape(); +} + +void LLPanelProfile::onOpen(const LLSD& key) +{ + getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId()); + + // support commands to open further pieces of UI + if (key.has("show_tab_panel")) + { + std::string panel = key["show_tab_panel"].asString(); + if (panel == "create_classified") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + picks->createNewClassified(); + } + } + else if (panel == "classified_details") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openClassifiedInfo(params); + } + } + else if (panel == "edit_classified") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openClassifiedEdit(params); + } + } + else if (panel == "create_pick") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + picks->createNewPick(); + } + } + else if (panel == "edit_pick") + { + LLPanelPicks* picks = dynamic_cast(getTabContainer()[PANEL_PICKS]); + if (picks) + { + LLSD params = key; + params.erase("show_tab_panel"); + params.erase("open_tab_name"); + picks->openPickEdit(params); + } + } + } +} + +void LLPanelProfile::onTabSelected(const LLSD& param) +{ + std::string tab_name = param.asString(); + if (NULL != getTabContainer()[tab_name]) + { + getTabContainer()[tab_name]->onOpen(getAvatarId()); + } +} + +void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params) +{ + // Hide currently visible panel (STORM-690). + mChildStack.push(); + + // Add the panel or bring it to front. + if (panel->getParent() != this) + { + addChild(panel); + } + else + { + sendChildToFront(panel); + } + + panel->setVisible(TRUE); + panel->setFocus(TRUE); // prevent losing focus by the floater + panel->onOpen(params); + + LLRect new_rect = getRect(); + panel->reshape(new_rect.getWidth(), new_rect.getHeight()); + new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight()); + panel->setRect(new_rect); +} + +void LLPanelProfile::closePanel(LLPanel* panel) +{ + panel->setVisible(FALSE); + + if (panel->getParent() == this) + { + removeChild(panel); + + // Make the underlying panel visible. + mChildStack.pop(); + + // Prevent losing focus by the floater + const child_list_t* child_list = getChildList(); + if (child_list->size() > 0) + { + child_list->front()->setFocus(TRUE); + } + else + { + llwarns << "No underlying panel to focus." << llendl; + } + } +} + +S32 LLPanelProfile::notifyParent(const LLSD& info) +{ + std::string action = info["action"]; + // lets update Picks list after Pick was saved + if("save_new_pick" == action) + { + onOpen(info); + return 1; + } + + return LLPanel::notifyParent(info); +} +#endif // AI_UNUSED diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h new file mode 100644 index 000000000..73539dda2 --- /dev/null +++ b/indra/newview/llpanelprofile.h @@ -0,0 +1,106 @@ +/** +* @file llpanelprofile.h +* @brief Profile panel +* +* $LicenseInfo:firstyear=2009&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLPANELPROFILE_H +#define LL_LLPANELPROFILE_H + +#ifdef AI_UNUSED +#include "llpanel.h" +#include "llpanelavatar.h" + +class LLTabContainer; +#endif // AI_UNUSED + +std::string getProfileURL(const std::string& agent_name); + +#ifdef AI_UNUSED +/** +* Base class for Profile View and My Profile. +*/ +class LLPanelProfile : public LLPanel +{ + LOG_CLASS(LLPanelProfile); + +public: + /*virtual*/ BOOL postBuild(); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + /*virtual*/ void onOpen(const LLSD& key); + + virtual void openPanel(LLPanel* panel, const LLSD& params); + + virtual void closePanel(LLPanel* panel); + + S32 notifyParent(const LLSD& info); + +protected: + + LLPanelProfile(); + + virtual void onTabSelected(const LLSD& param); + + const LLUUID& getAvatarId() { return mAvatarId; } + + void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } + + typedef std::map profile_tabs_t; + + profile_tabs_t& getTabContainer() { return mTabContainer; } + +private: + + //-- ChildStack begins ---------------------------------------------------- + class ChildStack + { + LOG_CLASS(LLPanelProfile::ChildStack); + public: + ChildStack(); + ~ChildStack(); + void setParent(LLPanel* parent); + + bool push(); + bool pop(); + void preParentReshape(); + void postParentReshape(); + + private: + void dump(); + + typedef LLView::child_list_t view_list_t; + typedef std::list stack_t; + + stack_t mStack; + stack_t mSavedStack; + LLPanel* mParent; + }; + //-- ChildStack ends ------------------------------------------------------ + + profile_tabs_t mTabContainer; + ChildStack mChildStack; + LLUUID mAvatarId; +}; +#endif // AI_UNUSED + +#endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index a2625495c..dde9a9d47 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -77,6 +77,7 @@ bool LLViewerLogin::isSecondLife() bool LLViewerLogin::isInProductionGrid() { - return true; + // Return true (as before) on opensim grids, but return the real thing (agni or not) on SL. + return !gHippoGridManager->getConnectedGrid()->isSecondLife() || gHippoGridManager->getConnectedGrid()->isInProductionGrid(); } diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 641f338f2..141c746e0 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -35,11 +35,15 @@ #include "llplugincookiestore.h" // newview -#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions +#include "llpanelprofile.h" // getProfileURL (this is the original location LL put it). #include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals // third-party -#include "reader.h" // JSON +#ifdef LL_STANDALONE +#include // JSONCPP +#else +#include "reader.h" // prebuilt jsoncpp is wrongly packaged. +#endif /* * Workflow: @@ -57,7 +61,9 @@ /////////////////////////////////////////////////////////////////////////////// // LLWebProfileResponders::ConfigResponder -class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder +extern AIHTTPTimeoutPolicy webProfileResponders_timeout; + +class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::ResponderWithCompleted { LOG_CLASS(LLWebProfileResponders::ConfigResponder); @@ -71,7 +77,7 @@ public: U32 status, const std::string& reason, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + const buffer_ptr_t& buffer) { LLBufferStream istr(channels, buffer.get()); std::stringstream strstrm; @@ -116,13 +122,16 @@ public: LLWebProfile::post(mImagep, config, upload_url); } +protected: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return webProfileResponders_timeout; } + private: LLPointer mImagep; }; /////////////////////////////////////////////////////////////////////////////// // LLWebProfilePostImageRedirectResponder -class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::Responder +class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::ResponderWithCompleted { LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder); @@ -131,7 +140,7 @@ public: U32 status, const std::string& reason, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + const buffer_ptr_t& buffer) { if (status != 200) { @@ -149,6 +158,9 @@ public: LLWebProfile::reportImageUploadStatus(true); } +protected: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return webProfileResponders_timeout; } + private: LLPointer mImagep; }; @@ -156,11 +168,13 @@ private: /////////////////////////////////////////////////////////////////////////////// // LLWebProfileResponders::PostImageResponder -class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responder +class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::ResponderWithCompleted { LOG_CLASS(LLWebProfileResponders::PostImageResponder); public: + /*virtual*/ bool needsHeaders(void) const { return true; } + /*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content) { // Viewer seems to fail to follow a 303 redirect on POST request @@ -168,8 +182,10 @@ public: // Handle it manually. if (status == 303) { - LLSD headers = LLViewerMedia::getHeaders(); - headers["Cookie"] = LLWebProfile::getAuthCookie(); + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); const std::string& redir_url = content["location"]; LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl; LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers); @@ -185,9 +201,12 @@ public: // Override just to suppress warnings. /*virtual*/ void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + const buffer_ptr_t& buffer) { } + +protected: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return webProfileResponders_timeout; } }; /////////////////////////////////////////////////////////////////////////////// @@ -205,8 +224,10 @@ void LLWebProfile::uploadImage(LLPointer image, const std::str config_url += "&add_loc=" + std::string(add_location ? "1" : "0"); LL_DEBUGS("Snapshots") << "Requesting " << config_url << llendl; - LLSD headers = LLViewerMedia::getHeaders(); - headers["Cookie"] = getAuthCookie(); + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers); } @@ -229,9 +250,11 @@ void LLWebProfile::post(LLPointer image, const LLSD& config, c const std::string boundary = "----------------------------0123abcdefab"; - LLSD headers = LLViewerMedia::getHeaders(); - headers["Cookie"] = getAuthCookie(); - headers["Content-Type"] = "multipart/form-data; boundary=" + boundary; + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); + headers.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary); std::ostringstream body; @@ -280,7 +303,7 @@ void LLWebProfile::post(LLPointer image, const LLSD& config, c // postRaw() takes ownership of the buffer and releases it later. size_t size = body.str().size(); - U8 *data = new U8[size]; + char* data = new char [size]; memcpy(data, body.str().data(), size); // Send request, successful upload will trigger posting metadata. From 299382b907da4cd7151e70d0a8b2cb6d274a10a3 Mon Sep 17 00:00:00 2001 From: Damian Zhaoying Date: Thu, 15 Nov 2012 22:13:17 -0300 Subject: [PATCH 055/213] Add Merchant Outbox text files --- .../xui/es/floater_merchant_outbox.xml | 34 +++++++++++++++++++ .../xui/es/floater_region_debug_console.xml | 3 ++ .../default/xui/es/panel_outbox_inventory.xml | 3 ++ 3 files changed, 40 insertions(+) create mode 100644 indra/newview/skins/default/xui/es/floater_merchant_outbox.xml create mode 100644 indra/newview/skins/default/xui/es/floater_region_debug_console.xml create mode 100644 indra/newview/skins/default/xui/es/panel_outbox_inventory.xml diff --git a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml new file mode 100644 index 000000000..a0d5b5d31 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml @@ -0,0 +1,34 @@ + + + Sin Carpetas + 1 Carpeta + [NUM] Carpetas + Enviando Carpetas... + Inicializando... + + + + Cargando... + + + + + + Arrastra los Ãtems aquí para crear las carpetas + + +