From e8ec81bf04e11e47bcf4af2542cacf6fba277bed Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 14 Oct 2012 04:00:02 -0500 Subject: [PATCH 01/93] 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 02/93] 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 03/93] 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 04/93] 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 05/93] 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 06/93] 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 07/93] 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 08/93] 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 09/93] 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 10/93] 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 11/93] 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 12/93] 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 13/93] 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 14/93] 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 15/93] 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 16/93] 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 17/93] 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 18/93] 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 19/93] 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 20/93] 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 21/93] 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 22/93] 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 23/93] 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 24/93] 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 25/93] 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 26/93] 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 27/93] =?UTF-8?q?A=20few=20resolutions=20in=20the=20dropdo?= =?UTF-8?q?wn=20in=20the=20prefrences=20panel=20were=20not=20being=20parse?= =?UTF-8?q?d=20correctly.=20Use=20standard=20'x'=20instead=20of=20'=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 28/93] 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 29/93] 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 30/93] 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 31/93] 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 32/93] 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 33/93] 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 34/93] 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 35/93] 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 36/93] 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 37/93] 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 38/93] 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 39/93] 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 40/93] 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 41/93] 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 42/93] 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 43/93] 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 44/93] 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 45/93] 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 46/93] 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 47/93] 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 48/93] 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 49/93] 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 50/93] 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 51/93] 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 52/93] 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 53/93] 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 54/93] 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 746f419e8022b321583cac579d6c57525e1144b8 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sat, 17 Nov 2012 21:38:55 +0100 Subject: [PATCH 55/93] Fix detection of mIsInProductionGrid and fix getMarketplaceDomain() getMarketplaceDomain() should return aditi.lindenlab.com for aditi, not secondlife.aditi.lindenlab.com. mIsInProductionGrid wasn't set correctly. --- indra/newview/hippogridmanager.cpp | 9 ++++- indra/newview/llmarketplacefunctions.cpp | 42 ++++++++++++++++++++---- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index a626baaf8..4de1c7ad8 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -218,7 +218,6 @@ void HippoGridInfo::setGridName(const std::string& gridName) { setGridNick(gridName); }*/ - mIsInProductionGrid = gridName == "secondlife"; } void HippoGridInfo::setGridNick(std::string gridNick) @@ -228,12 +227,20 @@ void HippoGridInfo::setGridNick(std::string gridNick) { setGridName(gridNick); } + if(gridNick == "secondlife") + { + mIsInProductionGrid = true; + } } void HippoGridInfo::setLoginUri(const std::string& loginUri) { std::string uri = loginUri; mLoginUri = sanitizeUri(uri); + if (utf8str_tolower(LLURI(uri).hostName()) == "login.agni.lindenlab.com") + { + mIsInProductionGrid = true; + } } void HippoGridInfo::setLoginPage(const std::string& loginPage) diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 65cb7f8b8..d4863e96e 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -41,24 +41,54 @@ // Helpers // +static std::string getLoginUriDomain() +{ + LLURI uri(gHippoGridManager->getConnectedGrid()->getLoginUri()); + std::string hostname = uri.hostName(); // Ie, "login..lindenlab.com" + if (hostname.substr(0, 6) == "login.") + { + hostname = hostname.substr(6); // ".lindenlab.com" + } + return hostname; +} + +// Apart from well-known cases, in general this function returns the domain of the loginUri (with the "login." stripped off). +// This should be correct for all SL BETA grids, assuming they have the form of "login..lindenlab.com", in which +// case it returns ".lindenlab.com". +// +// Well-known cases that deviate from this: +// agni --> "secondlife.com" +// damballah --> "secondlife-staging.com" +// static std::string getMarketplaceDomain() { - std::string domain = "secondlife.com"; + std::string domain; if (gHippoGridManager->getCurrentGrid()->isSecondLife()) { - if (!gHippoGridManager->getConnectedGrid()->isInProductionGrid()) + if (gHippoGridManager->getConnectedGrid()->isInProductionGrid()) { - domain = "secondlife.aditi.lindenlab.com"; + domain = "secondlife.com"; // agni + } + else + { + // SecondLife(tm) BETA grid. + // Using the login URI is a bit of a kludge, but it's the best we've got at the moment. + domain = utf8str_tolower(getLoginUriDomain()); // .lindenlab.com; ie, "aditi.lindenlab.com". + std::string::size_type len = domain.length(); + llassert(len > 14 && domain.substr(len - 14) == ".lindenlab.com"); + if (domain == "damballah.lindenlab.com") + { + domain = "secondlife-staging.com"; + } } } else { // TODO: Find out if OpenSim, and Avination adopted any outbox stuffs, if so code HippoGridManager for this // Aurora grid has not. - // For now, reset domain on other grids, so we don't harass LL web services. - domain = ""; //gHippoGridManager->getCurrentGrid()->getMarketPlaceDomain(); + // For now, set domain on other grids to the loginUri domain, so we don't harass LL web services. + domain = getLoginUriDomain(); //gHippoGridManager->getCurrentGrid()->getMarketPlaceDomain(); } - return domain; } From 57b66a9be91a466b42efeeaa68d899ef5cc3b3cc Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 18 Nov 2012 01:28:23 +0100 Subject: [PATCH 56/93] Allow cookies when allowing redirects (next to when sending a Cookie ourselves). --- indra/llmessage/aicurl.cpp | 11 +++++++++++ indra/llmessage/llurlrequest.cpp | 11 ----------- indra/llmessage/llurlrequest.h | 5 ----- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index 2353f24bd..e06a01570 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -1344,11 +1344,22 @@ void BufferedCurlEasyRequest::prepRequest(AICurlEasyRequest_wat& curl_easy_reque curl_easy_request_w->setReadCallback(&curlReadCallback, lockobj); curl_easy_request_w->setHeaderCallback(&curlHeaderCallback, lockobj); + bool allow_cookies = headers.hasHeader("Cookie"); // Allow up to ten redirects. if (responder->followRedir()) { curl_easy_request_w->setopt(CURLOPT_FOLLOWLOCATION, 1); curl_easy_request_w->setopt(CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT); + // This is needed (at least) for authentication after temporary redirection + // to id.secondlife.com for marketplace.secondlife.com. + allow_cookies = true; + } + if (allow_cookies) + { + // Given an empty or non-existing file or by passing the empty string (""), + // this option will enable cookies for this curl handle, making it understand + // and parse received cookies and then use matching cookies in future requests. + curl_easy_request_w->setopt(CURLOPT_COOKIEFILE, ""); } // Keep responder alive. diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 927b64b7a..d2683a88c 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -85,11 +85,6 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string cons void LLURLRequest::initialize_impl(void) { - if (mHeaders.hasHeader("Cookie")) - { - allowCookies(); - } - // If the header is "Pragma" with no value, the caller intends to // force libcurl to drop the Pragma header it so gratuitously inserts. // Before inserting the header, force libcurl to not use the proxy. @@ -199,12 +194,6 @@ void LLURLRequest::useProxy(const std::string &proxy) } #endif -void LLURLRequest::allowCookies() -{ - AICurlEasyRequest_wat curlEasyRequest_w(*mCurlEasyRequest); - curlEasyRequest_w->setoptString(CURLOPT_COOKIEFILE, ""); -} - bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) { bool rv = false; diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index 8f019310f..fbe97c22f 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -84,11 +84,6 @@ class LLURLRequest : public AICurlEasyRequestStateMachine { /*virtual*/ ~LLURLRequest() { } public: - /** - * @brief Turn on cookie handling for this request with CURLOPT_COOKIEFILE. - */ - void allowCookies(void); - /** * @ brief Turn off (or on) the CURLOPT_PROXY header. */ From 549913667748a0e87792d0d777b04efd13ecb28a Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 18 Nov 2012 01:29:24 +0100 Subject: [PATCH 57/93] Don't send an Accept header for HEAD requests. --- indra/llmessage/llurlrequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index d2683a88c..479e35d7f 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -100,7 +100,7 @@ void LLURLRequest::initialize_impl(void) // but if they did not specify a Content-Type, then ask the injector. mHeaders.addHeader("Content-Type", mBody->contentType(), AIHTTPHeaders::keep_existing_header); } - else + else if (mAction != HTTP_HEAD) { // Check to see if we have already set Accept or not. If no one // set it, set it to application/llsd+xml since that's what we From f44de434c2e6e4ac6321bd73f9989e6564fb3c34 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 18 Nov 2012 02:07:19 +0100 Subject: [PATCH 58/93] Always use followRedir() to determine if redirections should be followed. Before every HEAD and GET request allowed redirection by default, without setting a limit on the number of redirections. This caused an infinite redirect loop when connecting to marketplace, in combination with the bug that we did not allow cookies. --- indra/llmessage/aicurlthread.cpp | 6 ++++++ indra/llmessage/llhttpclient.h | 3 ++- indra/llmessage/llurlrequest.cpp | 2 -- indra/newview/llmarketplacefunctions.cpp | 3 ++- indra/newview/lltexturefetch.cpp | 2 +- indra/newview/llviewermedia.cpp | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index 7009d5bf3..3343c0d30 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -2137,6 +2137,12 @@ void BufferedCurlEasyRequest::setStatusAndReason(U32 status, std::string const& mStatus = status; mReason = reason; AICurlInterface::Stats::status_count[AICurlInterface::Stats::status2index(mStatus)]++; + + // Sanity check. If the server replies with a redirect status then we better have that option turned on! + if ((status >= 300 && status < 400) && mResponder && !mResponder->followRedir()) + { + llerrs << "Received " << status << " (" << reason << ") for responder \"" << mTimeoutPolicy->name() << "\" which has no followRedir()!" << llendl; + } } void BufferedCurlEasyRequest::processOutput(void) diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 3e491de82..ec4e88955 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -161,7 +161,7 @@ public: // A derived class should return true if curl should follow redirections. // The default is not to follow redirections. - virtual bool followRedir(void) { return false; } + virtual bool followRedir(void) const { return false; } // Timeout policy to use. virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0; @@ -188,6 +188,7 @@ public: class ResponderHeadersOnly : public ResponderBase { private: /*virtual*/ bool needsHeaders(void) const { return true; } + /*virtual*/ bool followRedir(void) const { return true; } protected: // ResponderBase event diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 479e35d7f..3ffb9e5cc 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -202,13 +202,11 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w) { case HTTP_HEAD: curlEasyRequest_w->setopt(CURLOPT_NOBODY, 1); - curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; break; case HTTP_GET: curlEasyRequest_w->setopt(CURLOPT_HTTPGET, 1); - curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1); // Set Accept-Encoding to allow response compression curlEasyRequest_w->setoptString(CURLOPT_ENCODING, mNoCompression ? "identity" : ""); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index d4863e96e..970db1bd8 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -197,7 +197,8 @@ namespace LLMarketplaceImport public: AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportGetResponder_timeout; } - bool needsHeaders(void) const { return true; } + /*virtual*/ bool followRedir(void) const { return true; } + /*virtual*/ bool needsHeaders(void) const { return true; } void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 5d4894948..4250ac280 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -408,7 +408,7 @@ public: } } - virtual bool followRedir() + /*virtual*/ bool followRedir() const { return mFollowRedir; } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 94b05c958..cf60073a4 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -168,6 +168,7 @@ public: { } + /* virtual */ bool followRedir(void) const { return true; } /* virtual */ bool needsHeaders(void) const { return true; } /* virtual */ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) From 52673f52493b282c2b58af3f896605739850bfbb Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 18 Nov 2012 02:41:37 +0100 Subject: [PATCH 59/93] Slight update of README --- README | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/README b/README index 55c159679..4a048e09c 100644 --- a/README +++ b/README @@ -9,15 +9,30 @@ Sin-gu-la-ri-ty (noun) - a distinctive feature, a uniqueness; a point at which continuity breaks up; a point in history at which machine becomes smarter than humanity and/or fuses with it indivisively; or simply a cool sounding word with -my initials in it :) +the initials S.G. in it :) -Singularity Viewer is a Second Life protocol compatible client application. It -can be used to access Second LIfe service as well as a number of other such as -those based upon OpenSim plattform. It is directly based upon source code of -Ascent Viewer by Balseraph Software Group, which is in turn based upon source -code released by Linden Lab, with contributions from various sources. +Singularity Viewer is a SecondLife(tm) protocol compatible client application. +It can be used to access SecondLife services as well as a number of others such +as those based upon the OpenSim platform. + +Singulariy is maintained by a small group of volunteers who can be contacted +both, in-world (SingularityViewer group) as well on IRC (#SingularityViewer +@ FreeNode). Bug requests and features requests can be submitted through our +Issue Tracket (http://code.google.com/p/singularity-viewer/issues/list or from +the viewer menu: Help --> Bug Reporting --> Singularity Issue Tracker...) + As this Readme grows out of date, please refer to http://www.singularityviewer.org/about + +00000000011111111112222222222333333333344444444445555555555666666666677777777778 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 + +History + +The Singularity viewer was started by Siana Gearz in November 2010 by forking it +of the Ascent Viewer, by Balseraph Software Group, which in turn was based upon +source code released by Linden Lab. + From 5947769812369a7988a7f1db30df79e6fc0e4787 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 18 Nov 2012 03:29:01 +0100 Subject: [PATCH 60/93] Fix LLMimeDiscoveryResponder. Extract Content-Type also from a 405 reply. If all else fails, use a default mime-type for url's opened in the browser (start with http: or https:) of "text/html" instead of "none/none". --- indra/newview/llviewermedia.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index cf60073a4..13381f167 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -75,14 +75,15 @@ class LLMimeDiscoveryResponder : public LLHTTPClient::ResponderHeadersOnly { LOG_CLASS(LLMimeDiscoveryResponder); public: - LLMimeDiscoveryResponder( viewer_media_t media_impl) + LLMimeDiscoveryResponder(viewer_media_t media_impl, std::string const& default_mime_type) : mMediaImpl(media_impl), + mDefaultMimeType(default_mime_type), mInitialized(false) {} /*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) { - if (200 <= status && status < 300) + if (200 <= status && status < 300 || status == 405) // Using HEAD may result in a 405 METHOD NOT ALLOWED, but still have the right Content-TYpe header. { std::string media_type; if (headers.getFirstValue("content-type", media_type)) @@ -92,9 +93,13 @@ public: completeAny(status, mime_type); return; } - llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + if (200 <= status && status < 300) + { + llwarns << "LLMimeDiscoveryResponder::completedHeaders: OK HTTP status (" << status << ") but no Content-Type! Received headers: " << headers << llendl; + } } - completeAny(status, "none/none"); + llwarns << "LLMimeDiscoveryResponder::completedHeaders: Got status " << status << ". Using default mime-type: " << mDefaultMimeType << llendl; + completeAny(status, mDefaultMimeType); } void completeAny(U32 status, const std::string& mime_type) @@ -113,6 +118,7 @@ public: public: viewer_media_t mMediaImpl; + std::string mDefaultMimeType; bool mInitialized; }; @@ -1313,7 +1319,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi { if(mime_type.empty()) { - LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this)); + LLHTTPClient::getHeaderOnly(url, new LLMimeDiscoveryResponder(this, "text/html")); } else if(initializeMedia(mime_type) && (plugin = getMediaPlugin())) { From 9d8f31a0cbdf3c07d4e3c82d51311f0f63bb6b9d Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 18 Nov 2012 02:41:37 -0600 Subject: [PATCH 61/93] Some teleport reworking. Don't clear rebuild groups/resetVBO unless tp screen is up, or we've just changed sims. Also skip updateUI drawing if tp screen is up. --- indra/newview/llagent.cpp | 8 ++++++-- indra/newview/llappviewer.cpp | 6 ++++++ indra/newview/llflexibleobject.h | 1 + indra/newview/llviewerdisplay.cpp | 10 +++++++--- indra/newview/llviewertexturelist.cpp | 12 +++++++++++- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index cfe3a36ec..2b6e85eeb 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3515,8 +3515,12 @@ bool LLAgent::teleportCore(bool is_local) gTeleportDisplay = TRUE; gAgent.setTeleportState( LLAgent::TELEPORT_START ); - //release geometry from old location - gPipeline.resetVertexBuffers(); + /*static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); + if(!hide_tp_screen) + { + //release geometry from old location + gPipeline.resetVertexBuffers(); + }*/ if (gSavedSettings.getBOOL("SpeedRez")) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0051e4b01..f23d46e9b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3922,6 +3922,12 @@ void LLAppViewer::idle() return; } + static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); + if (!hide_tp_screen && gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && gAgent.getTeleportState() != LLAgent::TELEPORT_LOCAL) + { + return; + } + gViewerWindow->updateUI(); /////////////////////////////////////// diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index 7d0d4c83c..cba941bcd 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -76,6 +76,7 @@ private: S32 mInstanceIndex; public: + static void resetTimers() { memset(&sUpdateDelay[0], 0, sizeof(S32)*sUpdateDelay.size()); } static void updateClass(); LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 46a05bc6d..835c8ff97 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -422,6 +422,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo gAgent.setTeleportMessage(std::string()); } + static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { @@ -429,11 +430,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); - if(!gSavedSettings.getBOOL("AscentDisableTeleportScreens"))gViewerWindow->setShowProgress(TRUE); + if(!hide_tp_screen) + gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(0); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: @@ -457,14 +460,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gTextureList.mForceResetTextureStats = TRUE; - if(!gSavedSettings.getBOOL("AscentDisableTeleportScreens"))gAgentCamera.resetView(TRUE, TRUE); + if(!hide_tp_screen) + gAgentCamera.resetView(TRUE, TRUE); break; case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); - if( arrival_fraction > 1.f || gSavedSettings.getBOOL("AscentDisableTeleportScreens")) + if( arrival_fraction > 1.f || hide_tp_screen) { arrival_fraction = 1.f; LLFirstUse::useTeleport(); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 77de8ed09..763692846 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -65,6 +65,8 @@ #include "pipeline.h" #include "llappviewer.h" #include "llagent.h" +#include "llviewerdisplay.h" +#include "llflexibleobject.h" //////////////////////////////////////////////////////////////////////////// @@ -624,12 +626,20 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MEDIA("Media"); void LLViewerTextureList::updateImages(F32 max_time) { static BOOL cleared = FALSE; - if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && gAgent.getTeleportState() != LLAgent::TELEPORT_LOCAL ) + static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); + + //Can't check gTeleportDisplay due to a process_teleport_local(), which sets it to true for local teleports... so: + // Do this case if IS teleporting but NOT local teleporting, AND either the TP screen is set to appear OR we just entered the sim (TELEPORT_START_ARRIVAL) + if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && gAgent.getTeleportState() != LLAgent::TELEPORT_LOCAL && + (!hide_tp_screen || gAgent.getTeleportState() == LLAgent::TELEPORT_START_ARRIVAL)) { if(!cleared) { clearFetchingRequests(); + //gPipeline.clearRebuildGroups() really doesn't belong here... but since it is here, do a few other needed things too. gPipeline.clearRebuildGroups(); + gPipeline.resetVertexBuffers(); + LLVolumeImplFlexible::resetTimers(); cleared = TRUE; } return; From 6b473c6edcca0eb0c23d200cbb45fd321f64da96 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 18 Nov 2012 02:42:33 -0600 Subject: [PATCH 62/93] Avoid clearing hud object rebuild states when teleporting. --- indra/newview/pipeline.cpp | 42 ++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d08b6e903..3a766ed5e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2356,26 +2356,60 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority G void LLPipeline::clearRebuildGroups() { + LLSpatialGroup::sg_vector_t hudGroups; + 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); + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } } - mGroupQ1.clear(); + + // Clear the group + //mGroupQ1.clear(); //Assign already clears... + + // Copy the saved HUD groups back in + mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); mGroupQ1Locked = false; + // Clear the HUD groups + hudGroups.clear(); + mGroupQ2Locked = true; for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) { LLSpatialGroup* group = *iter; - group->clearState(LLSpatialGroup::IN_BUILD_Q2); + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } } - mGroupQ2.clear(); + // Clear the group + //mGroupQ2.clear(); //Assign already clears... + + // Copy the saved HUD groups back in + mGroupQ2.assign(hudGroups.begin(), hudGroups.end()); mGroupQ2Locked = false; } void LLPipeline::rebuildPriorityGroups() From 9a9b5ce61ea027eea47e7659c097f44208cd3d10 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 18 Nov 2012 02:48:55 -0600 Subject: [PATCH 63/93] LLRectBase<>::clipPointToRect could divide by zero, resulting in the resulting clampd values being invalid under some scenarios (worldmap panning could cause the mouse cursor to 'restore' to an invalid location upon mouseclick release.) --- indra/llmath/llrect.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index d7595dcee..d476ad3e6 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -124,8 +124,8 @@ public: if (end_y < mBottom) clip_y = end_y - mBottom; // clip_? and delta_? should have same sign, since starting point is in rect // so ratios will be positive - F32 ratio_x = ((F32)clip_x / (F32)delta_x); - F32 ratio_y = ((F32)clip_y / (F32)delta_y); + F32 ratio_x = delta_x ? ((F32)clip_x / (F32)delta_x) : 0.f; + F32 ratio_y = delta_y ? ((F32)clip_y / (F32)delta_y) : 0.f; if (ratio_x > ratio_y) { // clip along x direction From 2400d146ce1037306173e9ac27c4eca07fdcc647 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 19 Nov 2012 04:01:54 +0100 Subject: [PATCH 64/93] Clear the command queue after flushing statemachines Flushing the state machines can cause remove commands to be added to the command queue, so clearing it needs to be after. --- indra/llmessage/aicurl.cpp | 1 + indra/llmessage/aicurlprivate.h | 1 + indra/llmessage/aicurlthread.cpp | 12 ++++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index bfd2a2243..11668f5fc 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -418,6 +418,7 @@ void cleanupCurl(void) if (CurlMultiHandle::getTotalMultiHandles() != 0) llwarns << "Not all CurlMultiHandle objects were destroyed!" << llendl; AIStateMachine::flush(); + clearCommandQueue(); Stats::print(); ssl_cleanup(); diff --git a/indra/llmessage/aicurlprivate.h b/indra/llmessage/aicurlprivate.h index abb663d4a..ee28ae849 100644 --- a/indra/llmessage/aicurlprivate.h +++ b/indra/llmessage/aicurlprivate.h @@ -119,6 +119,7 @@ inline CURLMcode check_multi_code(CURLMcode code) { AICurlInterface::Stats::mult bool curlThreadIsRunning(void); void wakeUpCurlThread(void); void stopCurlThread(void); +void clearCommandQueue(void); #define DECLARE_SETOPT(param_type) \ CURLcode setopt(CURLoption option, param_type parameter) diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index 1fbe57d3e..ae686c087 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -1065,6 +1065,10 @@ void AICurlThread::wakeup_thread(void) DoutEntering(dc::curl, "AICurlThread::wakeup_thread"); llassert(is_main_thread()); + // If we are already exiting the viewer then return immediately. + if (!mRunning) + return; + // Try if curl thread is still awake and if so, pass the new commands directly. if (mWakeUpMutex.tryLock()) { @@ -2148,10 +2152,14 @@ void stopCurlThread(void) ms_sleep(10); } Dout(dc::curl, "Curl thread" << (curlThreadIsRunning() ? " not" : "") << " stopped after " << ((100 - count) * 10) << "ms."); - // Clear the command queue, for a cleaner cleanup. + } +} + +void clearCommandQueue(void) +{ + // Clear the command queue now in order to avoid the global deinitialization order fiasco. command_queue_wat command_queue_w(command_queue); command_queue_w->clear(); - } } //----------------------------------------------------------------------------- From aab195a6eb3f833114a679936228122ad6d6d0bf Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 19 Nov 2012 04:42:02 +0100 Subject: [PATCH 65/93] Fix deinitialization order fiasco. --- indra/llmessage/aicurlperhost.cpp | 11 ++++++++--- indra/llmessage/aicurlperhost.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/indra/llmessage/aicurlperhost.cpp b/indra/llmessage/aicurlperhost.cpp index 724d5bccd..7f7490865 100644 --- a/indra/llmessage/aicurlperhost.cpp +++ b/indra/llmessage/aicurlperhost.cpp @@ -56,12 +56,17 @@ PerHostRequestQueuePtr PerHostRequestQueue::instance(std::string const& hostname //static void PerHostRequestQueue::release(PerHostRequestQueuePtr& instance) { - if (instance->lastone()) + if (instance->exactly_two_left()) // Being 'instance' and the one in sInstanceMap. { + // The viewer can be have left main() we can't access the global sInstanceMap anymore. + if (LLApp::isStopped()) + { + return; + } instance_map_wat instance_map_w(sInstanceMap); - // It is possible that 'lastone' is not up to date anymore. + // It is possible that 'exactly_two_left' is not up to date anymore. // Therefore, recheck the condition now that we have locked sInstanceMap. - if (!instance->lastone()) + if (!instance->exactly_two_left()) { // Some other thread added this host in the meantime. return; diff --git a/indra/llmessage/aicurlperhost.h b/indra/llmessage/aicurlperhost.h index dac9d70c0..c464d490c 100644 --- a/indra/llmessage/aicurlperhost.h +++ b/indra/llmessage/aicurlperhost.h @@ -118,7 +118,7 @@ class PerHostRequestQueue { class RefCountedThreadSafePerHostRequestQueue : public threadsafe_PerHostRequestQueue { public: RefCountedThreadSafePerHostRequestQueue(void) : mReferenceCount(0) { } - bool lastone(void) const { llassert(mReferenceCount >= 2); return mReferenceCount == 2; } + bool exactly_two_left(void) const { return mReferenceCount == 2; } private: // Used by PerHostRequestQueuePtr. Object is deleted when reference count reaches zero. From 0f54e5fe46994d6c1915fa36b2b0a1b1ffd10202 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Thu, 22 Nov 2012 03:55:10 +0100 Subject: [PATCH 66/93] Remove erroneous assertion. --- indra/llmessage/aicurl.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index 11668f5fc..a0104c2a8 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -492,8 +492,6 @@ void Stats::print(void) // Even more strict, BufferedCurlEasyRequest may not be created directly either, only as // base class of ThreadSafeBufferedCurlEasyRequest. llassert(BufferedCurlEasyRequest_count == ThreadSafeBufferedCurlEasyRequest_count); - // Each AICurlEasyRequestStateMachine is responsible for exactly one easy handle. - llassert(easy_handles >= AICurlEasyRequest_count); // Each AICurlEasyRequestStateMachine has one AICurlEasyRequest member. llassert(AICurlEasyRequest_count >= AICurlEasyRequestStateMachine_count); // AIFIXME: is this really always the case? And why? From 165bebda3ec275740ba2299c17a3754f33791114 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Fri, 23 Nov 2012 03:19:39 +0100 Subject: [PATCH 67/93] Compile error and warning fixes for DEBUG_CURLIO without CWDEBUG. --- indra/llmessage/aicurlthread.cpp | 6 ++++-- indra/llmessage/debug_libcurl.cpp | 4 ++-- indra/llqtwebkit/llstyle.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index ae686c087..f39f38678 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -1613,7 +1613,9 @@ CURLMcode MultiHandle::remove_easy_request(addedEasyRequests_type::iterator cons ThreadSafeBufferedCurlEasyRequest* lockobj = iter->get_ptr().get(); #endif mAddedEasyRequests.erase(iter); +#if CWDEBUG Dout(dc::curl, "MultiHandle::remove_easy_request: Removed AICurlEasyRequest " << (void*)lockobj << "; now processing " << mAddedEasyRequests.size() << " easy handles."); +#endif // Attempt to add a queued request, if any. PerHostRequestQueue_wat(*per_host)->add_queued_to(this); @@ -2361,10 +2363,10 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size #if defined(CWDEBUG) || defined(DEBUG_CURLIO) int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr) { + BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr; + #ifdef CWDEBUG using namespace ::libcwd; - - BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr; std::ostringstream marker; marker << (void*)request->get_lockobj(); libcw_do.push_marker(); diff --git a/indra/llmessage/debug_libcurl.cpp b/indra/llmessage/debug_libcurl.cpp index 512bc696c..825cffcc9 100644 --- a/indra/llmessage/debug_libcurl.cpp +++ b/indra/llmessage/debug_libcurl.cpp @@ -624,7 +624,7 @@ void debug_curl_easy_reset(CURL* handle) CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) { - CURLcode ret; + CURLcode ret = CURLE_UNKNOWN_OPTION; // Suppress compiler warning. va_list ap; union param_type { long along; @@ -841,7 +841,7 @@ CURLMcode debug_curl_multi_remove_handle(CURLM* multi_handle, CURL* easy_handle) CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...) { - CURLMcode ret; + CURLMcode ret = CURLM_UNKNOWN_OPTION; // Suppress compiler warning. va_list ap; union param_type { long along; diff --git a/indra/llqtwebkit/llstyle.cpp b/indra/llqtwebkit/llstyle.cpp index ecd2b3eb8..8822d481a 100644 --- a/indra/llqtwebkit/llstyle.cpp +++ b/indra/llqtwebkit/llstyle.cpp @@ -71,7 +71,7 @@ void LLStyle::drawControl(ControlElement element, const QStyleOption *option, QP QPlastiqueStyle::drawControl(element, &localOption, painter, widget); return; } - + default: break; } From adebc36bc7203052d766ea6bf775808169f84b62 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 24 Nov 2012 01:00:25 -0600 Subject: [PATCH 68/93] Cheap workaround for osgrid giving us an invalid pure-white single-channel opaque water texture. First it purges the texture from the cache and attempts to refetch, and if it's still invalid it falls back to the transparent water texture (which won't actually be transparent due to blending being disabled). Also fixed some annoying console spam related to null textures, and also now using the correct glTexGen* function. More details in comments. --- indra/newview/lldrawpoolwater.cpp | 43 +++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 371f979a0..701da9b2a 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -53,6 +53,8 @@ #include "pipeline.h" #include "llviewershadermgr.h" #include "llwaterparammanager.h" +#include "llappviewer.h" +#include "lltexturecache.h" const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); @@ -260,8 +262,11 @@ void LLDrawPoolWater::render(S32 pass) { continue; } - gGL.getTexUnit(0)->bind(face->getTexture()); - face->renderIndexed(); + if(face->getTexture() && face->getTexture()->hasGLTexture()) + { + gGL.getTexUnit(0)->bind(face->getTexture()); + face->renderIndexed(); + } } // Now, disable texture coord generation on texture state 1 @@ -367,6 +372,34 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() gPipeline.disableLights(); + //Singu note: This is a hack around bizarre opensim behavior. The opaque water texture we get is pure white and only has one channel. + // This behavior is clearly incorrect, so we try to detect that case, purge it from the cache, and try to re-fetch the texture. + // If the re-fetched texture is still invalid, or doesn't exist, we use transparent water, which is fine since alphablend is unset. + // The current logic for refetching is crude here, and probably wont work if, say, a prim were to also have the texture for some reason, + // however it works well enough otherwise, and is much cleaner than diving into LLTextureList, LLViewerFetchedTexture, and LLViewerTexture. + // Perhaps a proper reload mechanism could be done if we ever add user-level texture reloading, but until then it's not a huge priority. + // Failing to fully refetch will just give us the same invalid texture we started with, which will result in the fallback texture being used. + if(mOpaqueWaterImagep != mWaterImagep) + { + if(mOpaqueWaterImagep->isMissingAsset()) + { + mOpaqueWaterImagep = mWaterImagep; + } + else if(mOpaqueWaterImagep->hasGLTexture() && mOpaqueWaterImagep->getComponents() < 3) + { + LLAppViewer::getTextureCache()->removeFromCache(mOpaqueWaterImagep->getID()); + static bool sRefetch = true; + if(sRefetch) + { + sRefetch = false; + gTextureList.deleteImage(gTextureList.findImage( mOpaqueWaterImagep->getID() )); + mOpaqueWaterImagep = NULL; + mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); + } + else + mOpaqueWaterImagep = mWaterImagep; + } + } mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); // Activate the texture binding and bind one @@ -380,8 +413,8 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() { glEnable(GL_TEXTURE_GEN_S); //texture unit 0 glEnable(GL_TEXTURE_GEN_T); //texture unit 0 - glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); } // Use the fact that we know all water faces are the same size @@ -674,7 +707,7 @@ void LLDrawPoolWater::shade() } LLVOWater* water = (LLVOWater*) face->getViewerObject(); - if(diffTex > -1 && face->getTexture()->hasGLTexture()) + if(diffTex > -1 && face->getTexture() && face->getTexture()->hasGLTexture()) gGL.getTexUnit(diffTex)->bind(face->getTexture()); sNeedsReflectionUpdate = TRUE; From 5e6ed2dc9f29e88602bd1d68c8a1fc6d9f1ca567 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 24 Nov 2012 11:21:29 -0600 Subject: [PATCH 69/93] Large update to the worldmap. Essentially, v3 merge, and reimplemented legacy tile drawing and opensim-specific changes. Also added a diagnostic view. --- indra/newview/CMakeLists.txt | 2 + indra/newview/llagent.cpp | 9 +- indra/newview/llappviewer.cpp | 2 +- indra/newview/llfloaterworldmap.cpp | 673 ++++---- indra/newview/llfloaterworldmap.h | 55 +- indra/newview/llmapresponders.cpp | 155 +- indra/newview/llstartup.cpp | 5 +- indra/newview/lltracker.h | 2 +- indra/newview/llurldispatcher.cpp | 7 +- indra/newview/llviewermenu.cpp | 1 - indra/newview/llworldmap.cpp | 1215 +++++--------- indra/newview/llworldmap.h | 300 ++-- indra/newview/llworldmapmessage.cpp | 301 ++++ indra/newview/llworldmapmessage.h | 79 + indra/newview/llworldmapview.cpp | 1446 ++++++++--------- indra/newview/llworldmapview.h | 20 +- indra/newview/llworldmipmap.cpp | 8 +- .../default/xui/en-us/floater_world_map.xml | 2 +- .../skins/default/xui/en-us/strings.xml | 1 + 19 files changed, 2039 insertions(+), 2244 deletions(-) create mode 100644 indra/newview/llworldmapmessage.cpp create mode 100644 indra/newview/llworldmapmessage.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e46a05a59..dcdf7c673 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -542,6 +542,7 @@ set(viewer_SOURCE_FILES llwlparamset.cpp llworld.cpp llworldmap.cpp + llworldmapmessage.cpp llworldmipmap.cpp llworldmapview.cpp llxmlrpctransaction.cpp @@ -1050,6 +1051,7 @@ set(viewer_HEADER_FILES llwlparamset.h llworld.h llworldmap.h + llworldmapmessage.h llworldmipmap.h llworldmapview.h llxmlrpctransaction.h diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 2b6e85eeb..5180856ed 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -77,6 +77,7 @@ #include "llvoavatarself.h" #include "llworld.h" #include "llworldmap.h" +#include "llworldmapmessage.h" //Misc non-standard includes #include "llurldispatcher.h" @@ -3688,7 +3689,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) (F32)(pos_global.mdV[VY] - region_origin.mdV[VY]), (F32)(pos_global.mdV[VZ])); pos_local += offset; - teleportRequest(info->getHandle(), pos_local); + teleportRequest(handle, pos_local); } else if(regionp && teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY]))) @@ -3737,10 +3738,6 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) mbTeleportKeepsLookAt = true; gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction U64 region_handle = to_region_handle(pos_global); - LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(region_handle); - if(simInfo) - region_handle = simInfo->getHandle(); - LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle)); teleportRequest(region_handle, pos_local, getTeleportKeepsLookAt()); } @@ -4180,7 +4177,7 @@ void LLAgent::showLureDestination(const std::string fromname, const int global_x { U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); - LLWorldMap::getInstance()->sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); //Will call onFoundLureDestination on response + LLWorldMapMessage::getInstance()->sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); //Will call onFoundLureDestination on response } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f23d46e9b..7bf666e42 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -504,7 +504,7 @@ static void settings_to_globals() gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK"); gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); - LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); + LLWorldMapView::sMapScale = llmax(.1f,gSavedSettings.getF32("MapScale")); LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); } diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index d541a93e5..c24c146f3 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -70,6 +70,7 @@ #include "llviewerregion.h" #include "llviewerstats.h" #include "llworldmap.h" +#include "llworldmapmessage.h" #include "llworldmapview.h" #include "lluictrlfactory.h" #include "llappviewer.h" @@ -88,6 +89,21 @@ //--------------------------------------------------------------------------- static const F32 MAP_ZOOM_TIME = 0.2f; +// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed +// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across +// sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit. +// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window. +static const S32 MAX_VISIBLE_REGIONS = 512; + +// It would be more logical to have this inside the method where it is used but to compile under gcc this +// struct has to be here. +struct SortRegionNames +{ + inline bool operator ()(std::pair const& _left, std::pair const& _right) + { + return(LLStringUtil::compareInsensitive(_left.second->getName(), _right.second->getName()) < 0); + } +}; enum EPanDirection { PAN_UP, @@ -97,17 +113,10 @@ enum EPanDirection }; // Values in pixels per region -static const F32 ZOOM_MIN = -8.f; // initial value, updated by adjustZoomSlider -static const F32 ZOOM_MAX = 0.f; -static const F32 ZOOM_INC = 0.2f; +static const F32 ZOOM_MAX = 128.f; -static const F32 SIM_COORD_MIN = 0.f; -static const F32 SIM_COORD_MAX = 255.f; static const F32 SIM_COORD_DEFAULT = 128.f; -static const F64 MAX_FLY_DISTANCE = 363.f; // Diagonal size of one sim. -static const F64 MAX_FLY_DISTANCE_SQUARED = MAX_FLY_DISTANCE * MAX_FLY_DISTANCE; - //--------------------------------------------------------------------------- // Globals //--------------------------------------------------------------------------- @@ -166,13 +175,16 @@ LLFloaterWorldMap::LLFloaterWorldMap() mInventory(NULL), mInventoryObserver(NULL), mFriendObserver(NULL), - mCompletingRegionName(""), + mCompletingRegionName(), + mCompletingRegionPos(), mWaitingForTracker(FALSE), - mExactMatch(FALSE), mIsClosing(FALSE), mSetToUserPosition(TRUE), mTrackedLocation(0,0,0), - mTrackedStatus(LLTracker::TRACKING_NOTHING) + mTrackedStatus(LLTracker::TRACKING_NOTHING), + mListFriendCombo(NULL), + mListLandmarkCombo(NULL), + mListSearchResults(NULL) { LLCallbackMap::map_t factory_map; factory_map["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL); @@ -197,54 +209,58 @@ BOOL LLFloaterWorldMap::postBuild() mPanel = getChild("objects_mapview"); - childSetCommitCallback("friend combo", onAvatarComboCommit, this); - LLComboBox *avatar_combo = getChild("friend combo"); - if (avatar_combo) - { - avatar_combo->selectFirstItem(); - avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange ); - avatar_combo->setTextEntryCallback( onComboTextEntry ); - } - - childSetAction("DoSearch", onLocationCommit, this); - + avatar_combo->selectFirstItem(); + avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange ); + avatar_combo->setTextEntryCallback( onComboTextEntry ); + mListFriendCombo = dynamic_cast(avatar_combo); + LLLineEditor *location_editor = getChild("location"); location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1)); location_editor->setKeystrokeCallback( onSearchTextEntry ); - childSetCommitCallback("search_results", onCommitSearchResult, this); - childSetDoubleClickCallback("search_results", onClickTeleportBtn); - childSetCommitCallback("spin x", onCommitLocation, this); - childSetCommitCallback("spin y", onCommitLocation, this); - childSetCommitCallback("spin z", onCommitLocation, this); + LLScrollListCtrl* search_results = getChild("search_results"); + search_results->setDoubleClickCallback(&LLFloaterWorldMap::onClickTeleportBtn_static); + search_results->setCallbackUserData(this); + mListSearchResults = dynamic_cast(search_results); + + - childSetCommitCallback("landmark combo", onLandmarkComboCommit, this); LLComboBox *landmark_combo = getChild( "landmark combo"); - if (landmark_combo) - { - landmark_combo->selectFirstItem(); - landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange ); - landmark_combo->setTextEntryCallback( onComboTextEntry ); - } - childSetAction("Go Home", onGoHome, this); + landmark_combo->selectFirstItem(); + landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange ); + landmark_combo->setTextEntryCallback( onComboTextEntry ); + mListLandmarkCombo = dynamic_cast(landmark_combo); + + avatar_combo->setCommitCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboCommit,this) ); + + search_results->setCommitCallback( boost::bind(&LLFloaterWorldMap::onCommitSearchResult,this) ); + + landmark_combo->setCommitCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit,this) ); + + getChild("spin x")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) ); + getChild("spin y")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) ); + getChild("spin z")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCoordinatesCommit,this) ); + + getChild("DoSearch")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onLocationCommit,this) ); + getChild("Go Home")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onGoHome,this) ); + getChild("Teleport")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn,this) ); + getChild("Show Destination")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onShowTargetBtn,this) ); + getChild("Show My Location")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onShowAgentBtn,this) ); + getChild("Clear")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onClearBtn,this) ); + getChild("copy_slurl")->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCopySLURL,this) ); - childSetAction("Teleport", onClickTeleportBtn, this); - - childSetAction("Show Destination", onShowTargetBtn, this); - childSetAction("Show My Location", onShowAgentBtn, this); - childSetAction("Clear", onClearBtn, this); - childSetAction("copy_slurl", onCopySLURL, this); - - mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f); - childSetValue("zoom slider", LLWorldMapView::sMapScale); + mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); + childSetValue("zoom slider", mCurZoomVal); setDefaultBtn(NULL); mZoomTimer.stop(); - + + onChangeMaturity(); + return TRUE; } @@ -253,13 +269,15 @@ LLFloaterWorldMap::~LLFloaterWorldMap() { // All cleaned up by LLView destructor mPanel = NULL; - + // Inventory deletes all observers on shutdown mInventory = NULL; mInventoryObserver = NULL; - + // avatar tracker will delete this for us. mFriendObserver = NULL; + + gFloaterWorldMap = NULL; } @@ -297,14 +315,8 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target) } map_panel->updateVisibleBlocks(); - // Reload the agent positions when we show the window - LLWorldMap::getInstance()->eraseItems(); - - // Reload any maps that may have changed - LLWorldMap::getInstance()->clearSimFlags(); - - const bool request_from_sim = true; - LLWorldMap::getInstance()->setCurrentLayer(0, request_from_sim); + // Reload items as they may have changed + LLWorldMap::getInstance()->reloadItems(); // We may already have a bounding box for the regions of the world, // so use that to adjust the view. @@ -338,9 +350,7 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target) // static void LLFloaterWorldMap::reloadIcons(void*) { - LLWorldMap::getInstance()->eraseItems(); - - LLWorldMap::getInstance()->sendMapLayerRequest(); + LLWorldMap::getInstance()->reloadItems(); } @@ -396,9 +406,7 @@ BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { if (!isMinimized() && isFrontmost()) { - LLRect area; - childGetRect("search_results", area); - if(!area.pointInRect(x, y)) + if(mPanel->pointInView(x, y)) { F32 slider_value = (F32)childGetValue("zoom slider").asReal(); slider_value += ((F32)clicks * -0.3333f); @@ -427,20 +435,6 @@ void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent // virtual void LLFloaterWorldMap::draw() { - // Hide/Show Mature Events controls - childSetVisible("events_mature_icon", gAgent.canAccessMature()); - childSetVisible("events_mature_label", gAgent.canAccessMature()); - childSetVisible("event_mature_chk", gAgent.canAccessMature()); - - childSetVisible("events_adult_icon", gAgent.canAccessMature()); - childSetVisible("events_adult_label", gAgent.canAccessMature()); - childSetVisible("event_adult_chk", gAgent.canAccessMature()); - bool adult_enabled = gAgent.canAccessAdult(); - if (!adult_enabled) - { - childSetValue("event_adult_chk", FALSE); - } - childSetEnabled("event_adult_chk", adult_enabled); // On orientation island, users don't have a home location yet, so don't // let them teleport "home". It dumps them in an often-crowed welcome @@ -481,7 +475,7 @@ void LLFloaterWorldMap::draw() { F64 seconds = LLTimer::getElapsedSeconds(); double value = fmod(seconds, 2); - value = 0.5 + 0.5*cos(value * 3.14159f); + value = 0.5 + 0.5*cos(value * F_PI); LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0); childSetColor("location_icon", loading_color); } @@ -499,36 +493,30 @@ void LLFloaterWorldMap::draw() childSetEnabled("Teleport", (BOOL)tracking_status); // childSetEnabled("Clear", (BOOL)tracking_status); - childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->mIsTrackingUnknownLocation); + childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->isTracking()); childSetEnabled("copy_slurl", (mSLURL.size() > 0) ); setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); - + //RN: snaps to zoom value because interpolation caused jitter in the text rendering - F32 interp = 1.f; - if (!mZoomTimer.getStarted()) + if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild("zoom slider")->getValue().asReal()) { - mCurZoomValInterpolationStart = mCurZoomVal; - if (mCurZoomVal < (F32)childGetValue("zoom slider").asReal()) - { - mZoomTimer.start(); - } + mZoomTimer.start(); } - if (mZoomTimer.getStarted()) - { - interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME; - } - if (interp >= 1.f) + F32 interp = mZoomTimer.getStarted() ? mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME : 1.f; + if (interp > 1.f) { interp = 1.f; mZoomTimer.stop(); } - // Interpolate between mCurZoomValInterpolationStart and "zoom slider". - mCurZoomVal = lerp(mCurZoomValInterpolationStart, (F32)childGetValue("zoom slider").asReal(), interp); + mCurZoomVal = lerp(mCurZoomVal, (F32)getChild("zoom slider")->getValue().asReal(), interp); F32 map_scale = 256.f*pow(2.f, mCurZoomVal); LLWorldMapView::setScale( map_scale ); + onChangeMaturity(); + + LLFloater::draw(); } @@ -632,32 +620,37 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); if (!sim_info) { - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE; - LLWorldMap::getInstance()->mInvalidLocation = FALSE; - LLWorldMap::getInstance()->mUnknownLocation = pos_global; + // We haven't found a region for that point yet, leave the tracking to the world map + LLWorldMap::getInstance()->setTracking(pos_global); LLTracker::stopTracking(NULL); S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); - LLWorldMap::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); + LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); setDefaultBtn(""); + + // clicked on a non-region - turn off coord display + enableTeleportCoordsDisplay( false ); + return; } if (sim_info->isDown()) { - // Down sim. Show the blue circle of death! - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE; - LLWorldMap::getInstance()->mUnknownLocation = pos_global; - LLWorldMap::getInstance()->mInvalidLocation = TRUE; + // Down region. Show the blue circle of death! + // i.e. let the world map that this and tell it it's invalid + LLWorldMap::getInstance()->setTracking(pos_global); + LLWorldMap::getInstance()->setTrackingInvalid(); LLTracker::stopTracking(NULL); setDefaultBtn(""); + + // clicked on a down region - turn off coord display + enableTeleportCoordsDisplay( false ); + return; } - + std::string sim_name = sim_info->getName(); - U32 locX, locY; - from_region_handle(sim_info->getHandle(), &locX, &locY); - F32 region_x = pos_global.mdV[VX] - locX; - F32 region_y = pos_global.mdV[VY] - locY; + F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); + F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); std::string full_name = llformat("%s (%d, %d, %d)", // sim_name.c_str(), // [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) @@ -670,13 +663,43 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) std::string tooltip(""); mTrackedStatus = LLTracker::TRACKING_LOCATION; LLTracker::trackLocation(pos_global, full_name, tooltip); - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - LLWorldMap::getInstance()->mIsTrackingDoubleClick = FALSE; - LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; - + LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking + + LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); + updateTeleportCoordsDisplay( coord_pos ); + + // we have a valid region - turn on coord display + enableTeleportCoordsDisplay( true ); + setDefaultBtn("Teleport"); } + +// enable/disable teleport destination coordinates +void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled ) +{ + childSetEnabled("spin x", enabled ); + childSetEnabled("spin y", enabled ); + childSetEnabled("spin z", enabled ); +} + +// update display of teleport destination coordinates - pos is in global coordinates +void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos ) +{ + // if we're going to update their value, we should also enable them + enableTeleportCoordsDisplay( true ); + + // convert global specified position to a local one + F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS ); + F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS ); + F32 region_local_z = (F32)llclamp( pos.mdV[VZ], 0.0, (F64)REGION_HEIGHT_METERS ); + + // write in the values + childSetValue("spin x", region_local_x ); + childSetValue("spin y", region_local_y ); + childSetValue("spin z", region_local_z ); + } + void LLFloaterWorldMap::updateLocation() { bool gotSimName; @@ -703,19 +726,16 @@ void LLFloaterWorldMap::updateLocation() // Fill out the location field childSetValue("location", agent_sim_name); + // update the coordinate display with location of avatar in region + updateTeleportCoordsDisplay( agentPos ); + + S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) ); + S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) ); + S32 z = llround( (F32)agentPos[VZ] ); + // Figure out where user is - LLVector3d agentPos = gAgent.getPositionGlobal(); - - S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) ); - S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) ); - S32 agent_z = llround( (F32)agentPos.mdV[VZ] ); - - childSetValue("spin x", LLSD(agent_x) ); - childSetValue("spin y", LLSD(agent_y) ); - childSetValue("spin z", LLSD(agent_z) ); - // Set the current SLURL - mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z); + mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, x, y, z); // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) @@ -751,16 +771,18 @@ void LLFloaterWorldMap::updateLocation() childSetValue("location", sim_name); - F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); - F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); - childSetValue("spin x", LLSD(region_x) ); - childSetValue("spin y", LLSD(region_y) ); - childSetValue("spin z", LLSD((F32)pos_global.mdV[VZ]) ); - + // refresh coordinate display to reflect where user clicked. + LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); + updateTeleportCoordsDisplay( coord_pos ); + // simNameFromPosGlobal can fail, so don't give the user an invalid SLURL if ( gotSimName ) { - mSLURL = LLURLDispatcher::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ])); + LLVector3d agentPos = gAgent.getPositionGlobal(); + S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) ); + S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) ); + S32 z = llround( (F32)agentPos[VZ] ); + mSLURL = LLURLDispatcher::buildSLURL(sim_name, x, y, z); } else { // Empty SLURL will disable the "Copy SLURL to clipboard" button @@ -795,15 +817,17 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3 { // fill in UI based on URL gFloaterWorldMap->childSetValue("location", region_name); - childSetValue("spin x", LLSD((F32)x_coord)); - childSetValue("spin y", LLSD((F32)y_coord)); - childSetValue("spin z", LLSD((F32)z_coord)); + + // Save local coords to highlight position after region global + // position is returned. + gFloaterWorldMap->mCompletingRegionPos.set( + (F32)x_coord, (F32)y_coord, (F32)z_coord); // pass sim name to combo box gFloaterWorldMap->mCompletingRegionName = region_name; - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name); LLStringUtil::toLower(gFloaterWorldMap->mCompletingRegionName); - LLWorldMap::getInstance()->mIsTrackingCommit = TRUE; + LLWorldMap::getInstance()->setTrackingCommit(); } } @@ -868,9 +892,9 @@ void LLFloaterWorldMap::friendsChanged() // No longer really builds a list. Instead, just updates mAvatarCombo. void LLFloaterWorldMap::buildAvatarIDList() { - LLCtrlListInterface *list = childGetListInterface("friend combo"); + LLCtrlListInterface *list = mListFriendCombo; if (!list) return; - + // Delete all but the "None" entry S32 list_size = list->getItemCount(); if (list_size > 1) @@ -904,12 +928,9 @@ void LLFloaterWorldMap::buildAvatarIDList() void LLFloaterWorldMap::buildLandmarkIDLists() { - LLCtrlListInterface *list = childGetListInterface("landmark combo"); - if (!list) - { - return; - } - + LLCtrlListInterface *list = mListLandmarkCombo; + if (!list) return; + // Delete all but the "None" entry S32 list_size = list->getItemCount(); if (list_size > 1) @@ -969,7 +990,7 @@ F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination, void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui) { - LLCtrlListInterface *list = childGetListInterface("search_results"); + LLCtrlListInterface *list = mListSearchResults; if (list) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); @@ -986,9 +1007,9 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui) { childSetValue("spin z", 0); } - LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; + //Singu Note: Don't do this. It basically 'eats' the first click onto void space if the previous tracked target was a valid sim. + //LLWorldMap::getInstance()->cancelTracking(); mCompletingRegionName = ""; - mExactMatch = FALSE; } @@ -996,7 +1017,7 @@ void LLFloaterWorldMap::clearLandmarkSelection(BOOL clear_ui) { if (clear_ui || !childHasKeyboardFocus("landmark combo")) { - LLCtrlListInterface *list = childGetListInterface("landmark combo"); + LLCtrlListInterface *list = mListLandmarkCombo; if (list) { list->selectByValue( "None" ); @@ -1010,7 +1031,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui) if (clear_ui || !childHasKeyboardFocus("friend combo")) { mTrackedStatus = LLTracker::TRACKING_NOTHING; - LLCtrlListInterface *list = childGetListInterface("friend combo"); + LLCtrlListInterface *list = mListFriendCombo; if (list) { list->selectByValue( "None" ); @@ -1023,22 +1044,22 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui) // can see the whole world, plus a little. void LLFloaterWorldMap::adjustZoomSliderBounds() { - // World size in regions - S32 world_width_regions = LLWorldMap::getInstance()->getWorldWidth() / REGION_WIDTH_UNITS; - S32 world_height_regions = LLWorldMap::getInstance()->getWorldHeight() / REGION_WIDTH_UNITS; - - // Pad the world size a little bit, so we have a nice border on - // the edge - world_width_regions++; - world_height_regions++; - + // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed + // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across + // sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit. + // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window. + S32 world_width_regions = MAX_VISIBLE_REGIONS; + S32 world_height_regions = MAX_VISIBLE_REGIONS; + // Find how much space we have to display the world - LLRect view_rect = mPanel->getRect(); - + LLWorldMapView* map_panel; + map_panel = (LLWorldMapView*)mPanel; + LLRect view_rect = map_panel->getRect(); + // View size in pixels S32 view_width = view_rect.getWidth(); S32 view_height = view_rect.getHeight(); - + // Pixels per region to display entire width/height F32 width_pixels_per_region = (F32) view_width / (F32) world_width_regions; F32 height_pixels_per_region = (F32) view_height / (F32) world_height_regions; @@ -1052,9 +1073,10 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() // Make sure the zoom slider can be moved at least a little bit. // Likewise, less than the increment pixels per region is just silly. - pixels_per_region = llclamp(pixels_per_region, 1.f, (F32)(pow(2.f, ZOOM_MAX) * 128.f)); - + pixels_per_region = llclamp(pixels_per_region, 1.f, ZOOM_MAX); + F32 min_power = log(pixels_per_region/256.f)/log(2.f); + childSetMinValue("zoom slider", min_power); } @@ -1063,34 +1085,10 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() // User interface widget callbacks //------------------------------------------------------------------------- -// static -void LLFloaterWorldMap::onPanBtn( void* userdata ) -{ - if( !gFloaterWorldMap ) return; - - EPanDirection direction = (EPanDirection)(intptr_t)userdata; - - S32 pan_x = 0; - S32 pan_y = 0; - switch( direction ) - { - case PAN_UP: pan_y = -1; break; - case PAN_DOWN: pan_y = 1; break; - case PAN_LEFT: pan_x = 1; break; - case PAN_RIGHT: pan_x = -1; break; - default: llassert(0); return; - } - - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->translatePan( pan_x, pan_y ); -} - -// static -void LLFloaterWorldMap::onGoHome(void*) +void LLFloaterWorldMap::onGoHome() { gAgent.teleportHome(); - gFloaterWorldMap->close(); + close(); } @@ -1122,7 +1120,7 @@ void LLFloaterWorldMap::onComboTextEntry( LLLineEditor* ctrl, void* userdata ) // Reset the tracking whenever we start typing into any of the search fields, // so that hitting does an auto-complete versus teleporting us to the // previously selected landmark/friend. - LLTracker::clearFocus(); + LLTracker::stopTracking(NULL); } // static @@ -1133,16 +1131,14 @@ void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl, void* userdata ) } // static -void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) +void LLFloaterWorldMap::onLandmarkComboCommit() { - LLFloaterWorldMap* self = gFloaterWorldMap; - - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } - - LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("landmark combo"); + + LLCtrlListInterface *list = mListLandmarkCombo; if (!list) return; LLUUID asset_id; @@ -1174,11 +1170,11 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) } } - self->trackLandmark( item_id); - onShowTargetBtn(self); - + trackLandmark( item_id); + onShowTargetBtn(); + // Reset to user postion if nothing is tracked - self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); } // static @@ -1208,31 +1204,28 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata } } - -// static -void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata ) +void LLFloaterWorldMap::onAvatarComboCommit() { - LLFloaterWorldMap* self = gFloaterWorldMap; - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } - - LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("friend combo"); + + LLCtrlListInterface *list = mListFriendCombo; if (!list) return; - + const LLUUID& new_avatar_id = list->getCurrentID(); if (new_avatar_id.notNull()) { std::string name; - LLComboBox* combo = gFloaterWorldMap->getChild("friend combo"); + LLComboBox* combo = getChild("friend combo"); if (combo) name = combo->getSimple(); - self->trackAvatar(new_avatar_id, name); - onShowTargetBtn(self); + trackAvatar(new_avatar_id, name); + onShowTargetBtn(); } else { // Reset to user postion if nothing is tracked - self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); } } @@ -1254,105 +1247,99 @@ void LLFloaterWorldMap::updateSearchEnabled() } } -// static -void LLFloaterWorldMap::onLocationCommit( void* userdata ) +void LLFloaterWorldMap::onLocationCommit() { - LLFloaterWorldMap *self = gFloaterWorldMap; - if( !self || self->mIsClosing ) + if( mIsClosing ) { return; } + + clearLocationSelection(FALSE); + mCompletingRegionName = ""; + mLastRegionName = ""; - self->clearLocationSelection(FALSE); - self->mCompletingRegionName = ""; - self->mLastRegionName = ""; - - std::string str = self->childGetValue("location").asString(); + std::string str = childGetValue("location").asString(); // Trim any leading and trailing spaces in the search target std::string saved_str = str; LLStringUtil::trim( str ); if ( str != saved_str ) { // Set the value in the UI if any spaces were removed - self->childSetValue("location", str); + childSetValue("location", str); + } + + // Don't try completing empty name (STORM-1427). + if (str.empty()) + { + return; } LLStringUtil::toLower(str); - gFloaterWorldMap->mCompletingRegionName = str; - LLWorldMap::getInstance()->mIsTrackingCommit = TRUE; - self->mExactMatch = FALSE; + mCompletingRegionName = str; + LLWorldMap::getInstance()->setTrackingCommit(); if (str.length() >= 3) { - LLWorldMap::getInstance()->sendNamedRegionRequest(str); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str); } else { str += "#"; - LLWorldMap::getInstance()->sendNamedRegionRequest(str); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str); } } - -// static -void LLFloaterWorldMap::onClearBtn(void* data) +void LLFloaterWorldMap::onCoordinatesCommit() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mTrackedStatus = LLTracker::TRACKING_NOTHING; + if( mIsClosing ) + { + return; + } + + S32 x_coord = (S32)childGetValue("spin x").asReal(); + S32 y_coord = (S32)childGetValue("spin y").asReal(); + S32 z_coord = (S32)childGetValue("spin z").asReal(); + + const std::string region_name = childGetValue("location").asString(); + + trackURL( region_name, x_coord, y_coord, z_coord ); +} + +void LLFloaterWorldMap::onClearBtn() +{ + mTrackedStatus = LLTracker::TRACKING_NOTHING; LLTracker::stopTracking((void *)(intptr_t)TRUE); - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - self->mSLURL = ""; // Clear the SLURL since it's invalid - self->mSetToUserPosition = TRUE; // Revert back to the current user position + LLWorldMap::getInstance()->cancelTracking(); + mSLURL = ""; // Clear the SLURL since it's invalid + mSetToUserPosition = TRUE; // Revert back to the current user position } -// static -void LLFloaterWorldMap::onFlyBtn(void* data) +void LLFloaterWorldMap::onShowTargetBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->fly(); + centerOnTarget(TRUE); } -void LLFloaterWorldMap::onShowTargetBtn(void* data) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->centerOnTarget(TRUE); -} - -void LLFloaterWorldMap::onShowAgentBtn(void* data) +void LLFloaterWorldMap::onShowAgentBtn() { LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate - // Set flag so user's location will be displayed if not tracking anything else - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->mSetToUserPosition = TRUE; + mSetToUserPosition = TRUE; } -// static -void LLFloaterWorldMap::onClickTeleportBtn(void* data) +void LLFloaterWorldMap::onClickTeleportBtn() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - self->teleport(); + teleport(); } -// static -void LLFloaterWorldMap::onCopySLURL(void* data) +void LLFloaterWorldMap::onCopySLURL() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(self->mSLURL)); + getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL)); LLSD args; - args["SLURL"] = self->mSLURL; + args["SLURL"] = mSLURL; LLNotificationsUtil::add("CopySLURL", args); } -void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*)data; - if(!self) return; - self->childSetEnabled("event_mature_chk", self->childGetValue("event_chk")); - self->childSetEnabled("event_adult_chk", self->childGetValue("event_chk")); -} - // protected void LLFloaterWorldMap::centerOnTarget(BOOL animate) { @@ -1374,9 +1361,12 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global = LLTracker::getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal(); } } - else if(LLWorldMap::getInstance()->mIsTrackingUnknownLocation) + else if(LLWorldMap::getInstance()->isTracking()) { - pos_global = LLWorldMap::getInstance()->mUnknownLocation - gAgentCamera.getCameraPositionGlobal();; + pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();; + + + } else { @@ -1472,24 +1462,6 @@ void LLFloaterWorldMap::teleport() } } -// static -void LLFloaterWorldMap::onGoToLandmarkDialog( S32 option, void* userdata ) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - switch( option ) - { - case 0: - self->teleportToLandmark(); - break; - case 1: - self->flyToLandmark(); - break; - default: - // nothing - break; - } -} - void LLFloaterWorldMap::flyToLandmark() { LLVector3d destination_pos_global; @@ -1570,59 +1542,57 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) LLScrollListCtrl *list = getChild("search_results"); list->operateOnAll(LLCtrlListInterface::OP_DELETE); - - LLSD selected_value = list->getSelectedValue(); - + S32 name_length = mCompletingRegionName.length(); + + LLSD match; - BOOL match_found = FALSE; S32 num_results = 0; - std::map::const_iterator it; - for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) + + std::vector > sim_info_vec(LLWorldMap::getInstance()->getRegionMap().begin(), LLWorldMap::getInstance()->getRegionMap().end()); + std::sort(sim_info_vec.begin(), sim_info_vec.end(), SortRegionNames()); + + for (std::vector >::const_iterator it = sim_info_vec.begin(); it != sim_info_vec.end(); ++it) { - LLSimInfo* info = (*it).second; - std::string sim_name = info->getName(); - std::string sim_name_lower = sim_name; + LLSimInfo* info = it->second; + std::string sim_name_lower = info->getName(); LLStringUtil::toLower(sim_name_lower); if (sim_name_lower.substr(0, name_length) == mCompletingRegionName) { - if (LLWorldMap::getInstance()->mIsTrackingCommit) + if (sim_name_lower == mCompletingRegionName) { - if (sim_name_lower == mCompletingRegionName) - { - selected_value = sim_name; - match_found = TRUE; - } + match = info->getName(); } LLSD value; - value["id"] = sim_name; + value["id"] = info->getName(); value["columns"][0]["column"] = "sim_name"; - value["columns"][0]["value"] = sim_name; + value["columns"][0]["value"] = info->getName(); list->addElement(value); num_results++; } } - list->selectByValue(selected_value); - - if (found_null_sim) + if (found_null_sim || match.isDefined()) { mCompletingRegionName = ""; } - - if (match_found) + + if (num_results > 0) { - mExactMatch = TRUE; + // if match found, highlight it and go + if (!match.isUndefined()) + { + list->selectByValue(match); + } + // else select first found item + else + { + list->selectFirstItem(); + } childSetFocus("search_results"); - onCommitSearchResult(NULL, this); - } - else if (!mExactMatch && num_results > 0) - { - list->selectFirstItem(); // select first item by default - childSetFocus("search_results"); - onCommitSearchResult(NULL, this); + onCommitSearchResult(); } else { @@ -1632,32 +1602,12 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) } } -// static -void LLFloaterWorldMap::onCommitLocation(LLUICtrl* ctrl, void* userdata) -{ - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); - if ( LLTracker::TRACKING_LOCATION == tracking_status) - { - LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); - pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x; - pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y; - pos_global.mdV[VZ] = local_z; - self->trackLocation(pos_global); - } -} -// static -void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) +void LLFloaterWorldMap::onCommitSearchResult() { - LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; - - LLCtrlListInterface *list = self->childGetListInterface("search_results"); + LLCtrlListInterface *list = mListSearchResults; if (!list) return; - + LLSD selected_value = list->getSelectedValue(); std::string sim_name = selected_value.asString(); if (sim_name.empty()) @@ -1674,19 +1624,52 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) if (info->isName(sim_name)) { LLVector3d pos_global = info->getGlobalOrigin(); - F64 local_x = self->childGetValue("spin x"); - F64 local_y = self->childGetValue("spin y"); - F64 local_z = self->childGetValue("spin z"); - pos_global.mdV[VX] += local_x; - pos_global.mdV[VY] += local_y; - pos_global.mdV[VZ] = local_z; + + const F64 SIM_COORD_DEFAULT = 128.0; + LLVector3 pos_local(SIM_COORD_DEFAULT, SIM_COORD_DEFAULT, 0.0f); + + // Did this value come from a trackURL() request? + if (!mCompletingRegionPos.isExactlyZero()) + { + pos_local = mCompletingRegionPos; + mCompletingRegionPos.clear(); + } + pos_global.mdV[VX] += (F64)pos_local.mV[VX]; + pos_global.mdV[VY] += (F64)pos_local.mV[VY]; + pos_global.mdV[VZ] = (F64)pos_local.mV[VZ]; - self->childSetValue("location", sim_name); - self->trackLocation(pos_global); - self->setDefaultBtn("Teleport"); + childSetValue("location", sim_name); + trackLocation(pos_global); + setDefaultBtn("Teleport"); break; } } - onShowTargetBtn(self); + onShowTargetBtn(); +} + +void LLFloaterWorldMap::onChangeMaturity() +{ + bool can_access_mature = gAgent.canAccessMature(); + bool can_access_adult = gAgent.canAccessAdult(); + + childSetVisible("events_mature_icon", can_access_mature); + childSetVisible("events_mature_label", can_access_mature); + childSetVisible("event_mature_chk", can_access_mature); + + childSetVisible("events_adult_icon", can_access_adult); + childSetVisible("events_adult_label", can_access_adult); + childSetVisible("event_adult_chk", can_access_adult); + + // disable mature / adult events. + if (!can_access_mature) + { + static LLCachedControl show_mature("MapShowMatureEvents",false); + show_mature = false; + } + if (!can_access_adult) + { + static LLCachedControl show_adult("MapShowAdultEvents",false); + show_adult = false; + } } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 80cc25abd..b7f00e1df 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -111,29 +111,26 @@ public: // teleport to the tracked item, if there is one void teleport(); + void onChangeMaturity(); -protected: - static void onPanBtn( void* userdata ); - - static void onGoHome(void* data); +protected: + void onGoHome(); static void onLandmarkComboPrearrange( LLUICtrl* ctrl, void* data ); - static void onLandmarkComboCommit( LLUICtrl* ctrl, void* data ); + void onLandmarkComboCommit(); static void onAvatarComboPrearrange( LLUICtrl* ctrl, void* data ); - static void onAvatarComboCommit( LLUICtrl* ctrl, void* data ); + void onAvatarComboCommit(); static void onComboTextEntry( LLLineEditor* ctrl, void* data ); static void onSearchTextEntry( LLLineEditor* ctrl, void* data ); - static void onClearBtn(void*); - static void onFlyBtn(void*); - static void onClickTeleportBtn(void*); - static void onShowTargetBtn(void*); - static void onShowAgentBtn(void*); - static void onCopySLURL(void*); - - static void onCheckEvents(LLUICtrl* ctrl, void*); + void onClearBtn(); + void onClickTeleportBtn(); + static void onClickTeleportBtn_static(void* data) {((LLFloaterWorldMap*)data)->onClickTeleportBtn();}; + void onShowTargetBtn(); + void onShowAgentBtn(); + void onCopySLURL(); void centerOnTarget(BOOL animate); void updateLocation(); @@ -142,7 +139,6 @@ protected: void fly(); void buildLandmarkIDLists(); - static void onGoToLandmarkDialog(S32 option,void* userdata); void flyToLandmark(); void teleportToLandmark(); void setLandmarkVisited(); @@ -152,24 +148,28 @@ protected: void teleportToAvatar(); void updateSearchEnabled(); - void onLocationFocusChanged( LLFocusableElement* focus ); - static void onLocationCommit( void* userdata ); - static void onCommitLocation( LLUICtrl* ctrl, void* userdata ); - static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata ); + void onLocationFocusChanged( LLFocusableElement* ctrl ); + void onLocationCommit(); + void onCoordinatesCommit(); + void onCommitSearchResult(); void cacheLandmarkPosition(); -protected: - LLPanel* mPanel; // Panel displaying the map +private: + LLPanel* mPanel; // Panel displaying the map // Sets sMapScale, in pixels per region F32 mCurZoomVal; - F32 mCurZoomValInterpolationStart; // Used during mZoomTimer interpolation. LLFrameTimer mZoomTimer; + // update display of teleport destination coordinates - pos is in global coordinates + void updateTeleportCoordsDisplay( const LLVector3d& pos ); + + // enable/disable teleport destination coordinates + void enableTeleportCoordsDisplay( bool enabled ); + LLDynamicArray mLandmarkAssetIDList; LLDynamicArray mLandmarkItemIDList; - BOOL mHasLandmarkPosition; static const LLUUID sHomeID; @@ -178,9 +178,12 @@ protected: LLFriendObserver* mFriendObserver; std::string mCompletingRegionName; + // Local position from trackURL() request, used to select final + // position once region lookup complete. + LLVector3 mCompletingRegionPos; + std::string mLastRegionName; BOOL mWaitingForTracker; - BOOL mExactMatch; BOOL mIsClosing; BOOL mSetToUserPosition; @@ -190,6 +193,10 @@ protected: std::string mTrackedSimName; std::string mTrackedAvatarName; std::string mSLURL; + + LLCtrlListInterface * mListFriendCombo; + LLCtrlListInterface * mListLandmarkCombo; + LLCtrlListInterface * mListSearchResults; }; extern LLFloaterWorldMap* gFloaterWorldMap; diff --git a/indra/newview/llmapresponders.cpp b/indra/newview/llmapresponders.cpp index cf0769bce..eaae3e450 100644 --- a/indra/newview/llmapresponders.cpp +++ b/indra/newview/llmapresponders.cpp @@ -38,6 +38,8 @@ #include "llviewertexturelist.h" #include "llworldmap.h" #include "llagent.h" +#include "llworldmapmessage.h" +#include "llsdserialize.h" //virtual void LLMapLayerResponder::result(const LLSD& result) @@ -45,22 +47,19 @@ void LLMapLayerResponder::result(const LLSD& result) llinfos << "LLMapLayerResponder::result from capabilities" << llendl; S32 agent_flags = result["AgentData"]["Flags"]; - - if (agent_flags != LLWorldMap::getInstance()->mCurrentMap) + U32 layer = flagsToLayer(agent_flags); + + if (layer != SIM_LAYER_COMPOSITE) { llwarns << "Invalid or out of date map image type returned!" << llendl; return; } LLUUID image_id; - //U32 left, right, top, bottom; - LLWorldMap::getInstance()->mMapLayers[agent_flags].clear(); - - bool use_web_map_tiles = LLWorldMap::useWebMapTiles(); + LLWorldMap::getInstance()->mMapLayers.clear(); LLSD::array_const_iterator iter; - BOOL adjust = FALSE; for(iter = result["LayerData"].beginArray(); iter != result["LayerData"].endArray(); ++iter) { const LLSD& layer_data = *iter; @@ -74,146 +73,12 @@ void LLMapLayerResponder::result(const LLSD& result) new_layer.LayerExtents.mTop = layer_data["Top"]; new_layer.LayerImageID = layer_data["ImageID"]; -// if (use_web_map_tiles) -// { -// new_layer.LayerImage = LLWorldMap::loadObjectsTile((U32)new_layer.LayerExtents.mLeft, (U32)new_layer.LayerExtents.mBottom); // no good... Maybe using of level 2 and higher web maps ? -// } -// else -// { - new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID); -// } + new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID); + gGL.getTexUnit(0)->bind(new_layer.LayerImage.get()); new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP); - F32 x_meters = F32(new_layer.LayerExtents.mLeft*REGION_WIDTH_UNITS); - F32 y_meters = F32(new_layer.LayerExtents.mBottom*REGION_WIDTH_UNITS); - adjust = LLWorldMap::getInstance()->extendAABB(U32(x_meters), U32(y_meters), - U32(x_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getWidth()), - U32(y_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getHeight())) || adjust; - - LLWorldMap::getInstance()->mMapLayers[agent_flags].push_back(new_layer); + LLWorldMap::getInstance()->mMapLayers.push_back(new_layer); } - - LLWorldMap::getInstance()->mMapLoaded[agent_flags] = TRUE; - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); - - /* - U32 agent_flags; - msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - - if (agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) - { - llwarns << "Invalid map image type returned! " << agent_flags << llendl; - return; - } - */ - - bool found_null_sim = false; - - adjust = FALSE; - if (result.has("MapBlocks")) - { - const LLSD& map_blocks = result["MapBlocks"]; - for (iter = map_blocks.beginArray(); iter != map_blocks.endArray(); ++iter) - { - const LLSD& map_block = *iter; - - S32 x_regions = map_block["X"]; - S32 y_regions = map_block["Y"]; - S32 x_size = map_block["SizeX"]; - S32 y_size = map_block["SizeY"]; - std::string name = map_block["Name"]; - S32 access = map_block["Access"]; - S32 region_flags = map_block["RegionFlags"]; - S32 water_height = map_block["WaterHeight"]; - LLUUID image_id = map_block["MapImageID"]; - - U32 x_meters = x_regions * REGION_WIDTH_UNITS; - U32 y_meters = y_regions * REGION_WIDTH_UNITS; - - if (access == 255) - { - // This region doesn't exist - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) - { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = TRUE; - } - - found_null_sim = true; - } - else - { - adjust = LLWorldMap::getInstance()->extendAABB(x_meters, - y_meters, - x_meters+REGION_WIDTH_UNITS, - y_meters+REGION_WIDTH_UNITS) || adjust; - U64 handle = to_region_handle(x_meters, y_meters); - - // llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl; - - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo == NULL) - { - siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); - } - - siminfo->setName( name ); - siminfo->setAccess( access ); /*Flawfinder: ignore*/ - siminfo->setRegionFlags( region_flags ); - siminfo->setWaterHeight( (F32) water_height ); - siminfo->setMapImageID( image_id, agent_flags ); - siminfo->setSize((U16)x_size, (U16)y_size); - if (use_web_map_tiles) - { - siminfo->mCurrentImage = LLWorldMap::loadObjectsTile((U32)x_regions, (U32)y_regions); - } - else - { - siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap]); - } - siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); - gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); - - if (siminfo->mMapImageID[2].notNull()) - { - siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[2]); - } - else - { - siminfo->mOverlayImage = NULL; - } - - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) - { - if (siminfo->isDown()) - { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = true; - } - else - { - // We were tracking this location, and it does exist - bool is_tracking_dbl = LLWorldMap::getInstance()->mIsTrackingDoubleClick == TRUE; - gFloaterWorldMap->trackLocation(LLWorldMap::getInstance()->mUnknownLocation); - if (is_tracking_dbl) - { - LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - gAgent.teleportViaLocation( pos_global ); - } - } - } - } - } - } - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); - gFloaterWorldMap->updateSims(found_null_sim); + LLWorldMap::getInstance()->mMapLoaded = true; } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 2b6ded3fd..bdae27c97 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -190,6 +190,7 @@ #include "llwind.h" #include "llworld.h" #include "llworldmap.h" +#include "llworldmapmessage.h" #include "llxfermanager.h" #include "pipeline.h" #include "llappviewer.h" @@ -3392,8 +3393,8 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply); msg->setHandlerFunc("MapLayerReply", LLWorldMap::processMapLayerReply); - msg->setHandlerFunc("MapBlockReply", LLWorldMap::processMapBlockReply); - msg->setHandlerFunc("MapItemReply", LLWorldMap::processMapItemReply); + msg->setHandlerFunc("MapBlockReply", LLWorldMapMessage::processMapBlockReply); + msg->setHandlerFunc("MapItemReply", LLWorldMapMessage::processMapItemReply); msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply); msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply); diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h index 285036527..c727c29d5 100644 --- a/indra/newview/lltracker.h +++ b/indra/newview/lltracker.h @@ -81,7 +81,7 @@ public: // these are static so that they can be used a callbacks static ETrackingStatus getTrackingStatus() { return instance()->mTrackingStatus; } static ETrackingLocationType getTrackedLocationType() { return instance()->mTrackingLocationType; } - static BOOL isTracking(void*) { return (BOOL) instance()->mTrackingStatus; } + static BOOL isTracking(void*) { return instance()->mTrackingStatus != TRACKING_NOTHING; } static void stopTracking(void*); static void clearFocus(); diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 1144c5827..a9971abbd 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -45,6 +45,7 @@ #include "llurlsimstring.h" #include "llweb.h" #include "llworldmap.h" +#include "llworldmapmessage.h" // library includes #include "llsd.h" @@ -243,7 +244,7 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous url_displayp->setName(region_name); // Request a region handle by name - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionNameCallback, url, false); // don't teleport @@ -282,7 +283,7 @@ void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::strin LLVector3d global_pos = from_region_handle(region_handle) + LLVector3d(local_pos); U64 new_region_handle = to_region_handle(global_pos); - LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, + LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle, LLURLDispatcherImpl::regionHandleCallback, url, teleport); } @@ -401,7 +402,7 @@ public: { url += tokens[i].asString() + "/"; } - LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, url, true); // teleport diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0c0b12075..569451ab0 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3596,7 +3596,6 @@ void set_god_level(U8 god_level) // God mode changes region visibility LLWorldMap::getInstance()->reset(); - LLWorldMap::getInstance()->setCurrentLayer(0); // inventory in items may change in god mode gObjectList.dirtyAllObjectInventory(); diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 7672cca2f..dda570ea8 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -47,46 +47,79 @@ #include "llviewertexturelist.h" #include "llviewerregion.h" #include "llregionflags.h" - #include "hippogridmanager.h" -bool LLWorldMap::sGotMapURL = false; -const F32 AGENTS_UPDATE_TIMER = 60.0; // Seconds between 2 agent requests for a region -const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes +#include "llworldmapmessage.h" +#include "hippogridmanager.h" + +bool LLWorldMap::sGotMapURL = false; +// Timers to temporise database requests +const F32 AGENTS_UPDATE_TIMER = 60.0; // Seconds between 2 agent requests for a region +const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // Seconds before we consider re-requesting item data for the grid + +//--------------------------------------------------------------------------- +// LLItemInfo +//--------------------------------------------------------------------------- -// For DEV-17507, do lazy image loading in llworldmapview.cpp instead, -// limiting requests to currently visible regions and minimizing the -// number of textures being requested simultaneously. -// -// Uncomment IMMEDIATE_IMAGE_LOAD to restore the old behavior -// -//#define IMMEDIATE_IMAGE_LOAD LLItemInfo::LLItemInfo(F32 global_x, F32 global_y, const std::string& name, - LLUUID id, - S32 extra, S32 extra2) + LLUUID id) : mName(name), mToolTip(""), mPosGlobal(global_x, global_y, 40.0), mID(id), - mSelected(FALSE), - mExtra(extra), - mExtra2(extra2) + mCount(1) +// mSelected(false) +// mColor() { - mRegionHandle = to_region_handle(mPosGlobal); } +//--------------------------------------------------------------------------- +// LLSimInfo +//--------------------------------------------------------------------------- + LLSimInfo::LLSimInfo(U64 handle) : mHandle(handle), mName(), mAgentsUpdateTime(0), - mShowAgentLocations(FALSE), mAccess(0x0), mRegionFlags(0x0), - mWaterHeight(0.f), - mAlpha(-1.f) + mFirstAgentRequest(true), + mSizeX(REGION_WIDTH_UNITS), + mSizeY(REGION_WIDTH_UNITS), + mAlpha(0.f) { } +void LLSimInfo::setLandForSaleImage (LLUUID image_id) +{ + mMapImageID[SIM_LAYER_OVERLAY] = image_id; + // Fetch the image + if (mMapImageID[SIM_LAYER_OVERLAY].notNull()) + { + mLayerImage[SIM_LAYER_OVERLAY] = LLViewerTextureManager::getFetchedTexture(mMapImageID[SIM_LAYER_OVERLAY], MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); + mLayerImage[SIM_LAYER_OVERLAY]->setAddressMode(LLTexUnit::TAM_CLAMP); + } + else + { + mLayerImage[SIM_LAYER_OVERLAY] = NULL; + } +} + +LLPointer LLSimInfo::getLandForSaleImage () +{ + if (mLayerImage[SIM_LAYER_OVERLAY].isNull() && mMapImageID[SIM_LAYER_OVERLAY].notNull()) + { + // Fetch the image if it hasn't been done yet (unlikely but...) + mLayerImage[SIM_LAYER_OVERLAY] = LLViewerTextureManager::getFetchedTexture(mMapImageID[SIM_LAYER_OVERLAY], MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); + mLayerImage[SIM_LAYER_OVERLAY]->setAddressMode(LLTexUnit::TAM_CLAMP); + } + if (!mLayerImage[SIM_LAYER_OVERLAY].isNull()) + { + // Boost the fetch level when we try to access that image + mLayerImage[SIM_LAYER_OVERLAY]->setBoostLevel(LLViewerTexture::BOOST_MAP); + } + return mLayerImage[SIM_LAYER_OVERLAY]; +} LLVector3d LLSimInfo::getGlobalPos(const LLVector3& local_pos) const { @@ -109,18 +142,31 @@ LLVector3 LLSimInfo::getLocalPos(LLVector3d global_pos) const void LLSimInfo::clearImage() { - if (!mOverlayImage.isNull()) + for(U32 layer = SIM_LAYER_BEGIN; layer < SIM_LAYER_COUNT;++layer) { - mOverlayImage->setBoostLevel(0); - mOverlayImage = NULL; + if(!mLayerImage[layer].isNull()) + { + mLayerImage[layer]->setBoostLevel(0); + mLayerImage[layer]=NULL; + } } } -void LLSimInfo::dropImagePriority() +void LLSimInfo::dropImagePriority(sim_layer_type layer/* = SIM_LAYER_COUNT*/) { - if (!mOverlayImage.isNull()) + if(layer == SIM_LAYER_COUNT) { - mOverlayImage->setBoostLevel(0); + for(U32 layer = SIM_LAYER_BEGIN; layer < SIM_LAYER_COUNT;++layer) + { + if(!mLayerImage[layer].isNull()) + { + mLayerImage[layer]->setBoostLevel(0); + } + } + } + else if(layer < SIM_LAYER_COUNT && layer >= SIM_LAYER_BEGIN && !mLayerImage[layer].isNull()) + { + mLayerImage[layer]->setBoostLevel(0); } } @@ -129,116 +175,154 @@ void LLSimInfo::updateAgentCount(F64 time) { if ((time - mAgentsUpdateTime > AGENTS_UPDATE_TIMER) || mFirstAgentRequest) { - LLWorldMap::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); mAgentsUpdateTime = time; mFirstAgentRequest = false; } } + +// Get the total agents count +const S32 LLSimInfo::getAgentCount() const +{ + S32 total_agent_count = 0; + for (LLSimInfo::item_info_list_t::const_iterator it = mAgentLocations.begin(); it != mAgentLocations.end(); ++it) + { + total_agent_count += it->getCount(); + } + return total_agent_count; +} + bool LLSimInfo::isName(const std::string& name) const { return (LLStringUtil::compareInsensitive(name, mName) == 0); } +void LLSimInfo::dump() const +{ + U32 x_pos, y_pos; + from_region_handle(mHandle, &x_pos, &y_pos); + + LL_INFOS("World Map") << x_pos << "," << y_pos + << " " << mName + << " " << (S32)mAccess + << " " << std::hex << mRegionFlags << std::dec + << " " << mSizeX << "x" << mSizeY +// << " " << mWaterHeight + << LL_ENDL; +} + +void LLSimInfo::clearItems() +{ + mTelehubs.clear(); + mInfohubs.clear(); + mPGEvents.clear(); + mMatureEvents.clear(); + mAdultEvents.clear(); + mLandForSale.clear(); + mLandForSaleAdult.clear(); +// We persist the agent count though as it is updated on a frequent basis +// mAgentLocations.clear(); +} + +void LLSimInfo::insertAgentLocation(const LLItemInfo& item) +{ + std::string name = item.getName(); + + // Find the last item in the list with a different name and erase them + item_info_list_t::iterator lastiter; + for (lastiter = mAgentLocations.begin(); lastiter != mAgentLocations.end(); ++lastiter) + { + LLItemInfo& info = *lastiter; + if (info.isName(name)) + { + break; + } + } + if (lastiter != mAgentLocations.begin()) + { + mAgentLocations.erase(mAgentLocations.begin(), lastiter); + } + + // Now append the new location + mAgentLocations.push_back(item); +} + //--------------------------------------------------------------------------- // World Map //--------------------------------------------------------------------------- LLWorldMap::LLWorldMap() : - mIsTrackingUnknownLocation( FALSE ), - mInvalidLocation( FALSE ), - mIsTrackingDoubleClick( FALSE ), - mIsTrackingCommit( FALSE ), - mUnknownLocation( 0, 0, 0 ), - mRequestLandForSale(true), - mCurrentMap(0), - mMinX(U32_MAX), - mMaxX(U32_MIN), - mMinY(U32_MAX), - mMaxY(U32_MIN), - mNeighborMap(NULL), - mTelehubCoverageMap(NULL), - mNeighborMapWidth(0), - mNeighborMapHeight(0), - mSLURLRegionName(), - mSLURLRegionHandle(0), - mSLURL(), - mSLURLCallback(0), - mSLURLTeleport(false) + mIsTrackingLocation( false ), + mIsTrackingFound( false ), + mIsInvalidLocation( false ), + mIsTrackingDoubleClick( false ), + mIsTrackingCommit( false ), + mTrackingLocation( 0, 0, 0 ), + mFirstRequest(true), + mMapLoaded(false) { - for (S32 map=0; map LLWorldMap::LLWorldMap()" << LL_ENDL; + /*for (U32 map=SIM_LAYER_BEGIN; map LLWorldMap::~LLWorldMap()" << LL_ENDL; reset(); - for (S32 map=0; map REQUEST_ITEMS_TIMER) + bool clear = false; + if ((mRequestTimer.getElapsedTimeF32() > REQUEST_ITEMS_TIMER) || mFirstRequest || force) { mRequestTimer.reset(); - mTelehubs.clear(); - mInfohubs.clear(); - mPGEvents.clear(); - mMatureEvents.clear(); - mAdultEvents.clear(); - mLandForSale.clear(); + LLSimInfo* sim_info = NULL; + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + sim_info = it->second; + if (sim_info) + { + sim_info->clearItems(); + } + } + clear = true; + mFirstRequest = false; } -// mAgentLocationsMap.clear(); // persists -// mNumAgents.clear(); // persists + return clear; } - void LLWorldMap::clearImageRefs() { // We clear the reference to the images we're holding. @@ -252,11 +336,6 @@ void LLWorldMap::clearImageRefs() sim_info = it->second; if(sim_info) { - if (sim_info->mCurrentImage) - { - sim_info->mCurrentImage->setBoostLevel(0); - sim_info->mCurrentImage = NULL; - } sim_info->clearImage(); } } @@ -265,12 +344,13 @@ void LLWorldMap::clearImageRefs() // Doesn't clear the already-loaded sim infos, just re-requests them void LLWorldMap::clearSimFlags() { - for (S32 map=0; map::const_iterator it; - for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + sim_info_map_t::iterator it = mSimInfoMap.find(handle); + if (it != mSimInfoMap.end()) { - const U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - if(handle == findhandle) - { - return info; - } - U32 x = 0, y = 0; - from_region_handle(findhandle, &x, &y); - U32 checkRegionX, checkRegionY; - from_region_handle(handle, &checkRegionX, &checkRegionY); - - if(x >= checkRegionX && x < (checkRegionX + info->getSizeX()) && - y >= checkRegionY && y < (checkRegionY + info->getSizeY())) - { - return info; - } + return it->second; } return NULL; } @@ -358,256 +423,75 @@ bool LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global, std::string return (sim_info != NULL); } -void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer) -{ - //TODO: we only have 1 layer -SG - mCurrentMap = layer; - if (!mMapLoaded[layer] || request_layer) - { - sendMapLayerRequest(); - } - - if (mTelehubs.size() == 0 || - mInfohubs.size() == 0) - { - // Request for telehubs - sendItemRequest(MAP_ITEM_TELEHUB); - } - - if (mPGEvents.size() == 0) - { - // Request for events - sendItemRequest(MAP_ITEM_PG_EVENT); - } - - if (mMatureEvents.size() == 0) - { - // Request for events (mature) - sendItemRequest(MAP_ITEM_MATURE_EVENT); - } - - if (mAdultEvents.size() == 0) - { - // Request for events (adult) - sendItemRequest(MAP_ITEM_ADULT_EVENT); - } - - if (mLandForSale.size() == 0) - { - // Request for Land For Sale - sendItemRequest(MAP_ITEM_LAND_FOR_SALE); - } - - if (mLandForSaleAdult.size() == 0) - { - // Request for Land For Sale - sendItemRequest(MAP_ITEM_LAND_FOR_SALE_ADULT); - } - - clearImageRefs(); - clearSimFlags(); -} - -void LLWorldMap::sendItemRequest(U32 type, U64 handle) -{ - LLMessageSystem* msg = gMessageSystem; - S32 layer = mCurrentMap; - - msg->newMessageFast(_PREHASH_MapItemRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, layer); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - - msg->nextBlockFast(_PREHASH_RequestData); - msg->addU32Fast(_PREHASH_ItemType, type); - msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim - - gAgent.sendReliableMessage(); -} - // public void LLWorldMap::sendMapLayerRequest() { if (!gAgent.getRegion()) return; - LLSD body; - body["Flags"] = mCurrentMap; std::string url = gAgent.getRegion()->getCapability( gAgent.isGodlike() ? "MapLayerGod" : "MapLayer"); + U32 flags = layerToFlags((sim_layer_type)SIM_LAYER_COMPOSITE); if (!url.empty()) { - llinfos << "LLWorldMap::sendMapLayerRequest via capability" << llendl; + LLSD body; + body["Flags"] = (LLSD::Integer)flags; + //llinfos << "LLWorldMap::sendMapLayerRequest via capability" << llendl; LLHTTPClient::post(url, body, new LLMapLayerResponder()); } else { - llinfos << "LLWorldMap::sendMapLayerRequest via message system" << llendl; + //llinfos << "LLWorldMap::sendMapLayerRequest via message system" << llendl; LLMessageSystem* msg = gMessageSystem; - S32 layer = mCurrentMap; // Request for layer msg->newMessageFast(_PREHASH_MapLayerRequest); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, layer); + msg->addU32Fast(_PREHASH_Flags, flags); msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim gAgent.sendReliableMessage(); - - if (mRequestLandForSale) - { - msg->newMessageFast(_PREHASH_MapLayerRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, 2); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - gAgent.sendReliableMessage(); - } } } -// public -void LLWorldMap::sendNamedRegionRequest(std::string region_name) -{ - LLMessageSystem* msg = gMessageSystem; - S32 layer = mCurrentMap; - // Request for layer - msg->newMessageFast(_PREHASH_MapNameRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, layer); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - msg->nextBlockFast(_PREHASH_NameData); - msg->addStringFast(_PREHASH_Name, region_name); - gAgent.sendReliableMessage(); -} -// public -void LLWorldMap::sendNamedRegionRequest(std::string region_name, - url_callback_t callback, - const std::string& callback_url, - bool teleport) // immediately teleport when result returned -{ - mSLURLRegionName = region_name; - mSLURLRegionHandle = 0; - mSLURL = callback_url; - mSLURLCallback = callback; - mSLURLTeleport = teleport; - - sendNamedRegionRequest(region_name); -} - -void LLWorldMap::sendHandleRegionRequest(U64 region_handle, - url_callback_t callback, - const std::string& callback_url, - bool teleport) // immediately teleport when result returned -{ - mSLURLRegionName.clear(); - mSLURLRegionHandle = region_handle; - mSLURL = callback_url; - mSLURLCallback = callback; - mSLURLTeleport = teleport; - - U32 global_x; - U32 global_y; - from_region_handle(region_handle, &global_x, &global_y); - U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); - U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); - - sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); -} - -// public -void LLWorldMap::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent) -{ - S32 layer = mCurrentMap; - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_MapBlockRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - U32 flags = layer; - flags |= (return_nonexistent ? 0x10000 : 0); - msg->addU32Fast(_PREHASH_Flags, flags); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - msg->nextBlockFast(_PREHASH_PositionData); - msg->addU16Fast(_PREHASH_MinX, min_x); - msg->addU16Fast(_PREHASH_MinY, min_y); - msg->addU16Fast(_PREHASH_MaxX, max_x); - msg->addU16Fast(_PREHASH_MaxY, max_y); - gAgent.sendReliableMessage(); - - if (mRequestLandForSale) - { - msg->newMessageFast(_PREHASH_MapBlockRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addU32Fast(_PREHASH_Flags, 2); - msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim - msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim - msg->nextBlockFast(_PREHASH_PositionData); - msg->addU16Fast(_PREHASH_MinX, min_x); - msg->addU16Fast(_PREHASH_MinY, min_y); - msg->addU16Fast(_PREHASH_MaxX, max_x); - msg->addU16Fast(_PREHASH_MaxY, max_y); - gAgent.sendReliableMessage(); - } -} // public static void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) { - llinfos << "LLWorldMap::processMapLayerReply from message system" << llendl; + //llinfos << "LLWorldMap::processMapLayerReply from message system" << llendl; U32 agent_flags; msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - if (agent_flags != (U32)LLWorldMap::getInstance()->mCurrentMap) + U32 layer = flagsToLayer(agent_flags); + if (layer != SIM_LAYER_COMPOSITE) { llwarns << "Invalid or out of date map image type returned!" << llendl; return; } LLUUID image_id; - //U32 left, right, top, bottom; S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_LayerData); - LLWorldMap::getInstance()->mMapLayers[agent_flags].clear(); + LLWorldMap::getInstance()->mMapLayers.clear(); -// bool use_web_map_tiles = useWebMapTiles(); - BOOL adjust = FALSE; for (S32 block=0; blockgetUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block); - + U32 left, right, top, bottom; msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Left, left, block); msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Right, right, block); msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Top, top, block); msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Bottom, bottom, block); -// if (use_web_map_tiles) -// { -// new_layer.LayerImage = loadObjectsTile(left, bottom); // no good... Maybe using of level 2 and higher web maps ? -// } -// else -// { - new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); -// } + new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); gGL.getTexUnit(0)->bind(new_layer.LayerImage.get()); new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -617,269 +501,148 @@ void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) new_layer.LayerExtents.mBottom = bottom; new_layer.LayerExtents.mTop = top; - F32 x_meters = F32(left*REGION_WIDTH_UNITS); - F32 y_meters = F32(bottom*REGION_WIDTH_UNITS); - adjust = LLWorldMap::getInstance()->extendAABB(U32(x_meters), U32(y_meters), - U32(x_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getWidth()), - U32(y_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getHeight())) || adjust; - - LLWorldMap::getInstance()->mMapLayers[agent_flags].push_back(new_layer); + LLWorldMap::getInstance()->mMapLayers.push_back(new_layer); } - LLWorldMap::getInstance()->mMapLoaded[agent_flags] = TRUE; - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); + LLWorldMap::getInstance()->mMapLoaded = true; } // public static bool LLWorldMap::useWebMapTiles() { - return gSavedSettings.getBOOL("UseWebMapTiles") && - (( gHippoGridManager->getConnectedGrid()->isSecondLife() || sGotMapURL) && LLWorldMap::getInstance()->mCurrentMap == 0); + static const LLCachedControl use_web_map_tiles("UseWebMapTiles",false); + return use_web_map_tiles && + (( gHippoGridManager->getConnectedGrid()->isSecondLife() || sGotMapURL)); } -// public static -LLPointer LLWorldMap::loadObjectsTile(U32 grid_x, U32 grid_y) +void LLWorldMap::reloadItems(bool force) { - // Get the grid coordinates - std::string imageurl = gSavedSettings.getString("MapServerURL") + llformat("map-%d-%d-%d-objects.jpg", 1, grid_x, grid_y); - - LLPointer img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl,TRUE,LLViewerTexture::BOOST_MAP,LLViewerTexture::LOD_TEXTURE); - img->setBoostLevel(LLViewerTexture::BOOST_MAP); - - // Return the smart pointer - return img; -} - -// public static -void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) -{ - U32 agent_flags; - msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - - if ((S32)agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) + //LL_INFOS("World Map") << "LLWorldMap::reloadItems()" << LL_ENDL; + if (clearItems(force)) { - llwarns << "Invalid map image type returned! " << agent_flags << llendl; - return; + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_TELEHUB); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_PG_EVENT); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_MATURE_EVENT); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_ADULT_EVENT); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_LAND_FOR_SALE); } - - S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data); - - bool found_null_sim = false; - -#ifdef IMMEDIATE_IMAGE_LOAD - bool use_web_map_tiles = useWebMapTiles(); -#endif - BOOL adjust = FALSE; - for (S32 block=0; blockgetU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block); - msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block); - msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); - msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block); - msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block); - msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block); - msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block); - msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block); - if(msg->getNumberOfBlocksFast(_PREHASH_Size) > 0) + if(!mMapLoaded || force) + sendMapLayerRequest(); + } +} + + +// static public +// Insert a region in the region map +// returns true if region inserted, false otherwise +bool LLWorldMap::insertRegion(U32 x_world, U32 y_world, U32 x_size, U32 y_size, U32 agent_flags, std::string& name, LLUUID& image_id, U32 accesscode, U32 region_flags) +{ + // This region doesn't exist + if (accesscode == 255) + { + // Checks if the track point is in it and invalidates it if it is + if (LLWorldMap::getInstance()->isTrackingInRectangle( x_world, y_world, x_world + REGION_WIDTH_UNITS, y_world + REGION_WIDTH_UNITS)) { - msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block); - msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block); + LLWorldMap::getInstance()->setTrackingInvalid(); } - if(x_size == 0 || (x_size % 16) != 0|| (y_size % 16) != 0) + // return failure to insert + return false; + } + else + { + U64 handle = to_region_handle(x_world, y_world); + //LL_INFOS("World Map") << "Map sim : " << name << ", ID : " << image_id.getString() << LL_ENDL; + // Insert the region in the region map of the world map + // Loading the LLSimInfo object with what we got and insert it in the map + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if (siminfo == NULL) { - x_size = 256; - y_size = 256; + siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); } - U32 x_meters = x_regions * REGION_WIDTH_UNITS; - U32 y_meters = y_regions * REGION_WIDTH_UNITS; + siminfo->setName( name ); + siminfo->setAccess( accesscode ); + siminfo->setRegionFlags( region_flags ); + //siminfo->setWaterHeight((F32) water_height); + U32 layer = flagsToLayer(agent_flags); + if (layer == SIM_LAYER_OVERLAY) + siminfo->setLandForSaleImage(image_id); + else if(layer < SIM_LAYER_COUNT) + siminfo->setMapImageID( image_id, layer ); + siminfo->setSize( x_size, y_size ); - U64 handle = to_region_handle(x_meters, y_meters); - - if (accesscode == 255) + // Handle the location tracking (for teleport, UI feedback and info display) + if (LLWorldMap::getInstance()->isTrackingInRectangle( x_world, y_world, x_world + REGION_WIDTH_UNITS, y_world + REGION_WIDTH_UNITS)) { - // This region doesn't exist - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) + if (siminfo->isDown()) { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = TRUE; - } - - found_null_sim = true; - } - else - { - adjust = LLWorldMap::getInstance()->extendAABB(x_meters, - y_meters, - x_meters+REGION_WIDTH_UNITS, - y_meters+REGION_WIDTH_UNITS) || adjust; - //LL_INFOS("World Map") << "Map sim : " << name << ", ID : " << image_id.getString() << LL_ENDL; - // Insert the region in the region map of the world map - // Loading the LLSimInfo object with what we got and insert it in the map - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo == NULL) - { - siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); - } - - siminfo->setName( name ); - siminfo->setAccess( accesscode ); - siminfo->setRegionFlags( region_flags ); - siminfo->setWaterHeight((F32) water_height); - siminfo->setMapImageID( image_id, agent_flags ); - siminfo->setSize( x_size, y_size ); - -#ifdef IMMEDIATE_IMAGE_LOAD - if (use_web_map_tiles) - { - siminfo->mCurrentImage = loadObjectsTile((U32)x_regions, (U32)y_regions); + // We were tracking this location, but it's no available + LLWorldMap::getInstance()->setTrackingInvalid(); } else { - siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); + // We were tracking this location, and it does exist and is available + LLWorldMap::getInstance()->setTrackingValid(); } - gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); - siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); -#endif + } + // return insert region success + return true; + } +} + +// static public +// Insert an item in the relevant region map +// returns true if item inserted, false otherwise +bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID& uuid, U32 type, S32 extra, S32 extra2) +{ + // Create an item record for the received object + LLItemInfo new_item((F32)x_world, (F32)y_world, name, uuid); + + // Compute a region handle based on the objects coordinates + LLVector3d pos((F32)x_world, (F32)y_world, 40.0); + U64 handle = to_region_handle(pos); + + // Get the region record for that handle or NULL if we haven't browsed it yet + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if (siminfo == NULL) + { + siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); + } + + //LL_INFOS("World Map") << "Process item : type = " << type << LL_ENDL; + switch (type) + { + case MAP_ITEM_TELEHUB: // telehubs + { + /* Merov: we are not using the hub color anymore for display so commenting that out + // Telehub color + U32 X = x_world / REGION_WIDTH_UNITS; + U32 Y = y_world / REGION_WIDTH_UNITS; + F32 red = fmod((F32)X * 0.11f, 1.f) * 0.8f; + F32 green = fmod((F32)Y * 0.11f, 1.f) * 0.8f; + F32 blue = fmod(1.5f * (F32)(X + Y) * 0.11f, 1.f) * 0.8f; + F32 add_amt = (X % 2) ? 0.15f : -0.15f; + add_amt += (Y % 2) ? -0.15f : 0.15f; + LLColor4 color(red + add_amt, green + add_amt, blue + add_amt); + new_item.setColor(color); + */ - if (siminfo->mMapImageID[2].notNull()) + // extra2 specifies whether this is an infohub or a telehub. + if (extra2) { -#ifdef IMMEDIATE_IMAGE_LOAD - siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTextureURL(siminfo->mMapImageID[2]); -#endif + siminfo->insertInfoHub(new_item); } else { - siminfo->mOverlayImage = NULL; - } - - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && - LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) - { - if (siminfo->isDown()) - { - // We were tracking this location, but it doesn't exist - LLWorldMap::getInstance()->mInvalidLocation = true; - } - else - { - // We were tracking this location, and it does exist - bool is_tracking_dbl = LLWorldMap::getInstance()->mIsTrackingDoubleClick == TRUE; - gFloaterWorldMap->trackLocation(LLWorldMap::getInstance()->mUnknownLocation); - if (is_tracking_dbl) - { - LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - gAgent.teleportViaLocation( pos_global ); - } - } + siminfo->insertTeleHub(new_item); } + break; } - - if(LLWorldMap::getInstance()->mSLURLCallback != NULL) - { - // Server returns definitive capitalization, SLURL might not have that. - if ((LLStringUtil::compareInsensitive(LLWorldMap::getInstance()->mSLURLRegionName, name)==0) - || (LLWorldMap::getInstance()->mSLURLRegionHandle == handle)) - { - url_callback_t callback = LLWorldMap::getInstance()->mSLURLCallback; - - LLWorldMap::getInstance()->mSLURLCallback = NULL; - LLWorldMap::getInstance()->mSLURLRegionName.clear(); - LLWorldMap::getInstance()->mSLURLRegionHandle = 0; - - callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); - } - } - if( gAgent.mPendingLure && - (U16)(gAgent.mPendingLure->mPosGlobal.mdV[0] / REGION_WIDTH_UNITS) == x_regions && - (U16)(gAgent.mPendingLure->mPosGlobal.mdV[1] / REGION_WIDTH_UNITS) == y_regions ) - { - gAgent.onFoundLureDestination(); - } - } - - if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); - gFloaterWorldMap->updateSims(found_null_sim); -} - -// public static -void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) -{ - U32 type; - msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type); - - S32 num_blocks = msg->getNumberOfBlocks("Data"); - - for (S32 block=0; blockgetU32Fast(_PREHASH_Data, _PREHASH_X, X, block); - msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block); - msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); - msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block); - msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block); - msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block); - - F32 world_x = (F32)X; - X /= REGION_WIDTH_UNITS; - F32 world_y = (F32)Y; - Y /= REGION_WIDTH_UNITS; - - LLItemInfo new_item(world_x, world_y, name, uuid, extra, extra2); - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(new_item.getRegionHandle()); - - switch (type) - { - case MAP_ITEM_TELEHUB: // telehubs - { - // Telehub color, store in extra as 4 U8's - U8 *color = (U8 *)&new_item.mExtra; - - F32 red = fmod((F32)X * 0.11f, 1.f) * 0.8f; - F32 green = fmod((F32)Y * 0.11f, 1.f) * 0.8f; - F32 blue = fmod(1.5f * (F32)(X + Y) * 0.11f, 1.f) * 0.8f; - F32 add_amt = (X % 2) ? 0.15f : -0.15f; - add_amt += (Y % 2) ? -0.15f : 0.15f; - color[0] = U8((red + add_amt) * 255); - color[1] = U8((green + add_amt) * 255); - color[2] = U8((blue + add_amt) * 255); - color[3] = 255; - - // extra2 specifies whether this is an infohub or a telehub. - if (extra2) - { - LLWorldMap::getInstance()->mInfohubs.push_back(new_item); - } - else - { - LLWorldMap::getInstance()->mTelehubs.push_back(new_item); - } - - break; - } - case MAP_ITEM_PG_EVENT: // events - case MAP_ITEM_MATURE_EVENT: - case MAP_ITEM_ADULT_EVENT: + case MAP_ITEM_PG_EVENT: // events + case MAP_ITEM_MATURE_EVENT: + case MAP_ITEM_ADULT_EVENT: { struct tm* timep; // Convert to Pacific, based on server's opinion of whether @@ -894,252 +657,64 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) timep->tm_min, (timep->tm_hour < 12 ? "AM" : "PM") ) ); - // HACK: store Z in extra2 - new_item.setElevation((F64)extra2); - if (type == MAP_ITEM_PG_EVENT) - { - LLWorldMap::getInstance()->mPGEvents.push_back(new_item); - } - else if (type == MAP_ITEM_MATURE_EVENT) - { - LLWorldMap::getInstance()->mMatureEvents.push_back(new_item); - } - else if (type == MAP_ITEM_ADULT_EVENT) - { - LLWorldMap::getInstance()->mAdultEvents.push_back(new_item); - } - - break; - } - case MAP_ITEM_LAND_FOR_SALE: // land for sale - case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale + // HACK: store Z in extra2 + new_item.setElevation((F64)extra2); + if (type == MAP_ITEM_PG_EVENT) { - new_item.setTooltip(llformat("%d sq. m. %s%d", new_item.mExtra, - gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(), - new_item.mExtra2)); - if (type == MAP_ITEM_LAND_FOR_SALE) - { - LLWorldMap::getInstance()->mLandForSale.push_back(new_item); - } - else if (type == MAP_ITEM_LAND_FOR_SALE_ADULT) - { - LLWorldMap::getInstance()->mLandForSaleAdult.push_back(new_item); + siminfo->insertPGEvent(new_item); + } + else if (type == MAP_ITEM_MATURE_EVENT) + { + siminfo->insertMatureEvent(new_item); + } + else if (type == MAP_ITEM_ADULT_EVENT) + { + siminfo->insertAdultEvent(new_item); + } + break; + } + case MAP_ITEM_LAND_FOR_SALE: // land for sale + case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale + { + new_item.setTooltip(llformat("%d sq. m. %s%d", extra, + gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(), + extra2)); + if (type == MAP_ITEM_LAND_FOR_SALE) + { + siminfo->insertLandForSale(new_item); + } + else if (type == MAP_ITEM_LAND_FOR_SALE_ADULT) + { + siminfo->insertLandForSaleAdult(new_item); } break; } case MAP_ITEM_CLASSIFIED: // classifieds { - //DEPRECATED: no longer used - break; - } - case MAP_ITEM_AGENT_LOCATIONS: // agent locations - { - if (!siminfo) - { - llinfos << "siminfo missing for " << new_item.getGlobalPosition().mdV[0] << ", " << new_item.getGlobalPosition().mdV[1] << llendl; - break; - } -// llinfos << "New Location " << new_item.mName << llendl; - - item_info_list_t& agentcounts = LLWorldMap::getInstance()->mAgentLocationsMap[new_item.getRegionHandle()]; - - // Find the last item in the list with a different name and erase them - item_info_list_t::iterator lastiter; - for (lastiter = agentcounts.begin(); lastiter!=agentcounts.end(); ++lastiter) - { - const LLItemInfo& info = *lastiter; - if (info.isName(new_item.getName())) - { - break; - } - } - if (lastiter != agentcounts.begin()) - { - agentcounts.erase(agentcounts.begin(), lastiter); - } - // Now append the new location - if (new_item.mExtra > 0) - { - agentcounts.push_back(new_item); - } - break; - } - default: - break; - }; - } -} - -void LLWorldMap::dump() -{ - for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - - llinfos << x_pos << "," << y_pos - << " " << info->getName() - << " " << (S32)info->getAccess() - << " " << std::hex << info->getRegionFlags() << std::dec - << " " << info->getWaterHeight() - //<< " " << info->mTelehubName - //<< " " << info->mTelehubPosition - << llendl; - - if (info->mCurrentImage) - { - llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel() - << " fullwidth " << info->mCurrentImage->getWidth(0) - << " fullheight " << info->mCurrentImage->getHeight(0) - << " maxvirt " << info->mCurrentImage->getMaxVirtualSize() - << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() - << llendl; + //DEPRECATED: no longer used + break; } - } -} - - -BOOL LLWorldMap::extendAABB(U32 min_x, U32 min_y, U32 max_x, U32 max_y) -{ - BOOL rv = FALSE; - if (min_x < mMinX) - { - rv = TRUE; - mMinX = min_x; - } - if (min_y < mMinY) - { - rv = TRUE; - mMinY = min_y; - } - if (max_x > mMaxX) - { - rv = TRUE; - mMaxX = max_x; - } - if (max_y > mMaxY) - { - rv = TRUE; - mMaxY = max_y; - } - lldebugs << "World map aabb: (" << mMinX << ", " << mMinY << "), (" - << mMaxX << ", " << mMaxY << ")" << llendl; - return rv; -} - - -U32 LLWorldMap::getWorldWidth() const -{ - return mMaxX - mMinX; -} - - -U32 LLWorldMap::getWorldHeight() const -{ - return mMaxY - mMinY; -} - -BOOL LLWorldMap::coveredByTelehub(LLSimInfo* infop) -{ - /*if (!mTelehubCoverageMap) - { - return FALSE; - } - U32 x_pos, y_pos; - from_region_handle(infop->mHandle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - - S32 index = x_pos - (mMinX / REGION_WIDTH_UNITS - 1) + (mNeighborMapWidth * (y_pos - (mMinY / REGION_WIDTH_UNITS - 1))); - return mTelehubCoverageMap[index] != 0; */ - return FALSE; -} - -void LLWorldMap::updateTelehubCoverage() -{ - /*S32 neighbor_width = getWorldWidth() / REGION_WIDTH_UNITS + 2; - S32 neighbor_height = getWorldHeight() / REGION_WIDTH_UNITS + 2; - if (neighbor_width > mNeighborMapWidth || neighbor_height > mNeighborMapHeight) - { - mNeighborMapWidth = neighbor_width; - mNeighborMapHeight = neighbor_height; - delete mNeighborMap; - delete mTelehubCoverageMap; - - mNeighborMap = new U8[mNeighborMapWidth * mNeighborMapHeight]; - mTelehubCoverageMap = new U8[mNeighborMapWidth * mNeighborMapHeight]; - } - - memset(mNeighborMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8)); - memset(mTelehubCoverageMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8)); - - // leave 1 sim border - S32 min_x = (mMinX / REGION_WIDTH_UNITS) - 1; - S32 min_y = (mMinY / REGION_WIDTH_UNITS) - 1; - - std::map::const_iterator it; - for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - //LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - x_pos -= min_x; - y_pos -= min_y; - - S32 index = x_pos + (mNeighborMapWidth * y_pos); - mNeighborMap[index - 1]++; - mNeighborMap[index + 1]++; - mNeighborMap[index - mNeighborMapWidth]++; - mNeighborMap[index + mNeighborMapWidth]++; - } - - for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - x_pos -= min_x; - y_pos -= min_y; - - S32 index = x_pos + (mNeighborMapWidth * y_pos); - - if (!info->mTelehubName.empty() && mNeighborMap[index]) + case MAP_ITEM_AGENT_LOCATIONS: // agent locations { - S32 x_start = llmax(0, S32(x_pos - 5)); - S32 x_span = llmin(mNeighborMapWidth - 1, (S32)(x_pos + 5)) - x_start + 1; - S32 y_start = llmax(0, (S32)y_pos - 5); - S32 y_end = llmin(mNeighborMapHeight - 1, (S32)(y_pos + 5)); - for (S32 y_index = y_start; y_index <= y_end; y_index++) +// LL_INFOS("World Map") << "New Location " << new_item.mName << LL_ENDL; + if (extra > 0) { - memset(&mTelehubCoverageMap[x_start + y_index * mNeighborMapWidth], 0xff, sizeof(U8) * x_span); + new_item.setCount(extra); + siminfo->insertAgentLocation(new_item); } + break; } + default: + break; } + return true; +} - for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) - { - U64 handle = (*it).first; - //LLSimInfo* info = (*it).second; - - U32 x_pos, y_pos; - from_region_handle(handle, &x_pos, &y_pos); - x_pos /= REGION_WIDTH_UNITS; - y_pos /= REGION_WIDTH_UNITS; - - S32 index = x_pos - min_x + (mNeighborMapWidth * (y_pos - min_y)); - mTelehubCoverageMap[index] *= mNeighborMap[index]; - }*/ +bool LLWorldMap::isTrackingInRectangle(F64 x0, F64 y0, F64 x1, F64 y1) +{ + if (!mIsTrackingLocation) + return false; + return ((mTrackingLocation[0] >= x0) && (mTrackingLocation[0] < x1) && (mTrackingLocation[1] >= y0) && (mTrackingLocation[1] < y1)); } // Drop priority of all images being fetched by the map @@ -1155,19 +730,85 @@ void LLWorldMap::dropImagePriorities() } } -LLPointer LLSimInfo::getLandForSaleImage () +// Load all regions in a given rectangle (in region grid coordinates, i.e. world / 256 meters) +void LLWorldMap::updateRegions(S32 x0, S32 y0, S32 x1, S32 y1) { - if (mOverlayImage.isNull() && mMapImageID[2].notNull()) + // Convert those boundaries to the corresponding (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) block coordinates + U32 global_x0 = x0 / MAP_BLOCK_SIZE; + U32 global_x1 = x1 / MAP_BLOCK_SIZE; + U32 global_y0 = y0 / MAP_BLOCK_SIZE; + U32 global_y1 = y1 / MAP_BLOCK_SIZE; + + //Singu note: There's a bunch of extra logic here, as opensim grids support sim coordinates that extend beyond the range + // used on the official grid. We basically just extend what LL had here by nesting the mMapBlockLoaded array in a 'dynamic' grid, + // essentially making that array a 'block' itself. An std::map was used to conserve memory, as we selectively only allocate desired + // blocks, and although lookups aren't blazingly fast with that container, it isn't likeley to accumulate very many entries. + + //MapBlockRequest uses U16 for coordinate components. + // In order not to exceed U16_MAX values, MAP_BLOCK_RES*MAP_BLOCK_SIZE*(i or j) can't exceed U16_MAX(65535) + U32 max_range = (U16_MAX+1)/MAP_BLOCK_RES/MAP_BLOCK_SIZE - 1; + + //Desired coordinate ranges in our 'dynamic' grid of 512x512 grids of 4x4 sim blocks. + U32 map_block_x0 = global_x0 / MAP_BLOCK_RES; + U32 map_block_x1 = llmin(global_x1 / MAP_BLOCK_RES, max_range); + U32 map_block_y0 = global_y0 / MAP_BLOCK_RES; + U32 map_block_y1 = llmin(global_y1 / MAP_BLOCK_RES, max_range); + + const bool layer_start = useWebMapTiles() ? SIM_LAYER_OVERLAY : SIM_LAYER_BEGIN; + for (U32 i = map_block_x0; i <= map_block_x1; ++i) { - // Fetch the image if it hasn't been done yet (unlikely but...) - mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID[2], MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); - mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP); - } - if (!mOverlayImage.isNull()) + for (U32 j = map_block_y0; j <= map_block_y1; ++j) { - // Boost the fetch level when we try to access that image - mOverlayImage->setBoostLevel(LLViewerTexture::BOOST_MAP); + + //Desired coordinate ranges in our 512x512 grids of 4x4 sim blocks. + x0 = global_x0 - i * MAP_BLOCK_RES; + x1 = llmin(global_x1 - i * (U32)MAP_BLOCK_RES, (U32)MAP_BLOCK_RES-1); + y0 = global_y0 - j * MAP_BLOCK_RES; + y1 = llmin(global_y1 - j * (U32)MAP_BLOCK_RES, (U32)MAP_BLOCK_RES-1); + + for(U32 layer = layer_start;layer &block = mMapBlockMap[layer][(i << 16) | j]; + if(block.empty()) + { + //New block. Allocate the array and set all entries to false. (seen as mMapBlockLoaded in v3) + block.resize(MAP_BLOCK_RES*MAP_BLOCK_RES,false); + } + + // Load the region info those blocks + for (S32 block_x = llmax(x0, 0); block_x <= llmin(x1, MAP_BLOCK_RES-1); ++block_x) + { + for (S32 block_y = llmax(y0, 0); block_y <= llmin(y1, MAP_BLOCK_RES-1); ++block_y) + { + S32 offset = block_x | (block_y * MAP_BLOCK_RES); + // if(!mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset]) + if (!block[offset]) + { + U16 min_x = (block_x + i * MAP_BLOCK_RES) * MAP_BLOCK_SIZE; + U16 max_x = min_x + MAP_BLOCK_SIZE - 1; + U16 min_y = (block_y + j * MAP_BLOCK_RES) * MAP_BLOCK_SIZE; + U32 max_y = min_y + MAP_BLOCK_SIZE - 1; + + //LL_INFOS("World Map") << "Loading Block (" << block_x << "," << block_y << ")" << LL_ENDL; + LLWorldMapMessage::getInstance()->sendMapBlockRequest(min_x, min_y, max_x, max_y, false, layerToFlags((sim_layer_type)layer)); + block[offset] = true; + } + } + } + } + } } - return mOverlayImage; } +void LLWorldMap::dump() +{ + LL_INFOS("World Map") << "LLWorldMap::dump()" << LL_ENDL; + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + LLSimInfo* info = it->second; + if (info) + { + info->dump(); + } + } +} diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index c9e6be37e..c34dc0f21 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -51,39 +51,80 @@ class LLMessageSystem; - +// Description of objects like hubs, events, land for sale, people and more (TBD). +// Note: we don't store a "type" in there so we need to store instances of this class in +// well known objects (i.e. list of objects which type is "well known"). class LLItemInfo { public: - LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id, S32 extra = 0, S32 extra2 = 0); + LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id); // Setters void setTooltip(const std::string& tooltip) { mToolTip = tooltip; } void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; } + void setCount(S32 count) { mCount = count; } +// void setSelected(bool selected) { mSelected = selected; } +// void setColor(LLColor4 color) { mColor = color; } + // Accessors const LLVector3d& getGlobalPosition() const { return mPosGlobal; } const std::string& getName() const { return mName; } const std::string& getToolTip() const { return mToolTip; } const LLUUID& getUUID() const { return mID; } - U64 getRegionHandle() const { return mRegionHandle; } + S32 getCount() const { return mCount; } + + U64 getRegionHandle() const { return to_region_handle(mPosGlobal); } // Build the handle on the fly + bool isName(const std::string& name) const { return (mName == name); } // True if name same as item's name +// bool isSelected() const { return mSelected; } + private: - std::string mName; - std::string mToolTip; - LLVector3d mPosGlobal; - LLUUID mID; - U64 mRegionHandle; -public: //public for now.. non-standard. - BOOL mSelected; - S32 mExtra; - S32 mExtra2; + std::string mName; // Name of the individual item + std::string mToolTip; // Tooltip : typically, something to be displayed to the user when selecting this item + LLVector3d mPosGlobal; // Global world position + LLUUID mID; // UUID of the item + S32 mCount; // Number of elements in item (e.g. people count) + // Currently not used but might prove useful one day so we comment out +// bool mSelected; // Selected or not: updated by the viewer UI, not the simulator or asset DB +// LLColor4 mColor; // Color of the item }; -#define MAP_SIM_IMAGE_TYPES 3 -// 0 - Prim -// 1 - Terrain Only -// 2 - Overlay: Land For Sale +//Layer types that we intend to support. +enum sim_layer_type +{ + SIM_LAYER_BEGIN, + SIM_LAYER_COMPOSITE=0, //Legacy terrain+prim texture provided in MapBlockReply message. + SIM_LAYER_OVERLAY, //The land-for-sale overlay texture provided in MapBlockReply message. + SIM_LAYER_COUNT +}; +//The MapBlockRequest message 'layerflags' don't match the order of the sim_layer_type, so a few +//simple inline functions have been provided to convert between sim_layer_type and layerflag. +inline U32 layerToFlags(sim_layer_type layer) +{ + static U32 flags[SIM_LAYER_COUNT] = {0,2}; + return flags[layer]; +} +inline U32 flagsToLayer(U32 flags) +{ + //We only want the low two bytes, so mask out the rest. + if((flags & 0xFFFF) == 0) + return SIM_LAYER_COMPOSITE; + else if((flags & 0xFFFF) == 2) + return SIM_LAYER_OVERLAY; + else + return U32_MAX; +} + +// Info per region +// Such records are stored in a global map hold by the LLWorldMap and indexed by region handles. +// To avoid creating too many of them, they are requested in "blocks" corresponding to areas covered by the screen. +// Unfortunately, when the screen covers the whole world (zoomed out), that can translate in requesting info for +// every sim on the grid... Not good... +// To avoid this, the code implements a cut-off threshold for overlay graphics and, therefore, all LLSimInfo. +// In other words, when zooming out too much, we simply stop requesting LLSimInfo and +// LLItemInfo and just display the map tiles. +// As they are stored in different structures (LLSimInfo and LLWorldMipmap), this strategy is now workable. class LLSimInfo { public: @@ -96,17 +137,17 @@ public: LLVector3 getLocalPos(LLVector3d global_pos) const; void clearImage(); // Clears the reference to the Land for sale image for that region - void dropImagePriority(); // Drops the boost level of the Land for sale image for that region - LLPointer getLandForSaleImage(); // Get the overlay image, fetch it if necessary + void dropImagePriority(sim_layer_type layer = SIM_LAYER_COUNT); // Drops the boost level of the Land for sale image for that region void updateAgentCount(F64 time); // Send an item request for agent count on that region if time's up + // Setters void setName(std::string& name) { mName = name; } - void setSize(U16 sizeX, U16 sizeY) { mSizeX = sizeX; mSizeY = sizeY; } - void setAccess (U8 accesscode) { mAccess = accesscode; } + void setAccess (U32 accesscode) { mAccess = accesscode; } void setRegionFlags (U32 region_flags) { mRegionFlags = region_flags; } - void setWaterHeight (F32 water_height) { mWaterHeight = water_height; } + void setSize(U16 sizeX, U16 sizeY) { mSizeX = sizeX; mSizeY = sizeY; } void setAlpha(F32 alpha) { mAlpha = alpha; } + void setLandForSaleImage (LLUUID image_id); void setMapImageID (const LLUUID& id, const U8 &layer) { mMapImageID[layer] = id; } // Accessors @@ -115,43 +156,73 @@ public: const U32 getRegionFlags() const { return mRegionFlags; } const std::string getAccessString() const { return LLViewerRegion::accessToString((U8)mAccess); } const U8 getAccess() const { return mAccess; } + const S32 getAgentCount() const; // Compute the total agents count + LLPointer getLandForSaleImage(); // Get the overlay image, fetch it if necessary - const F32 getWaterHeight() const { return mWaterHeight; } const F32 getAlpha() const { return mAlpha; } - const U64 getHandle() const { return mHandle; } const U16 getSizeX() const { return mSizeX; } const U16 getSizeY() const { return mSizeY; } bool isName(const std::string& name) const; bool isDown() { return (mAccess == SIM_ACCESS_DOWN); } bool isPG() { return (mAccess <= SIM_ACCESS_PG); } bool isAdult() { return (mAccess == SIM_ACCESS_ADULT); } + + // Debug only + void dump() const; // Print the region info to the standard output + + // Items lists handling + typedef std::vector item_info_list_t; + void clearItems(); + + void insertTeleHub(const LLItemInfo& item) { mTelehubs.push_back(item); } + void insertInfoHub(const LLItemInfo& item) { mInfohubs.push_back(item); } + void insertPGEvent(const LLItemInfo& item) { mPGEvents.push_back(item); } + void insertMatureEvent(const LLItemInfo& item) { mMatureEvents.push_back(item); } + void insertAdultEvent(const LLItemInfo& item) { mAdultEvents.push_back(item); } + void insertLandForSale(const LLItemInfo& item) { mLandForSale.push_back(item); } + void insertLandForSaleAdult(const LLItemInfo& item) { mLandForSaleAdult.push_back(item); } + void insertAgentLocation(const LLItemInfo& item); + + const LLSimInfo::item_info_list_t& getTeleHub() const { return mTelehubs; } + const LLSimInfo::item_info_list_t& getInfoHub() const { return mInfohubs; } + const LLSimInfo::item_info_list_t& getPGEvent() const { return mPGEvents; } + const LLSimInfo::item_info_list_t& getMatureEvent() const { return mMatureEvents; } + const LLSimInfo::item_info_list_t& getAdultEvent() const { return mAdultEvents; } + const LLSimInfo::item_info_list_t& getLandForSale() const { return mLandForSale; } + const LLSimInfo::item_info_list_t& getLandForSaleAdult() const { return mLandForSaleAdult; } + const LLSimInfo::item_info_list_t& getAgentLocation() const { return mAgentLocations; } + private: U64 mHandle; std::string mName; F64 mAgentsUpdateTime; // Time stamp giving the last time the agents information was requested for that region bool mFirstAgentRequest; // Init agent request flag - U8 mAccess; + + U32 mAccess; // Down/up and maturity rating of the region U32 mRegionFlags; - F32 mWaterHeight; U16 mSizeX; U16 mSizeY; F32 mAlpha; public: - BOOL mShowAgentLocations; // are agents visible? - - // Image ID for the current overlay mode. - LLUUID mMapImageID[MAP_SIM_IMAGE_TYPES]; - - // Hold a reference to the currently displayed image. - LLPointer mCurrentImage; - LLPointer mOverlayImage; + // Handling the "land for sale / land for auction" overlay image + LLUUID mMapImageID[SIM_LAYER_COUNT]; // Image ID of the overlay image + LLPointer mLayerImage[SIM_LAYER_COUNT]; + + // Items for this region + // Those are data received through item requests (as opposed to block requests for the rest of the data) + item_info_list_t mTelehubs; // List of tele hubs in the region + item_info_list_t mInfohubs; // List of info hubs in the region + item_info_list_t mPGEvents; // List of PG events in the region + item_info_list_t mMatureEvents; // List of Mature events in the region + item_info_list_t mAdultEvents; // List of Adult events in the region (AO) + item_info_list_t mLandForSale; // List of Land for sales in the region + item_info_list_t mLandForSaleAdult; // List of Adult Land for sales in the region (AO) + item_info_list_t mAgentLocations; // List of agents in the region }; -#define MAP_BLOCK_RES 256 - struct LLWorldMapLayer { BOOL LayerDefined; @@ -162,6 +233,11 @@ struct LLWorldMapLayer LLWorldMapLayer() : LayerDefined(FALSE) { } }; +// We request region data on the world by "blocks" of (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) regions +// This is to reduce the number of requests to the asset DB and get things in big "blocks" +const S32 MAP_MAX_SIZE = 2048; +const S32 MAP_BLOCK_SIZE = 4; +const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE); class LLWorldMap : public LLSingleton { @@ -175,135 +251,103 @@ public: // clears the list void reset(); - // clear the visible items - void eraseItems(); - - // Removes references to cached images - void clearImageRefs(); - - // Clears the flags indicating that we've received sim infos - // Causes a re-request of the sim info without erasing extisting info - void clearSimFlags(); - - // Drops the priority of the images being fetched - void dropImagePriorities(); + void clearImageRefs(); // Clears the image references + void dropImagePriorities(); // Drops the priority of the images being fetched + void reloadItems(bool force = false); // Reload the items (people, hub, etc...) // Region Map access typedef std::map sim_info_map_t; const LLWorldMap::sim_info_map_t& getRegionMap() const { return mSimInfoMap; } - // Returns simulator information, or NULL if out of range + void updateRegions(S32 x0, S32 y0, S32 x1, S32 y1); // Requests region info for a rectangle of regions (in grid coordinates) + + // Insert a region and items in the map global instance + // Note: x_world and y_world in world coordinates (meters) + static bool insertRegion(U32 x_world, U32 y_world, U32 x_size, U32 y_size, U32 agent_flags, std::string& name, LLUUID& image_id, U32 accesscode, U32 region_flags); + static bool insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID& uuid, U32 type, S32 extra, S32 extra2); + + // Get info on sims (region) : note that those methods only search the range of loaded sims (the one that are being browsed) + // *not* the entire world. So a NULL return does not mean a down or unexisting region, just an out of range region. LLSimInfo* simInfoFromHandle(const U64 handle); - - // Returns simulator information, or NULL if out of range LLSimInfo* simInfoFromPosGlobal(const LLVector3d& pos_global); - - // Returns simulator information for named sim, or NULL if non-existent LLSimInfo* simInfoFromName(const std::string& sim_name); // Gets simulator name for a global position, returns true if it was found bool simNameFromPosGlobal(const LLVector3d& pos_global, std::string& outSimName ); - - // Sets the current layer - void setCurrentLayer(S32 layer, bool request_layer = false); - - void sendMapLayerRequest(); - void sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent = false); - void sendNamedRegionRequest(std::string region_name); - void sendNamedRegionRequest(std::string region_name, - url_callback_t callback, - const std::string& callback_url, - bool teleport); - void sendHandleRegionRequest(U64 region_handle, - url_callback_t callback, - const std::string& callback_url, - bool teleport); - void sendItemRequest(U32 type, U64 handle = 0); - - static void processMapLayerReply(LLMessageSystem*, void**); - static void processMapBlockReply(LLMessageSystem*, void**); - static void processMapItemReply(LLMessageSystem*, void**); - + static void gotMapServerURL(bool flag) { sGotMapURL = flag; } static bool useWebMapTiles(); - static LLPointer loadObjectsTile(U32 grid_x, U32 grid_y); void dump(); - // Extend the bounding box of the list of simulators. Returns true - // if the extents changed. - BOOL extendAABB(U32 x_min, U32 y_min, U32 x_max, U32 y_max); + // Track handling + void cancelTracking() { mIsTrackingLocation = false; mIsTrackingFound = false; mIsInvalidLocation = false; mIsTrackingDoubleClick = false; mIsTrackingCommit = false; } - // build coverage maps for telehub region visualization - void updateTelehubCoverage(); - BOOL coveredByTelehub(LLSimInfo* infop); + void setTracking(const LLVector3d& loc) { mIsTrackingLocation = true; mTrackingLocation = loc; mIsTrackingFound = false; mIsInvalidLocation = false; mIsTrackingDoubleClick = false; mIsTrackingCommit = false;} + void setTrackingInvalid() { mIsTrackingFound = true; mIsInvalidLocation = true; } + void setTrackingValid() { mIsTrackingFound = true; mIsInvalidLocation = false; } + void setTrackingDoubleClick() { mIsTrackingDoubleClick = true; } + void setTrackingCommit() { mIsTrackingCommit = true; } + + bool isTracking() { return mIsTrackingLocation; } + bool isTrackingValidLocation() { return mIsTrackingFound && !mIsInvalidLocation; } + bool isTrackingInvalidLocation() { return mIsTrackingFound && mIsInvalidLocation; } + bool isTrackingDoubleClick() { return mIsTrackingDoubleClick; } + bool isTrackingCommit() { return mIsTrackingCommit; } + bool isTrackingInRectangle(F64 x0, F64 y0, F64 x1, F64 y1); + + LLVector3d getTrackedPositionGlobal() const { return mTrackingLocation; } + + std::vector::iterator getMapLayerBegin() { return mMapLayers.begin(); } + std::vector::iterator getMapLayerEnd() { return mMapLayers.end(); } + std::map >::const_iterator findMapBlock(U32 layer, U32 x, U32 y) const + { return LLWorldMap::instance().mMapBlockMap[layer].find((x<<16)|y); } + std::map >::const_iterator getMapBlockEnd(U32 layer) const + { return LLWorldMap::instance().mMapBlockMap[layer].end(); } - // Bounds of the world, in meters - U32 getWorldWidth() const; - U32 getWorldHeight() const; - // World Mipmap delegation: currently used when drawing the mipmap void equalizeBoostLevels(); LLPointer getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load = true) { return mWorldMipmap.getObjectsTile(grid_x, grid_y, level, load); } + static void processMapLayerReply(LLMessageSystem*, void**); private: bool clearItems(bool force = false); // Clears the item lists + void clearSimFlags(); // Clears the block flags indicating that we've already requested region infos // Create a region record corresponding to the handle, insert it in the region map and returns a pointer LLSimInfo* createSimInfoFromHandle(const U64 handle); - + // Map from region-handle to simulator info sim_info_map_t mSimInfoMap; -public: + // Request legacy background layers. + void sendMapLayerRequest(); - BOOL mIsTrackingUnknownLocation, mInvalidLocation, mIsTrackingDoubleClick, mIsTrackingCommit; - LLVector3d mUnknownLocation; - - bool mRequestLandForSale; - - typedef std::vector item_info_list_t; - item_info_list_t mTelehubs; - item_info_list_t mInfohubs; - item_info_list_t mPGEvents; - item_info_list_t mMatureEvents; - item_info_list_t mAdultEvents; - item_info_list_t mLandForSale; - item_info_list_t mLandForSaleAdult; - - std::map mNumAgents; - - typedef std::map agent_list_map_t; - agent_list_map_t mAgentLocationsMap; - - std::vector mMapLayers[MAP_SIM_IMAGE_TYPES]; - BOOL mMapLoaded[MAP_SIM_IMAGE_TYPES]; - BOOL * mMapBlockLoaded[MAP_SIM_IMAGE_TYPES]; - S32 mCurrentMap; - - // AABB of the list of simulators - U32 mMinX; - U32 mMaxX; - U32 mMinY; - U32 mMaxY; - - U8* mNeighborMap; - U8* mTelehubCoverageMap; - S32 mNeighborMapWidth; - S32 mNeighborMapHeight; + std::vector mMapLayers; + bool mMapLoaded; private: LLWorldMipmap mWorldMipmap; + // The World is divided in "blocks" of (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) regions that get requested at once. + // This boolean table avoids "blocks" to be requested multiple times. + // Issue: Not sure this scheme is foolproof though as I've seen + // cases where a block is never retrieved and, because of this boolean being set, never re-requested + //bool * mMapBlockLoaded[MAP_SIM_IMAGE_TYPES]; // Telling us if the block of regions has been requested or not + std::map > mMapBlockMap[SIM_LAYER_COUNT]; + + // Track location data : used while there's nothing tracked yet by LLTracker + bool mIsTrackingLocation; // True when we're tracking a point + bool mIsTrackingFound; // True when the tracking position has been found, valid or not + bool mIsInvalidLocation; // The region is down or the location does not correspond to an existing region + bool mIsTrackingDoubleClick; // User double clicked to set the location (i.e. teleport when found please...) + bool mIsTrackingCommit; // User used the search or landmark fields to set the location + LLVector3d mTrackingLocation; // World global position being tracked + + // General grid items request timing flags (used for events,hubs and land for sale) LLTimer mRequestTimer; - - // search for named region for url processing - std::string mSLURLRegionName; - U64 mSLURLRegionHandle; - std::string mSLURL; - url_callback_t mSLURLCallback; - bool mSLURLTeleport; - + bool mFirstRequest; + static bool sGotMapURL; }; diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp new file mode 100644 index 000000000..b25a3db75 --- /dev/null +++ b/indra/newview/llworldmapmessage.cpp @@ -0,0 +1,301 @@ +/** + * @file llworldmapmessage.cpp + * @brief Handling of the messages to the DB made by and for the world map. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llworldmapmessage.h" +#include "message.h" + +#include "llworldmap.h" +#include "llagent.h" +#include "llfloaterworldmap.h" + +const U32 LAYER_FLAG = 2; + +//--------------------------------------------------------------------------- +// World Map Message Handling +//--------------------------------------------------------------------------- + +LLWorldMapMessage::LLWorldMapMessage() : + mSLURLRegionName(), + mSLURLRegionHandle(0), + mSLURL(), + mSLURLCallback(0), + mSLURLTeleport(false) +{ +} + +LLWorldMapMessage::~LLWorldMapMessage() +{ +} + +void LLWorldMapMessage::sendItemRequest(U32 type, U64 handle) +{ + //LL_INFOS("World Map") << "Send item request : type = " << type << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_MapItemRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, LAYER_FLAG); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + + msg->nextBlockFast(_PREHASH_RequestData); + msg->addU32Fast(_PREHASH_ItemType, type); + msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim + + gAgent.sendReliableMessage(); +} + +void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name) +{ + //LL_INFOS("World Map") << "LLWorldMap::sendNamedRegionRequest()" << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + + // Request for layer + msg->newMessageFast(_PREHASH_MapNameRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, LAYER_FLAG); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_NameData); + msg->addStringFast(_PREHASH_Name, region_name); + gAgent.sendReliableMessage(); +} + +void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name, + url_callback_t callback, + const std::string& callback_url, + bool teleport) // immediately teleport when result returned +{ + //LL_INFOS("World Map") << "LLWorldMap::sendNamedRegionRequest()" << LL_ENDL; + mSLURLRegionName = region_name; + mSLURLRegionHandle = 0; + mSLURL = callback_url; + mSLURLCallback = callback; + mSLURLTeleport = teleport; + + sendNamedRegionRequest(region_name); +} + +void LLWorldMapMessage::sendHandleRegionRequest(U64 region_handle, + url_callback_t callback, + const std::string& callback_url, + bool teleport) // immediately teleport when result returned +{ + //LL_INFOS("World Map") << "LLWorldMap::sendHandleRegionRequest()" << LL_ENDL; + mSLURLRegionName.clear(); + mSLURLRegionHandle = region_handle; + mSLURL = callback_url; + mSLURLCallback = callback; + mSLURLTeleport = teleport; + + U32 global_x; + U32 global_y; + from_region_handle(region_handle, &global_x, &global_y); + U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); + U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); + + sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true, LAYER_FLAG); +} + +// public +void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent, S32 layer) +{ + //LL_INFOS("World Map") << "LLWorldMap::sendMapBlockRequest()" << ", min = (" << min_x << ", " << min_y << "), max = (" << max_x << ", " << max_y << "), nonexistent = " << return_nonexistent << LL_ENDL; + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MapBlockRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + U32 flags = layer; + flags |= (return_nonexistent ? 0x10000 : 0); + msg->addU32Fast(_PREHASH_Flags, flags); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_PositionData); + msg->addU16Fast(_PREHASH_MinX, min_x); + msg->addU16Fast(_PREHASH_MinY, min_y); + msg->addU16Fast(_PREHASH_MaxX, max_x); + msg->addU16Fast(_PREHASH_MaxY, max_y); + gAgent.sendReliableMessage(); +} + +// public static +void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**) +{ + U32 agent_flags; + msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); + + U32 layer = flagsToLayer(agent_flags); + if (layer >= SIM_LAYER_COUNT) + { + llwarns << "Invalid map image type returned! layer = " << agent_flags << llendl; + return; + } + + S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data); + //LL_INFOS("World Map") << "LLWorldMap::processMapBlockReply(), num_blocks = " << num_blocks << LL_ENDL; + + bool found_null_sim = false; + + for (S32 block=0; blockgetU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block); + msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block); + msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); + msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block); + msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block); +// msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block); +// msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block); + msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block); + if(msg->getNumberOfBlocksFast(_PREHASH_Size) > 0) + { + msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block); + msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block); + } + if(x_size == 0 || (x_size % 16) != 0|| (y_size % 16) != 0) + { + x_size = 256; + y_size = 256; + } + + U32 x_world = (U32)(x_regions) * REGION_WIDTH_UNITS; + U32 y_world = (U32)(y_regions) * REGION_WIDTH_UNITS; + + // name shouldn't be empty, see EXT-4568 + //llassert(!name.empty()); + + //Opensim bug. BlockRequest can return sims without names, with an accesscode that isn't 255. + // skip if this has happened. + if(name.empty() && accesscode != 255) + continue; + + // Insert that region in the world map, if failure, flag it as a "null_sim" + if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, x_size, y_size, agent_flags, name, image_id, (U32)accesscode, region_flags))) + { + found_null_sim = true; + } + + // If we hit a valid tracking location, do what needs to be done app level wise + if (LLWorldMap::getInstance()->isTrackingValidLocation()) + { + LLVector3d pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal(); + if (LLWorldMap::getInstance()->isTrackingDoubleClick()) + { + // Teleport if the user double clicked + gAgent.teleportViaLocation(pos_global); + } + // Update the "real" tracker information + gFloaterWorldMap->trackLocation(pos_global); + } + + // Handle the SLURL callback if any + url_callback_t callback = LLWorldMapMessage::getInstance()->mSLURLCallback; + if(callback != NULL) + { + U64 handle = to_region_handle(x_world, y_world); + // Check if we reached the requested region + if ((LLStringUtil::compareInsensitive(LLWorldMapMessage::getInstance()->mSLURLRegionName, name)==0) + || (LLWorldMapMessage::getInstance()->mSLURLRegionHandle == handle)) + { + LLWorldMapMessage::getInstance()->mSLURLCallback = NULL; + LLWorldMapMessage::getInstance()->mSLURLRegionName.clear(); + LLWorldMapMessage::getInstance()->mSLURLRegionHandle = 0; + + callback(handle, LLWorldMapMessage::getInstance()->mSLURL, image_id, LLWorldMapMessage::getInstance()->mSLURLTeleport); + } + } + if( gAgent.mPendingLure && + (U16)(gAgent.mPendingLure->mPosGlobal.mdV[0] / REGION_WIDTH_UNITS) == x_regions && + (U16)(gAgent.mPendingLure->mPosGlobal.mdV[1] / REGION_WIDTH_UNITS) == y_regions ) + { + gAgent.onFoundLureDestination(); + } + } + // Tell the UI to update itself + gFloaterWorldMap->updateSims(found_null_sim); +} + +// public static +void LLWorldMapMessage::processMapItemReply(LLMessageSystem* msg, void**) +{ + //LL_INFOS("World Map") << "LLWorldMap::processMapItemReply()" << LL_ENDL; + U32 type; + msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type); + + S32 num_blocks = msg->getNumberOfBlocks("Data"); + + for (S32 block=0; blockgetU32Fast(_PREHASH_Data, _PREHASH_X, X, block); + msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block); + msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block); + msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block); + msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block); + msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block); + + LLWorldMap::getInstance()->insertItem(X, Y, name, uuid, type, extra, extra2); + } +} +void LLWorldMapMessage::handleSLURL(std::string& name, U32 x_world, U32 y_world, LLUUID image_id) +{ + // Handle the SLURL callback if any + url_callback_t callback = LLWorldMapMessage::getInstance()->mSLURLCallback; + if(callback != NULL) + { + U64 handle = to_region_handle(x_world, y_world); + // Check if we reached the requested region + if ((LLStringUtil::compareInsensitive(LLWorldMapMessage::getInstance()->mSLURLRegionName, name)==0) + || (LLWorldMapMessage::getInstance()->mSLURLRegionHandle == handle)) + { + LLWorldMapMessage::getInstance()->mSLURLCallback = NULL; + LLWorldMapMessage::getInstance()->mSLURLRegionName.clear(); + LLWorldMapMessage::getInstance()->mSLURLRegionHandle = 0; + + callback(handle, LLWorldMapMessage::getInstance()->mSLURL, image_id, LLWorldMapMessage::getInstance()->mSLURLTeleport); + } + } +} + diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h new file mode 100644 index 000000000..bd4bd7545 --- /dev/null +++ b/indra/newview/llworldmapmessage.h @@ -0,0 +1,79 @@ +/** + * @file llworldmapmessage.h + * @brief Handling of the messages to the DB made by and for the world map. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWORLDMAPMESSAGE_H +#define LL_LLWORLDMAPMESSAGE_H + +// Handling of messages (send and process) as well as SLURL callback if necessary +class LLMessageSystem; + +class LLWorldMapMessage : public LLSingleton +{ +public: + typedef boost::function + url_callback_t; + + LLWorldMapMessage(); + ~LLWorldMapMessage(); + + // Process incoming answers to map stuff requests + static void processMapBlockReply(LLMessageSystem*, void**); + static void processMapItemReply(LLMessageSystem*, void**); + + // Request data for all regions in a rectangular area. Coordinates in grids (i.e. meters / 256). + void sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent, S32 layer = 2); + + // Various methods to request LLSimInfo data to the simulator and asset DB + void sendNamedRegionRequest(std::string region_name); + void sendNamedRegionRequest(std::string region_name, + url_callback_t callback, + const std::string& callback_url, + bool teleport); + void sendHandleRegionRequest(U64 region_handle, + url_callback_t callback, + const std::string& callback_url, + bool teleport); + + // Request item data for regions + // Note: the handle works *only* when requesting agent count (type = MAP_ITEM_AGENT_LOCATIONS). In that case, + // the request will actually be transitting through the spaceserver (all that is done on the sim). + // All other values of type do create a global grid request to the asset DB. So no need to try to get, say, + // the events for one particular region. For such a request, the handle is ignored. + void sendItemRequest(U32 type, U64 handle = 0); + + void handleSLURL(std::string& name, U32 x_world, U32 y_world, LLUUID image_id); + +private: + // Search for region (by name or handle) for SLURL processing and teleport + // None of this relies explicitly on the LLWorldMap instance so better handle it here + std::string mSLURLRegionName; + U64 mSLURLRegionHandle; + std::string mSLURL; + url_callback_t mSLURLCallback; + bool mSLURLTeleport; +}; + +#endif // LL_LLWORLDMAPMESSAGE_H diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index bdd3b6054..038b4ae33 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -109,8 +109,6 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL; -F32 LLWorldMapView::sThresholdA = 48.f; -F32 LLWorldMapView::sThresholdB = 96.f; F32 LLWorldMapView::sPanX = 0.f; F32 LLWorldMapView::sPanY = 0.f; F32 LLWorldMapView::sTargetPanX = 0.f; @@ -124,11 +122,18 @@ F32 CONE_SIZE = 0.6f; std::map LLWorldMapView::sStringsMap; -const int SIM_NULL_MAP_SCALE=4; // width in pixels, where we start drawing "null" sims +F32 DRAW_TEXT_THRESHOLD = 96.f; + const int SIM_MAP_AGENT_SCALE=8; // width in pixels, where we start drawing agents -const int SIM_MAP_SCALE=4; // width in pixels, where we start drawing sim tiles +const int SIM_DATA_SCALE=12; // width in pixels where we start requesting sim info const int SIM_LANDFORSALE_SCALE=32; +const int SIM_COMPOSITE_SCALE=2; // width in pixels, where we start drawing sim tiles. (legacy tiling method) +const int SIM_FETCH_SCALE=SIM_DATA_SCALE; // width in pixels, where we start requesting sim tile textures. (legacy tiling method) + +// When on, draw an outline for each mipmap tile gotten from S3 +#define DEBUG_DRAW_TILE 0 + void LLWorldMapView::initClass() { @@ -241,6 +246,7 @@ LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect ) LLWorldMapView::~LLWorldMapView() { + //LL_INFOS("World Map") << "Destroying the map -> LLWorldMapView::~LLWorldMapView()" << LL_ENDL; cleanupTextures(); } @@ -254,6 +260,10 @@ void LLWorldMapView::cleanupTextures() // static void LLWorldMapView::setScale( F32 scale ) { + if(!LLWorldMap::useWebMapTiles()) //adjust the scale range if drawing legacy tiles to avoid drawing a bajillion 1x1 tiles. + { + scale = SIM_COMPOSITE_SCALE + scale*((256.f-SIM_COMPOSITE_SCALE)/256.f); + } if (scale != sMapScale) { F32 old_scale = sMapScale; @@ -306,7 +316,7 @@ void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) BOOL is_agent_in_region(LLViewerRegion* region, LLSimInfo* info) { - return ((region && info) && (info->isName(region->getName()))); + return (region && info && info->isName(region->getName())); } @@ -348,15 +358,25 @@ void LLWorldMapView::draw() gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); - if(gHippoGridManager->getConnectedGrid()->isSecondLife()) + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + if(LLWorldMap::useWebMapTiles()) drawMipmap(width, height); else - drawTiles(width, height); - LLFontGL* font = LLFontGL::getFontSansSerifSmall(); + drawLegacyBackgroundLayers(width, height); - - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gGL.setColorMask(true, true); + //Singu Note: This is done before drawing the transparent offline overlay. drawMipmap doesn't actually + // fill every possible block on the minimap. Every space must be filled for the offline overlay to look correct. + // Draw background rectangle + LLGLSUIDefault gls_ui; + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); + gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA); + gGL.color4fv( mBackgroundColor.mV ); + gl_rect_2d(0, height, width, 0); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + } // Draw the region name in the lower left corner for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); @@ -364,7 +384,7 @@ void LLWorldMapView::draw() { U64 handle = it->first; LLSimInfo* info = it->second; - + LLVector3d origin_global = from_region_handle(handle); // Find x and y position relative to camera's center. @@ -376,27 +396,104 @@ void LLWorldMapView::draw() // When the view isn't panned, 0,0 = center of rectangle F32 bottom = sPanY + half_height + relative_y; F32 left = sPanX + half_width + relative_x; - //F32 top = bottom + sMapScale ; - //F32 right = left + sMapScale ; + F32 top = bottom + sMapScale * ((F32)info->getSizeY() / REGION_WIDTH_METERS); + F32 right = left + sMapScale * ((F32)info->getSizeX() / REGION_WIDTH_METERS); + + // Discard if region is outside the screen rectangle (not visible on screen) + if ((top < 0.f) || (bottom > height) || + (right < 0.f) || (left > width) ) + { + // Drop the "land for sale" fetching priority since it's outside the view rectangle + info->dropImagePriority(); + continue; + } + + // This list is used by other methods to know which regions are indeed displayed on screen + + mVisibleRegions.push_back(handle); - info->mShowAgentLocations = (sMapScale >= SIM_MAP_AGENT_SCALE); - mVisibleRegions.push_back(handle); // Update the agent count for that region if we're not too zoomed out already if (sMapScale >= SIM_MAP_AGENT_SCALE) { info->updateAgentCount(current_time); } - std::string mesg; - if (sMapScale < sThresholdA) + F32 alpha = !LLWorldMap::useWebMapTiles() ? drawLegacySimTile(*info,left,top,right,bottom) : 1.f; + + if (info->isDown()) { + // Draw a transparent red square over down sims + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); + gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.begin(LLRender::QUADS); + gGL.vertex2f(left, top); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + gGL.vertex2f(right, top); + gGL.end(); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); } - else if (sMapScale < sThresholdB) + // As part of the AO project, we no longer want to draw access indicators; + // it's too complicated to get all the rules straight and will only + // cause confusion. + /********************** + else if (!info->isPG() && gAgent.isTeen()) { - // mesg = llformat( info->mAgents); + // If this is a mature region, and you are not, draw a line across it + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.color3f(1.f, 0.f, 0.f); + gGL.begin(LLRender::LINES); + gGL.vertex2f(left, top); + gGL.vertex2f(right, bottom); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, top); + gGL.end(); + } + **********************/ + else if (map_show_land_for_sale && (sMapScale >= SIM_LANDFORSALE_SCALE)) + { + // Draw the overlay image "Land for Sale / Land for Auction" + LLViewerFetchedTexture* overlayimage = info->getLandForSaleImage(); + if (overlayimage) + { + // Inform the fetch mechanism of the size we need + S32 draw_size = llround(sMapScale); + overlayimage->setKnownDrawSize( llround(draw_size * LLUI::sGLScaleFactor.mV[VX] * ((F32)info->getSizeX() / REGION_WIDTH_METERS)), + llround(draw_size * LLUI::sGLScaleFactor.mV[VY] * ((F32)info->getSizeY() / REGION_WIDTH_METERS))); + // Draw something whenever we have enough info + if (overlayimage->hasGLTexture() && !overlayimage->isMissingAsset() && overlayimage->getID() != IMG_DEFAULT) + { + gGL.getTexUnit(0)->bind(overlayimage); + gGL.color4f(1.f, 1.f, 1.f, alpha); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3f(left, top, -0.5f); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3f(left, bottom, -0.5f); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3f(right, bottom, -0.5f); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3f(right, top, -0.5f); + gGL.end(); + } + } } else { + // If we're not displaying the "land for sale", drop fetching priority of both. + info->dropImagePriority(SIM_LAYER_OVERLAY); + } + + // Draw the region name in the lower left corner + if (sMapScale >= DRAW_TEXT_THRESHOLD) + { + LLFontGL* font = LLFontGL::getFontSansSerifSmall(); + std::string mesg; + //mesg = llformat("%d / %s (%s)", // info->mAgents, // info->mName.c_str(), @@ -404,14 +501,18 @@ void LLWorldMapView::draw() // [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) { - mesg = RlvStrings::getString(RLV_STRING_HIDDEN); + if(!info->getName().empty()) + mesg = RlvStrings::getString(RLV_STRING_HIDDEN); } // [/RLVa:KB] else if (info->isDown()) { - mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str()); + if(info->getName().empty()) + mesg = llformat( "(%s)", sStringsMap["offline"].c_str()); + else + mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str()); } - else + else if(!info->getName().empty()) // Online sims should have names... { mesg = info->getName(); U8 access = info->getAccess(); @@ -434,91 +535,151 @@ void LLWorldMapView::draw() break; } } - } - - if (!mesg.empty()) - { - font->renderUTF8( - mesg, 0, - llfloor(left + 3), - llfloor(bottom + 2), - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); - - // If map texture is still loading, - // display "Loading" placeholder text. - /*if ((simimage != NULL) && - simimage->getDiscardLevel() != 1 && - simimage->getDiscardLevel() != 0) + if (!mesg.empty()) { font->renderUTF8( - sStringsMap["loading"], 0, - llfloor(left + 18), - llfloor(top - 25), - LLColor4::white, - LLFontGL::LEFT, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); - }*/ + mesg, 0, + llfloor(left + 3), llfloor(bottom + 2), + LLColor4::white, + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); + } } + } - } - - - // Draw background rectangle - LLGLSUIDefault gls_ui; + static const LLCachedControl map_show_requests("MapShowRequests", false); + if(map_show_requests) { + const F32 map_to_pixels = MAP_MAX_SIZE*sMapScale; + const F32 block_to_pixels = MAP_BLOCK_SIZE*sMapScale; + const F32 padding = .25f*sMapScale; + + //In sim coords. + const F32 centerX = -sPanX/sMapScale + camera_global.mdV[VX]/REGION_WIDTH_METERS; + const F32 centerY = -sPanY/sMapScale + camera_global.mdV[VY]/REGION_WIDTH_METERS; + const F32 bottom = centerY - half_height/sMapScale ; + const F32 left = centerX - half_width/sMapScale ; + const F32 top = centerY + half_height/sMapScale ; + const F32 right = centerX + half_width/sMapScale ; + + const U32 max_range = (U16_MAX+1)/MAP_BLOCK_RES/MAP_BLOCK_SIZE - 1; + const U32 map_block_x0 = (U32)(llmax(left,0.f) / MAP_MAX_SIZE); + const U32 map_block_x1 = llclamp(U32(right / MAP_MAX_SIZE), U32(0), max_range); + const U32 map_block_y0 = (U32)(llmax(bottom,0.f) / MAP_MAX_SIZE); + const U32 map_block_y1 = llclamp(U32(top / MAP_MAX_SIZE), U32(0), max_range); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); - gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA); - gGL.color4fv( mBackgroundColor.mV ); - gl_rect_2d(0, height, width, 0); + + for(U32 i = map_block_x0; i <= map_block_x1; ++i) + { + const F32 base_left = i*map_to_pixels-left*sMapScale; + const F32 base_right = base_left + map_to_pixels; + if( base_right <= 0.f) + continue; + if( base_left >= width) + break; + for (U32 j = map_block_y0; j <= map_block_y1; ++j) + { + const F32 base_bottom = j*map_to_pixels-bottom*sMapScale; + const F32 base_top = base_bottom + map_to_pixels; + if( base_top <= 0.f) + continue; + if( base_bottom >= height) + break; + + std::map >::const_iterator it = LLWorldMap::getInstance()->findMapBlock(SIM_LAYER_OVERLAY,i,j); + + if(it != LLWorldMap::getInstance()->getMapBlockEnd(SIM_LAYER_OVERLAY)) + gGL.color4f(0.5f, 0.0f, 0.0f, 0.4f); + else + gGL.color4f(0.2f, .2f, 0.2f, 0.4f); + gGL.begin(LLRender::QUADS); + gGL.vertex2f(base_left+padding, base_top-padding); + gGL.vertex2f(base_left+padding, base_bottom+padding); + gGL.vertex2f(base_right-padding, base_bottom+padding); + gGL.vertex2f(base_right-padding, base_top-padding); + gGL.end(); + if(it != LLWorldMap::getInstance()->getMapBlockEnd(SIM_LAYER_OVERLAY)) + { + for(U32 x=0;x= width) + break; + for(U32 y=0;y= height) + break; + if(it->second[x | (y * MAP_BLOCK_RES)]) + gGL.color4f(0.0f, 0.5f, 0.0f, 0.4f); + else + gGL.color4f(0.4f, 0.0f, 0.0f, 0.4f); + gGL.begin(LLRender::QUADS); + gGL.vertex2f(block_left+padding, block_top-padding); + gGL.vertex2f(block_left+padding, block_bottom+padding); + gGL.vertex2f(block_right-padding, block_bottom+padding); + gGL.vertex2f(block_right-padding, block_top-padding); + gGL.end(); + + for(U32 sim_x=0;sim_x map_show_infohubs("MapShowInfohubs"); - if (map_show_infohubs) //(sMapScale >= sThresholdB) - { - drawGenericItems(LLWorldMap::getInstance()->mInfohubs, sInfohubImage); - } - - // Telehubs static const LLCachedControl map_show_telehubs("MapShowTelehubs"); - if (map_show_telehubs) //(sMapScale >= sThresholdB) + static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); + static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); + if(sMapScale >= DRAW_TEXT_THRESHOLD && (map_show_infohubs || + map_show_telehubs || + map_show_land_for_sale || + map_show_mature_events || + map_show_adult_events)) { - drawGenericItems(LLWorldMap::getInstance()->mTelehubs, sTelehubImage); + drawItems(); } - // Home Sweet Home + // Draw the Home location (always) LLVector3d home; if (gAgent.getHomePosGlobal(&home)) { drawImage(home, sHomeImage); } - static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); - if (map_show_land_for_sale) - { - drawGenericItems(LLWorldMap::getInstance()->mLandForSale, sForSaleImage); - // for 1.23, we're showing normal land and adult land in the same UI; you don't - // get a choice about which ones you want. If you're currently asking for adult - // content and land you'll get the adult land. - if (gAgent.canAccessAdult()) - { - drawGenericItems(LLWorldMap::getInstance()->mLandForSaleAdult, sForSaleAdultImage); - } - } - - drawEvents(); - - // Now draw your avatar after all that other stuff. + // Draw the current agent after all that other stuff. LLVector3d pos_global = gAgent.getPositionGlobal(); drawImage(pos_global, sAvatarYouImage); @@ -539,7 +700,7 @@ void LLWorldMapView::draw() // Draw icons for the avatars in each region. // Drawn after your avatar so you can see nearby people. static const LLCachedControl map_show_people("MapShowPeople"); - if (map_show_people) + if (map_show_people && sMapScale >= SIM_MAP_AGENT_SCALE) { drawAgents(); } @@ -561,23 +722,33 @@ void LLWorldMapView::draw() drawTracking( pos_global, gTrackColor, TRUE, LLTracker::getLabel(), LLTracker::getToolTip() ); } } - else if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation) + else if (LLWorldMap::getInstance()->isTracking()) { - if (LLWorldMap::getInstance()->mInvalidLocation) + if (LLWorldMap::getInstance()->isTrackingInvalidLocation()) { - // We know this location to be invalid + // We know this location to be invalid, draw a blue circle LLColor4 loading_color(0.0, 0.5, 1.0, 1.0); - drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Invalid Location", ""); + drawTracking( LLWorldMap::getInstance()->getTrackedPositionGlobal(), loading_color, TRUE, LLTrans::getString("InvalidLocation"), ""); } else { + // We don't know yet what that location is, draw a throbing blue circle double value = fmod(current_time, 2); - value = 0.5 + 0.5*cos(value * 3.14159f); + value = 0.5 + 0.5*cos(value * F_PI); LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0); - drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Loading...", ""); + drawTracking( LLWorldMap::getInstance()->getTrackedPositionGlobal(), loading_color, TRUE, LLTrans::getString("LoadingData"), ""); } } // #endif used to be here + + //Provide some feedback, because nothing will load if zoomed far out on the map when using legacy sim drawing. + if(!LLWorldMap::useWebMapTiles() && (sMapScale < SIM_FETCH_SCALE || sMapScale < SIM_DATA_SCALE)) + { + LLFontGL::getFontSansSerifSmall()->renderUTF8("(Zoom to resume loading)", 0, + width-2, LLFontGL::getFontSansSerifSmall()->getLineHeight()*1.5f, + LLColor4::white, + LLFontGL::RIGHT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); + } // turn off the scissor LLGLDisable no_scissor(GL_SCISSOR_TEST); @@ -598,63 +769,50 @@ void LLWorldMapView::setVisible(BOOL visible) LLPanel::setVisible(visible); if (!visible) { - for (S32 map = 0; map < MAP_SIM_IMAGE_TYPES; map++) - { - for (U32 layer_idx=0; layer_idxmMapLayers[map].size(); ++layer_idx) - { - if (LLWorldMap::getInstance()->mMapLayers[map][layer_idx].LayerDefined) - { - LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[map][layer_idx]; - layer->LayerImage->setBoostLevel(0); - } - } - } - for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); - it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) + std::vector::iterator begin = LLWorldMap::getInstance()->getMapLayerBegin(); + std::vector::iterator end = LLWorldMap::getInstance()->getMapLayerEnd(); + for(std::vector::iterator it = begin; it != end; ++it) { - LLSimInfo* info = (*it).second; - if (info->mCurrentImage.notNull()) + if (it->LayerDefined) { - info->mCurrentImage->setBoostLevel(0); - } - if (info->mOverlayImage.notNull()) - { - info->mOverlayImage->setBoostLevel(0); + it->LayerImage->setBoostLevel(0); } } + // Drop the download of tiles and images priority to nil if we hide the map + LLWorldMap::getInstance()->dropImagePriorities(); } } -void LLWorldMapView::drawTiles(S32 width, S32 height) { +void LLWorldMapView::drawLegacyBackgroundLayers(S32 width, S32 height) { const F32 half_width = F32(width) / 2.0f; const F32 half_height = F32(height) / 2.0f; - F32 layer_alpha = 1.f; LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - // Draw one image per layer - for (U32 layer_idx=0; layer_idxmMapLayers[LLWorldMap::getInstance()->mCurrentMap].size(); ++layer_idx) + std::vector::const_iterator begin = LLWorldMap::getInstance()->getMapLayerBegin(); + std::vector::const_iterator end = LLWorldMap::getInstance()->getMapLayerEnd(); + for (std::vector::const_iterator it = begin; it != end; ++it) { - if (!LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx].LayerDefined) + if (!it->LayerDefined) { continue; } - LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx]; - LLViewerTexture *current_image = layer->LayerImage; + const LLWorldMapLayer& layer = *it; + LLViewerTexture *current_image = layer.LayerImage; - if (current_image->isMissingAsset()) + if (!current_image || current_image->isMissingAsset() || current_image->getID() == IMG_DEFAULT) { continue; // better to draw nothing than the missing asset image } - LLVector3d origin_global((F64)layer->LayerExtents.mLeft * REGION_WIDTH_METERS, (F64)layer->LayerExtents.mBottom * REGION_WIDTH_METERS, 0.f); + LLVector3d origin_global((F64)layer.LayerExtents.mLeft * REGION_WIDTH_METERS, (F64)layer.LayerExtents.mBottom * REGION_WIDTH_METERS, 0.f); // Find x and y position relative to camera's center. LLVector3d rel_region_pos = origin_global - camera_global; F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - F32 pix_width = sMapScale*(layer->LayerExtents.getWidth() + 1); - F32 pix_height = sMapScale*(layer->LayerExtents.getHeight() + 1); + F32 pix_width = sMapScale*(layer.LayerExtents.getWidth() + 1); + F32 pix_height = sMapScale*(layer.LayerExtents.getHeight() + 1); // When the view isn't panned, 0,0 = center of rectangle F32 bottom = sPanY + half_height + relative_y; @@ -674,11 +832,11 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { continue; } - current_image->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE); + current_image->setBoostLevel(LLViewerTexture::BOOST_MAP); current_image->setKnownDrawSize(llround(pix_width * LLUI::sGLScaleFactor.mV[VX]), llround(pix_height * LLUI::sGLScaleFactor.mV[VY])); - if (!current_image->hasGLTexture()) + if (!current_image->hasGLTexture()) //Still loading. { continue; // better to draw nothing than the default image } @@ -690,10 +848,8 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.getTexUnit(0)->bind(current_image); // Draw map image into RGB - //gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gGL.setColorMask(true, false); - gGL.color4f(1.f, 1.f, 1.f, layer_alpha); - + gGL.color4f(1.f, 1.f, 1.f, 1.f); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.0f, 1.0f); gGL.vertex3f(left, top, -1.0f); @@ -704,7 +860,6 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.texCoord2f(1.0f, 1.0f); gGL.vertex3f(right, top, -1.0f); gGL.end(); - // draw an alpha of 1 where the sims are visible gGL.setColorMask(false, true); gGL.color4f(1.f, 1.f, 1.f, 1.f); @@ -719,455 +874,78 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.texCoord2f(1.0f, 1.0f); gGL.vertex2f(right, top); gGL.end(); + + gGL.setColorMask(true, true); } +} - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gGL.setColorMask(true, true); - - F32 sim_alpha = 1.f; - - // Draw one image per region, centered on the camera position. +F32 LLWorldMapView::drawLegacySimTile(LLSimInfo& sim_info, S32 left, S32 top, S32 right, S32 bottom) +{ + const F32 ALPHA_CUTOFF = 0.001f; const S32 MAX_SIMULTANEOUS_TEX = 100; const S32 MAX_REQUEST_PER_TICK = 5; const S32 MIN_REQUEST_PER_TICK = 1; S32 textures_requested_this_tick = 0; + LLViewerFetchedTexture* simimage = sim_info.mLayerImage[SIM_LAYER_COMPOSITE]; - bool use_web_map_tiles = LLWorldMap::useWebMapTiles(); - - for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); - it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) + const bool sim_visible = sMapScale >= SIM_COMPOSITE_SCALE; + const bool sim_fetchable = sMapScale >= SIM_FETCH_SCALE; + + if(sim_fetchable) { - U64 handle = (*it).first; - LLSimInfo* info = (*it).second; - - LLViewerTexture* simimage = info->mCurrentImage; - LLViewerTexture* overlayimage = info->mOverlayImage; - - if (sMapScale < SIM_MAP_SCALE) - { - if (simimage != NULL) simimage->setBoostLevel(0); - if (overlayimage != NULL) overlayimage->setBoostLevel(0); - continue; - } - - LLVector3d origin_global = from_region_handle(handle); - LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - - // Find x and y position relative to camera's center. - LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - - // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom + sMapScale * ((F32)info->getSizeY() / 256.f); - F32 right = left + sMapScale * ((F32)info->getSizeX() / 256.f); - - // Switch to world map texture (if available for this region) if either: - // 1. Tiles are zoomed out small enough, or - // 2. Sim's texture has not been loaded yet - F32 map_scale_cutoff = SIM_MAP_SCALE; -#if 0 // This is always false, as REGION_FLAGS_NULL_LAYER doesn't exist anymore - if ((info->getRegionFlags() & REGION_FLAGS_NULL_LAYER) > 0) - { - map_scale_cutoff = SIM_NULL_MAP_SCALE; - } -#endif - - bool sim_visible = - (sMapScale >= map_scale_cutoff) && - (simimage != NULL) && - (simimage->hasGLTexture()); - - if (sim_visible) - { - // Fade in - if (info->getAlpha() < 0.0f) - info->setAlpha( 1.f ); // don't fade initially - else - info->setAlpha(lerp(info->getAlpha(), 1.f, LLCriticalDamp::getInterpolant(0.15f))); - } - else - { - // Fade out - if (info->getAlpha() < 0.0f) - info->setAlpha( 0.f ); // don't fade initially - else - info->setAlpha(lerp(info->getAlpha(), 0.f, LLCriticalDamp::getInterpolant(0.15f))); - } - - // discard regions that are outside the rectangle - // and discard small regions - if (top < 0.f || - bottom > height || - right < 0.f || - left > width ) - { - if (simimage != NULL) simimage->setBoostLevel(0); - if (overlayimage != NULL) overlayimage->setBoostLevel(0); - continue; - } - - if (info->mCurrentImage.isNull()) + if (!simimage && sim_info.mMapImageID[SIM_LAYER_COMPOSITE].notNull() && sim_info.mMapImageID[SIM_LAYER_COMPOSITE] != IMG_DEFAULT) { if ((textures_requested_this_tick < MIN_REQUEST_PER_TICK) || ((LLAppViewer::getTextureFetch()->getNumRequests() < MAX_SIMULTANEOUS_TEX) && (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) { textures_requested_this_tick++; - if (use_web_map_tiles && info->getSizeX() == REGION_WIDTH_UNITS && - info->getSizeY() == REGION_WIDTH_UNITS) - { - LLVector3d region_pos = info->getGlobalOrigin(); - info->mCurrentImage = LLWorldMap::loadObjectsTile((U32)(region_pos.mdV[VX] / REGION_WIDTH_UNITS), (U32)(region_pos.mdV[VY] / REGION_WIDTH_UNITS)); - } - else - { - info->mCurrentImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE); - } - info->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); - simimage = info->mCurrentImage; - gGL.getTexUnit(0)->bind(simimage); - } - } - if (info->mOverlayImage.isNull() && info->mMapImageID[2].notNull()) - { - if ((textures_requested_this_tick < MIN_REQUEST_PER_TICK) || - ((LLAppViewer::getTextureFetch()->getNumRequests() < MAX_SIMULTANEOUS_TEX) && - (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) - { - textures_requested_this_tick++; - info->mOverlayImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[2], MIPMAP_TRUE); - info->mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP); - overlayimage = info->mOverlayImage; - gGL.getTexUnit(0)->bind(overlayimage); + simimage = sim_info.mLayerImage[SIM_LAYER_COMPOSITE] = LLViewerTextureManager::getFetchedTexture(sim_info.mMapImageID[SIM_LAYER_COMPOSITE], MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE); + simimage->setAddressMode(LLTexUnit::TAM_CLAMP); } } + } - // Bias the priority escalation for images nearer - LLVector3d center_global = origin_global; - center_global.mdV[VX] += 128.0; - center_global.mdV[VY] += 128.0; + const bool sim_drawable = simimage && !simimage->isMissingAsset() && simimage->getID() != IMG_DEFAULT; + const bool sim_fetching = sim_drawable && !simimage->hasGLTexture(); + const F32 fade_target = sim_visible ? 1.f : 0.f; + //Logic is a bit confusing here. Basically, we want to fade out on zoom-out, and fade in on either zoom-in OR texture has finished fetching. + //However, we instantly hide the tile if the texture is invalid or hasn't loaded. The tile never would have been visible before this, anyhow. + if (!sim_drawable || sim_fetching) + sim_info.setAlpha( 0.f ); + else if (llabs(sim_info.getAlpha() - fade_target) > ALPHA_CUTOFF) //This gives us a nice fade when a visible sims texture finishes loading, or visiblity has changed. + sim_info.setAlpha(lerp(sim_info.getAlpha(), fade_target, LLCriticalDamp::getInterpolant(0.15f))); + F32 alpha = sim_info.getAlpha(); + + //call setKnownDrawSize if image is still loading, or its actually being drawn. + if(sim_fetching || alpha >= ALPHA_CUTOFF) + { S32 draw_size = llround(sMapScale); - if (simimage != NULL) + simimage->setKnownDrawSize( llround(draw_size * LLUI::sGLScaleFactor.mV[VX] * ((F32)sim_info.getSizeX() / REGION_WIDTH_METERS)), + llround(draw_size * LLUI::sGLScaleFactor.mV[VY] * ((F32)sim_info.getSizeY() / REGION_WIDTH_METERS))); + simimage->setBoostLevel(LLViewerTexture::BOOST_MAP); + if(alpha >= ALPHA_CUTOFF) { - simimage->setBoostLevel(LLViewerTexture::BOOST_MAP); - simimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX] * ((F32)info->getSizeX() / REGION_WIDTH_UNITS)), - llround(draw_size * LLUI::sGLScaleFactor.mV[VY] * ((F32)info->getSizeY() / REGION_WIDTH_UNITS))); - } - - if (overlayimage != NULL) - { - overlayimage->setBoostLevel(LLViewerTexture::BOOST_MAP); - overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX] * ((F32)info->getSizeX() / REGION_WIDTH_UNITS)), - llround(draw_size * LLUI::sGLScaleFactor.mV[VY] * ((F32)info->getSizeY() / REGION_WIDTH_UNITS))); - } - -// LLTextureView::addDebugImage(simimage); - - if (sim_visible && info->getAlpha() > 0.001f) - { - // Draw using the texture. If we don't clamp we get artifact at - // the edge. - LLGLSUIDefault gls_ui; - if (simimage != NULL) - gGL.getTexUnit(0)->bind(simimage); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - F32 alpha = sim_alpha * info->getAlpha(); - gGL.color4f(1.f, 1.0f, 1.0f, alpha); - + gGL.getTexUnit(0)->bind(simimage); + gGL.color4f(1.f, 1.f, 1.f, alpha); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); - gGL.vertex3f(left, top, 0.f); + gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(left, bottom, 0.f); + gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); - gGL.vertex3f(right, bottom, 0.f); + gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); - gGL.vertex3f(right, top, 0.f); - gGL.end(); - - static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); - if (map_show_land_for_sale && overlayimage && overlayimage->hasGLTexture()) - { - gGL.getTexUnit(0)->bind(overlayimage); - gGL.color4f(1.f, 1.f, 1.f, alpha); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex3f(left, top, -0.5f); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(left, bottom, -0.5f); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex3f(right, bottom, -0.5f); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex3f(right, top, -0.5f); - gGL.end(); - } - - 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.setSceneBlendType(LLRender::BT_REPLACE); - gGL.setColorMask(false, true); - gGL.color4f(1.f, 1.f, 1.f, 1.f); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); - gGL.vertex2f(left, top); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, bottom); - gGL.vertex2f(right, top); - gGL.end(); - - gGL.setColorMask(true, true); - } - } - - if (info->isDown()) - { - // Draw a transparent red square over down sims - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); - gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); - gGL.vertex2f(left, top); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, bottom); gGL.vertex2f(right, top); gGL.end(); } - - // As part of the AO project, we no longer want to draw access indicators; - // it's too complicated to get all the rules straight and will only - // cause confusion. - /********************** - // If this is mature, and you are not, draw a line across it - if (info->mAccess != SIM_ACCESS_DOWN - && info->mAccess > SIM_ACCESS_PG - && gAgent.isTeen()) - { - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color3f(1.f, 0.f, 0.f); - gGL.begin(LLRender::LINES); - gGL.vertex2f(left, top); - gGL.vertex2f(right, bottom); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, top); - gGL.end(); - } - **********************/ } -} - -void LLWorldMapView::drawGenericItems(const LLWorldMap::item_info_list_t& items, LLUIImagePtr image) -{ - LLWorldMap::item_info_list_t::const_iterator e; - for (e = items.begin(); e != items.end(); ++e) + else //Either the texture is invalid or view has zoomed out far enough and the sim has fully faded away. { - drawGenericItem(*e, image); + sim_info.dropImagePriority(SIM_LAYER_COMPOSITE); } -} - -void LLWorldMapView::drawGenericItem(const LLItemInfo& item, LLUIImagePtr image) -{ - drawImage(item.getGlobalPosition(), image); -} - - -void LLWorldMapView::drawImage(const LLVector3d& global_pos, LLUIImagePtr image, const LLColor4& color) -{ - LLVector3 pos_map = globalPosToView( global_pos ); - image->draw(llround(pos_map.mV[VX] - image->getWidth() /2.f), - llround(pos_map.mV[VY] - image->getHeight()/2.f), - color); -} - -void LLWorldMapView::drawImageStack(const LLVector3d& global_pos, LLUIImagePtr image, U32 count, F32 offset, const LLColor4& color) -{ - LLVector3 pos_map = globalPosToView( global_pos ); - for(U32 i=0; idraw(llround(pos_map.mV[VX] - image->getWidth() /2.f), - llround(pos_map.mV[VY] - image->getHeight()/2.f + i*offset), - color); - } -} - - -void LLWorldMapView::drawAgents() -{ - if(sMapScale < SIM_MAP_AGENT_SCALE) - return; - - F32 agents_scale = (sMapScale * 0.9f) / 256.f; - - LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); - // LLColor4 friend_color = gColors.getColor( "MapFriend" ); - - for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) - { - U64 handle = *iter; - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo && (siminfo->isDown())) - { - continue; - } - LLWorldMap::agent_list_map_t::iterator counts_iter = LLWorldMap::getInstance()->mAgentLocationsMap.find(handle); - if (siminfo && siminfo->mShowAgentLocations && counts_iter != LLWorldMap::getInstance()->mAgentLocationsMap.end()) - { - // Show Individual agents (or little stacks where real agents are) - LLWorldMap::item_info_list_t& agentcounts = counts_iter->second; - S32 sim_agent_count = 0; - for (LLWorldMap::item_info_list_t::iterator iter = agentcounts.begin(); - iter != agentcounts.end(); ++iter) - { - const LLItemInfo& info = *iter; - S32 agent_count = info.mExtra; - sim_agent_count += info.mExtra; - // 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 - { - // Show agent 'stack' at center of sim - S32 num_agents = LLWorldMap::getInstance()->mNumAgents[handle]; - if (num_agents > 0) - { - LLVector3d region_center = from_region_handle(handle); - region_center[VX] += REGION_WIDTH_METERS / 2; - region_center[VY] += REGION_WIDTH_METERS / 2; - // Reduce the stack size as you zoom out - always display at lease one agent where there is one or more - 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); - } - } - } -} - - -void LLWorldMapView::drawEvents() -{ - bool mature_enabled = gAgent.canAccessMature(); - bool adult_enabled = gAgent.canAccessAdult(); - - static const LLCachedControl map_show_pg_events("MapShowPGEvents"); - static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); - static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); - - BOOL show_pg = map_show_pg_events; - BOOL show_mature = mature_enabled && map_show_mature_events; - BOOL show_adult = adult_enabled && map_show_adult_events; - - // First the non-selected events - LLWorldMap::item_info_list_t::const_iterator e; - if (show_pg) - { - for (e = LLWorldMap::getInstance()->mPGEvents.begin(); e != LLWorldMap::getInstance()->mPGEvents.end(); ++e) - { - if (!e->mSelected) - { - drawGenericItem(*e, sEventImage); - } - } - } - if (show_mature) - { - for (e = LLWorldMap::getInstance()->mMatureEvents.begin(); e != LLWorldMap::getInstance()->mMatureEvents.end(); ++e) - { - if (!e->mSelected) - { - drawGenericItem(*e, sEventMatureImage); - } - } - } - if (show_adult) - { - for (e = LLWorldMap::getInstance()->mAdultEvents.begin(); e != LLWorldMap::getInstance()->mAdultEvents.end(); ++e) - { - if (!e->mSelected) - { - drawGenericItem(*e, sEventAdultImage); - } - } - } - // Then the selected events - if (show_pg) - { - for (e = LLWorldMap::getInstance()->mPGEvents.begin(); e != LLWorldMap::getInstance()->mPGEvents.end(); ++e) - { - if (e->mSelected) - { - drawGenericItem(*e, sEventImage); - } - } - } - if (show_mature) - { - for (e = LLWorldMap::getInstance()->mMatureEvents.begin(); e != LLWorldMap::getInstance()->mMatureEvents.end(); ++e) - { - if (e->mSelected) - { - drawGenericItem(*e, sEventMatureImage); - } - } - } - if (show_adult) - { - for (e = LLWorldMap::getInstance()->mAdultEvents.begin(); e != LLWorldMap::getInstance()->mAdultEvents.end(); ++e) - { - if (e->mSelected) - { - drawGenericItem(*e, sEventAdultImage); - } - } - } -} - - -void LLWorldMapView::drawFrustum() -{ - // Draw frustum - F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; - - F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); - F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); - F32 far_clip_pixels = far_clip_meters * meters_to_pixels; - - F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); - F32 half_width_pixels = half_width_meters * meters_to_pixels; - - F32 ctr_x = getRect().getWidth() * 0.5f + sPanX; - F32 ctr_y = getRect().getHeight() * 0.5f + sPanY; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // Since we don't rotate the map, we have to rotate the frustum. - gGL.pushMatrix(); - gGL.translatef( ctr_x, ctr_y, 0 ); - gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); - - // Draw triangle with more alpha in far pixels to make it - // fade out in distance. - gGL.begin( LLRender::TRIANGLES ); - gGL.color4f(1.f, 1.f, 1.f, 0.25f); - gGL.vertex2f( 0, 0 ); - - gGL.color4f(1.f, 1.f, 1.f, 0.02f); - gGL.vertex2f( -half_width_pixels, far_clip_pixels ); - - gGL.color4f(1.f, 1.f, 1.f, 0.02f); - gGL.vertex2f( half_width_pixels, far_clip_pixels ); - gGL.end(); - gGL.popMatrix(); + return alpha; } void LLWorldMapView::drawMipmap(S32 width, S32 height) @@ -1205,90 +983,6 @@ void LLWorldMapView::drawMipmap(S32 width, S32 height) // Render the current level sVisibleTilesLoaded = drawMipmapLevel(width, height, level); - const F32 half_width = F32(width) / 2.0f; - const F32 half_height = F32(height) / 2.0f; - LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - - for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); - it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) - { - U64 handle = it->first; - LLSimInfo* info = it->second; - - LLVector3d origin_global = from_region_handle(handle); - - // Find x and y position relative to camera's center. - LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - - // Coordinates of the sim in pixels in the UI panel - // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom + sMapScale ; - F32 right = left + sMapScale ; - - // Discard if region is outside the screen rectangle (not visible on screen) - if ((top < 0.f) || (bottom > height) || - (right < 0.f) || (left > width) ) - { - // Drop the "land for sale" fetching priority since it's outside the view rectangle - info->dropImagePriority(); - continue; - } - - if (info->isDown()) - { - // Draw a transparent red square over down sims - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); - gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); - gGL.vertex2f(left, top); - gGL.vertex2f(left, bottom); - gGL.vertex2f(right, bottom); - gGL.vertex2f(right, top); - gGL.end(); - } - - if (gSavedSettings.getBOOL("MapShowLandForSale") && (sMapScale >= SIM_LANDFORSALE_SCALE)) - { - // Draw the overlay image "Land for Sale / Land for Auction" - LLViewerFetchedTexture* overlayimage = info->getLandForSaleImage(); - if (overlayimage) - { - // Inform the fetch mechanism of the size we need - S32 draw_size = llround(sMapScale); - overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); - // Draw something whenever we have enough info - if (overlayimage->hasGLTexture() && !overlayimage->isMissingAsset()) - { - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - gGL.getTexUnit(0)->bind(overlayimage); - gGL.color4f(1.f, 1.f, 1.f, 1.f); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex3f(left, top, -0.5f); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex3f(left, bottom, -0.5f); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex3f(right, bottom, -0.5f); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex3f(right, top, -0.5f); - gGL.end(); - } - } - } - else - { - // If we're not displaying the "land for sale", drop its fetching priority - info->dropImagePriority(); - } - } - return; } @@ -1341,13 +1035,13 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load F32 left = pos_screen[VX]; F32 bottom = pos_screen[VY]; // Compute the NE corner coordinates of the tile now - LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(to_region_handle(grid_x, grid_y)); + /*LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(to_region_handle(grid_x, grid_y)); if(simInfo != NULL) { pos_global[VX] += ((F32)tile_width * ((F32)simInfo->getSizeX() / REGION_WIDTH_METERS)); pos_global[VY] += ((F32)tile_width * ((F32)simInfo->getSizeY() / REGION_WIDTH_METERS)); } - else + else*/ { pos_global[VX] += tile_width; pos_global[VY] += tile_width; @@ -1360,10 +1054,7 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load LLGLSUIDefault gls_ui; gGL.getTexUnit(0)->bind(simimage.get()); simimage->setAddressMode(LLTexUnit::TAM_CLAMP); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.color4f(1.f, 1.0f, 1.0f, 1.0f); - gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex3f(left, top, 0.f); @@ -1378,6 +1069,7 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load drawTileOutline(level, top, left, bottom, right); #endif // DEBUG_DRAW_TILE } + //else } else { @@ -1391,6 +1083,206 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load return (completed_tiles == total_tiles); } +// Draw lines (rectangle outline and cross) to visualize the position of the tile +// Used for debug only +void LLWorldMapView::drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right) +{ + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + if (level == 1) + gGL.color3f(1.f, 0.f, 0.f); // red + else if (level == 2) + gGL.color3f(0.f, 1.f, 0.f); // green + else if (level == 3) + gGL.color3f(0.f, 0.f, 1.f); // blue + else if (level == 4) + gGL.color3f(1.f, 1.f, 0.f); // yellow + else if (level == 5) + gGL.color3f(1.f, 0.f, 1.f); // magenta + else if (level == 6) + gGL.color3f(0.f, 1.f, 1.f); // cyan + else if (level == 7) + gGL.color3f(1.f, 1.f, 1.f); // white + else + gGL.color3f(0.f, 0.f, 0.f); // black + gGL.begin(LLRender::LINE_STRIP); + gGL.vertex2f(left, top); + gGL.vertex2f(right, bottom); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, top); + gGL.vertex2f(left, top); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + gGL.vertex2f(right, top); + gGL.end(); + + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); +} + +void LLWorldMapView::drawGenericItems(const LLSimInfo::item_info_list_t& items, LLUIImagePtr image) +{ + LLSimInfo::item_info_list_t::const_iterator e; + for (e = items.begin(); e != items.end(); ++e) + { + drawGenericItem(*e, image); + } +} + +void LLWorldMapView::drawGenericItem(const LLItemInfo& item, LLUIImagePtr image) +{ + drawImage(item.getGlobalPosition(), image); +} + + +void LLWorldMapView::drawImage(const LLVector3d& global_pos, LLUIImagePtr image, const LLColor4& color) +{ + LLVector3 pos_map = globalPosToView( global_pos ); + image->draw(llround(pos_map.mV[VX] - image->getWidth() /2.f), + llround(pos_map.mV[VY] - image->getHeight()/2.f), + color); +} + +void LLWorldMapView::drawImageStack(const LLVector3d& global_pos, LLUIImagePtr image, U32 count, F32 offset, const LLColor4& color) +{ + LLVector3 pos_map = globalPosToView( global_pos ); + for(U32 i=0; idraw(llround(pos_map.mV[VX] - image->getWidth() /2.f), + llround(pos_map.mV[VY] - image->getHeight()/2.f + i*offset), + color); + } +} + +void LLWorldMapView::drawItems() +{ + bool mature_enabled = gAgent.canAccessMature(); + bool adult_enabled = gAgent.canAccessAdult(); + + static const LLCachedControl map_show_infohubs("MapShowInfohubs"); + static const LLCachedControl map_show_telehubs("MapShowTelehubs"); + static const LLCachedControl map_show_pg_events("MapShowPGEvents"); + static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); + static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + + BOOL show_mature = mature_enabled && map_show_mature_events; + BOOL show_adult = adult_enabled && map_show_adult_events; + + for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) + { + U64 handle = *iter; + LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if ((info == NULL) || (info->isDown())) + { + continue; + } + // Infohubs + if (map_show_infohubs) + { + drawGenericItems(info->getInfoHub(), sInfohubImage); + } + // Telehubs + if (map_show_telehubs) + { + drawGenericItems(info->getTeleHub(), sTelehubImage); + } + // Land for sale + if (map_show_land_for_sale) + { + drawGenericItems(info->getLandForSale(), sForSaleImage); + // for 1.23, we're showing normal land and adult land in the same UI; you don't + // get a choice about which ones you want. If you're currently asking for adult + // content and land you'll get the adult land. + if (gAgent.canAccessAdult()) + { + drawGenericItems(info->getLandForSaleAdult(), sForSaleAdultImage); + } + } + // PG Events + if (map_show_pg_events) + { + drawGenericItems(info->getPGEvent(), sEventImage); + } + // Mature Events + if (show_mature) + { + drawGenericItems(info->getMatureEvent(), sEventMatureImage); + } + // Adult Events + if (show_adult) + { + drawGenericItems(info->getAdultEvent(), sEventAdultImage); + } + } +} + +void LLWorldMapView::drawAgents() +{ + F32 agents_scale = (sMapScale * 0.9f) / 256.f; + + LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); + // LLColor4 friend_color = gColors.getColor( "MapFriend" ); + + for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) + { + U64 handle = *iter; + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if ((siminfo == NULL) || (siminfo->isDown())) + { + continue; + } + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getAgentLocation().begin(); + while (it != siminfo->getAgentLocation().end()) + { + // Show Individual agents (or little stacks where real agents are) + + // 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; + // Reduce the stack size as you zoom out - always display at lease one agent where there is one or more + S32 agent_count = (S32)(((it->getCount()-1) * agents_scale + (it->getCount()-1) * 0.1f)+.1f) + 1; + drawImageStack(it->getGlobalPosition(), sAvatarSmallImage, agent_count, 3.f, avatar_color); + ++it; + } + } +} + +void LLWorldMapView::drawFrustum() +{ + // Draw frustum + F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; + + F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); + F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); + F32 far_clip_pixels = far_clip_meters * meters_to_pixels; + + F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); + F32 half_width_pixels = half_width_meters * meters_to_pixels; + + F32 ctr_x = getRect().getWidth() * 0.5f + sPanX; + F32 ctr_y = getRect().getHeight() * 0.5f + sPanY; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // Since we don't rotate the map, we have to rotate the frustum. + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); + gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); + + // Draw triangle with more alpha in far pixels to make it + // fade out in distance. + gGL.begin( LLRender::TRIANGLES ); + gGL.color4f(1.f, 1.f, 1.f, 0.25f); + gGL.vertex2f( 0, 0 ); + + gGL.color4f(1.f, 1.f, 1.f, 0.02f); + gGL.vertex2f( -half_width_pixels, far_clip_pixels ); + + gGL.color4f(1.f, 1.f, 1.f, 0.02f); + gGL.vertex2f( half_width_pixels, far_clip_pixels ); + gGL.end(); + gGL.popMatrix(); +} LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos ) { LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal(); @@ -1461,9 +1353,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& text_x, text_y, LLColor4::white, LLFontGL::HCENTER, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); + LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); if (tooltip != "") { @@ -1474,9 +1364,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& text_x, text_y, LLColor4::white, LLFontGL::HCENTER, - LLFontGL::BASELINE, - LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW); + LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); } } } @@ -1510,8 +1398,9 @@ LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y ) BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen ) { LLVector3d pos_global = viewPosToGlobal(x, y); + U64 handle = to_region_handle(pos_global); - LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); + LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if (info) { LLViewerRegion *region = gAgent.getRegion(); @@ -1525,8 +1414,8 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic if (!info->isDown()) { - S32 agent_count = LLWorldMap::getInstance()->mNumAgents[info->getHandle()]; - if (region && region->getHandle() == info->getHandle()) + S32 agent_count = info->getAgentCount(); + if (region && (region->getHandle() == handle)) { ++agent_count; // Bump by 1 if we're here } @@ -1614,7 +1503,7 @@ static void drawDot(F32 x_pixels, F32 y_pixels, // static void LLWorldMapView::drawAvatar(F32 x_pixels, F32 y_pixels, - LLColor4 color, + const LLColor4& color, F32 relative_z, F32 dot_radius) { @@ -1925,7 +1814,7 @@ bool LLWorldMapView::checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bo gFloaterWorldMap->trackGenericItem(item); } - item.mSelected = TRUE; +// item.mSelected = TRUE; *id = item.getUUID(); return true; @@ -1949,111 +1838,119 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, *hit_type = 0; // hit nothing - LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; - LLWorldMap::getInstance()->mIsTrackingDoubleClick = FALSE; - LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; + LLWorldMap::getInstance()->cancelTracking(); - LLWorldMap::item_info_list_t::iterator it; - - // clear old selected stuff - for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it) - { - (*it).mSelected = FALSE; - } - for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it) - { - (*it).mSelected = FALSE; - } - for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) - { - (*it).mSelected = FALSE; - } - for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it) - { - (*it).mSelected = FALSE; - } - - // Select event you clicked on static const LLCachedControl map_show_pg_events("MapShowPGEvents"); - if (map_show_pg_events) - { - for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it) - { - LLItemInfo& event = *it; - - if (checkItemHit(x, y, event, id, false)) - { - *hit_type = MAP_ITEM_PG_EVENT; - mItemPicked = TRUE; - gFloaterWorldMap->trackEvent(event); - return; - } - } - } static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); - if (map_show_mature_events) - { - for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it) - { - LLItemInfo& event = *it; - - if (checkItemHit(x, y, event, id, false)) - { - *hit_type = MAP_ITEM_MATURE_EVENT; - mItemPicked = TRUE; - gFloaterWorldMap->trackEvent(event); - return; - } - } - } static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); - if (map_show_adult_events) - { - for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) - { - LLItemInfo& event = *it; - - if (checkItemHit(x, y, event, id, false)) - { - *hit_type = MAP_ITEM_ADULT_EVENT; - mItemPicked = TRUE; - gFloaterWorldMap->trackEvent(event); - return; - } - } - } static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); - if (map_show_land_for_sale) - { - for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it) - { - LLItemInfo& land = *it; - if (checkItemHit(x, y, land, id, true)) - { - *hit_type = MAP_ITEM_LAND_FOR_SALE; - mItemPicked = TRUE; - return; - } - } - - for (it = LLWorldMap::getInstance()->mLandForSaleAdult.begin(); it != LLWorldMap::getInstance()->mLandForSaleAdult.end(); ++it) - { - LLItemInfo& land = *it; + if(sMapScale >= DRAW_TEXT_THRESHOLD) + { + bool show_mature = gAgent.canAccessMature() && map_show_mature_events; + bool show_adult = gAgent.canAccessAdult() && map_show_adult_events; - if (checkItemHit(x, y, land, id, true)) - { - *hit_type = MAP_ITEM_LAND_FOR_SALE_ADULT; - mItemPicked = TRUE; - return; - } + // Test hits if trackable data are displayed, otherwise, we don't even bother + if (map_show_pg_events || show_mature || show_adult || map_show_land_for_sale) + { + // Iterate through the visible regions + for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) + { + U64 handle = *iter; + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if ((siminfo == NULL) || (siminfo->isDown())) + { + continue; + } + // If on screen check hits with the visible item lists + if (map_show_pg_events) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getPGEvent().begin(); + while (it != siminfo->getPGEvent().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, false)) + { + *hit_type = MAP_ITEM_PG_EVENT; + mItemPicked = TRUE; + gFloaterWorldMap->trackEvent(event); + return; + } + ++it; + } + } + if (show_mature) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getMatureEvent().begin(); + while (it != siminfo->getMatureEvent().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, false)) + { + *hit_type = MAP_ITEM_MATURE_EVENT; + mItemPicked = TRUE; + gFloaterWorldMap->trackEvent(event); + return; + } + ++it; + } + } + if (show_adult) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getAdultEvent().begin(); + while (it != siminfo->getAdultEvent().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, false)) + { + *hit_type = MAP_ITEM_ADULT_EVENT; + mItemPicked = TRUE; + gFloaterWorldMap->trackEvent(event); + return; + } + ++it; + } + } + if (map_show_land_for_sale) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getLandForSale().begin(); + while (it != siminfo->getLandForSale().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, true)) + { + *hit_type = MAP_ITEM_LAND_FOR_SALE; + mItemPicked = TRUE; + return; + } + ++it; + } + // for 1.23, we're showing normal land and adult land in the same UI; you don't + // get a choice about which ones you want. If you're currently asking for adult + // content and land you'll get the adult land. + if (gAgent.canAccessAdult()) + { + LLSimInfo::item_info_list_t::const_iterator it = siminfo->getLandForSaleAdult().begin(); + while (it != siminfo->getLandForSaleAdult().end()) + { + LLItemInfo event = *it; + if (checkItemHit(x, y, event, id, true)) + { + *hit_type = MAP_ITEM_LAND_FOR_SALE_ADULT; + mItemPicked = TRUE; + return; + } + ++it; + } + } + } + } } } - // If we get here, we haven't clicked on an icon + // If we get here, we haven't clicked on anything gFloaterWorldMap->trackLocation(pos_global); mItemPicked = FALSE; - *id = LLUUID::null; return; } @@ -2114,58 +2011,35 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) return FALSE; } -U32 LLWorldMapView::updateBlock(S32 block_x, S32 block_y) +void LLWorldMapView::updateVisibleBlocks() { - U32 blocks_requested = 0; - S32 offset = block_x | (block_y * MAP_BLOCK_RES); - if (!LLWorldMap::getInstance()->mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset]) - { -// llinfos << "Loading Block (" << block_x << "," << block_y << ")" << llendl; - LLWorldMap::getInstance()->sendMapBlockRequest(block_x << 3, block_y << 3, (block_x << 3) + 7, (block_y << 3) + 7); - LLWorldMap::getInstance()->mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset] = TRUE; - blocks_requested++; - } - return blocks_requested; -} - -U32 LLWorldMapView::updateVisibleBlocks() -{ - if (sMapScale < SIM_MAP_SCALE) + if (sMapScale < SIM_DATA_SCALE) { // We don't care what is loaded if we're zoomed out - return 0; + return; } + // Load the blocks visible in the current World Map view + + // Get the World Map view coordinates and boundaries LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - - F32 pixels_per_region = sMapScale; const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); - // Convert pan to sim coordinates - S32 world_center_x_lo = S32(((-sPanX - width/2) / pixels_per_region) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_x_hi = S32(((-sPanX + width/2) / pixels_per_region) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_y_lo = S32(((-sPanY - height/2) / pixels_per_region) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); - S32 world_center_y_hi = S32(((-sPanY + height/2)/ pixels_per_region) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); + const F32 half_width = F32(width) / 2.0f; + const F32 half_height = F32(height) / 2.0f; - // Find the corresponding 8x8 block - S32 world_block_x_lo = world_center_x_lo >> 3; - S32 world_block_x_hi = world_center_x_hi >> 3; - S32 world_block_y_lo = world_center_y_lo >> 3; - S32 world_block_y_hi = world_center_y_hi >> 3; + // Compute center into sim grid coordinates + S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); + S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); - U32 blocks_requested = 0; - const U32 max_blocks_requested = 9; + // Compute the boundaries into sim grid coordinates + S32 world_left = world_center_x - S32(half_width / sMapScale) - 1; + S32 world_right = world_center_x + S32(half_width / sMapScale) + 1; + S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1; + S32 world_top = world_center_y + S32(half_height / sMapScale) + 1; - for (S32 block_x = llmax(world_block_x_lo, 0); block_x <= llmin(world_block_x_hi, MAP_BLOCK_RES-1); ++block_x) - { - for (S32 block_y = llmax(world_block_y_lo, 0); block_y <= llmin(world_block_y_hi, MAP_BLOCK_RES-1); ++block_y) - { - blocks_requested += updateBlock(block_x, block_y); - if (blocks_requested >= max_blocks_requested) - return blocks_requested; - } - } - return blocks_requested; + //LL_INFOS("World Map") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; + LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top); } BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) @@ -2255,9 +2129,9 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) } default: { - if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation) + if (LLWorldMap::getInstance()->isTracking()) { - LLWorldMap::getInstance()->mIsTrackingDoubleClick = TRUE; + LLWorldMap::getInstance()->setTrackingDoubleClick(); } else { diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index 97c79dddf..1df0bfba2 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -86,16 +86,17 @@ public: LLVector3d viewPosToGlobal(S32 x,S32 y); virtual void draw(); - void drawTiles(S32 width, S32 height); - void drawGenericItems(const LLWorldMap::item_info_list_t& items, LLUIImagePtr image); + void drawLegacyBackgroundLayers(S32 width, S32 height); //draw legacy background 'layer' tiles. Only available on official grids, I believe. + F32 drawLegacySimTile(LLSimInfo& sim_info, S32 left, S32 top, S32 right, S32 bottom); //draw legacy sim texture (provided in MapBlockReply message). + void drawGenericItems(const LLSimInfo::item_info_list_t& items, LLUIImagePtr image); void drawGenericItem(const LLItemInfo& item, LLUIImagePtr image); void drawImage(const LLVector3d& global_pos, LLUIImagePtr image, const LLColor4& color = LLColor4::white); void drawImageStack(const LLVector3d& global_pos, LLUIImagePtr image, U32 count, F32 offset, const LLColor4& color); void drawAgents(); - void drawEvents(); + void drawItems(); void drawFrustum(); void drawMipmap(S32 width, S32 height); - bool drawMipmapLevel(S32 width, S32 height, S32 level, bool load = true); + bool drawMipmapLevel(S32 width, S32 height, S32 level, bool load = true); static void cleanupTextures(); @@ -119,7 +120,7 @@ public: S32 overlap ); static void drawAvatar( F32 x_pixels, F32 y_pixels, - LLColor4 color, + const LLColor4& color, F32 relative_z = 0.f, F32 dot_radius = 3.f); static void drawIconName(F32 x_pixels, @@ -132,9 +133,7 @@ public: static void clearLastClick() { sHandledLastClick = FALSE; } // if the view changes, download additional sim info as needed - // return value is number of blocks newly requested. - U32 updateBlock(S32 block_x, S32 block_y); - U32 updateVisibleBlocks(); + void updateVisibleBlocks(); protected: void setDirectionPos( LLTextBox* text_box, F32 rotation ); @@ -161,8 +160,6 @@ public: static LLUIImagePtr sForSaleImage; static LLUIImagePtr sForSaleAdultImage; - static F32 sThresholdA; - static F32 sThresholdB; static F32 sPixelsPerMeter; // world meters to map pixels static F32 sMapScale; // scale = size of a region in pixels @@ -202,6 +199,9 @@ public: handle_list_t mVisibleRegions; // set every frame static std::map sStringsMap; + +private: + void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); }; #endif diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index 17ca2d573..0302ac92f 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -78,7 +78,7 @@ void LLWorldMipmap::equalizeBoostLevels() // For each tile for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++) { - LLPointer img = iter->second; + LLPointer img = iter->second; S32 current_boost_level = img->getBoostLevel(); if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE) { @@ -120,7 +120,7 @@ void LLWorldMipmap::dropBoostLevels() // For each tile for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++) { - LLPointer img = iter->second; + LLPointer img = iter->second; img->setBoostLevel(LLViewerTexture::BOOST_NONE); } } @@ -195,7 +195,7 @@ LLPointer LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 // END DEBUG //LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL; - LLPointer img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl); + LLPointer img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); img->setBoostLevel(LLViewerTexture::BOOST_MAP); // Return the smart pointer @@ -224,7 +224,7 @@ void LLWorldMipmap::cleanMissedTilesFromLevel(S32 level) sublevel_tiles_t::iterator it = level_mipmap.begin(); while (it != level_mipmap.end()) { - LLPointer img = it->second; + LLPointer img = it->second; if (img->isMissingAsset()) { level_mipmap.erase(it++); diff --git a/indra/newview/skins/default/xui/en-us/floater_world_map.xml b/indra/newview/skins/default/xui/en-us/floater_world_map.xml index ebbda0fc8..c7c1be574 100644 --- a/indra/newview/skins/default/xui/en-us/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en-us/floater_world_map.xml @@ -172,7 +172,7 @@ tool_tip="Copies current location as SLURL to be used on the web." width="222" /> diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index 3ef6bc38d..4c701634e 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -123,6 +123,7 @@ Loading... + Invalid Location From e17405d80ac3f86f163bcd690b615c112f434073 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Wed, 28 Nov 2012 17:04:24 +0100 Subject: [PATCH 70/93] Fixed snapping of rotation in the edge-on case Patch by https://codereview.secondlife.com/users/cron.stardust/ Jira: https://jira.secondlife.com/browse/STORM-1919 --- doc/contributions.txt | 1 + indra/newview/llmaniprotate.cpp | 232 +++++++++++++++++--------------- 2 files changed, 123 insertions(+), 110 deletions(-) diff --git a/doc/contributions.txt b/doc/contributions.txt index 882dca18c..9eb4520cd 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -248,6 +248,7 @@ Celierra Darling VWR-6975 Cron Stardust VWR-10579 + STORM-1919 Cypren Christenson SNOW-129 SNOW-140 diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 304f00e4b..33baf4231 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1381,74 +1381,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); projected_mouse -= snap_plane_center; - S32 snap_plane = 0; - - F32 dot = cam_to_snap_plane * constraint_axis; - if (llabs(dot) < 0.01f) - { - // looking at ring edge on, project onto view plane and check if mouse is past ring - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); - projected_mouse -= snap_plane_center; - dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis > 0) - { - snap_plane = 1; - } - projected_mouse -= dot * constraint_axis; - } - else if (dot > 0.f) - { - // look for mouse position outside and in front of snap circle - if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) - { - snap_plane = 1; - } - } - else - { - // look for mouse position inside or in back of snap circle - if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) - { - snap_plane = 1; - } - } - - if (snap_plane == 0) - { - // try other plane - snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) - { - cam_to_snap_plane.setVec(1.f, 0.f, 0.f); - } - else - { - cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_to_snap_plane.normVec(); - } - - hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); - projected_mouse -= snap_plane_center; - - dot = cam_to_snap_plane * constraint_axis; + if (gSavedSettings.getBOOL("SnapEnabled")) { + S32 snap_plane = 0; + + F32 dot = cam_to_snap_plane * constraint_axis; if (llabs(dot) < 0.01f) { // looking at ring edge on, project onto view plane and check if mouse is past ring getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); projected_mouse -= snap_plane_center; dot = projected_mouse * constraint_axis; - if (projected_mouse * constraint_axis < 0) + if (projected_mouse * constraint_axis > 0) { - snap_plane = 2; + snap_plane = 1; } projected_mouse -= dot * constraint_axis; } - else if (dot < 0.f) + else if (dot > 0.f) { // look for mouse position outside and in front of snap circle if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) { - snap_plane = 2; + snap_plane = 1; } } else @@ -1456,78 +1410,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) // look for mouse position inside or in back of snap circle if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) { - snap_plane = 2; + snap_plane = 1; } } - } - - if (snap_plane > 0) - { - LLVector3 cam_at_axis; - if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + + if (snap_plane == 0) { - cam_at_axis.setVec(1.f, 0.f, 0.f); + // try other plane + snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f)); + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_to_snap_plane.setVec(1.f, 0.f, 0.f); + } + else + { + cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_to_snap_plane.normVec(); + } + + hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis); + projected_mouse -= snap_plane_center; + + dot = cam_to_snap_plane * constraint_axis; + if (llabs(dot) < 0.01f) + { + // looking at ring edge on, project onto view plane and check if mouse is past ring + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane); + projected_mouse -= snap_plane_center; + dot = projected_mouse * constraint_axis; + if (projected_mouse * constraint_axis < 0) + { + snap_plane = 2; + } + projected_mouse -= dot * constraint_axis; + } + else if (dot < 0.f) + { + // look for mouse position outside and in front of snap circle + if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f) + { + snap_plane = 2; + } + } + else + { + // look for mouse position inside or in back of snap circle + if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit) + { + snap_plane = 2; + } + } } - else - { - cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); - cam_at_axis.normVec(); - } - - // first, project mouse onto screen plane at point tangent to rotation radius. - getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); - // project that point onto rotation plane - projected_mouse -= snap_plane_center; - projected_mouse -= projected_vec(projected_mouse, constraint_axis); - - F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); - F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; - if (llabs(mouse_lateral_dist) > 0.01f) - { - mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - - (mouse_lateral_dist * mouse_lateral_dist)); - } - LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); - projected_mouse -= mouse_depth * projected_camera_at; - - if (!mInSnapRegime) - { - mSmoothRotate = TRUE; - } - mInSnapRegime = TRUE; - // 0 to 360 deg - F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); - F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); - //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); - - LLVector3 object_axis; - getObjectAxisClosestToMouse(object_axis); - object_axis = object_axis * first_object_node->mSavedRotation; - - // project onto constraint plane - object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); - object_axis.normVec(); - - if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + if (snap_plane > 0) { - F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); - angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + LLVector3 cam_at_axis; + if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) + { + cam_at_axis.setVec(1.f, 0.f, 0.f); + } + else + { + cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent(); + cam_at_axis.normVec(); + } + + // first, project mouse onto screen plane at point tangent to rotation radius. + getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis); + // project that point onto rotation plane + projected_mouse -= snap_plane_center; + projected_mouse -= projected_vec(projected_mouse, constraint_axis); + + F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec()); + F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters; + if (llabs(mouse_lateral_dist) > 0.01f) + { + mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - + (mouse_lateral_dist * mouse_lateral_dist)); + } + LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis); + projected_mouse -= mouse_depth * projected_camera_at; + + if (!mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = TRUE; + // 0 to 360 deg + F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f); + + F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT); + //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f); + + LLVector3 object_axis; + getObjectAxisClosestToMouse(object_axis); + object_axis = object_axis * first_object_node->mSavedRotation; + + // project onto constraint plane + object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis(); + object_axis.normVec(); + + if (relative_mouse_angle < SNAP_ANGLE_DETENTE) + { + F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f)); + angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + else + { + angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + } + return LLQuaternion( -angle, constraint_axis ); } else { - angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2); + if (mInSnapRegime) + { + mSmoothRotate = TRUE; + } + mInSnapRegime = FALSE; } - return LLQuaternion( -angle, constraint_axis ); } - else - { + else { if (mInSnapRegime) { mSmoothRotate = TRUE; } mInSnapRegime = FALSE; - + } + + if (!mInSnapRegime) + { LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis; up_from_axis.normVec(); LLVector3 cur_intersection; From c0c9c51e43c6b2d26ca09efb5eb86e9c3d95d0fa Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 29 Nov 2012 10:03:48 -0600 Subject: [PATCH 71/93] Some minor syntax grooming in LLNetMap::draw --- indra/newview/llnetmap.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 86294d46b..f948b480b 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -381,27 +381,29 @@ void LLNetMap::draw() LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); for(U32 i=0; igetFullName(avatar_ids[i], avName); - if(LLMuteList::getInstance()->isMuted(avatar_ids[i])) + gCacheName->getFullName(id, avName); + if(LLMuteList::getInstance()->isMuted(id)) { avColor = muted_color; } - LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(positions[i]); + LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(pos); LLUUID estate_owner = avatar_region? avatar_region->getOwner() : LLUUID::null; // MOYMOD Minimap custom av colors. - boost::unordered_map::const_iterator it = mm_MarkerColors.find(avatar_ids[i]); + boost::unordered_map::const_iterator it = mm_MarkerColors.find(id); if(it != mm_MarkerColors.end()) { avColor = it->second; @@ -412,12 +414,12 @@ void LLNetMap::draw() avColor = linden_color; } //check if they are an estate owner at their current position - else if(estate_owner.notNull() && avatar_ids[i] == estate_owner) + else if(estate_owner.notNull() && id == estate_owner) { avColor = em_color; } //without these dots, SL would suck. - else if(is_agent_friend(avatar_ids[i])) + else if(is_agent_friend(id)) { avColor = friend_color; } @@ -432,8 +434,8 @@ void LLNetMap::draw() if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) { closest_dist = dist_to_cursor; - mClosestAgentToCursor = avatar_ids[i]; - mClosestAgentPosition = positions[i]; + mClosestAgentToCursor = id; + mClosestAgentPosition = pos; } } From 3a4b6cf6b64458e413c07cf5cf1a54966f9aefb9 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 29 Nov 2012 10:07:25 -0600 Subject: [PATCH 72/93] Hovertext updates marked objects as 'moved' when inappropriate. http://hg.secondlife.com/viewer-development/commits/8ccf2b0fa3857a6610f6ea03166e5a4494ca6d03 --- indra/newview/llviewerobject.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6bba93d49..ec4dd8ed4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1265,11 +1265,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, mText->setString(mHudTextString); } - if (mDrawable.notNull()) - { - setChanged(MOVED | SILHOUETTE); - gPipeline.markMoved(mDrawable, FALSE); // undamped - } + setChanged(MOVED | SILHOUETTE); } else if (mText.notNull()) { From 8b19f82c0b04375366c6fd997c8f2e466cc00d1d Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 29 Nov 2012 11:58:41 -0600 Subject: [PATCH 73/93] Trivial changes. Resolved some sign mismatch warnings, and now using LLCachedControl for 'SGIgnoreSimulatorCameraConstraint' setting lookup. --- indra/llmessage/aicurl.cpp | 2 +- indra/llmessage/aicurlperhost.cpp | 6 +++--- indra/newview/llagentcamera.cpp | 3 ++- indra/newview/llviewerobjectlist.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index a0104c2a8..9f1b0d30b 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -495,7 +495,7 @@ void Stats::print(void) // Each AICurlEasyRequestStateMachine has one AICurlEasyRequest member. llassert(AICurlEasyRequest_count >= AICurlEasyRequestStateMachine_count); // AIFIXME: is this really always the case? And why? - llassert(easy_handles <= ResponderBase_count); + llassert(easy_handles <= S32(ResponderBase_count)); } } // namespace AICurlInterface diff --git a/indra/llmessage/aicurlperhost.cpp b/indra/llmessage/aicurlperhost.cpp index 7f7490865..b444ba6df 100644 --- a/indra/llmessage/aicurlperhost.cpp +++ b/indra/llmessage/aicurlperhost.cpp @@ -92,13 +92,13 @@ void PerHostRequestQueue::release(PerHostRequestQueuePtr& instance) bool PerHostRequestQueue::throttled() const { - llassert(mAdded <= curl_concurrent_connections_per_host); - return mAdded == curl_concurrent_connections_per_host; + llassert(mAdded <= int(curl_concurrent_connections_per_host)); + return mAdded == int(curl_concurrent_connections_per_host); } void PerHostRequestQueue::added_to_multi_handle(void) { - llassert(mAdded < curl_concurrent_connections_per_host); + llassert(mAdded < int(curl_concurrent_connections_per_host)); ++mAdded; } diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 93390e1e5..efa26eb7f 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1844,8 +1844,9 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset ); } + static const LLCachedControl sg_ignore_sim_cam_consts("SGIgnoreSimulatorCameraConstraints",false); if ( !mCameraCollidePlane.isExactlyZero() - && !gSavedSettings.getBOOL("SGIgnoreSimulatorCameraConstraints") + && !sg_ignore_sim_cam_consts && isAgentAvatarValid() && !gAgentAvatarp->isSitting()) { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 9f8b9c0a4..2934596e1 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1471,7 +1471,7 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) } else { - llassert(idx < mActiveObjects.size()); + llassert(idx < (S32)mActiveObjects.size()); llassert(mActiveObjects[idx] == objectp); if (idx >= (S32)mActiveObjects.size() || From 0554ecae5c6f72a1c0c5819858563e00aaf04e36 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 2 Dec 2012 17:06:54 -0600 Subject: [PATCH 74/93] Added explicit texture reloading. Accessable in the 'tools' submenus for the agent, avatars, and selected objects. --- indra/llrender/llimagegl.cpp | 14 ++- indra/llrender/llimagegl.h | 1 + indra/newview/lldrawpoolwater.cpp | 4 +- indra/newview/llviewermenu.cpp | 105 ++++++++++++++++++ indra/newview/llviewertexture.cpp | 24 ++++ indra/newview/llviewertexture.h | 2 + .../default/xui/en-us/menu_pie_avatar.xml | 3 + .../default/xui/en-us/menu_pie_object.xml | 5 +- .../skins/default/xui/en-us/menu_pie_self.xml | 3 + 9 files changed, 156 insertions(+), 5 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 03eddae8d..bd5d4a58e 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1329,6 +1329,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ llassert(mCurrentDiscardLevel >= 0); discard_level = mCurrentDiscardLevel; } + discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); if (mTexName != 0 && discard_level == mCurrentDiscardLevel) { @@ -1586,7 +1587,18 @@ void LLImageGL::destroyGLTexture() } } - +//force to invalidate the gl texture, most likely a sculpty texture +void LLImageGL::forceToInvalidateGLTexture() +{ + if (mTexName != 0) + { + destroyGLTexture(); + } + else + { + mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. + } +} //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index ef9a2ec09..4ec1905cc 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -119,6 +119,7 @@ public: // Read back a raw image for this discard level, if it exists BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); void destroyGLTexture(); + void forceToInvalidateGLTexture(); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); void setComponents(S8 ncomponents) { mComponents = ncomponents; } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 701da9b2a..c9e956a09 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -392,9 +392,7 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() if(sRefetch) { sRefetch = false; - gTextureList.deleteImage(gTextureList.findImage( mOpaqueWaterImagep->getID() )); - mOpaqueWaterImagep = NULL; - mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); + ((LLViewerFetchedTexture*)mOpaqueWaterImagep.get())->forceRefetch(); } else mOpaqueWaterImagep = mWaterImagep; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b80200e16..9c1dea408 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -264,6 +264,10 @@ #include "llagentui.h" #include "llpathfindingmanager.h" +#include "lltexturecache.h" +#include "llvovolume.h" +#include + #include "hippogridmanager.h" using namespace LLOldEvents; @@ -2265,6 +2269,105 @@ class LLObjectDerender : public view_listener_t } }; +class LLTextureReloader +{ +public: + ~LLTextureReloader() + { + for(std::set< LLViewerFetchedTexture*>::iterator it=mTextures.begin();it!=mTextures.end();++it) + { + LLViewerFetchedTexture* img = *it; + const LLUUID& id = img->getID(); + if(id.notNull() && id != IMG_DEFAULT && id != IMG_DEFAULT_AVATAR && img != LLViewerFetchedTexture::sDefaultImagep) + { + LLAppViewer::getTextureCache()->removeFromCache(id); + img->forceRefetch(); + for (S32 i = 0; i < img->getNumVolumes(); ++i) + { + LLVOVolume* volume = (*(img->getVolumeList()))[i]; + if (volume && volume->isSculpted() && !volume->isMesh()) + volume->notifyMeshLoaded(); + } + } + } + } + void addTexture(LLViewerTexture* texture) + { + if(!texture) + return; + const LLUUID& id = texture->getID(); + if(id.notNull() && id != IMG_DEFAULT && id != IMG_DEFAULT_AVATAR && texture != LLViewerFetchedTexture::sDefaultImagep) + { + LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(texture); + if(img) + mTextures.insert(img); + } + } + +private: + std::set< LLViewerFetchedTexture*> mTextures; +}; +class LLAvatarReloadTextures : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + if(avatar) + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(avatar->getID()); + LLTextureReloader texture_list; + for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) + { + if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i)) + { + if(avatar->isSelf()) + { + LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)i); + U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) + { + texture_list.addTexture(((LLVOAvatarSelf*)avatar)->getLocalTextureGL((ETextureIndex)i,wearable_index)); + } + } + } + else + { + texture_list.addTexture(avatar->getTEImage((ETextureIndex)i)); + } + } + } + return true; + } +}; +class LLObjectReloadTextures : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLTextureReloader texture_list; + for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); + iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) + { + LLViewerObject* object = (*iter)->getObject(); + + for (U8 i = 0; i < object->getNumTEs(); i++) + { + if((*iter)->isTESelected(i)) + { + texture_list.addTexture(object->getTEImage(i)); + } + if(object->isSculpted() && !object->isMesh()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if(sculpt_params) + { + texture_list.addTexture(LLViewerTextureManager::getFetchedTexture(sculpt_params->getSculptTexture())); + } + } + } + } + return true; + } +}; //--------------------------------------------------------------------------- // Land pie menu @@ -9468,6 +9571,8 @@ void initialize_menus() addMenu(new LLObjectInspect(), "Object.Inspect"); // Visual mute, originally by Phox. addMenu(new LLObjectDerender(), "Object.DERENDER"); + addMenu(new LLAvatarReloadTextures(), "Avatar.ReloadTextures"); + addMenu(new LLObjectReloadTextures(), "Object.ReloadTextures"); addMenu(new LLObjectExport(), "Object.Export"); addMenu(new LLObjectImport(), "Object.Import"); addMenu(new LLObjectImportUpload(), "Object.ImportUpload"); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 2dd04cf80..11fb67c92 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1333,6 +1333,30 @@ void LLViewerFetchedTexture::cleanup() mSavedRawDiscardLevel = -1; } +void LLViewerFetchedTexture::forceRefetch() +{ + bool needs_aux = mNeedsAux; + bool save_raw = mForceToSaveRawImage; + S32 raw_discard = mDesiredSavedRawDiscardLevel; + F32 raw_time = mKeptSavedRawImageTime; + callback_list_t callback_list = mLoadedCallbackList; + mLoadedCallbackList.clear(); + LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); + if(mGLTexturep) + mGLTexturep->forceToInvalidateGLTexture(); + init(false); + mRawImage = NULL; + mAuxRawImage = NULL; + if(save_raw) + forceToSaveRawImage(raw_discard,raw_time); + for(callback_list_t::iterator iter = callback_list.begin(); + iter != callback_list.end(); ++iter) + { + LLLoadedCallbackEntry *entryp = *iter; + setLoadedCallback(entryp->mCallback,entryp->mDesiredDiscard,entryp->mNeedsImageRaw,needs_aux,entryp->mUserData,entryp->mSourceCallbackList,entryp->mPaused); + } +} + void LLViewerFetchedTexture::setForSculpt() { static const S32 MAX_INTERVAL = 8 ; //frames diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 85a6b4915..b0a6ad6a8 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -504,6 +504,8 @@ public: void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} void forceToDeleteRequest(); + void forceRefetch(); + protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml b/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml index 6258c7d69..c57ab3059 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml @@ -46,6 +46,9 @@ + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_object.xml b/indra/newview/skins/default/xui/en-us/menu_pie_object.xml index d130d12d5..67153b629 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_object.xml @@ -72,7 +72,10 @@ + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_self.xml b/indra/newview/skins/default/xui/en-us/menu_pie_self.xml index 9ae376800..07e2c301f 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_self.xml @@ -86,6 +86,9 @@ + + + - SaveScriptsAsMono - - Comment - When set to TRUE, save scripts in inventory as Mono scripts instead of LSL2 - Persist - 1 - Type - Boolean - Value - 1 - PreviewSoundRect Comment diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index 8b90011f2..f8eac7fec 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -268,7 +268,7 @@ void LLPrefsAscentSys::refreshValues() mResetCameraAfterTP = gSavedSettings.getBOOL("OptionRotateCamAfterLocalTP"); mOffsetTPByUserHeight = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); mPreviewAnimInWorld = gSavedSettings.getBOOL("PreviewAnimInWorld"); -// mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveScriptsAsMono"); + mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveInventoryScriptsAsMono"); mAlwaysRezInGroup = gSavedSettings.getBOOL("AscentAlwaysRezInGroup"); mBuildAlwaysEnabled = gSavedSettings.getBOOL("AscentBuildAlwaysEnabled"); mAlwaysShowFly = gSavedSettings.getBOOL("AscentFlyAlwaysEnabled"); @@ -417,7 +417,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("OptionRotateCamAfterLocalTP", mResetCameraAfterTP); gSavedSettings.setBOOL("OptionOffsetTPByAgentHeight", mOffsetTPByUserHeight); gSavedSettings.setBOOL("PreviewAnimInWorld", mPreviewAnimInWorld); -// gSavedSettings.setBOOL("SaveScriptsAsMono", mSaveScriptsAsMono); + gSavedSettings.setBOOL("SaveInventoryScriptsAsMono", mSaveScriptsAsMono); gSavedSettings.setBOOL("AscentAlwaysRezInGroup", mAlwaysRezInGroup); gSavedSettings.setBOOL("AscentBuildAlwaysEnabled", mBuildAlwaysEnabled); gSavedSettings.setBOOL("AscentFlyAlwaysEnabled", mAlwaysShowFly); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 3b233bb28..336828999 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -59,7 +59,7 @@ protected: BOOL mResetCameraAfterTP; BOOL mOffsetTPByUserHeight; BOOL mPreviewAnimInWorld; -// BOOL mSaveScriptsAsMono; + BOOL mSaveScriptsAsMono; BOOL mAlwaysRezInGroup; BOOL mBuildAlwaysEnabled; BOOL mAlwaysShowFly; diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml index 7e0017333..5412db7df 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml @@ -11,7 +11,7 @@ label="Offset TP target by half agent height" tool_tip="Tries to aim the TP so that your feet land at the point you're aiming for." name="offset_teleport_check"/> - diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_ascent_system.xml b/indra/newview/skins/default/xui/fr/panel_preferences_ascent_system.xml index 1a12b036d..2c974d9ce 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_ascent_system.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_ascent_system.xml @@ -30,7 +30,7 @@ tool_tip="L'animation est jouée avec votre avatar avant d'être téléchargée." mouse_opaque="true" name="preview_anim_in_world_check" radio_style="false" width="400" /> - Date: Mon, 3 Dec 2012 15:03:52 -0600 Subject: [PATCH 76/93] Misc changes via v3 merge. Nothing big. --- indra/newview/llvoavatar.cpp | 30 +++++++++++++++--------- indra/newview/llvoavatarself.cpp | 40 +++++++++++++++++++++++--------- indra/newview/llvovolume.cpp | 1 + indra/newview/pipeline.cpp | 2 ++ indra/newview/pipeline.h | 2 ++ 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 2274242d3..d147f6c4b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1861,8 +1861,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector) const LLVector3& shift = reinterpret_cast(shift_vector); mLastAnimExtents[0] += shift; mLastAnimExtents[1] += shift; - mNeedsImpostorUpdate = TRUE; - mNeedsAnimUpdate = TRUE; } void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) @@ -5243,7 +5241,20 @@ void LLVOAvatar::updateTextures() LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index); U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); const LLTextureEntry *te = getTE(texture_index); - const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + + // getTE can return 0. + // Not sure yet why it does, but of course it crashes when te->mScale? gets used. + // Put safeguard in place so this corner case get better handling and does not result in a crash. + F32 texel_area_ratio = 1.0f; + if( te ) + { + texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + } + else + { + llwarns << "getTE( " << texture_index << " ) returned 0" <getID() != IMG_DEFAULT_AVATAR && - img->getID() != IMG_DEFAULT); - } - else - { - llwarns << "Image doesn't exist" << llendl; + llwarns << "getImage( " << te << ", " << index << " ) returned 0" << llendl; return FALSE; } + + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && + getImage(te, index)->getID() != IMG_DEFAULT); } //virtual diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 3381d0890..2a23972df 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2308,11 +2308,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) if (isAllLocalTextureDataFinal()) { LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedDoneNotification" + << llendl; } else { args["STATUS"] = debugDumpAllLocalTextureDataInfo(); LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args); + LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() + << "sec ]" + << avString() + << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() + << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() + << " Notification " << "AvatarRezSelfBakedUpdateNotification" + << llendl; } } @@ -2320,6 +2334,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) } } +// FIXME: This is not called consistently. Something may be broken. void LLVOAvatarSelf::outputRezDiagnostics() const { if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) @@ -2328,11 +2343,11 @@ void LLVOAvatarSelf::outputRezDiagnostics() const } const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); - llinfos << "REZTIME: Myself rez stats:" << llendl; - llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; - llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; - llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; - llinfos << "\t Load time for each texture: " << llendl; + LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; + LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; + LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl; for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i) { std::stringstream out; @@ -2356,12 +2371,14 @@ void LLVOAvatarSelf::outputRezDiagnostics() const // Don't print out non-existent textures. if (j != 0) - llinfos << out.str() << llendl; + { + LL_DEBUGS("Avatar") << out.str() << LL_ENDL; + } } - llinfos << "\t Time points for each upload (start / finish)" << llendl; + LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl; for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i) { - llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; + LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; } for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); @@ -2373,15 +2390,16 @@ void LLVOAvatarSelf::outputRezDiagnostics() const if (!layerset) continue; const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite(); if (!layerset_buffer) continue; - llinfos << layerset_buffer->dumpTextureInfo() << llendl; + LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl; } } void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const { - LL_DEBUGS("Avatar Rez") + LL_INFOS("Avatar") + << avString() << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) - << llendl; + << LL_ENDL; } void LLVOAvatarSelf::reportAvatarRezTime() const diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 975019a03..d76f6e40d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3063,6 +3063,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a* pos = dst_face.mPositions; + if( pos && dst_face.mExtents ) { LLFastTimer t(FTM_SKIN_RIGGED); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f24e7faf6..348222110 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1800,6 +1800,7 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) @@ -2443,6 +2444,7 @@ void LLPipeline::rebuildPriorityGroups() group->clearState(LLSpatialGroup::IN_BUILD_Q1); } + mGroupSaveQ1 = mGroupQ1; mGroupQ1.clear(); mGroupQ1Locked = false; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e3fdf1ecc..c88e76f69 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -658,6 +658,8 @@ protected: LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref + LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called U32 mMeshDirtyQueryObject; From ca3e0d2ba9d41c7df19b01c80e0b518b0d25b06e Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 4 Dec 2012 02:59:19 -0600 Subject: [PATCH 77/93] Use the correct font name. "SANSSERIF_SMALL", not "SANSSERIFSMALL" --- indra/newview/llpaneldirbrowser.cpp | 20 ++++++++++---------- indra/newview/llpanelgrouplandmoney.cpp | 8 ++++---- indra/newview/llpanelgrouproles.cpp | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/indra/newview/llpaneldirbrowser.cpp b/indra/newview/llpaneldirbrowser.cpp index 4680780da..1af94ef4e 100644 --- a/indra/newview/llpaneldirbrowser.cpp +++ b/indra/newview/llpaneldirbrowser.cpp @@ -648,7 +648,7 @@ void LLPanelDirBrowser::processDirPlacesReply(LLMessageSystem* msg, void**) std::string buffer = llformat("%.0f", (F64)dwell); row["columns"][3]["column"] = "dwell"; row["columns"][3]["value"] = buffer; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; list->addElement(row); self->mResultsContents[parcel_id.asString()] = content; @@ -792,11 +792,11 @@ void LLPanelDirBrowser::processDirEventsReply(LLMessageSystem* msg, void**) row["columns"][2]["column"] = "date"; row["columns"][2]["value"] = date; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; row["columns"][3]["column"] = "time"; row["columns"][3]["value"] = llformat("%u", unix_time); - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; list->addElement(row, ADD_SORTED); @@ -879,7 +879,7 @@ void LLPanelDirBrowser::processDirGroupsReply(LLMessageSystem* msg, void**) row["columns"][2]["column"] = "members"; row["columns"][2]["value"] = members; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; row["columns"][3]["column"] = "score"; row["columns"][3]["value"] = search_order; @@ -1069,12 +1069,12 @@ void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**) } row["columns"][3]["column"] = "price"; row["columns"][3]["value"] = buffer; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; buffer = llformat("%d", actual_area); row["columns"][4]["column"] = "area"; row["columns"][4]["value"] = buffer; - row["columns"][4]["font"] = "SANSSERIFSMALL"; + row["columns"][4]["font"] = "SANSSERIF_SMALL"; if (!auction) { @@ -1091,19 +1091,19 @@ void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**) buffer = llformat("%.1f", price_per_meter); row["columns"][5]["column"] = "per_meter"; row["columns"][5]["value"] = buffer; - row["columns"][5]["font"] = "SANSSERIFSMALL"; + row["columns"][5]["font"] = "SANSSERIF_SMALL"; } else { // Auctions start at L$1 per meter row["columns"][5]["column"] = "per_meter"; row["columns"][5]["value"] = "1.0"; - row["columns"][5]["font"] = "SANSSERIFSMALL"; + row["columns"][5]["font"] = "SANSSERIF_SMALL"; } row["columns"][6]["column"] = "landtype"; row["columns"][6]["value"] = land_type; - row["columns"][6]["font"] = "SANSSERIFSMALL"; + row["columns"][6]["font"] = "SANSSERIF_SMALL"; list->addElement(row); self->mResultsContents[parcel_id.asString()] = content; @@ -1138,7 +1138,7 @@ void LLPanelDirBrowser::addClassified(LLCtrlListInterface *list, const LLUUID& p row["columns"][2]["column"] = "price"; row["columns"][2]["value"] = price_for_listing; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; list->addElement(row); } diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 9b7ee5c78..64aefdbbf 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -462,19 +462,19 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) row["columns"][0]["column"] = "name"; row["columns"][0]["value"] = name; - row["columns"][0]["font"] = "SANSSERIFSMALL"; + row["columns"][0]["font"] = "SANSSERIF_SMALL"; row["columns"][1]["column"] = "location"; row["columns"][1]["value"] = location; - row["columns"][1]["font"] = "SANSSERIFSMALL"; + row["columns"][1]["font"] = "SANSSERIF_SMALL"; row["columns"][2]["column"] = "area"; row["columns"][2]["value"] = area; - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; row["columns"][3]["column"] = "type"; row["columns"][3]["value"] = land_type; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; // hidden is always last column row["columns"][4]["column"] = "hidden"; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 155ab8dde..1a6013cfe 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -790,7 +790,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, row["columns"][column_index]["column"] = "action"; row["columns"][column_index]["value"] = (*ra_it)->mDescription; - row["columns"][column_index]["font"] = "SANSSERIFSMALL"; + row["columns"][column_index]["font"] = "SANSSERIF_SMALL"; LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it)); @@ -1679,7 +1679,7 @@ void LLPanelGroupMembersSubTab::updateMembers() row["columns"][2]["column"] = "online"; row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); - row["columns"][2]["font"] = "SANSSERIFSMALL"; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; mMembersList->addElement(row);//, ADD_SORTED); mHasMatch = TRUE; From ef6f411b7003cbe7faae3da24376664bc557d129 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 4 Dec 2012 21:54:01 -0600 Subject: [PATCH 78/93] Removed LLUICtrl::setDoubleClickCallback and LLPanel::childSetDoubleClickCallback as they aren't used/needed and complicate things. Added LLPanel::childSetAction overload that accepts boost::singal2::signal (for boost::bind). Now using boost::function for various callbacks in LLScrollListCtrl (for boost::bind). --- indra/llui/llpanel.cpp | 24 ++++++-------- indra/llui/llpanel.h | 4 +-- indra/llui/llscrolllistctrl.cpp | 8 ++--- indra/llui/llscrolllistctrl.h | 15 +++++---- indra/llui/lluictrl.cpp | 4 --- indra/llui/lluictrl.h | 1 - indra/newview/hbfloatergrouptitles.cpp | 3 +- indra/newview/jcfloaterareasearch.cpp | 3 +- indra/newview/llfloateractivespeakers.cpp | 4 +-- indra/newview/llfloateravatarlist.cpp | 2 +- indra/newview/llfloateravatarpicker.cpp | 33 ++++++++++--------- indra/newview/llfloateravatarpicker.h | 2 +- indra/newview/llfloaterexploresounds.cpp | 7 ++-- indra/newview/llfloaterfriends.cpp | 2 +- indra/newview/llfloatergesture.cpp | 5 +-- indra/newview/llfloatergroups.cpp | 9 ++--- indra/newview/llfloaterland.cpp | 2 +- indra/newview/llfloaterlandholdings.cpp | 9 ++--- indra/newview/llfloaternewim.cpp | 3 +- .../newview/llfloaternotificationsconsole.cpp | 6 ++-- indra/newview/llfloaterteleporthistory.cpp | 4 +-- indra/newview/llfloatertopobjects.cpp | 7 ++-- indra/newview/llfloaterworldmap.cpp | 6 +--- indra/newview/llfloaterworldmap.h | 1 - indra/newview/llpanelavatar.cpp | 3 +- indra/newview/llpanelgroupgeneral.cpp | 3 +- indra/newview/llpanelgrouproles.cpp | 5 ++- indra/newview/llpanelgroupvoting.cpp | 6 ++-- indra/newview/llpreviewgesture.cpp | 4 +-- 29 files changed, 82 insertions(+), 103 deletions(-) diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index dc89e9a4f..588a36a0f 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -765,19 +765,6 @@ void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl* } } -void LLPanel::childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void *userdata ) -{ - LLUICtrl* child = getChild(id, true); - if (child) - { - child->setDoubleClickCallback(cb); - if (userdata) - { - child->setCallbackUserData(userdata); - } - } -} - void LLPanel::childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*)) { LLUICtrl* child = getChild(id, true); @@ -962,7 +949,7 @@ void LLPanel::childSetWrappedText(const std::string& id, const std::string& text } } -void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void* value) +void LLPanel::childSetAction(const std::string& id, boost::function function, void* value) { LLButton* button = getChild(id); if (button) @@ -971,6 +958,15 @@ void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void } } +void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function) +{ + LLButton* button = getChild(id); + if (button) + { + button->setClickedCallback(function); + } +} + void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value) { LLTextBox* textbox = getChild(id); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index dbf17aec6..385276c64 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -170,7 +170,6 @@ public: BOOL childHasFocus(const std::string& id); void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL ); - void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL ); void childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*) ); void childSetUserData(const std::string& id, void* userdata); @@ -211,7 +210,8 @@ public: void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) ); // LLButton - void childSetAction(const std::string& id, void(*function)(void*), void* value); + void childSetAction(const std::string& id, boost::function function, void* value); + void childSetAction(const std::string& id, const commit_signal_t::slot_type& function); void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL); void childSetControlName(const std::string& id, const std::string& control_name); diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index ea168a35c..cadc34046 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2050,7 +2050,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if(mOnMaximumSelectCallback) { - mOnMaximumSelectCallback(mCallbackUserData); + mOnMaximumSelectCallback(); } break; } @@ -2088,7 +2088,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if(mOnMaximumSelectCallback) { - mOnMaximumSelectCallback(mCallbackUserData); + mOnMaximumSelectCallback(); } } } @@ -2181,7 +2181,7 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) { if( mCanSelect && mOnDoubleClickCallback ) { - mOnDoubleClickCallback( mCallbackUserData ); + mOnDoubleClickCallback(); } } } @@ -3320,7 +3320,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata) if (parent->mOnSortChangedCallback) { - parent->mOnSortChangedCallback(parent->getCallbackUserData()); + parent->mOnSortChangedCallback(); } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 4060c1466..5c678f601 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -385,6 +385,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, public LLCtrlListInterface, public LLCtrlScrollInterface { public: + typedef boost::function callback_t; LLScrollListCtrl( const std::string& name, const LLRect& rect, @@ -466,9 +467,11 @@ public: void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change void highlightNthItem( S32 index ); - void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } - void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } - void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } + void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; } + void setMaximumSelectCallback( callback_t cb ) { mOnMaximumSelectCallback = cb; } + void setSortChangedCallback( callback_t cb ) { mOnSortChangedCallback = cb; } + // Convenience function; *TODO: replace with setter above + boost::bind() in calling code + void setDoubleClickCallback( boost::function cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); } void swapWithNext(S32 index); void swapWithPrevious(S32 index); @@ -700,9 +703,9 @@ private: LLColor4 mDefaultListTextColor; S32 mBorderThickness; - void (*mOnDoubleClickCallback)(void* userdata); - void (*mOnMaximumSelectCallback)(void* userdata ); - void (*mOnSortChangedCallback)(void* userdata); + callback_t mOnDoubleClickCallback; + callback_t mOnMaximumSelectCallback; + callback_t mOnSortChangedCallback; S32 mHighlightedItem; class LLViewBorder* mBorder; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 23d4290b5..58cb3e5fa 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -527,10 +527,6 @@ BOOL LLUICtrl::getTentative() const return mTentative; } -// virtual -void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) ) -{ -} // virtual void LLUICtrl::setColor(const LLColor4& color) diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index c8f9b4b85..d0de1a4a1 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -103,7 +103,6 @@ public: // Default to no-op: virtual void onTabInto(); virtual void clear(); - virtual void setDoubleClickCallback( void (*cb)(void*) ); virtual void setColor(const LLColor4& color); virtual void setAlpha(F32 alpha); virtual void setMinValue(LLSD min_value); diff --git a/indra/newview/hbfloatergrouptitles.cpp b/indra/newview/hbfloatergrouptitles.cpp index bd6de9efd..9ebdae508 100644 --- a/indra/newview/hbfloatergrouptitles.cpp +++ b/indra/newview/hbfloatergrouptitles.cpp @@ -127,8 +127,7 @@ BOOL HBFloaterGroupTitles::postBuild() { return FALSE; } - mTitlesList->setCallbackUserData(this); - mTitlesList->setDoubleClickCallback(onActivate); + mTitlesList->setDoubleClickCallback(boost::bind(&HBFloaterGroupTitles::onActivate,this)); childSetAction("activate", onActivate, this); update_titles_list(this); return TRUE; diff --git a/indra/newview/jcfloaterareasearch.cpp b/indra/newview/jcfloaterareasearch.cpp index 3cb15b052..e4ecb7b53 100644 --- a/indra/newview/jcfloaterareasearch.cpp +++ b/indra/newview/jcfloaterareasearch.cpp @@ -88,8 +88,7 @@ void JCFloaterAreaSearch::close(bool app) BOOL JCFloaterAreaSearch::postBuild() { mResultList = getChild("result_list"); - mResultList->setCallbackUserData(this); - mResultList->setDoubleClickCallback(onDoubleClick); + mResultList->setDoubleClickCallback(onDoubleClick,this); mResultList->sortByColumn("Name", TRUE); mCounterText = getChild("counter"); diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp index 9aa5a7adf..23a6d04be 100644 --- a/indra/newview/llfloateractivespeakers.cpp +++ b/indra/newview/llfloateractivespeakers.cpp @@ -333,10 +333,10 @@ BOOL LLPanelActiveSpeakers::postBuild() mSpeakerList = getChild("speakers_list"); mSpeakerList->sortByColumn(sort_column, sort_ascending); - mSpeakerList->setDoubleClickCallback(onDoubleClickSpeaker); + mSpeakerList->setDoubleClickCallback(boost::bind(&onDoubleClickSpeaker,this)); mSpeakerList->setCommitOnSelectionChange(TRUE); mSpeakerList->setCommitCallback(onSelectSpeaker); - mSpeakerList->setSortChangedCallback(onSortChanged); + mSpeakerList->setSortChangedCallback(boost::bind(&LLPanelActiveSpeakers::onSortChanged,this)); mSpeakerList->setCallbackUserData(this); mMuteTextCtrl = getChild("mute_text_btn"); diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index c214f3480..9d7321405 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -354,7 +354,7 @@ BOOL LLFloaterAvatarList::postBuild() mAvatarList->setCommitOnSelectionChange(TRUE); mAvatarList->setCallbackUserData(this); mAvatarList->setCommitCallback(onSelectName); - mAvatarList->setDoubleClickCallback(onClickFocus); + mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this)); refreshAvatarList(); gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index b93812506..b7d465ed9 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -108,23 +108,25 @@ BOOL LLFloaterAvatarPicker::postBuild() childSetKeystrokeCallback("Edit", editKeystroke, this); childSetKeystrokeCallback("EditUUID", editKeystroke, this); - childSetAction("Find", onBtnFind, this); - childDisable("Find"); - childSetAction("Refresh", onBtnRefresh, this); - childSetCommitCallback("near_me_range", onRangeAdjust, this); + childSetAction("Find", boost::bind(&LLFloaterAvatarPicker::onBtnFind, this)); + getChildView("Find")->setEnabled(FALSE); + childSetAction("Refresh", boost::bind(&LLFloaterAvatarPicker::onBtnRefresh, this)); + getChild("near_me_range")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onRangeAdjust, _1, this)); - childSetDoubleClickCallback("SearchResults", onBtnSelect); - childSetDoubleClickCallback("NearMe", onBtnSelect); - childSetCommitCallback("SearchResults", onList, this); - childSetCommitCallback("NearMe", onList, this); - childDisable("SearchResults"); + LLScrollListCtrl* searchresults = getChild("SearchResults"); + searchresults->setDoubleClickCallback( boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + searchresults->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, _1, this)); + getChildView("SearchResults")->setEnabled(FALSE); - childSetAction("Select", onBtnSelect, this); - childDisable("Select"); + LLScrollListCtrl* nearme = getChild("NearMe"); + nearme->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + nearme->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, _1, this)); - childSetAction("Cancel", onBtnClose, this); + childSetAction("Select", boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + getChildView("Select")->setEnabled(FALSE); + childSetAction("Cancel", boost::bind(&LLFloaterAvatarPicker::onBtnClose, this)); - childSetFocus("Edit"); + getChild("Edit")->setFocus(TRUE); LLPanel* search_panel = getChild("SearchPanel"); if (search_panel) @@ -162,10 +164,9 @@ LLFloaterAvatarPicker::~LLFloaterAvatarPicker() sInstance = NULL; } -void LLFloaterAvatarPicker::onBtnFind(void* userdata) +void LLFloaterAvatarPicker::onBtnFind() { - LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; - if(self) self->find(); + find(); } static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vector& avatar_names, std::vector& avatar_ids) diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 17b928f40..467aa6f68 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -56,7 +56,7 @@ private: static void editKeystroke(class LLLineEditor* caller, void* user_data); - static void onBtnFind(void* userdata); + void onBtnFind(); static void onBtnSelect(void* userdata); static void onBtnRefresh(void* userdata); static void onRangeAdjust(LLUICtrl* source, void* data); diff --git a/indra/newview/llfloaterexploresounds.cpp b/indra/newview/llfloaterexploresounds.cpp index 6ada9c155..00cbcab59 100644 --- a/indra/newview/llfloaterexploresounds.cpp +++ b/indra/newview/llfloaterexploresounds.cpp @@ -75,15 +75,16 @@ void LLFloaterExploreSounds::close(bool app_quitting) BOOL LLFloaterExploreSounds::postBuild(void) { - childSetDoubleClickCallback("sound_list", handle_play_locally, this); + LLScrollListCtrl* soundlist = getChild("sound_list"); + soundlist->setDoubleClickCallback(boost::bind(&LLFloaterExploreSounds::handle_play_locally,this)); + soundlist->sortByColumn("playing", TRUE); childSetAction("play_locally_btn", handle_play_locally, this); childSetAction("look_at_btn", handle_look_at, this); childSetAction("stop_btn", handle_stop, this); childSetAction("bl_btn", blacklistSound, this); - LLScrollListCtrl* list = getChild("sound_list"); - list->sortByColumn("playing", TRUE); + return TRUE; } diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 2b09b57d4..289a030a1 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -369,7 +369,7 @@ BOOL LLPanelFriends::postBuild() mFriendsList->setCommitOnSelectionChange(TRUE); childSetCommitCallback("friend_list", onSelectName, this); childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); - childSetDoubleClickCallback("friend_list", onClickIM); + mFriendsList->setDoubleClickCallback(onClickIM, this); // // Contact search and group system. diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index c2d7ac14b..14b2ddf44 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -114,8 +114,9 @@ BOOL LLFloaterGesture::postBuild() setTitle(label); - childSetCommitCallback("gesture_list", onCommitList, this); - childSetDoubleClickCallback("gesture_list", onClickPlay); + LLScrollListCtrl* gesture_list = getChild("avatar_list"); + gesture_list->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList,this)); + gesture_list->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay,this)); childSetAction("inventory_btn", onClickInventory, this); diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index ddc601f9d..357e2966c 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -136,8 +136,7 @@ BOOL LLFloaterGroupPicker::postBuild() setDefaultBtn("OK"); - childSetDoubleClickCallback("group list", onBtnOK); - childSetUserData("group list", this); + group_list->setDoubleClickCallback(boost::bind(&LLFloaterGroupPicker::onBtnOK,this)); childEnable("OK"); @@ -222,7 +221,8 @@ BOOL LLPanelGroups::postBuild() const std::string none_text = getString("none"); LLScrollListCtrl *group_list = getChild("group list"); init_group_list(group_list, gAgent.getGroupID(), none_text); - group_list->setSortChangedCallback(onGroupSortChanged); //Force 'none' to always be first entry. + group_list->setSortChangedCallback(boost::bind(&onGroupSortChanged,this)); //Force 'none' to always be first entry. + group_list->setDoubleClickCallback(boost::bind(&LLPanelGroups::onBtnIM,this)); childSetAction("Activate", onBtnActivate, this); @@ -242,9 +242,6 @@ BOOL LLPanelGroups::postBuild() setDefaultBtn("IM"); - childSetDoubleClickCallback("group list", onBtnIM); - childSetUserData("group list", this); - reset(); return TRUE; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 3d1a4452f..9c372771e 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1126,7 +1126,7 @@ BOOL LLPanelLandObjects::postBuild() mOwnerList = getChild("owner list"); mOwnerList->sortByColumnIndex(3, FALSE); childSetCommitCallback("owner list", onCommitList, this); - mOwnerList->setDoubleClickCallback(onDoubleClickOwner); + mOwnerList->setDoubleClickCallback(boost::bind(&LLPanelLandObjects::onDoubleClickOwner, this)); return TRUE; } diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index bd1186b15..832bf6b86 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -100,11 +100,12 @@ BOOL LLFloaterLandHoldings::postBuild() childSetAction("Teleport", onClickTeleport, this); childSetAction("Show on Map", onClickMap, this); - // Grant list - childSetDoubleClickCallback("grant list", onGrantList); - childSetUserData("grant list", this); + LLScrollListCtrl *grant_list = getChild("grant list"); - LLCtrlListInterface *list = childGetListInterface("grant list"); + // Grant list + grant_list->setDoubleClickCallback(boost::bind(&LLFloaterLandHoldings::onGrantList,this)); + + LLCtrlListInterface *list = grant_list->getListInterface(); if (!list) return TRUE; S32 count = gAgent.mGroups.count(); diff --git a/indra/newview/llfloaternewim.cpp b/indra/newview/llfloaternewim.cpp index de1a306da..8bff4f17f 100644 --- a/indra/newview/llfloaternewim.cpp +++ b/indra/newview/llfloaternewim.cpp @@ -60,8 +60,7 @@ BOOL LLFloaterNewIM::postBuild() mSelectionList = getChild("user_list"); if (mSelectionList) { - mSelectionList->setDoubleClickCallback(&LLFloaterNewIM::onStart); - mSelectionList->setCallbackUserData(this); + mSelectionList->setDoubleClickCallback(boost::bind(&LLFloaterNewIM::onStart,this)); } else { diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index e6250063f..5d6b771d5 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -77,12 +77,10 @@ BOOL LLNotificationChannelPanel::postBuild() mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false)); LLScrollListCtrl* scroll = getChild("notifications_list"); - scroll->setDoubleClickCallback(onClickNotification); - scroll->setCallbackUserData(this); + scroll->setDoubleClickCallback(boost::bind(&LLNotificationChannelPanel::onClickNotification,this)); scroll = getChild("notification_rejects_list"); - scroll->setDoubleClickCallback(onClickNotificationReject); - scroll->setCallbackUserData(this); + scroll->setDoubleClickCallback(boost::bind(&LLNotificationChannelPanel::onClickNotificationReject,this)); return TRUE; } diff --git a/indra/newview/llfloaterteleporthistory.cpp b/indra/newview/llfloaterteleporthistory.cpp index 14ddd9541..6f3d06407 100644 --- a/indra/newview/llfloaterteleporthistory.cpp +++ b/indra/newview/llfloaterteleporthistory.cpp @@ -96,8 +96,8 @@ BOOL LLFloaterTeleportHistory::postBuild() } // setup callbacks for the scroll list - mPlacesList->setDoubleClickCallback(onTeleport); - childSetCommitCallback("places_list", onPlacesSelected, this); + mPlacesList->setDoubleClickCallback(boost::bind(&LLFloaterTeleportHistory::onTeleport,this)); + mPlacesList->setCommitCallback(boost::bind(&LLFloaterTeleportHistory::onPlacesSelected,_1,this)); childSetAction("teleport", onTeleport, this); childSetAction("show_on_map", onShowOnMap, this); childSetAction("copy_slurl", onCopySLURL, this); diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 8abbc2d26..c230aef4c 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -92,12 +92,13 @@ LLFloaterTopObjects::~LLFloaterTopObjects() // virtual BOOL LLFloaterTopObjects::postBuild() { - childSetCommitCallback("objects_list", onCommitObjectsList, this); - childSetDoubleClickCallback("objects_list", onDoubleClickObjectsList); - childSetFocus("objects_list"); + LLScrollListCtrl *objects_list = getChild("objects_list"); if (objects_list) { + objects_list->setCommitCallback(boost::bind(&LLFloaterTopObjects::onCommitObjectsList,_1,this)); + objects_list->setDoubleClickCallback(boost::bind(&LLFloaterTopObjects::onDoubleClickObjectsList,this)); + objects_list->setFocus(true); objects_list->setCommitOnSelectionChange(TRUE); } diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index c24c146f3..feef951f2 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -220,13 +220,9 @@ BOOL LLFloaterWorldMap::postBuild() location_editor->setKeystrokeCallback( onSearchTextEntry ); LLScrollListCtrl* search_results = getChild("search_results"); - search_results->setDoubleClickCallback(&LLFloaterWorldMap::onClickTeleportBtn_static); - search_results->setCallbackUserData(this); + search_results->setDoubleClickCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn,this)); mListSearchResults = dynamic_cast(search_results); - - - LLComboBox *landmark_combo = getChild( "landmark combo"); landmark_combo->selectFirstItem(); diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index b7f00e1df..53cd425b7 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -127,7 +127,6 @@ protected: void onClearBtn(); void onClickTeleportBtn(); - static void onClickTeleportBtn_static(void* data) {((LLFloaterWorldMap*)data)->onClickTeleportBtn();}; void onShowTargetBtn(); void onShowAgentBtn(); void onCopySLURL(); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 14709805e..b068adfe0 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -582,11 +582,10 @@ BOOL LLPanelAvatarSecondLife::postBuild(void) childSetAction("Offer Teleport...", LLPanelAvatar::onClickOfferTeleport, getPanelAvatar() ); - childSetDoubleClickCallback("groups", onDoubleClickGroup, this ); + getChild("groups")->setDoubleClickCallback(boost::bind(&LLPanelAvatarSecondLife::onDoubleClickGroup,this)); childSetAction("bigimg", onClickImage, this); - getChild("img")->setFallbackImageName("default_profile_picture.j2c"); return TRUE; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 5aecdce57..21833ce17 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -156,8 +156,7 @@ BOOL LLPanelGroupGeneral::postBuild() mListVisibleMembers = getChild("visible_members", recurse); if (mListVisibleMembers) { - mListVisibleMembers->setDoubleClickCallback(&LLPanelGroupGeneral::openProfile); - mListVisibleMembers->setCallbackUserData(this); + mListVisibleMembers->setDoubleClickCallback(boost::bind(&LLPanelGroupGeneral::openProfile,this)); } // Options diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 1a6013cfe..d0a878877 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -890,11 +890,10 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE; // We want to be notified whenever a member is selected. - mMembersList->setCallbackUserData(this); mMembersList->setCommitOnSelectionChange(TRUE); - mMembersList->setCommitCallback(onMemberSelect); + mMembersList->setCommitCallback(boost::bind(&LLPanelGroupMembersSubTab::onMemberSelect,_1,this)); // Show the member's profile on double click. - mMembersList->setDoubleClickCallback(onMemberDoubleClick); + mMembersList->setDoubleClickCallback(boost::bind(&LLPanelGroupMembersSubTab::onMemberDoubleClick,this)); LLButton* button = parent->getChild("member_invite", recurse); if ( button ) diff --git a/indra/newview/llpanelgroupvoting.cpp b/indra/newview/llpanelgroupvoting.cpp index 89134c437..73b00c509 100644 --- a/indra/newview/llpanelgroupvoting.cpp +++ b/indra/newview/llpanelgroupvoting.cpp @@ -1579,11 +1579,9 @@ BOOL LLPanelGroupVoting::postBuild() //associate callbacks if ( success ) { - mImpl->mProposals->setDoubleClickCallback(impl::onDoubleClickProposal); - mImpl->mProposals->setCallbackUserData(mImpl); + mImpl->mProposals->setDoubleClickCallback(boost::bind(&LLPanelGroupVoting::impl::onDoubleClickProposal,mImpl)); - mImpl->mVotesHistory->setDoubleClickCallback(impl::onDoubleClickHistoryItem); - mImpl->mVotesHistory->setCallbackUserData(mImpl); + mImpl->mVotesHistory->setDoubleClickCallback(boost::bind(&LLPanelGroupVoting::impl::onDoubleClickHistoryItem,mImpl)); mImpl->mBtnAbstain->setClickedCallback(boost::bind(&impl::onClickAbstain,mImpl)); diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index ecb260704..69b272186 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -434,8 +434,8 @@ BOOL LLPreviewGesture::postBuild() list = getChild("library_list"); list->setCommitCallback(onCommitLibrary); - list->setDoubleClickCallback(onClickAdd); list->setCallbackUserData(this); + list->setDoubleClickCallback(boost::bind(&LLPreviewGesture::onClickAdd,this)); mLibraryList = list; btn = getChild( "add_btn"); @@ -527,12 +527,10 @@ BOOL LLPreviewGesture::postBuild() btn = getChild( "save_btn"); btn->setClickedCallback(boost::bind(&LLPreviewGesture::onClickSave,this)); - btn->setCallbackUserData(this); mSaveBtn = btn; btn = getChild( "preview_btn"); btn->setClickedCallback(boost::bind(&LLPreviewGesture::onClickPreview,this)); - btn->setCallbackUserData(this); mPreviewBtn = btn; From 26191dd27415a42c1c0f969d01f7751ff59d75de Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 6 Dec 2012 17:13:17 -0600 Subject: [PATCH 79/93] Migrate to boost::bind for a bunch of CommitCallbacks. Converted several static member functions to nonstatic member functions --- indra/llcharacter/llmultigesture.cpp | 3 +- indra/llcharacter/llmultigesture.h | 3 +- indra/newview/floaterao.cpp | 48 +-- indra/newview/floaterao.h | 8 +- indra/newview/floaterlocalassetbrowse.cpp | 27 +- indra/newview/floaterlocalassetbrowse.h | 6 +- indra/newview/lldebugmessagebox.cpp | 14 +- indra/newview/llfloateractivespeakers.cpp | 10 +- indra/newview/llfloateractivespeakers.h | 1 - indra/newview/llfloateravatarlist.cpp | 16 +- indra/newview/llfloateravatarlist.h | 2 +- indra/newview/llfloatercolorpicker.cpp | 17 +- indra/newview/llfloatercolorpicker.h | 2 +- indra/newview/llfloaterdaycycle.cpp | 4 +- indra/newview/llfloaterdaycycle.h | 2 +- indra/newview/llfloaterfriends.cpp | 2 +- indra/newview/llfloatergesture.cpp | 21 +- indra/newview/llfloatergesture.h | 2 +- indra/newview/llfloatergroups.cpp | 38 +-- indra/newview/llfloatergroups.h | 3 +- indra/newview/llfloaterland.cpp | 25 +- indra/newview/llfloaterland.h | 2 +- indra/newview/llpaneldirland.cpp | 2 +- indra/newview/llpanelgroupgeneral.cpp | 79 ++--- indra/newview/llpanelgroupgeneral.h | 8 +- indra/newview/llpreviewgesture.cpp | 387 +++++++++------------- indra/newview/llpreviewgesture.h | 34 +- 27 files changed, 326 insertions(+), 440 deletions(-) diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp index e7e6575de..d8290681a 100644 --- a/indra/llcharacter/llmultigesture.cpp +++ b/indra/llcharacter/llmultigesture.cpp @@ -50,8 +50,7 @@ LLMultiGesture::LLMultiGesture() mSteps(), mPlaying(FALSE), mCurrentStep(0), - mDoneCallback(NULL), - mCallbackData(NULL) + mDoneCallback(NULL) { reset(); } diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h index 0c027b31b..d34366671 100644 --- a/indra/llcharacter/llmultigesture.h +++ b/indra/llcharacter/llmultigesture.h @@ -100,8 +100,7 @@ public: // Timer for waiting LLFrameTimer mWaitTimer; - void (*mDoneCallback)(LLMultiGesture* gesture, void* data); - void* mCallbackData; + boost::function mDoneCallback; // Animations that we requested to start std::set mRequestedAnimIDs; diff --git a/indra/newview/floaterao.cpp b/indra/newview/floaterao.cpp index f7bdf090f..59f922cca 100644 --- a/indra/newview/floaterao.cpp +++ b/indra/newview/floaterao.cpp @@ -356,9 +356,9 @@ BOOL LLFloaterAO::postBuild() childSetAction("newcard",onClickNewCard,this); childSetAction("prevstand",onClickPrevStand,this); childSetAction("nextstand",onClickNextStand,this); - childSetCommitCallback("AOEnabled",onClickToggleAO); - childSetCommitCallback("AOSitsEnabled",onClickToggleSits); - childSetCommitCallback("standtime",onSpinnerCommit); + getChild("AOEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleAO)); + getChild("AOSitsEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleSits)); + getChild("standtime")->setCommitCallback(boost::bind(&LLFloaterAO::onSpinnerCommit,_1)); mcomboBox_stands = getChild("stands"); mcomboBox_walks = getChild("walks"); mcomboBox_runs = getChild("runs"); @@ -376,28 +376,28 @@ BOOL LLFloaterAO::postBuild() mcomboBox_lands = getChild("lands"); mcomboBox_standups = getChild("standups"); mcomboBox_prejumps = getChild("prejumps"); - getChild("stands")->setCommitCallback(onComboBoxCommit); - getChild("walks")->setCommitCallback(onComboBoxCommit); - getChild("runs")->setCommitCallback(onComboBoxCommit); - getChild("jumps")->setCommitCallback(onComboBoxCommit); - getChild("sits")->setCommitCallback(onComboBoxCommit); - getChild("gsits")->setCommitCallback(onComboBoxCommit); - getChild("crouchs")->setCommitCallback(onComboBoxCommit); - getChild("cwalks")->setCommitCallback(onComboBoxCommit); - getChild("falls")->setCommitCallback(onComboBoxCommit); - getChild("hovers")->setCommitCallback(onComboBoxCommit); - getChild("flys")->setCommitCallback(onComboBoxCommit); - getChild("flyslows")->setCommitCallback(onComboBoxCommit); - getChild("flyups")->setCommitCallback(onComboBoxCommit); - getChild("flydowns")->setCommitCallback(onComboBoxCommit); - getChild("lands")->setCommitCallback(onComboBoxCommit); - getChild("standups")->setCommitCallback(onComboBoxCommit); - getChild("prejumps")->setCommitCallback(onComboBoxCommit); + getChild("stands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("walks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("runs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("jumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("sits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("gsits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("crouchs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("cwalks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("falls")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("hovers")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flys")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flyslows")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flyups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("flydowns")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("lands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("standups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); + getChild("prejumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1)); return TRUE; } -void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl, void* userdata) +void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl) { LLSpinCtrl* spin = (LLSpinCtrl*) ctrl; if(spin) @@ -409,7 +409,7 @@ void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl, void* userdata) } } -void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl, void* userdata) +void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl) { LLComboBox* box = (LLComboBox*)ctrl; if(box) @@ -727,12 +727,12 @@ void LLFloaterAO::onClickLess(void* data) updateLayout(sInstance); } -void LLFloaterAO::onClickToggleAO(LLUICtrl *, void*) +void LLFloaterAO::onClickToggleAO() { run(); } -void LLFloaterAO::onClickToggleSits(LLUICtrl *, void*) +void LLFloaterAO::onClickToggleSits() { run(); } diff --git a/indra/newview/floaterao.h b/indra/newview/floaterao.h index 55cc7c052..72bdf2903 100644 --- a/indra/newview/floaterao.h +++ b/indra/newview/floaterao.h @@ -68,8 +68,8 @@ public: static void show(void*); static void init(); - static void onClickToggleAO(LLUICtrl *, void*); - static void onClickToggleSits(LLUICtrl *, void*); + static void onClickToggleAO(); + static void onClickToggleSits(); static void run(); static void updateLayout(LLFloaterAO* floater); @@ -115,8 +115,8 @@ private: static AONoteCardDropTarget* mAOItemDropTarget; static void AOItemDrop(LLViewerInventoryItem* item); - static void onSpinnerCommit(LLUICtrl* ctrl, void* userdata); - static void onComboBoxCommit(LLUICtrl* ctrl, void* userdata); + static void onSpinnerCommit(LLUICtrl* ctrl); + static void onComboBoxCommit(LLUICtrl* ctrl); static BOOL SetDefault(void *userdata, LLUUID ao_id, std::string defaultanim); BOOL mDirty; diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp index eeb1ebfd4..ef6de943d 100644 --- a/indra/newview/floaterlocalassetbrowse.cpp +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -800,13 +800,13 @@ FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() mUploadBtn->setClickedCallback( onClickUpload, this); // combo callback - mTypeComboBox->setCommitCallback(onCommitTypeCombo); + mTypeComboBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onCommitTypeCombo,this)); // scrolllist callbacks - mBitmapList->setCommitCallback(onChooseBitmapList); + mBitmapList->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onChooseBitmapList,this)); // checkbox callbacks - mUpdateChkBox->setCommitCallback(onClickUpdateChkbox); + mUpdateChkBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpdateChkbox,this)); } @@ -857,34 +857,33 @@ void FloaterLocalAssetBrowser::onClickUpload(void* userdata) } } -void FloaterLocalAssetBrowser::onChooseBitmapList(LLUICtrl* ctrl, void *userdata) +void FloaterLocalAssetBrowser::onChooseBitmapList() { - bool button_status = sLFInstance->mBitmapList->isEmpty(); - sLFInstance->mDelBtn->setEnabled(!button_status); - sLFInstance->mUploadBtn->setEnabled(!button_status); + bool button_status = mBitmapList->isEmpty(); + mDelBtn->setEnabled(!button_status); + mUploadBtn->setEnabled(!button_status); - sLFInstance->UpdateRightSide(); + UpdateRightSide(); } -void FloaterLocalAssetBrowser::onClickUpdateChkbox(LLUICtrl *ctrl, void *userdata) +void FloaterLocalAssetBrowser::onClickUpdateChkbox() { - std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); if ( !temp_str.empty() ) { gLocalBrowser->onUpdateBool( (LLUUID)temp_str ); - sLFInstance->UpdateRightSide(); + UpdateRightSide(); } } -void FloaterLocalAssetBrowser::onCommitTypeCombo(LLUICtrl* ctrl, void *userdata) +void FloaterLocalAssetBrowser::onCommitTypeCombo() { - std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + std::string temp_str = mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); if ( !temp_str.empty() ) { S32 selection = sLFInstance->mTypeComboBox->getCurrentIndex(); gLocalBrowser->onSetType( (LLUUID)temp_str, selection ); - } } diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h index fb26cdccc..b95845710 100644 --- a/indra/newview/floaterlocalassetbrowse.h +++ b/indra/newview/floaterlocalassetbrowse.h @@ -236,13 +236,13 @@ private: static void onClickUpload(void* userdata); // ScrollList callback declarations - static void onChooseBitmapList(LLUICtrl* ctrl, void* userdata); + void onChooseBitmapList(); // Checkbox callback declarations - static void onClickUpdateChkbox(LLUICtrl* ctrl, void* userdata); + void onClickUpdateChkbox(); // Combobox type select - static void onCommitTypeCombo(LLUICtrl* ctrl, void* userdata); + void onCommitTypeCombo(); // Widgets LLButton* mAddBtn; diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp index 4188ecc0e..ab5ddf18b 100644 --- a/indra/newview/lldebugmessagebox.cpp +++ b/indra/newview/lldebugmessagebox.cpp @@ -112,7 +112,7 @@ void LLDebugVarMessageBox::show(const std::string& title, F32 *var, F32 max_valu { box->mSlider1->setValue(*var); } - box->mSlider1->setCommitCallback(slider_changed); + box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); box->mSlider1->setCallbackUserData(box); #endif } @@ -129,8 +129,7 @@ void LLDebugVarMessageBox::show(const std::string& title, S32 *var, S32 max_valu { box->mSlider1->setValue((F32)*var); } - box->mSlider1->setCommitCallback(slider_changed); - box->mSlider1->setCallbackUserData(box); + box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); #endif } @@ -142,20 +141,17 @@ void LLDebugVarMessageBox::show(const std::string& title, LLVector3 *var, LLVect box->mSlider1->setMaxValue(max_value.mV[VX]); box->mSlider1->setMinValue(-max_value.mV[VX]); box->mSlider1->setIncrement(increment.mV[VX]); - box->mSlider1->setCommitCallback(slider_changed); - box->mSlider1->setCallbackUserData(box); + box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); box->mSlider2->setMaxValue(max_value.mV[VX]); box->mSlider2->setMinValue(-max_value.mV[VX]); box->mSlider2->setIncrement(increment.mV[VX]); - box->mSlider2->setCommitCallback(slider_changed); - box->mSlider2->setCallbackUserData(box); + box->mSlider2->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); box->mSlider3->setMaxValue(max_value.mV[VX]); box->mSlider3->setMinValue(-max_value.mV[VX]); box->mSlider3->setIncrement(increment.mV[VX]); - box->mSlider3->setCommitCallback(slider_changed); - box->mSlider3->setCallbackUserData(box); + box->mSlider3->setCommitCallback(boost::bind(&LLDebugVarMessageBox::slider_changed,_1,box)); #endif } diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp index 23a6d04be..7934fda10 100644 --- a/indra/newview/llfloateractivespeakers.cpp +++ b/indra/newview/llfloateractivespeakers.cpp @@ -335,7 +335,7 @@ BOOL LLPanelActiveSpeakers::postBuild() mSpeakerList->sortByColumn(sort_column, sort_ascending); mSpeakerList->setDoubleClickCallback(boost::bind(&onDoubleClickSpeaker,this)); mSpeakerList->setCommitOnSelectionChange(TRUE); - mSpeakerList->setCommitCallback(onSelectSpeaker); + mSpeakerList->setCommitCallback(boost::bind(&LLPanelActiveSpeakers::handleSpeakerSelect,this)); mSpeakerList->setSortChangedCallback(boost::bind(&LLPanelActiveSpeakers::onSortChanged,this)); mSpeakerList->setCallbackUserData(this); @@ -813,14 +813,6 @@ void LLPanelActiveSpeakers::onDoubleClickSpeaker(void* user_data) } } -//static -void LLPanelActiveSpeakers::onSelectSpeaker(LLUICtrl* source, void* user_data) -{ - LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data; - panelp->handleSpeakerSelect(); -} - - //static void LLPanelActiveSpeakers::onSortChanged(void* user_data) { diff --git a/indra/newview/llfloateractivespeakers.h b/indra/newview/llfloateractivespeakers.h index b8a9ece01..d641bcdf1 100644 --- a/indra/newview/llfloateractivespeakers.h +++ b/indra/newview/llfloateractivespeakers.h @@ -232,7 +232,6 @@ public: static void onVolumeChange(LLUICtrl* source, void* user_data); static void onClickProfile(void* user_data); static void onDoubleClickSpeaker(void* user_data); - static void onSelectSpeaker(LLUICtrl* source, void* user_data); static void onSortChanged(void* user_data); static void onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data); static void onModeratorMuteText(LLUICtrl* ctrl, void* user_data); diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 9d7321405..dda0f3512 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -353,7 +353,7 @@ BOOL LLFloaterAvatarList::postBuild() mAvatarList->sortByColumn("distance", TRUE); mAvatarList->setCommitOnSelectionChange(TRUE); mAvatarList->setCallbackUserData(this); - mAvatarList->setCommitCallback(onSelectName); + mAvatarList->setCommitCallback(boost::bind(&LLFloaterAvatarList::onSelectName,this)); mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this)); refreshAvatarList(); @@ -1753,21 +1753,19 @@ void LLFloaterAvatarList::onClickTeleport(void* userdata) } } -void LLFloaterAvatarList::onSelectName(LLUICtrl*, void* userdata) +void LLFloaterAvatarList::onSelectName() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (item) { LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); + LLAvatarListEntry* entry = getAvatarEntry(agent_id); if (entry) { BOOL enabled = entry->isDrawn(); - self->childSetEnabled("focus_btn", enabled); - self->childSetEnabled("prev_in_list_btn", enabled); - self->childSetEnabled("next_in_list_btn", enabled); + childSetEnabled("focus_btn", enabled); + childSetEnabled("prev_in_list_btn", enabled); + childSetEnabled("next_in_list_btn", enabled); } } } diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 46bdd1a0f..9b660c800 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -290,7 +290,7 @@ private: static void callbackEjectFromEstate(const LLSD& notification, const LLSD& response); static void callbackBanFromEstate(const LLSD& notification, const LLSD& response); - static void onSelectName(LLUICtrl*, void *userdata); + static void onSelectName(); static void onCommitUpdateRate(LLUICtrl*, void *userdata); static void onClickSendKeys(void *userdata); diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 474e4d874..aa14a4953 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -238,8 +238,7 @@ postBuild() mApplyImmediateCheck = getChild("apply_immediate"); mApplyImmediateCheck->set(gSavedSettings.getBOOL("ApplyColorImmediately")); - mApplyImmediateCheck->setCommitCallback(onImmediateCheck); - mApplyImmediateCheck->setCallbackUserData(this); + mApplyImmediateCheck->setCommitCallback(boost::bind(&LLFloaterColorPicker::onImmediateCheck,this)); childSetCommitCallback("rspin", onTextCommit, (void*)this ); childSetCommitCallback("gspin", onTextCommit, (void*)this ); @@ -500,17 +499,13 @@ onTextCommit ( LLUICtrl* ctrl, void* data ) } } -void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data) +void LLFloaterColorPicker::onImmediateCheck() { - LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data; - if (self) - { - gSavedSettings.setBOOL("ApplyColorImmediately", self->mApplyImmediateCheck->get()); + gSavedSettings.setBOOL("ApplyColorImmediately", mApplyImmediateCheck->get()); - if (self->mApplyImmediateCheck->get()) - { - LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); - } + if (mApplyImmediateCheck->get()) + { + LLColorSwatchCtrl::onColorChanged ( getSwatch(), LLColorSwatchCtrl::COLOR_CHANGE ); } } diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index b93ea664c..6e9e75e3a 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -126,7 +126,7 @@ class LLFloaterColorPicker static void onClickPipette ( void* data ); static void onTextCommit ( LLUICtrl* ctrl, void* data ); static void onHexCommit ( LLUICtrl* ctrl, void* data ); - static void onImmediateCheck ( LLUICtrl* ctrl, void* data ); + void onImmediateCheck(); static void onColorSelect( const LLTextureEntry& te, void *data ); private: // turns on or off text entry commit call backs diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index 7028e5016..3a4e829cf 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -156,7 +156,7 @@ void LLFloaterDayCycle::initCallbacks(void) childSetAction("DayCycleSavePreset", onSavePreset, comboBox); childSetAction("DayCycleDeletePreset", onDeletePreset, comboBox); - comboBox->setCommitCallback(onChangePresetName); + comboBox->setCommitCallback(boost::bind(&LLFloaterDayCycle::onChangePresetName,_1)); childSetAction("WLAddKey", onAddKey, NULL); @@ -478,7 +478,7 @@ bool LLFloaterDayCycle::newPromptCallback(const LLSD& notification, const LLSD& } -void LLFloaterDayCycle::onChangePresetName(LLUICtrl* ctrl, void * userData) +void LLFloaterDayCycle::onChangePresetName(LLUICtrl* ctrl) { LLComboBox * combo_box = static_cast(ctrl); diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h index 9adfc3a02..863ed5418 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -117,7 +117,7 @@ public: static bool newPromptCallback(const LLSD& notification, const LLSD& response); /// what to do when you change the preset name - static void onChangePresetName(LLUICtrl* ctrl, void* userData); + static void onChangePresetName(LLUICtrl* ctrl); /// toggle for Linden time static void onUseLindenTime(void* userData); diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 289a030a1..276e29d47 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -367,7 +367,7 @@ BOOL LLPanelFriends::postBuild() { mFriendsList = getChild("friend_list"); mFriendsList->setCommitOnSelectionChange(TRUE); - childSetCommitCallback("friend_list", onSelectName, this); + mFriendsList->setCommitCallback(onSelectName, this); childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); mFriendsList->setDoubleClickCallback(onClickIM, this); diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index 14b2ddf44..66c41cd7b 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -169,7 +169,7 @@ void LLFloaterGesture::show() self->mSelectedID = LLUUID::null; // Update button labels - onCommitList(NULL, self); + self->onCommitList(); self->open(); /*Flawfinder: ignore*/ } @@ -214,7 +214,7 @@ void LLFloaterGesture::refreshAll() } // Update button labels - onCommitList(NULL, sInstance); + sInstance->onCommitList(); } } @@ -405,22 +405,19 @@ void LLFloaterGesture::onClickEdit(void* data) } } -// static -void LLFloaterGesture::onCommitList(LLUICtrl* ctrl, void* data) +void LLFloaterGesture::onCommitList() { - LLFloaterGesture* self = (LLFloaterGesture*)data; + const LLUUID& item_id = childGetValue("gesture_list").asUUID(); - const LLUUID& item_id = self->childGetValue("gesture_list").asUUID(); - - self->mSelectedID = item_id; + mSelectedID = item_id; if (LLGestureMgr::instance().isGesturePlaying(item_id)) { - self->childSetVisible("play_btn", false); - self->childSetVisible("stop_btn", true); + childSetVisible("play_btn", false); + childSetVisible("stop_btn", true); } else { - self->childSetVisible("play_btn", true); - self->childSetVisible("stop_btn", false); + childSetVisible("play_btn", true); + childSetVisible("stop_btn", false); } } diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h index 4e11a10e6..ba4da14f2 100644 --- a/indra/newview/llfloatergesture.h +++ b/indra/newview/llfloatergesture.h @@ -74,7 +74,7 @@ protected: static void onClickEdit(void* data); static void onClickPlay(void* data); static void onClickNew(void* data); - static void onCommitList(LLUICtrl* ctrl, void* data); + void onCommitList(); protected: LLUUID mSelectedID; diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 357e2966c..c786e94a6 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -70,9 +70,6 @@ std::map LLFloaterGroupPicker::sInstances; // helper functions void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask = GP_ALL_POWERS); -//callbacks -void onGroupSortChanged(void* user_data); - ///---------------------------------------------------------------------------- /// Class LLFloaterGroupPicker ///---------------------------------------------------------------------------- @@ -128,7 +125,8 @@ BOOL LLFloaterGroupPicker::postBuild() { const std::string none_text = getString("none"); - init_group_list(getChild("group list"), gAgent.getGroupID(), none_text, mPowersMask); + LLScrollListCtrl* group_list = getChild("group list"); + init_group_list(group_list, gAgent.getGroupID(), none_text, mPowersMask); childSetAction("OK", onBtnOK, this); @@ -213,15 +211,14 @@ void LLPanelGroups::reset() BOOL LLPanelGroups::postBuild() { - childSetCommitCallback("group list", onGroupList, this); - childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); const std::string none_text = getString("none"); LLScrollListCtrl *group_list = getChild("group list"); init_group_list(group_list, gAgent.getGroupID(), none_text); - group_list->setSortChangedCallback(boost::bind(&onGroupSortChanged,this)); //Force 'none' to always be first entry. + group_list->setCommitCallback(boost::bind(&LLPanelGroups::onGroupList,this)); + group_list->setSortChangedCallback(boost::bind(&LLPanelGroups::onGroupSortChanged,this)); //Force 'none' to always be first entry. group_list->setDoubleClickCallback(boost::bind(&LLPanelGroups::onBtnIM,this)); childSetAction("Activate", onBtnActivate, this); @@ -475,15 +472,20 @@ bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& res return false; } -void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata) +void LLPanelGroups::onGroupSortChanged() { - LLPanelGroups *self = (LLPanelGroups*)userdata; - if(!self) + LLScrollListCtrl *group_list = getChild("group list"); + if(!group_list) return; - self->enableButtons(); + group_list->moveToFront(group_list->getItemIndex(LLUUID::null)); +} - LLScrollListCtrl *group_list = (LLScrollListCtrl*)self->getChild("group list"); +void LLPanelGroups::onGroupList() +{ + enableButtons(); + + LLScrollListCtrl *group_list = getChild("group list"); if(!group_list) return; @@ -558,18 +560,6 @@ LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_g return element; } -void onGroupSortChanged(void* user_data) -{ - LLPanelGroups *panel = (LLPanelGroups*)user_data; - if(!panel) - return; - LLScrollListCtrl *group_list = (LLScrollListCtrl*)panel->getChild("group list"); - if(!group_list) - return; - - group_list->moveToFront(group_list->getItemIndex(LLUUID::null)); -} - void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask) { S32 count = gAgent.mGroups.count(); diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h index 5311809eb..ebf37acd7 100644 --- a/indra/newview/llfloatergroups.h +++ b/indra/newview/llfloatergroups.h @@ -103,7 +103,8 @@ protected: // highlight_id is a group id to highlight void enableButtons(); - static void onGroupList(LLUICtrl* ctrl, void* userdata); + void onGroupSortChanged(); + void onGroupList(); static void onBtnCreate(void* userdata); static void onBtnActivate(void* userdata); static void onBtnInfo(void* userdata); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 9c372771e..08425f69b 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1125,7 +1125,7 @@ BOOL LLPanelLandObjects::postBuild() mOwnerList = getChild("owner list"); mOwnerList->sortByColumnIndex(3, FALSE); - childSetCommitCallback("owner list", onCommitList, this); + mOwnerList->setCommitCallback(boost::bind(&LLPanelLandObjects::onCommitList,this)); mOwnerList->setDoubleClickCallback(boost::bind(&LLPanelLandObjects::onDoubleClickOwner, this)); return TRUE; @@ -1621,16 +1621,13 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo } } -// static -void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data) +void LLPanelLandObjects::onCommitList() { - LLPanelLandObjects* self = (LLPanelLandObjects*)data; - - if (FALSE == self->mOwnerList->getCanSelect()) + if (FALSE == mOwnerList->getCanSelect()) { return; } - LLScrollListItem *item = self->mOwnerList->getFirstSelected(); + LLScrollListItem *item = mOwnerList->getFirstSelected(); if (item) { // Look up the selected name, for future dialog box use. @@ -1641,19 +1638,19 @@ void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data) return; } // Is this a group? - self->mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP; + mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP; cell = item->getColumn(2); - self->mSelectedName = cell->getValue().asString(); + mSelectedName = cell->getValue().asString(); cell = item->getColumn(3); - self->mSelectedCount = atoi(cell->getValue().asString().c_str()); + mSelectedCount = atoi(cell->getValue().asString().c_str()); // Set the selection, and enable the return button. - self->mSelectedOwners.clear(); - self->mSelectedOwners.insert(item->getUUID()); - self->mBtnReturnOwnerList->setEnabled(TRUE); + mSelectedOwners.clear(); + mSelectedOwners.insert(item->getUUID()); + mBtnReturnOwnerList->setEnabled(TRUE); // Highlight this user's objects - clickShowCore(self, RT_LIST, &(self->mSelectedOwners)); + clickShowCore(this, RT_LIST, &(mSelectedOwners)); } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 19e8b5260..f578c68d2 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -274,7 +274,7 @@ public: static void onDoubleClickOwner(void*); - static void onCommitList(LLUICtrl* ctrl, void* data); + void onCommitList(); static void onLostFocus(LLFocusableElement* caller, void* user_data); static void onCommitClean(LLUICtrl* caller, void* user_data); static void processParcelObjectOwnersReply(LLMessageSystem *msg, void **); diff --git a/indra/newview/llpaneldirland.cpp b/indra/newview/llpaneldirland.cpp index c1b4c8ce9..d89c049fa 100644 --- a/indra/newview/llpaneldirland.cpp +++ b/indra/newview/llpaneldirland.cpp @@ -111,7 +111,7 @@ BOOL LLPanelDirLand::postBuild() LLScrollListCtrl* results = getChild("results"); if (results) { - results->setSortChangedCallback(onClickSort); + results->setSortChangedCallback(boost::bind(&LLPanelDirLand::onClickSort,this)); results->sortByColumn(mCurrentSortColumn,mCurrentSortAscending); LLStringUtil::format_map_t args; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 21833ce17..b0dfb3704 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -118,18 +118,16 @@ BOOL LLPanelGroupGeneral::postBuild() mInsignia = getChild("insignia", recurse); if (mInsignia) { - mInsignia->setCommitCallback(onCommitAny); - mInsignia->setCallbackUserData(this); + mInsignia->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); mDefaultIconID = mInsignia->getImageAssetID(); } mEditCharter = getChild("charter", recurse); if(mEditCharter) { - mEditCharter->setCommitCallback(onCommitAny); + mEditCharter->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); mEditCharter->setFocusReceivedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this)); mEditCharter->setFocusChangedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this)); - mEditCharter->setCallbackUserData(this); } mBtnJoinGroup = getChild("join_button", recurse); @@ -163,16 +161,14 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlShowInGroupList = getChild("show_in_group_list", recurse); if (mCtrlShowInGroupList) { - mCtrlShowInGroupList->setCommitCallback(&LLPanelGroupGeneral::onCommitAny); - mCtrlShowInGroupList->setCallbackUserData(this); + mCtrlShowInGroupList->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); } mComboMature = getChild("group_mature_check", recurse); if(mComboMature) { mComboMature->setCurrentByIndex(0); - mComboMature->setCommitCallback(onCommitAny); - mComboMature->setCallbackUserData(this); + mComboMature->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); if (gAgent.isTeen()) { // Teens don't get to set mature flag. JC @@ -183,23 +179,20 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlOpenEnrollment = getChild("open_enrollement", recurse); if (mCtrlOpenEnrollment) { - mCtrlOpenEnrollment->setCommitCallback(onCommitAny); - mCtrlOpenEnrollment->setCallbackUserData(this); + mCtrlOpenEnrollment->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); } mCtrlEnrollmentFee = getChild("check_enrollment_fee", recurse); if (mCtrlEnrollmentFee) { mCtrlEnrollmentFee->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); - mCtrlEnrollmentFee->setCommitCallback(onCommitEnrollment); - mCtrlEnrollmentFee->setCallbackUserData(this); + mCtrlEnrollmentFee->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitEnrollment,this)); } mSpinEnrollmentFee = getChild("spin_enrollment_fee", recurse); if (mSpinEnrollmentFee) { - mSpinEnrollmentFee->setCommitCallback(onCommitAny); - mSpinEnrollmentFee->setCallbackUserData(this); + mSpinEnrollmentFee->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this)); mSpinEnrollmentFee->setPrecision(0); mSpinEnrollmentFee->resetDirty(); } @@ -215,8 +208,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveNotices = getChild("receive_notices", recurse); if (mCtrlReceiveNotices) { - mCtrlReceiveNotices->setCommitCallback(onCommitUserOnly); - mCtrlReceiveNotices->setCallbackUserData(this); + mCtrlReceiveNotices->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this)); mCtrlReceiveNotices->set(accept_notices); mCtrlReceiveNotices->setEnabled(data.mID.notNull()); mCtrlReceiveNotices->resetDirty(); @@ -225,8 +217,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveChat = getChild("receive_chat", recurse); if (mCtrlReceiveChat) { - mCtrlReceiveChat->setCommitCallback(onCommitUserOnly); - mCtrlReceiveChat->setCallbackUserData(this); + mCtrlReceiveChat->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this)); mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID)); mCtrlReceiveChat->setEnabled(mGroupID.notNull()); mCtrlReceiveChat->resetDirty(); @@ -235,8 +226,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlListGroup = getChild("list_groups_in_profile", recurse); if (mCtrlListGroup) { - mCtrlListGroup->setCommitCallback(onCommitUserOnly); - mCtrlListGroup->setCallbackUserData(this); + mCtrlListGroup->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this)); mCtrlListGroup->set(list_in_profile); mCtrlListGroup->setEnabled(data.mID.notNull()); mCtrlListGroup->resetDirty(); @@ -247,8 +237,7 @@ BOOL LLPanelGroupGeneral::postBuild() mComboActiveTitle = getChild("active_title", recurse); if (mComboActiveTitle) { - mComboActiveTitle->setCommitCallback(onCommitTitle); - mComboActiveTitle->setCallbackUserData(this); + mComboActiveTitle->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitTitle,this)); mComboActiveTitle->resetDirty(); } @@ -283,60 +272,54 @@ void LLPanelGroupGeneral::onFocusEdit() notifyObservers(); } -void LLPanelGroupGeneral::onCommitAny(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitAny() { - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; - self->updateChanged(); - self->notifyObservers(); + updateChanged(); + notifyObservers(); } // static -void LLPanelGroupGeneral::onCommitUserOnly(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitUserOnly() { - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; - self->mChanged = TRUE; - self->notifyObservers(); + mChanged = TRUE; + notifyObservers(); } -// static -void LLPanelGroupGeneral::onCommitEnrollment(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitEnrollment() { - onCommitAny(ctrl, data); + onCommitAny(); - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; // Make sure both enrollment related widgets are there. - if (!self->mCtrlEnrollmentFee || !self->mSpinEnrollmentFee) + if (!mCtrlEnrollmentFee || !mSpinEnrollmentFee) { return; } // Make sure the agent can change enrollment info. - if (!gAgent.hasPowerInGroup(self->mGroupID,GP_MEMBER_OPTIONS) - || !self->mAllowEdit) + if (!gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS) + || !mAllowEdit) { return; } - if (self->mCtrlEnrollmentFee->get()) + if (mCtrlEnrollmentFee->get()) { - self->mSpinEnrollmentFee->setEnabled(TRUE); + mSpinEnrollmentFee->setEnabled(TRUE); } else { - self->mSpinEnrollmentFee->setEnabled(FALSE); - self->mSpinEnrollmentFee->set(0); + mSpinEnrollmentFee->setEnabled(FALSE); + mSpinEnrollmentFee->set(0); } } -// static -void LLPanelGroupGeneral::onCommitTitle(LLUICtrl* ctrl, void* data) +void LLPanelGroupGeneral::onCommitTitle() { - LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; - if (self->mGroupID.isNull() || !self->mAllowEdit) return; - LLGroupMgr::getInstance()->sendGroupTitleUpdate(self->mGroupID,self->mComboActiveTitle->getCurrentID()); - self->update(GC_TITLES); - self->mComboActiveTitle->resetDirty(); + if (mGroupID.isNull() || !mAllowEdit) return; + LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID()); + update(GC_TITLES); + mComboActiveTitle->resetDirty(); } // static diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 2eeb901c7..1c275d9aa 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -68,10 +68,10 @@ public: private: void onFocusEdit(); - static void onCommitAny(LLUICtrl* ctrl, void* data); - static void onCommitUserOnly(LLUICtrl* ctrl, void* data); - static void onCommitTitle(LLUICtrl* ctrl, void* data); - static void onCommitEnrollment(LLUICtrl* ctrl, void* data); + void onCommitAny(); + void onCommitUserOnly(); + void onCommitTitle(); + void onCommitEnrollment(); static void onClickJoin(void* userdata); static void onClickInfo(void* userdata); static void onReceiveNotices(LLUICtrl* ctrl, void* data); diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 69b272186..c79287e54 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -120,70 +120,67 @@ struct SortItemPtrsByName // static LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& item_id, const LLUUID& object_id, BOOL take_focus) { - LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id); - if (previewp) + LLPreviewGesture* preview = (LLPreviewGesture*)LLPreview::find(item_id); + if (preview) { previewp->open(); /*Flawfinder: ignore*/ - if (take_focus) + } + else + { + preview = new LLPreviewGesture(); + + // Finish internal construction + preview->init(item_id, object_id); + + // Builds and adds to gFloaterView + LLUICtrlFactory::getInstance()->buildFloater(preview, "floater_preview_gesture.xml"); + preview->setTitle(title); + + // Move window to top-left of screen + LLMultiFloater* hostp = preview->getHost(); + if (hostp == NULL) { - previewp->setFocus(TRUE); + LLRect r = self->getRect(); + LLRect screen = gFloaterView->getRect(); + r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight()); + preview->setRect(r); + } + else + { + // re-add to host to update title + hostp->addFloater(preview, TRUE); } - return previewp; - } - LLPreviewGesture* self = new LLPreviewGesture(); + // Start speculative download of sounds and animations + const LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); + LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); - // Finish internal construction - self->init(item_id, object_id); + const LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); + LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); - // Builds and adds to gFloaterView - LLUICtrlFactory::getInstance()->buildFloater(self, "floater_preview_gesture.xml"); - self->setTitle(title); - - // Move window to top-left of screen - LLMultiFloater* hostp = self->getHost(); - if (hostp == NULL) - { - LLRect r = self->getRect(); - LLRect screen = gFloaterView->getRect(); - r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight()); - self->setRect(r); - } - else - { - // re-add to host to update title - hostp->addFloater(self, TRUE); - } - - // Start speculative download of sounds and animations - LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); - LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); - - LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); - LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); - - // this will call refresh when we have everything. - LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); - if (item && !item->isFinished()) - { - LLInventoryGestureAvailable* observer; - observer = new LLInventoryGestureAvailable(); - observer->watchItem(item_id); - gInventory.addObserver(observer); - item->fetchFromServer(); - } - else - { - // not sure this is necessary. - self->refresh(); + // this will call refresh when we have everything. + LLViewerInventoryItem* item = (LLViewerInventoryItem*)preview->getItem(); + if (item && !item->isFinished()) + { + LLInventoryGestureAvailable* observer; + observer = new LLInventoryGestureAvailable(); + observer->watchItem(item_id); + gInventory.addObserver(observer); + item->fetchFromServer(); + } + else + { + // not sure this is necessary. + preview->refresh(); + } } if (take_focus) { - self->setFocus(TRUE); + preview->setFocus(TRUE); } - return self; + return preview; } void LLPreviewGesture::draw() @@ -334,7 +331,7 @@ bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const L case 0: // "Yes" LLGestureMgr::instance().stopGesture(mPreviewGesture); mCloseAfterSave = TRUE; - onClickSave(this); + onClickSave(); break; case 1: // "No" @@ -403,9 +400,9 @@ BOOL LLPreviewGesture::postBuild() edit = getChild("trigger_editor"); edit->setKeystrokeCallback(onKeystrokeCommit); - edit->setCommitCallback(onCommitSetDirty); - edit->setCommitOnFocusLost(TRUE); edit->setCallbackUserData(this); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); + edit->setCommitOnFocusLost(TRUE); edit->setIgnoreTab(TRUE); mTriggerEditor = edit; @@ -416,25 +413,23 @@ BOOL LLPreviewGesture::postBuild() edit = getChild("replace_editor"); edit->setEnabled(FALSE); edit->setKeystrokeCallback(onKeystrokeCommit); - edit->setCommitCallback(onCommitSetDirty); - edit->setCommitOnFocusLost(TRUE); edit->setCallbackUserData(this); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); + edit->setCommitOnFocusLost(TRUE); + edit->setIgnoreTab(TRUE); mReplaceEditor = edit; combo = getChild( "modifier_combo"); - combo->setCommitCallback(onCommitSetDirty); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); mModifierCombo = combo; combo = getChild( "key_combo"); - combo->setCommitCallback(onCommitSetDirty); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSetDirty,this)); mKeyCombo = combo; list = getChild("library_list"); - list->setCommitCallback(onCommitLibrary); - list->setCallbackUserData(this); + list->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitLibrary,this)); list->setDoubleClickCallback(boost::bind(&LLPreviewGesture::onClickAdd,this)); mLibraryList = list; @@ -459,8 +454,7 @@ BOOL LLPreviewGesture::postBuild() mDeleteBtn = btn; list = getChild("step_list"); - list->setCommitCallback(onCommitStep); - list->setCallbackUserData(this); + list->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitStep,this)); mStepList = list; // Options @@ -470,42 +464,38 @@ BOOL LLPreviewGesture::postBuild() combo = getChild( "animation_list"); combo->setVisible(FALSE); - combo->setCommitCallback(onCommitAnimation); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitAnimation,this)); mAnimationCombo = combo; LLRadioGroup* group; group = getChild("animation_trigger_type"); group->setVisible(FALSE); - group->setCommitCallback(onCommitAnimationTrigger); - group->setCallbackUserData(this); + group->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitAnimationTrigger,this)); mAnimationRadio = group; combo = getChild( "sound_list"); combo->setVisible(FALSE); - combo->setCommitCallback(onCommitSound); - combo->setCallbackUserData(this); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitSound,this)); mSoundCombo = combo; edit = getChild("chat_editor"); edit->setVisible(FALSE); - edit->setCommitCallback(onCommitChat); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitChat,this)); //edit->setKeystrokeCallback(onKeystrokeCommit); + //edit->setCallbackUserData(this); edit->setCommitOnFocusLost(TRUE); - edit->setCallbackUserData(this); + edit->setIgnoreTab(TRUE); mChatEditor = edit; check = getChild( "wait_anim_check"); check->setVisible(FALSE); - check->setCommitCallback(onCommitWait); - check->setCallbackUserData(this); + check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitWait,this)); mWaitAnimCheck = check; check = getChild( "wait_time_check"); check->setVisible(FALSE); - check->setCommitCallback(onCommitWait); - check->setCallbackUserData(this); + check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitWait,this)); mWaitTimeCheck = check; edit = getChild("wait_time_editor"); @@ -513,16 +503,16 @@ BOOL LLPreviewGesture::postBuild() edit->setVisible(FALSE); edit->setPrevalidate(LLLineEditor::prevalidateFloat); // edit->setKeystrokeCallback(onKeystrokeCommit); + //edit->setCallbackUserData(this); edit->setCommitOnFocusLost(TRUE); - edit->setCommitCallback(onCommitWaitTime); - edit->setCallbackUserData(this); + edit->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitWaitTime,this)); + edit->setIgnoreTab(TRUE); mWaitTimeEditor = edit; // Buttons at the bottom check = getChild( "active_check"); - check->setCommitCallback(onCommitActive); - check->setCallbackUserData(this); + check->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitActive,this)); mActiveCheck = check; btn = getChild( "save_btn"); @@ -1403,47 +1393,35 @@ void LLPreviewGesture::updateLabel(LLScrollListItem* item) text_cell->setText(label); } -// static -void LLPreviewGesture::onCommitSetDirty(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitSetDirty() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } -// static -void LLPreviewGesture::onCommitLibrary(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitLibrary() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); + LLScrollListItem* library_item = mLibraryList->getFirstSelected(); if (library_item) { - self->mStepList->deselectAllItems(); - self->refresh(); + mStepList->deselectAllItems(); + refresh(); } } -// static -void LLPreviewGesture::onCommitStep(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitStep() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; - self->mLibraryList->deselectAllItems(); - self->refresh(); + mLibraryList->deselectAllItems(); + refresh(); } - -// static -void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitAnimation() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (step_item) { LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); @@ -1451,40 +1429,37 @@ void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) { // Assign the animation name LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationCombo->getCurrentIndex() == 0) + if (mAnimationCombo->getCurrentIndex() == 0) { anim_step->mAnimName.clear(); anim_step->mAnimAssetID.setNull(); } else { - anim_step->mAnimName = self->mAnimationCombo->getSimple(); - anim_step->mAnimAssetID = self->mAnimationCombo->getCurrentID(); + anim_step->mAnimName = mAnimationCombo->getSimple(); + anim_step->mAnimAssetID = mAnimationCombo->getCurrentID(); } //anim_step->mFlags = 0x0; // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } } -// static -void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) +void LLPreviewGesture::onCommitAnimationTrigger() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (step_item) { LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() == STEP_ANIMATION) { LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationRadio->getSelectedIndex() == 0) + if (mAnimationRadio->getSelectedIndex() == 0) { // start anim_step->mFlags &= ~ANIM_FLAG_STOP; @@ -1497,18 +1472,15 @@ void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } } -// static -void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitSound() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (step_item) { LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); @@ -1516,90 +1488,81 @@ void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) { // Assign the sound name LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - sound_step->mSoundName = self->mSoundCombo->getSimple(); - sound_step->mSoundAssetID = self->mSoundCombo->getCurrentID(); + sound_step->mSoundName = mSoundCombo->getSimple(); + sound_step->mSoundAssetID = mSoundCombo->getCurrentID(); sound_step->mFlags = 0x0; // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } } -// static -void LLPreviewGesture::onCommitChat(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitChat() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() != STEP_CHAT) return; LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - chat_step->mChatText = self->mChatEditor->getText(); + chat_step->mChatText = mChatEditor->getText(); chat_step->mFlags = 0x0; // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } -// static -void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitWait() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); - if (step->getType() != STEP_WAIT) return; + if (getType() != STEP_WAIT) return; LLGestureStepWait* wait_step = (LLGestureStepWait*)step; U32 flags = 0x0; - if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; - if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; + if (mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; + if (mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; wait_step->mFlags = flags; { LLLocale locale(LLLocale::USER_LOCALE); - F32 wait_seconds = (F32)atof(self->mWaitTimeEditor->getText().c_str()); + F32 wait_seconds = (F32)atof(mWaitTimeEditor->getText().c_str()); if (wait_seconds < 0.f) wait_seconds = 0.f; if (wait_seconds > 3600.f) wait_seconds = 3600.f; wait_step->mWaitSeconds = wait_seconds; } // Enable the input area if necessary - self->mWaitTimeEditor->setEnabled(self->mWaitTimeCheck->get()); + mWaitTimeEditor->setEnabled(mWaitTimeCheck->get()); // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } -// static -void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitWaitTime() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + LLScrollListItem* step_item = mStepList->getFirstSelected(); if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() != STEP_WAIT) return; - self->mWaitTimeCheck->set(TRUE); - onCommitWait(ctrl, data); + mWaitTimeCheck->set(TRUE); + onCommitWait(); } @@ -1608,18 +1571,15 @@ void LLPreviewGesture::onKeystrokeCommit(LLLineEditor* caller, void* data) { // Just commit every keystroke - onCommitSetDirty(caller, data); + ((LLPreviewGesture*)data)->onCommitSetDirty(); } -// static -void LLPreviewGesture::onClickAdd(void* data) +void LLPreviewGesture::onClickAdd() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); + LLScrollListItem* library_item = mLibraryList->getFirstSelected(); if (!library_item) return; - S32 library_item_index = self->mLibraryList->getFirstSelectedIndex(); + S32 library_item_index = mLibraryList->getFirstSelectedIndex(); const LLScrollListCell* library_cell = library_item->getColumn(0); const std::string& library_text = library_cell->getValue().asString(); @@ -1630,9 +1590,9 @@ void LLPreviewGesture::onClickAdd(void* data) return; } - self->addStep( (EStepType)library_item_index ); - self->mDirty = TRUE; - self->refresh(); + addStep( (EStepType)library_item_index ); + mDirty = TRUE; + refresh(); } LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type ) @@ -1732,129 +1692,110 @@ std::string LLPreviewGesture::getLabel(std::vector labels) return result; } -// static -void LLPreviewGesture::onClickUp(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - S32 selected_index = self->mStepList->getFirstSelectedIndex(); +void LLPreviewGesture::onClickUp() +{ + S32 selected_index = mStepList->getFirstSelectedIndex(); if (selected_index > 0) { - self->mStepList->swapWithPrevious(selected_index); - self->mDirty = TRUE; - self->refresh(); + mStepList->swapWithPrevious(selected_index); + mDirty = TRUE; + refresh(); } } -// static -void LLPreviewGesture::onClickDown(void* data) +void LLPreviewGesture::onClickDown() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - S32 selected_index = self->mStepList->getFirstSelectedIndex(); + S32 selected_index = mStepList->getFirstSelectedIndex(); if (selected_index < 0) return; - S32 count = self->mStepList->getItemCount(); + S32 count = mStepList->getItemCount(); if (selected_index < count-1) { - self->mStepList->swapWithNext(selected_index); - self->mDirty = TRUE; - self->refresh(); + mStepList->swapWithNext(selected_index); + mDirty = TRUE; + refresh(); } } -// static -void LLPreviewGesture::onClickDelete(void* data) +void LLPreviewGesture::onClickDelete() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* item = self->mStepList->getFirstSelected(); - S32 selected_index = self->mStepList->getFirstSelectedIndex(); + LLScrollListItem* item = mStepList->getFirstSelected(); + S32 selected_index = mStepList->getFirstSelectedIndex(); if (item && selected_index >= 0) { LLGestureStep* step = (LLGestureStep*)item->getUserdata(); delete step; - step = NULL; - self->mStepList->deleteSingleItem(selected_index); + mStepList->deleteSingleItem(selected_index); - self->mDirty = TRUE; - self->refresh(); + mDirty = TRUE; + refresh(); } } -// static -void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data) +void LLPreviewGesture::onCommitActive() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - if (!LLGestureMgr::instance().isGestureActive(self->mItemUUID)) + if (!LLGestureMgr::instance().isGestureActive(mItemUUID)) { - LLGestureMgr::instance().activateGesture(self->mItemUUID); + LLGestureMgr::instance().activateGesture(mItemUUID); } else { - LLGestureMgr::instance().deactivateGesture(self->mItemUUID); + LLGestureMgr::instance().deactivateGesture(mItemUUID); } // Make sure the (active) label in the inventory gets updated. - LLViewerInventoryItem* item = gInventory.getItem(self->mItemUUID); + LLViewerInventoryItem* item = gInventory.getItem(mItemUUID); if (item) { gInventory.updateItem(item); gInventory.notifyObservers(); } - self->refresh(); + refresh(); } -// static -void LLPreviewGesture::onClickSave(void* data) +void LLPreviewGesture::onClickSave() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - self->saveIfNeeded(); + saveIfNeeded(); } -// static -void LLPreviewGesture::onClickPreview(void* data) +void LLPreviewGesture::onClickPreview() { - LLPreviewGesture* self = (LLPreviewGesture*)data; - - if (!self->mPreviewGesture) + if (!mPreviewGesture) { // make temporary gesture - self->mPreviewGesture = self->createGesture(); + mPreviewGesture = createGesture(); // add a callback - self->mPreviewGesture->mDoneCallback = onDonePreview; - self->mPreviewGesture->mCallbackData = self; + mPreviewGesture->mDoneCallback = boost::bind(&LLPreviewGesture::onDonePreview,this,_1); // set the button title - self->mPreviewBtn->setLabel(self->getString("stop_txt")); + mPreviewBtn->setLabel(getString("stop_txt")); // play it, and delete when done - LLGestureMgr::instance().playGesture(self->mPreviewGesture); + LLGestureMgr::instance().playGesture(mPreviewGesture); - self->refresh(); + refresh(); } else { // Will call onDonePreview() below - LLGestureMgr::instance().stopGesture(self->mPreviewGesture); + LLGestureMgr::instance().stopGesture(mPreviewGesture); - self->refresh(); + refresh(); } } // static -void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data) +void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture) { - LLPreviewGesture* self = (LLPreviewGesture*)data; + mPreviewBtn->setLabel(getString("preview_txt")); - self->mPreviewBtn->setLabel(self->getString("preview_txt")); + delete mPreviewGesture; + mPreviewGesture = NULL; - delete self->mPreviewGesture; - self->mPreviewGesture = NULL; - - self->refresh(); + refresh(); } diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index 8434a46e5..d4d7228f4 100644 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -116,30 +116,30 @@ protected: static std::string getLabel(std::vector labels); static void updateLabel(LLScrollListItem* item); - static void onCommitSetDirty(LLUICtrl* ctrl, void* data); - static void onCommitLibrary(LLUICtrl* ctrl, void* data); - static void onCommitStep(LLUICtrl* ctrl, void* data); - static void onCommitAnimation(LLUICtrl* ctrl, void* data); - static void onCommitSound(LLUICtrl* ctrl, void* data); - static void onCommitChat(LLUICtrl* ctrl, void* data); - static void onCommitWait(LLUICtrl* ctrl, void* data); - static void onCommitWaitTime(LLUICtrl* ctrl, void* data); + void onCommitSetDirty(); + void onCommitLibrary(); + void onCommitStep(); + void onCommitAnimation(); + void onCommitSound(); + void onCommitChat(); + void onCommitWait(); + void onCommitWaitTime(); - static void onCommitAnimationTrigger(LLUICtrl* ctrl, void *data); + void onCommitAnimationTrigger(); // Handy function to commit each keystroke static void onKeystrokeCommit(LLLineEditor* caller, void* data); - static void onClickAdd(void* data); - static void onClickUp(void* data); - static void onClickDown(void* data); - static void onClickDelete(void* data); + void onClickAdd(); + void onClickUp(); + void onClickDown(); + void onClickDelete(); - static void onCommitActive(LLUICtrl* ctrl, void* data); - static void onClickSave(void* data); - static void onClickPreview(void* data); + void onCommitActive(); + void onClickSave(); + void onClickPreview(); - static void onDonePreview(LLMultiGesture* gesture, void* data); + void onDonePreview(LLMultiGesture* gesture); virtual const char *getTitleName() const { return "Gesture"; } From e750c598be36458320d5731ae1ae199651575896 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 6 Dec 2012 17:16:44 -0600 Subject: [PATCH 80/93] Updated avatar radar. Focusprev/focusnext now obey the order of the actual displayed avatar list. Cleaned up some commit callbacks. --- indra/newview/llagentcamera.cpp | 15 +- indra/newview/llagentcamera.h | 2 +- indra/newview/llfloateravatarlist.cpp | 560 ++++++++++---------------- indra/newview/llfloateravatarlist.h | 108 ++--- 4 files changed, 277 insertions(+), 408 deletions(-) diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index efa26eb7f..8e940c4f5 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2803,18 +2803,18 @@ void LLAgentCamera::lookAtLastChat() } //Pulled implementation out of lookAtLastChat and adapted to work for for general objects -void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) +bool LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) { // Block if camera is animating or not in normal third person camera mode if (mCameraAnimating || !cameraThirdPerson()) { - return; + return false; } LLViewerObject *chatter = gObjectList.findObject(object_id); if (!chatter) { - return; + return false; } LLVector3 delta_pos; @@ -2845,7 +2845,7 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) new_camera_pos += left * 0.3f; new_camera_pos += up * 0.2f; - //setFocusOnAvatar(FALSE, FALSE); + setFocusOnAvatar(FALSE, FALSE); if (chatter_av->mHeadp) { @@ -2863,7 +2863,6 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) else mCameraFocusOffsetTarget.setVec(radius, radius, 0.f); } - setFocusOnAvatar(FALSE, TRUE); } else { @@ -2883,17 +2882,15 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) new_camera_pos += left * 0.3f; new_camera_pos += up * 0.2f; - //setFocusOnAvatar(FALSE, FALSE); - + setFocusOnAvatar(FALSE, FALSE); setFocusGlobal(chatter->getPositionGlobal(), object_id); if(self) mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); else mCameraFocusOffsetTarget.setVec(radius, radius, 0.f); - - setFocusOnAvatar(FALSE, TRUE); } + return true; } diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 663742751..c18b493c2 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -234,7 +234,7 @@ public: BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); ELookAtType getLookAtType(); void lookAtLastChat(); - void lookAtObject(const LLUUID &object_id, bool self=true); + bool lookAtObject(const LLUUID &object_id, bool self=true); void slamLookAt(const LLVector3 &look_at); // Set the physics data BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); EPointAtType getPointAtType(); diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index dda0f3512..ed54b156f 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -52,7 +52,7 @@ #include #include - +#include #include "llworld.h" #include "llsdutil.h" @@ -137,10 +137,11 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool } LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, const LLVector3d &position) : - mID(id), mName(name), mPosition(position), mDrawPosition(), mMarked(FALSE), mFocused(FALSE), + mID(id), mName(name), mPosition(position), mDrawPosition(), mMarked(false), mFocused(false), mUpdateTimer(), mFrame(gFrameCount), mInSimFrame(U32_MAX), mInDrawFrame(U32_MAX), mInChatFrame(U32_MAX), mInShoutFrame(U32_MAX), - mActivityType(ACTIVITY_NEW), mActivityTimer() + mActivityType(ACTIVITY_NEW), mActivityTimer(), + mIsInList(false) { } @@ -220,12 +221,12 @@ bool LLAvatarListEntry::getAlive() return ((current - mFrame) <= 2); } -F32 LLAvatarListEntry::getEntryAgeSeconds() +F32 LLAvatarListEntry::getEntryAgeSeconds() const { return mUpdateTimer.getElapsedTimeF32(); } -BOOL LLAvatarListEntry::isDead() +bool LLAvatarListEntry::isDead() const { return getEntryAgeSeconds() > DEAD_KEEP_TIME; } @@ -239,7 +240,7 @@ void LLAvatarListEntry::setActivity(ACTIVITY_TYPE activity) } } -LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() +const LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() { if ( mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT ) { @@ -250,10 +251,14 @@ LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() return mActivityType; } -LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")) +LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")), + mTracking(false), + mUpdate(true), + mDirtyAvatarSorting(false), + mUpdateRate(gSavedSettings.getU32("RadarUpdateRate") * 3 + 3), + mAvatarList(NULL) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_radar.xml"); - mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; } LLFloaterAvatarList::~LLFloaterAvatarList() @@ -315,46 +320,46 @@ void LLFloaterAvatarList::onClose(bool app_quitting) } } +void cmd_profile(const LLAvatarListEntry* entry); +void cmd_toggle_mark(LLAvatarListEntry* entry); +void cmd_ar(const LLAvatarListEntry* entry); +void cmd_teleport(const LLAvatarListEntry* entry); BOOL LLFloaterAvatarList::postBuild() { - // Default values - mTracking = FALSE; - mUpdate = TRUE; - // Set callbacks - childSetAction("profile_btn", onClickProfile, this); - childSetAction("im_btn", onClickIM, this); - childSetAction("offer_btn", onClickTeleportOffer, this); - childSetAction("track_btn", onClickTrack, this); - childSetAction("mark_btn", onClickMark, this); - childSetAction("focus_btn", onClickFocus, this); - childSetAction("prev_in_list_btn", onClickPrevInList, this); - childSetAction("next_in_list_btn", onClickNextInList, this); - childSetAction("prev_marked_btn", onClickPrevMarked, this); - childSetAction("next_marked_btn", onClickNextMarked, this); + childSetAction("profile_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_profile, false)); + childSetAction("im_btn", boost::bind(&LLFloaterAvatarList::onClickIM, this)); + childSetAction("offer_btn", boost::bind(&LLFloaterAvatarList::onClickTeleportOffer, this)); + childSetAction("track_btn", boost::bind(&LLFloaterAvatarList::onClickTrack, this)); + childSetAction("mark_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_toggle_mark, false)); + childSetAction("focus_btn", boost::bind(&LLFloaterAvatarList::onClickFocus, this)); + childSetAction("prev_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, FALSE)); + childSetAction("next_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, FALSE)); + childSetAction("prev_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, TRUE)); + childSetAction("next_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, TRUE)); - childSetAction("get_key_btn", onClickGetKey, this); + childSetAction("get_key_btn", boost::bind(&LLFloaterAvatarList::onClickGetKey, this)); - childSetAction("freeze_btn", onClickFreeze, this); - childSetAction("eject_btn", onClickEject, this); - childSetAction("mute_btn", onClickMute, this); - childSetAction("ar_btn", onClickAR, this); - childSetAction("teleport_btn", onClickTeleport, this); - childSetAction("estate_eject_btn", onClickEjectFromEstate, this); - childSetAction("estate_ban_btn", onClickBanFromEstate, this); + childSetAction("freeze_btn", boost::bind(&LLFloaterAvatarList::onClickFreeze, this)); + childSetAction("eject_btn", boost::bind(&LLFloaterAvatarList::onClickEject, this)); + childSetAction("mute_btn", boost::bind(&LLFloaterAvatarList::onClickMute, this)); + childSetAction("ar_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_ar, true)); + childSetAction("teleport_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_teleport, true)); + childSetAction("estate_eject_btn", boost::bind(&LLFloaterAvatarList::onClickEjectFromEstate, this)); + childSetAction("estate_ban_btn",boost::bind(&LLFloaterAvatarList:: onClickBanFromEstate, this)); - childSetAction("send_keys_btn", onClickSendKeys, this); + childSetAction("send_keys_btn", boost::bind(&LLFloaterAvatarList::sendKeys, this)); getChild("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate")); - childSetCommitCallback("update_rate", onCommitUpdateRate, this); + getChild("update_rate")->setCommitCallback(boost::bind(&LLFloaterAvatarList::onCommitUpdateRate, this)); // Get a pointer to the scroll list from the interface mAvatarList = getChild("avatar_list"); mAvatarList->sortByColumn("distance", TRUE); mAvatarList->setCommitOnSelectionChange(TRUE); - mAvatarList->setCallbackUserData(this); mAvatarList->setCommitCallback(boost::bind(&LLFloaterAvatarList::onSelectName,this)); mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this)); + mAvatarList->setSortChangedCallback(boost::bind(&LLFloaterAvatarList::onAvatarSortingChanged,this)); refreshAvatarList(); gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle); @@ -438,9 +443,9 @@ void LLFloaterAvatarList::updateAvatarList() sorted_avatar_ids = avatar_ids; std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end()); - for (std::vector::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) + BOOST_FOREACH(std::vector::value_type& iter, LLCharacter::sInstances) { - LLUUID avid = (*iter)->getID(); + LLUUID avid = iter->getID(); if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid)) { @@ -512,12 +517,13 @@ void LLFloaterAvatarList::updateAvatarList() continue; } - if (mAvatars.count(avid) > 0) + LLAvatarListEntry* entry = getAvatarEntry(avid); + if (entry) { // Avatar already in list, update position F32 dist = (F32)(position - mypos).magVec(); - mAvatars[avid].setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0); - if(avatarp->isTyping())mAvatars[avid].setActivity(LLAvatarListEntry::ACTIVITY_TYPING); + entry->setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0); + if(avatarp->isTyping())entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING); } else { @@ -525,7 +531,7 @@ void LLFloaterAvatarList::updateAvatarList() LLAvatarListEntry entry(avid, name, position); if(announce && avatarp->getRegion() == gAgent.getRegion()) announce_keys.push(avid); - mAvatars[avid] = entry; + mAvatars.push_back(entry); } } else @@ -545,18 +551,19 @@ void LLFloaterAvatarList::updateAvatarList() continue; //prevent (Loading...) } - if (mAvatars.count(avid) > 0) + LLAvatarListEntry* entry = getAvatarEntry(avid); + if (entry) { // Avatar already in list, update position F32 dist = (F32)(position - mypos).magVec(); - mAvatars[avid].setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0); + entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0); } else { LLAvatarListEntry entry(avid, name, position); if(announce && gAgent.getRegion()->pointInRegionGlobal(position)) announce_keys.push(avid); - mAvatars[avid] = entry; + mAvatars.push_back(entry); } } } @@ -618,28 +625,39 @@ void LLFloaterAvatarList::updateAvatarList() void LLFloaterAvatarList::expireAvatarList() { // llinfos << "radar: expiring" << llendl; - std::map::iterator iter; - std::queue delete_queue; - bool alive; - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) + for(av_list_t::iterator it = mAvatars.begin(); it != mAvatars.end();) { - LLAvatarListEntry *entry = &iter->second; - - alive = entry->getAlive(); - - if (entry->isDead()) + if(!it->isDead()) + (it++)->getAlive(); + else { - //llinfos << "radar: expiring avatar " << entry->getName() << llendl; - LLUUID av_id = entry->getID(); - delete_queue.push(av_id); + std::swap(*it,mAvatars.back()); + mAvatars.pop_back(); + if(!mAvatars.size()) + return; } } +} - while (!delete_queue.empty()) +void LLFloaterAvatarList::updateAvatarSorting() +{ + if(mDirtyAvatarSorting) { - mAvatars.erase(delete_queue.front()); - delete_queue.pop(); + mDirtyAvatarSorting = false; + if(mAvatars.size() <= 1) //Nothing to sort. + return; + const std::vector list = mAvatarList->getAllData(); + av_list_t::iterator insert_it = mAvatars.begin(); + for(std::vector::const_iterator it=list.begin();it!=list.end();++it) + { + av_list_t::iterator av_it = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch((*it)->getUUID())); + if(av_it!=mAvatars.end()) + { + std::iter_swap(insert_it++,av_it); + if(insert_it+1 == mAvatars.end()) //We've ran out of elements to sort + return; + } + } } } @@ -666,25 +684,24 @@ void LLFloaterAvatarList::refreshAvatarList() posagent.setVec(gAgent.getPositionAgent()); LLVector3d simpos = mypos - posagent; - std::map::iterator iter; - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) + BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { LLSD element; LLUUID av_id; std::string av_name; - LLAvatarListEntry* entry = &iter->second; - // Skip if avatar hasn't been around - if (entry->isDead()) + if (entry.isDead()) { continue; } - av_id = entry->getID(); - av_name = entry->getName().c_str(); + entry.setInList(); - LLVector3d position = entry->getPosition(); + av_id = entry.getID(); + av_name = entry.getName().c_str(); + + LLVector3d position = entry.getPosition(); BOOL UnknownAltitude = false; LLVector3d delta = position - mypos; @@ -720,7 +737,7 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_MARK]["column"] = "marked"; element["columns"][LIST_MARK]["type"] = "text"; - if (entry->isMarked()) + if (entry.isMarked()) { element["columns"][LIST_MARK]["value"] = "X"; element["columns"][LIST_MARK]["color"] = LLColor4::blue.getValue(); @@ -734,7 +751,7 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_AVATAR_NAME]["column"] = "avatar_name"; element["columns"][LIST_AVATAR_NAME]["type"] = "text"; element["columns"][LIST_AVATAR_NAME]["value"] = av_name; - if (entry->isFocused()) + if (entry.isFocused()) { element["columns"][LIST_AVATAR_NAME]["font-style"] = "BOLD"; } @@ -742,7 +759,7 @@ void LLFloaterAvatarList::refreshAvatarList() // custom colors for certain types of avatars! //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB //element["columns"][LIST_AVATAR_NAME]["color"] = gColors.getColor( "MapAvatar" ).getValue(); - LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition()); + LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry.getPosition()); LLUUID estate_owner = LLUUID::null; if(parent_estate && parent_estate->isAlive()) { @@ -793,7 +810,7 @@ void LLFloaterAvatarList::refreshAvatarList() if (UnknownAltitude) { strcpy(temp, "?"); - if (entry->isDrawn()) + if (entry.isDrawn()) { color = sRadarTextDrawDist; } @@ -814,7 +831,7 @@ void LLFloaterAvatarList::refreshAvatarList() } else { - if (entry->isDrawn()) + if (entry.isDrawn()) { color = sRadarTextDrawDist; } @@ -872,7 +889,7 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_ACTIVITY]["type"] = "icon"; std::string activity_icon = ""; - switch(entry->getActivity()) + switch(entry.getActivity()) { case LLAvatarListEntry::ACTIVITY_MOVING: activity_icon = "inv_item_animation.tga"; @@ -947,18 +964,17 @@ void LLFloaterAvatarList::refreshAvatarList() mAvatarList->sortItems(); mAvatarList->selectMultiple(selected); mAvatarList->setScrollPos(scrollpos); + + mDirtyAvatarSorting = true; // llinfos << "radar refresh: done" << llendl; } -// static -void LLFloaterAvatarList::onClickIM(void* userdata) +void LLFloaterAvatarList::onClickIM() { //llinfos << "LLFloaterFriends::onClickIM()" << llendl; - LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata; - - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + LLDynamicArray ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { if (ids.size() == 1) @@ -986,42 +1002,34 @@ void LLFloaterAvatarList::onClickIM(void* userdata) } } -void LLFloaterAvatarList::onClickTeleportOffer(void* userdata) +void LLFloaterAvatarList::onClickTeleportOffer() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + LLDynamicArray ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { handle_lure(ids); } } -void LLFloaterAvatarList::onClickTrack(void* userdata) +void LLFloaterAvatarList::onClickTrack() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (!item) return; LLUUID agent_id = item->getUUID(); - if (self->mTracking && self->mTrackedAvatar == agent_id) { + if (mTracking && mTrackedAvatar == agent_id) + { LLTracker::stopTracking(NULL); - self->mTracking = FALSE; + mTracking = FALSE; } else { - self->mTracking = TRUE; - self->mTrackedAvatar = agent_id; + mTracking = TRUE; + mTrackedAvatar = agent_id; // trackAvatar only works for friends allowing you to see them on map... // LLTracker::trackAvatar(agent_id, self->mAvatars[agent_id].getName()); - std::string name = self->mAvatars[agent_id].getName(); - if (!self->mUpdate) - { - name += "\n(last known position)"; - } - LLTracker::trackLocation(self->mAvatars[agent_id].getPosition(), name, name); + trackAvatar(getAvatarEntry(mTrackedAvatar)); } } @@ -1031,15 +1039,12 @@ void LLFloaterAvatarList::refreshTracker() if (LLTracker::isTracking(NULL)) { - LLVector3d pos = mAvatars[mTrackedAvatar].getPosition(); - if (pos != LLTracker::getTrackedPositionGlobal()) + if(LLAvatarListEntry* entry = getAvatarEntry(mTrackedAvatar)) { - std::string name = mAvatars[mTrackedAvatar].getName(); - if (!mUpdate) + if (entry->getPosition() != LLTracker::getTrackedPositionGlobal()) { - name += "\n(last known position)"; + trackAvatar(entry); } - LLTracker::trackLocation(pos, name, name); } } else @@ -1050,6 +1055,17 @@ void LLFloaterAvatarList::refreshTracker() } } +void LLFloaterAvatarList::trackAvatar(const LLAvatarListEntry* entry) +{ + if(!entry) return; + std::string name = entry->getName(); + if (!mUpdate) + { + name += "\n(last known position)"; + } + LLTracker::trackLocation(entry->getPosition(), name, name); +} + LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) { if (avatar.isNull()) @@ -1057,32 +1073,11 @@ LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) return NULL; } - std::map::iterator iter; - - iter = mAvatars.find(avatar); - if (iter == mAvatars.end()) - { + av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(avatar)); + if(iter != mAvatars.end()) + return &(*iter); + else return NULL; - } - - return &iter->second; -} - -//static -void LLFloaterAvatarList::onClickMark(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); - - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - LLUUID avid = *itr; - LLAvatarListEntry* entry = self->getAvatarEntry(avid); - if (entry != NULL) - { - entry->toggleMark(); - } - } } BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) @@ -1094,8 +1089,7 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) LLUUID agent_id = item->getUUID(); if (( KEY_RETURN == key ) && (MASK_NONE == mask)) { - self->mFocusedAvatar = agent_id; - self->focusOnCurrent(); + self->setFocusAvatar(agent_id); return TRUE; } else if (( KEY_RETURN == key ) && (MASK_CONTROL == mask)) @@ -1142,143 +1136,73 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) return LLPanel::handleKeyHere(key, mask); } -void LLFloaterAvatarList::onClickFocus(void* userdata) +void LLFloaterAvatarList::onClickFocus() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (item) { - self->mFocusedAvatar = item->getUUID(); - self->focusOnCurrent(); + setFocusAvatar(item->getUUID()); } } void LLFloaterAvatarList::removeFocusFromAll() { - std::map::iterator iter; - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) + BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { - LLAvatarListEntry* entry = &iter->second; - entry->setFocus(FALSE); + entry.setFocus(FALSE); } } -void LLFloaterAvatarList::focusOnCurrent() +void LLFloaterAvatarList::setFocusAvatar(const LLUUID& id) { - std::map::iterator iter; - LLAvatarListEntry* entry; - - if (mAvatars.size() == 0) + av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(id)); + if(iter != mAvatars.end()) { - return; + if(!gAgentCamera.lookAtObject(id, false)) + return; + removeFocusFromAll(); + iter->setFocus(TRUE); } +} - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) +template +void decrement_focus_target(T begin, T end, BOOL marked_only) +{ + T iter = begin; + while(iter != end && !iter->isFocused()) ++iter; + if(iter == end) + return; + T prev_iter = iter; + while(prev_iter != begin) { - entry = &iter->second; - - if (entry->isDead()) - continue; - - if (entry->getID() == mFocusedAvatar) + LLAvatarListEntry& entry = *(--prev_iter); + if(entry.isInList() && (entry.isMarked() || !marked_only) && gAgentCamera.lookAtObject(entry.getID(), false)) { - removeFocusFromAll(); - entry->setFocus(TRUE); - gAgentCamera.lookAtObject(mFocusedAvatar, false); + iter->setFocus(FALSE); + prev_iter->setFocus(TRUE); + gAgentCamera.lookAtObject(prev_iter->getID(), false); return; } } + gAgentCamera.lookAtObject(iter->getID(), false); } void LLFloaterAvatarList::focusOnPrev(BOOL marked_only) { - std::map::iterator iter; - LLAvatarListEntry* prev = NULL; - LLAvatarListEntry* entry; - - if (mAvatars.size() == 0) - { - return; - } - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) - { - entry = &iter->second; - - if (entry->isDead()) - continue; - - if (prev != NULL && entry->getID() == mFocusedAvatar) - { - break; - } - - if ((!marked_only && entry->isDrawn()) || entry->isMarked()) - { - prev = entry; - } - } - - if (prev != NULL) - { - removeFocusFromAll(); - prev->setFocus(TRUE); - mFocusedAvatar = prev->getID(); - gAgentCamera.lookAtObject(mFocusedAvatar, false); - } + updateAvatarSorting(); + decrement_focus_target(mAvatars.begin(), mAvatars.end(), marked_only); } void LLFloaterAvatarList::focusOnNext(BOOL marked_only) { - std::map::iterator iter; - BOOL found = FALSE; - LLAvatarListEntry* next = NULL; - LLAvatarListEntry* entry; - - if (mAvatars.size() == 0) - { - return; - } - - for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) - { - entry = &iter->second; - - if (entry->isDead()) - continue; - - if (next == NULL && ((!marked_only && entry->isDrawn()) || entry->isMarked())) - { - next = entry; - } - - if (found && ((!marked_only && entry->isDrawn()) || entry->isMarked())) - { - next = entry; - break; - } - - if (entry->getID() == mFocusedAvatar) - { - found = TRUE; - } - } - - if (next != NULL) - { - removeFocusFromAll(); - next->setFocus(TRUE); - mFocusedAvatar = next->getID(); - gAgentCamera.lookAtObject(mFocusedAvatar, false); - } + updateAvatarSorting(); + decrement_focus_target(mAvatars.rbegin(), mAvatars.rend(), marked_only); } /*static*/ void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) { // twisted laws - LLViewerObject* voavatar = gObjectList.findObject(uuid); + LLVOAvatar* voavatar = gObjectList.findAvatar(uuid); if(voavatar && voavatar->isAvatar()) { gAgentCamera.setFocusOnAvatar(FALSE, FALSE); @@ -1291,39 +1215,9 @@ void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) } } -//static -void LLFloaterAvatarList::onClickPrevInList(void* userdata) +void LLFloaterAvatarList::onClickGetKey() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnPrev(FALSE); -} - -//static -void LLFloaterAvatarList::onClickNextInList(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnNext(FALSE); -} - -//static -void LLFloaterAvatarList::onClickPrevMarked(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnPrev(TRUE); -} - -//static -void LLFloaterAvatarList::onClickNextMarked(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->focusOnNext(TRUE); -} - -//static -void LLFloaterAvatarList::onClickGetKey(void *userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if (NULL == item) return; @@ -1334,7 +1228,7 @@ void LLFloaterAvatarList::onClickGetKey(void *userdata) gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); } -//static + void LLFloaterAvatarList::sendKeys() { LLViewerRegion* regionp = gAgent.getRegion(); @@ -1432,11 +1326,6 @@ bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const } return false; } -//static -void LLFloaterAvatarList::onClickSendKeys(void *userdata) -{ - LLFloaterAvatarList::getInstance()->sendKeys(); -} static void send_freeze(const LLUUID& avatar_id, bool freeze) { @@ -1521,46 +1410,44 @@ static void send_estate_message( msg->sendReliable(gAgent.getRegion()->getHost()); } -static void cmd_freeze(const LLUUID& avatar, const std::string& name) { send_freeze(avatar, true); } -static void cmd_unfreeze(const LLUUID& avatar, const std::string& name) { send_freeze(avatar, false); } -static void cmd_eject(const LLUUID& avatar, const std::string& name) { send_eject(avatar, false); } -static void cmd_ban(const LLUUID& avatar, const std::string& name) { send_eject(avatar, true); } -static void cmd_profile(const LLUUID& avatar, const std::string& name) { LLFloaterAvatarInfo::showFromDirectory(avatar); } -static void cmd_estate_eject(const LLUUID& avatar, const std::string& name){ send_estate_message("teleporthomeuser", avatar); } -static void cmd_estate_ban(const LLUUID &avatar, const std::string &name) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, avatar); } +static void cmd_append_names(const LLAvatarListEntry* entry, std::string &str, std::string &sep) + { if(!str.empty())str.append(sep);str.append(entry->getName()); } +static void cmd_toggle_mark(LLAvatarListEntry* entry) { entry->toggleMark(); } +static void cmd_ar(const LLAvatarListEntry* entry) { LLFloaterReporter::showFromObject(entry->getID()); } +static void cmd_profile(const LLAvatarListEntry* entry) { LLFloaterAvatarInfo::showFromDirectory(entry->getID()); } +static void cmd_teleport(const LLAvatarListEntry* entry) { gAgent.teleportViaLocation(entry->getPosition()); } +static void cmd_freeze(const LLAvatarListEntry* entry) { send_freeze(entry->getID(), true); } +static void cmd_unfreeze(const LLAvatarListEntry* entry) { send_freeze(entry->getID(), false); } +static void cmd_eject(const LLAvatarListEntry* entry) { send_eject(entry->getID(), false); } +static void cmd_ban(const LLAvatarListEntry* entry) { send_eject(entry->getID(), true); } +static void cmd_estate_eject(const LLAvatarListEntry* entry){ send_estate_message("teleporthomeuser", entry->getID()); } +static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, entry->getID()); } -void LLFloaterAvatarList::doCommand(void (*func)(const LLUUID& avatar, const std::string& name)) +void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/) { - LLDynamicArray ids = mAvatarList->getSelectedIDs(); - + LLDynamicArray ids; + if(!single) + ids = mAvatarList->getSelectedIDs(); + else + ids.put(getSelectedID()); for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) { - LLUUID avid = *itr; + LLUUID& avid = *itr; + if(avid.isNull()) + continue; LLAvatarListEntry* entry = getAvatarEntry(avid); if (entry != NULL) { llinfos << "Executing command on " << entry->getName() << llendl; - func(avid, entry->getName()); + func(entry); } } } std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator) { - std::string ret = ""; - - LLDynamicArray ids = mAvatarList->getSelectedIDs(); - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - LLUUID avid = *itr; - LLAvatarListEntry* entry = getAvatarEntry(avid); - if (entry != NULL) - { - if (!ret.empty()) ret += separator; - ret += entry->getName(); - } - } - + std::string ret; + doCommand(boost::bind(&cmd_append_names,_1,ref(ret),separator)); return ret; } @@ -1585,6 +1472,9 @@ LLUUID LLFloaterAvatarList::getSelectedID() //static void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1600,6 +1490,9 @@ void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& r //static void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1615,6 +1508,9 @@ void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& re //static void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1626,6 +1522,9 @@ void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, cons //static void LLFloaterAvatarList::callbackBanFromEstate(const LLSD& notification, const LLSD& response) { + if(!instanceExists()) + return; + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0) @@ -1648,29 +1547,25 @@ void LLFloaterAvatarList::callbackIdle(void* userdata) } } -void LLFloaterAvatarList::onClickFreeze(void* userdata) +void LLFloaterAvatarList::onClickFreeze() { LLSD args; LLSD payload; - args["AVATAR_NAME"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["AVATAR_NAME"] = getSelectedNames(); LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, callbackFreeze); } -//static -void LLFloaterAvatarList::onClickEject(void* userdata) +void LLFloaterAvatarList::onClickEject() { LLSD args; LLSD payload; - args["AVATAR_NAME"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["AVATAR_NAME"] = getSelectedNames(); LLNotificationsUtil::add("EjectAvatarFullname", args, payload, callbackEject); } -//static -void LLFloaterAvatarList::onClickMute(void* userdata) +void LLFloaterAvatarList::onClickMute() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + LLDynamicArray ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) @@ -1695,62 +1590,25 @@ void LLFloaterAvatarList::onClickMute(void* userdata) } } -//static -void LLFloaterAvatarList::onClickEjectFromEstate(void* userdata) +void LLFloaterAvatarList::onClickEjectFromEstate() { LLSD args; LLSD payload; - args["EVIL_USER"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["EVIL_USER"] = getSelectedNames(); LLNotificationsUtil::add("EstateKickUser", args, payload, callbackEjectFromEstate); } -//static -void LLFloaterAvatarList::onClickBanFromEstate(void* userdata) +void LLFloaterAvatarList::onClickBanFromEstate() { LLSD args; LLSD payload; - args["EVIL_USER"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); + args["EVIL_USER"] = getSelectedNames(); LLNotificationsUtil::add("EstateBanUser", args, payload, callbackBanFromEstate); } -//static -void LLFloaterAvatarList::onClickAR(void* userdata) +void LLFloaterAvatarList::onAvatarSortingChanged() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); - if (item) - { - LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); - if (entry) - { - LLFloaterReporter::showFromObject(entry->getID()); - } - } -} - -// static -void LLFloaterAvatarList::onClickProfile(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - self->doCommand(cmd_profile); -} - -//static -void LLFloaterAvatarList::onClickTeleport(void* userdata) -{ - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); - if (item) - { - LLUUID agent_id = item->getUUID(); - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); - if (entry) - { -// llinfos << "Trying to teleport to " << entry->getName() << " at " << entry->getPosition() << llendl; - gAgent.teleportViaLocation(entry->getPosition()); - } - } + mDirtyAvatarSorting = true; } void LLFloaterAvatarList::onSelectName() @@ -1770,9 +1628,7 @@ void LLFloaterAvatarList::onSelectName() } } -void LLFloaterAvatarList::onCommitUpdateRate(LLUICtrl*, void* userdata) +void LLFloaterAvatarList::onCommitUpdateRate() { - LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; - - self->mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; + mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; } diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 9b660c800..d9fe93581 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -59,7 +59,7 @@ enum ACTIVITY_TYPE */ void setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); - LLVector3d getPosition() { return mPosition; } + const LLVector3d& getPosition() const { return mPosition; } /** * @brief Returns the age of this entry in frames @@ -72,46 +72,61 @@ enum ACTIVITY_TYPE /** * @brief Returns the age of this entry in seconds */ - F32 getEntryAgeSeconds(); + F32 getEntryAgeSeconds() const; /** * @brief Returns the name of the avatar */ - std::string getName() { return mName; } + const std::string& getName() const { return mName; } /** * @brief Returns the ID of the avatar */ - LLUUID getID() { return mID; } + const LLUUID& getID() const { return mID; } void setActivity(ACTIVITY_TYPE activity); /** * @brief Returns the activity type */ - ACTIVITY_TYPE getActivity(); + const ACTIVITY_TYPE getActivity(); /** * @brief Sets the 'focus' status on this entry (camera focused on this avatar) */ void setFocus(BOOL value) { mFocused = value; } - BOOL isFocused() { return mFocused; } + bool isFocused() const { return mFocused; } - BOOL isMarked() { return mMarked; } + bool isMarked() const { return mMarked; } - BOOL isDrawn() { return (mInDrawFrame != U32_MAX); } + bool isDrawn() const { return (mInDrawFrame != U32_MAX); } - BOOL isInSim() { return (mInSimFrame != U32_MAX); } + bool isInSim() const { return (mInSimFrame != U32_MAX); } + /** + * @brief 'InList' signifies that the entry has been displayed in the floaters avatar list + * Until this happens our focusprev/focusnext logic should ignore this entry. + */ + + void setInList() { mIsInList = true; } + + bool isInList() const { return mIsInList; } /** * @brief Returns whether the item is dead and shouldn't appear in the list * @returns TRUE if dead */ - BOOL isDead(); + bool isDead() const; void toggleMark() { mMarked = !mMarked; } + struct uuidMatch + { + uuidMatch(const LLUUID& id) : mID(id) {} + bool operator()(const LLAvatarListEntry& l) { return l.getID() == mID; } + LLUUID mID; + }; + private: friend class LLFloaterAvatarList; @@ -119,8 +134,9 @@ private: std::string mName; LLVector3d mPosition; LLVector3d mDrawPosition; - BOOL mMarked; - BOOL mFocused; + bool mMarked; + bool mFocused; + bool mIsInList; /** * @brief Timer to keep track of whether avatars are still there @@ -212,7 +228,9 @@ public: static void lookAtAvatar(LLUUID &uuid); static void sound_trigger_hook(LLMessageSystem* msg,void **); - static void sendKeys(); + void sendKeys(); + + typedef std::vector av_list_t; private: // when a line editor loses keyboard focus, it is committed. @@ -230,8 +248,7 @@ private: LIST_CLIENT, }; - - typedef void (*avlist_command_t)(const LLUUID &avatar, const std::string &name); + typedef boost::function avlist_command_t; /** * @brief Removes focus status from all avatars in list @@ -239,9 +256,9 @@ private: void removeFocusFromAll(); /** - * @brief Focus camera on current avatar + * @brief Focus camera on specified avatar */ - void focusOnCurrent(); + void setFocusAvatar(const LLUUID& id); /** * @brief Focus camera on previous avatar @@ -255,6 +272,9 @@ private: */ void focusOnNext(BOOL marked_only); + void refreshTracker(); + void trackAvatar(const LLAvatarListEntry* entry); + /** * @brief Handler for the "refresh" button click. * I am unsure whether this is actually necessary at the time. @@ -263,42 +283,38 @@ private: * @param userdata Pointer to user data (LLFloaterAvatarList instance) */ - static void onClickProfile(void *userdata); - static void onClickIM(void *userdata); - static void onClickTeleportOffer(void *userdata); - static void onClickTrack(void *userdata); - static void onClickMark(void *userdata); - static void onClickFocus(void *userdata); + void onClickIM(); + void onClickTeleportOffer(); + void onClickTrack(); + void onClickMute(); + void onClickFocus(); + void onClickGetKey(); - static void onClickPrevInList(void *userdata); - static void onClickNextInList(void *userdata); - static void onClickPrevMarked(void *userdata); - static void onClickNextMarked(void *userdata); - static void onClickGetKey(void *userdata); + void onSelectName(); + void onCommitUpdateRate(); - static void onClickFreeze(void *userdata); - static void onClickEject(void *userdata); - static void onClickMute(void *userdata); - static void onClickAR(void *userdata); - static void onClickTeleport(void *userdata); - static void onClickEjectFromEstate(void *userdata); - static void onClickBanFromEstate(void *userdata); + /** + * @brief These callbacks fire off notifications, which THEN fire the related callback* functions. + */ + void onClickFreeze(); + void onClickEject(); + void onClickEjectFromEstate(); + void onClickBanFromEstate(); + void onAvatarSortingChanged(); + /** + * @brief Called via notification feedback. + */ static void callbackFreeze(const LLSD& notification, const LLSD& response); static void callbackEject(const LLSD& notification, const LLSD& response); - static void callbackAR(void *userdata); static void callbackEjectFromEstate(const LLSD& notification, const LLSD& response); static void callbackBanFromEstate(const LLSD& notification, const LLSD& response); - static void onSelectName(); - - static void onCommitUpdateRate(LLUICtrl*, void *userdata); - static void onClickSendKeys(void *userdata); static bool onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response ); static void callbackIdle(void *userdata); - void doCommand(avlist_command_t cmd); + void doCommand(avlist_command_t cmd, bool single = false); /** * @brief Cleanup avatar list, removing dead entries from it. @@ -307,28 +323,28 @@ private: * to do something to them. */ void expireAvatarList(); + void updateAvatarSorting(); private: /** * @brief Pointer to the avatar scroll list */ LLScrollListCtrl* mAvatarList; - std::map mAvatars; + av_list_t mAvatars; + bool mDirtyAvatarSorting; /** * @brief TRUE when Updating */ - BOOL mUpdate; + bool mUpdate; /** * @brief Update rate (if min frames per update) */ U32 mUpdateRate; - - void refreshTracker(); // tracking data - BOOL mTracking; // Tracking ? + bool mTracking; // Tracking ? LLUUID mTrackedAvatar; // Who we are tracking /** From f80394fc0240b890d0defaf28403ea4bab6bb9cb Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 6 Dec 2012 17:19:10 -0600 Subject: [PATCH 81/93] llpreviewgesture.cpp changes snuck past me in an early commit. --- indra/newview/llpreviewgesture.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index c79287e54..8349b5e03 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -123,7 +123,7 @@ LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& LLPreviewGesture* preview = (LLPreviewGesture*)LLPreview::find(item_id); if (preview) { - previewp->open(); /*Flawfinder: ignore*/ + preview->open(); /*Flawfinder: ignore*/ } else { @@ -140,7 +140,7 @@ LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& LLMultiFloater* hostp = preview->getHost(); if (hostp == NULL) { - LLRect r = self->getRect(); + LLRect r = preview->getRect(); LLRect screen = gFloaterView->getRect(); r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight()); preview->setRect(r); @@ -928,13 +928,13 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs, LLVFile file(vfs, asset_uuid, type, LLVFile::READ); S32 size = file.getSize(); - char* buffer = new char[size+1]; - file.read((U8*)buffer, size); /*Flawfinder: ignore*/ + std::vector buffer(size+1); + file.read((U8*)&buffer[0], size); buffer[size] = '\0'; LLMultiGesture* gesture = new LLMultiGesture(); - LLDataPackerAsciiBuffer dp(buffer, size+1); + LLDataPackerAsciiBuffer dp(&buffer[0], size+1); BOOL ok = gesture->deserialize(dp); if (ok) @@ -956,9 +956,6 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs, delete gesture; gesture = NULL; - delete [] buffer; - buffer = NULL; - self->mAssetStatus = PREVIEW_ASSET_LOADED; } else @@ -1526,7 +1523,7 @@ void LLPreviewGesture::onCommitWait() if (!step_item) return; LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); - if (getType() != STEP_WAIT) return; + if (step->getType() != STEP_WAIT) return; LLGestureStepWait* wait_step = (LLGestureStepWait*)step; U32 flags = 0x0; From d6b486524c68d8c8b32643d869c1d7f5a0fc4000 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Fri, 7 Dec 2012 00:31:10 +0100 Subject: [PATCH 82/93] Fix include of reader.h --- indra/newview/llwebprofile.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 141c746e0..31751fddf 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -38,11 +38,12 @@ #include "llpanelprofile.h" // getProfileURL (this is the original location LL put it). #include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals -// third-party -#ifdef LL_STANDALONE -#include // JSONCPP +// third-party JSONCPP +#if !defined(LL_STANDALONE) && defined(LINUX64) +// The prebuilt linux64 package is packaged wrongly. +#include // JSONCPP #else -#include "reader.h" // prebuilt jsoncpp is wrongly packaged. +#include // JSONCPP #endif /* From 9fb4e677a60e638a9609546d6b93ff1d5d59e50f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 8 Dec 2012 00:56:58 -0600 Subject: [PATCH 83/93] Updates to LLScrollListCtrl and related inter-dependencies. Also added ability to set face texture to 'None' (LLUUID::null). --- indra/llcommon/lldarray.h | 1 + indra/llui/llcombobox.cpp | 10 +- indra/llui/llpanel.h | 2 +- indra/llui/llscrolllistctrl.cpp | 963 ++++++++++-------- indra/llui/llscrolllistctrl.h | 327 +++--- indra/llui/lluictrl.h | 2 +- indra/newview/ascentfloatercontactgroups.cpp | 19 +- indra/newview/ascentfloatercontactgroups.h | 4 +- indra/newview/chatbar_as_cmdline.cpp | 9 +- indra/newview/jcfloaterareasearch.cpp | 4 +- indra/newview/llcompilequeue.cpp | 14 +- indra/newview/llfloateractivespeakers.cpp | 2 +- indra/newview/llfloateravatarlist.cpp | 26 +- indra/newview/llfloateravatarpicker.cpp | 1 + indra/newview/llfloaterbulkpermission.cpp | 8 +- indra/newview/llfloatercolorpicker.cpp | 170 +--- indra/newview/llfloatercolorpicker.h | 6 +- indra/newview/llfloaterexploresounds.cpp | 8 +- indra/newview/llfloaterfriends.cpp | 61 +- indra/newview/llfloaterfriends.h | 6 +- indra/newview/llfloaterland.cpp | 77 +- indra/newview/llfloatermessagelog.cpp | 6 +- indra/newview/llfloaternewim.cpp | 10 +- indra/newview/llfloaterregioninfo.cpp | 20 +- indra/newview/llfloatertopobjects.cpp | 2 +- indra/newview/llfloaterworldmap.cpp | 2 +- indra/newview/llgesturemgr.cpp | 4 +- indra/newview/llinventorybackup.cpp | 6 +- indra/newview/llnamelistctrl.cpp | 215 ++-- indra/newview/llnamelistctrl.h | 31 +- indra/newview/llpanelavatar.cpp | 2 +- indra/newview/llpaneldirbrowser.cpp | 4 +- indra/newview/llpanelface.cpp | 10 +- indra/newview/llpanelgroupgeneral.cpp | 3 +- indra/newview/llpanelgroupinvite.cpp | 3 +- indra/newview/llpanelgrouplandmoney.cpp | 2 +- indra/newview/llpanelgroupnotices.cpp | 4 +- indra/newview/llpanelgrouproles.cpp | 6 +- indra/newview/llpanelgroupvoting.cpp | 8 +- indra/newview/llpreviewscript.cpp | 12 +- indra/newview/llselectmgr.cpp | 10 +- indra/newview/llstartup.cpp | 1 - indra/newview/lltexturectrl.cpp | 225 ++-- indra/newview/lltooldraganddrop.cpp | 14 +- indra/newview/lltoolpipette.cpp | 24 +- indra/newview/lltoolpipette.h | 11 +- .../default/xui/en-us/floater_about_land.xml | 2 +- .../xui/en-us/floater_texture_ctrl.xml | 3 + .../skins/default/xui/en-us/floater_tools.xml | 2 +- 49 files changed, 1281 insertions(+), 1081 deletions(-) diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h index 5433e8d72..15e200186 100644 --- a/indra/llcommon/lldarray.h +++ b/indra/llcommon/lldarray.h @@ -56,6 +56,7 @@ public: }; LLDynamicArray(S32 size=0) : std::vector(size) { if (size < BlockSize) std::vector::reserve(BlockSize); } + LLDynamicArray(const std::vector& copy) : std::vector(copy) {} void reset() { std::vector::clear(); } diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index b1b8f42e4..7401d97f8 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -615,7 +615,7 @@ void LLComboBox::showList() S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); // make sure we have up to date content width metrics - mList->calcColumnWidths(); + mList->updateColumnWidths(); S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); if (mListPosition == BELOW) @@ -707,7 +707,7 @@ void LLComboBox::hideList() mButton->setToggleState(FALSE); mList->setVisible(FALSE); - mList->highlightNthItem(-1); + mList->mouseOverHighlightNthItem(-1); setUseBoundingRect(FALSE); if( gFocusMgr.getTopCtrl() == this ) @@ -731,7 +731,7 @@ void LLComboBox::onButtonDown(void *userdata) if (last_selected_item) { // highlight the original selection before potentially selecting a new item - self->mList->highlightNthItem(self->mList->getItemIndex(last_selected_item)); + self->mList->mouseOverHighlightNthItem(self->mList->getItemIndex(last_selected_item)); } if( self->mPrearrangeCallback ) @@ -839,7 +839,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask) if (last_selected_item) { // highlight the original selection before potentially selecting a new item - mList->highlightNthItem(mList->getItemIndex(last_selected_item)); + mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item)); } result = mList->handleKeyHere(key, mask); @@ -873,7 +873,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char) if (last_selected_item) { // highlight the original selection before potentially selecting a new item - mList->highlightNthItem(mList->getItemIndex(last_selected_item)); + mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item)); } result = mList->handleUnicodeCharHere(uni_char); if (mList->getLastSelectedItem() != last_selected_item) diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 385276c64..330378da0 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -57,7 +57,7 @@ const BOOL BORDER_NO = FALSE; * With or without border, * Can contain LLUICtrls. */ -class LLPanel : public LLUICtrl, public boost::signals2::trackable +class LLPanel : public LLUICtrl { public: diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index cadc34046..11d6433d0 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -66,8 +66,9 @@ static LLRegisterWidget r("scroll_list"); // local structures & classes. struct SortScrollListItem { - SortScrollListItem(const std::vector >& sort_orders) + SortScrollListItem(const std::vector >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal) : mSortOrders(sort_orders) + , mSortSignal(sort_signal) {} bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) @@ -80,12 +81,20 @@ struct SortScrollListItem S32 col_idx = it->first; BOOL sort_ascending = it->second; + S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column? + const LLScrollListCell *cell1 = i1->getColumn(col_idx); const LLScrollListCell *cell2 = i2->getColumn(col_idx); - S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column? if (cell1 && cell2) { - sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + if(mSortSignal) + { + sort_result = order * (*mSortSignal)(col_idx,i1, i2); + } + else + { + sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + } if (sort_result != 0) { break; // we have a sort order! @@ -95,8 +104,10 @@ struct SortScrollListItem return sort_result < 0; } + typedef std::vector > sort_order_t; + const LLScrollListCtrl::sort_signal_t* mSortSignal; const sort_order_t& mSortOrders; }; @@ -109,7 +120,6 @@ LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) mIcon(icon), // mCallback(NULL), - mUserData(NULL), // mColor(LLColor4::white) { @@ -119,7 +129,6 @@ LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width) : LLScrollListCell(width), // mCallback(NULL), - mUserData(NULL), // mColor(LLColor4::white) { @@ -131,6 +140,14 @@ LLScrollListIcon::~LLScrollListIcon() { } +/*virtual*/ +S32 LLScrollListIcon::getHeight() const +{ return mIcon ? mIcon->getHeight() : 0; } + +/*virtual*/ +const LLSD LLScrollListIcon::getValue() const +{ return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); } + void LLScrollListIcon::setValue(const LLSD& value) { if (value.isUUID()) @@ -174,15 +191,14 @@ S32 LLScrollListIcon::getWidth() const } // -void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data) +void LLScrollListIcon::setClickCallback(boost::function cb) { - mCallback = callback; - mUserData = user_data; + mCallback = cb; } BOOL LLScrollListIcon::handleClick() { - if(mCallback) return mCallback(mUserData); + if(mCallback) return mCallback(); return FALSE; } // @@ -195,46 +211,6 @@ void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_col } } -// -// LLScrollListCheck -// -LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) -{ - mCheckBox = check_box; - LLRect rect(mCheckBox->getRect()); - if (width) - { - - rect.mRight = rect.mLeft + width; - mCheckBox->setRect(rect); - setWidth(width); - } - else - { - setWidth(rect.getWidth()); //check_box->getWidth(); - } -} - -LLScrollListCheck::~LLScrollListCheck() -{ - delete mCheckBox; -} - -void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - mCheckBox->draw(); -} - -BOOL LLScrollListCheck::handleClick() -{ - if (mCheckBox->getEnabled()) - { - mCheckBox->toggle(); - } - // don't change selection when clicking on embedded checkbox - return TRUE; -} - // // // LLScrollListLineEditor @@ -288,25 +264,6 @@ BOOL LLScrollListLineEditor::handleUnicodeCharHere(llwchar uni_char ) } // -// -// LLScrollListSeparator -// -LLScrollListSeparator::LLScrollListSeparator(S32 width) : LLScrollListCell(width) -{ -} - -//virtual -S32 LLScrollListSeparator::getHeight() const -{ - return 5; -} - - -void LLScrollListSeparator::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - // *FIXME: use dynamic item heights and make separators narrow, and inactive - gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color); -} // // LLScrollListText @@ -327,6 +284,8 @@ LLScrollListText::LLScrollListText( const std::string& text, const LLFontGL* fon { sCount++; + mTextWidth = getWidth(); + // initialize rounded rect image if (!mRoundedRectImage) { @@ -381,6 +340,11 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +void LLScrollListText::setFontStyle(const U8 font_style) +{ + mFontStyle = font_style; +} + //virtual void LLScrollListText::setValue(const LLSD& text) { @@ -452,12 +416,77 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col mFontStyle, LLFontGL::NO_SHADOW, string_chars, - getWidth(), + getTextWidth(), &right_x, FALSE, TRUE); } +// +// LLScrollListCheck +// +LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) +{ + mCheckBox = check_box; + LLRect rect(mCheckBox->getRect()); + if (width) + { + + rect.mRight = rect.mLeft + width; + mCheckBox->setRect(rect); + setWidth(width); + } + else + { + setWidth(rect.getWidth()); //check_box->getWidth(); + } +} + +LLScrollListCheck::~LLScrollListCheck() +{ + delete mCheckBox; + mCheckBox = NULL; +} + +void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + mCheckBox->draw(); +} + +BOOL LLScrollListCheck::handleClick() +{ + if (mCheckBox->getEnabled()) + { + mCheckBox->toggle(); + } + // don't change selection when clicking on embedded checkbox + return TRUE; +} + +/*virtual*/ +const LLSD LLScrollListCheck::getValue() const +{ + return mCheckBox->getValue(); +} + +/*virtual*/ +void LLScrollListCheck::setValue(const LLSD& value) +{ + mCheckBox->setValue(value); +} + +/*virtual*/ +void LLScrollListCheck::onCommit() +{ + mCheckBox->onCommit(); +} + +/*virtual*/ +void LLScrollListCheck::setEnabled(BOOL enable) +{ + mCheckBox->setEnabled(enable); +} + LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible) : LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible), mDate(date) @@ -509,6 +538,21 @@ void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell ) } } + +S32 LLScrollListItem::getNumColumns() const +{ + return mColumns.size(); +} + +LLScrollListCell* LLScrollListItem::getColumn(const S32 i) const +{ + if (0 <= i && i < (S32)mColumns.size()) + { + return mColumns[i]; + } + return NULL; +} + std::string LLScrollListItem::getContentsCSV() const { std::string ret; @@ -529,12 +573,9 @@ std::string LLScrollListItem::getContentsCSV() const void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) { // draw background rect + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLRect bg_rect = rect; - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4fv(bg_color.mV); - gl_rect_2d( bg_rect ); - } + gl_rect_2d( bg_rect, bg_color ); S32 cur_x = rect.mLeft; S32 num_cols = getNumColumns(); @@ -548,7 +589,7 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLUI::pushMatrix(); { - LLUI::translate((F32) cur_x, (F32) rect.mBottom, 0.0f); + LLUI::translate((F32) cur_x, (F32) rect.mBottom); cell->draw( fg_color, highlight_color ); } @@ -559,74 +600,62 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const } -void LLScrollListItem::setEnabled(BOOL b) +// +// LLScrollListSeparator +// +/* + * Draws a horizontal line. + */ +class LLScrollListSeparator : public LLScrollListCell { - mEnabled = b; -} - -//--------------------------------------------------------------------------- -// LLScrollListItemComment -//--------------------------------------------------------------------------- -LLScrollListItemComment::LLScrollListItemComment(const std::string& comment_string, const LLColor4& color) -: LLScrollListItem(FALSE), - mColor(color) -{ - addColumn( comment_string, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ) ); -} - -void LLScrollListItemComment::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) -{ - LLScrollListCell* cell = getColumn(0); - if (cell) +public: + LLScrollListSeparator(S32 width) : LLScrollListCell(width) {} + virtual ~LLScrollListSeparator() {}; + virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) return; - - LLUI::pushMatrix(); - { - LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); - - // force first cell to be width of entire item - cell->setWidth(rect.getWidth()); - cell->draw( mColor, highlight_color ); - } - LLUI::popMatrix(); + // *FIXME: use dynamic item heights and make separators narrow, and inactive + gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color); } -} + virtual S32 getHeight() const { return 5; }; + virtual BOOL isText() const { return FALSE; } +}; //--------------------------------------------------------------------------- // LLScrollListItemSeparator //--------------------------------------------------------------------------- -LLScrollListItemSeparator::LLScrollListItemSeparator() -: LLScrollListItem(FALSE) -{ - LLScrollListSeparator* cell = new LLScrollListSeparator(0); - setNumColumns(1); - setColumn(0, cell); -} -void LLScrollListItemSeparator::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) +class LLScrollListItemSeparator : public LLScrollListItem { - //TODO* move LLScrollListSeparator::draw into here and get rid of it - LLScrollListCell* cell = getColumn(0); - if (cell) +public: + LLScrollListItemSeparator() : LLScrollListItem(FALSE) { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) return; - - LLUI::pushMatrix(); - { - LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); - - // force first cell to be width of entire item - cell->setWidth(rect.getWidth()); - cell->draw( fg_color, highlight_color ); - } - LLUI::popMatrix(); + LLScrollListSeparator* cell = new LLScrollListSeparator(0); + setNumColumns(1); + setColumn(0, cell); } -} + + /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) + { + //TODO* move LLScrollListSeparator::draw into here and get rid of it + LLScrollListCell* cell = getColumn(0); + if (cell) + { + // Two ways a cell could be hidden + if (cell->getWidth() < 0 + || !cell->getVisible()) return; + + LLUI::pushMatrix(); + { + LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); + + // force first cell to be width of entire item + cell->setWidth(rect.getWidth()); + cell->draw( fg_color, highlight_color ); + } + LLUI::popMatrix(); + } + } +}; //--------------------------------------------------------------------------- // LLScrollListCtrl @@ -636,36 +665,24 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, void (*commit_callback)(LLUICtrl* ctrl, void* userdata), void* callback_user_data, BOOL allow_multiple_selection, - BOOL show_border + BOOL show_border, + bool draw_heading ) : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data), mLineHeight(0), mScrollLines(0), mMouseWheelOpaque(true), mPageLines(0), - mHeadingHeight(20), mMaxSelectable(0), - mAllowMultipleSelection( allow_multiple_selection ), - mAllowKeyboardMovement(TRUE), - mCommitOnKeyboardMovement(TRUE), - mCommitOnSelectionChange(FALSE), - mSelectionChanged(FALSE), - mNeedsScroll(FALSE), - mCanSelect(TRUE), - mDisplayColumnHeaders(FALSE), - mColumnsDirty(FALSE), + mAllowKeyboardMovement(true), + mCommitOnKeyboardMovement(true), + mCommitOnSelectionChange(false), + mSelectionChanged(false), + mNeedsScroll(false), + mCanSelect(true), + mColumnsDirty(false), mMaxItemCount(INT_MAX), mMaxContentWidth(0), - mBackgroundVisible( TRUE ), - mDrawStripes(TRUE), - mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), - mBgReadOnlyColor( LLUI::sColorsGroup->getColor( "ScrollBgReadOnlyColor" ) ), - mBgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedBGColor") ), - mBgStripeColor( LLUI::sColorsGroup->getColor("ScrollBGStripeColor") ), - mFgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedFGColor") ), - mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ), - mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ), - mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), mDefaultListTextColor( LLUI::sColorsGroup->getColor("DefaultListText") ), mBorderThickness( 2 ), mOnDoubleClickCallback( NULL ), @@ -673,14 +690,30 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mOnSortChangedCallback( NULL ), mHighlightedItem(-1), mBorder(NULL), - mSearchColumn(0), + mSortCallback(NULL), + mCommentTextView(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), mTotalColumnPadding(0), - mSorted(TRUE), - mDirty(FALSE), + mSorted(true), + mDirty(false), mOriginalSelection(-1), - mDrewSelected(FALSE) + mLastSelected(NULL), + mHeadingHeight(20), + mAllowMultipleSelection( allow_multiple_selection ), + mDisplayColumnHeaders(draw_heading), + mBackgroundVisible(true), + mDrawStripes(true), + mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), + mBgReadOnlyColor( LLUI::sColorsGroup->getColor( "ScrollBgReadOnlyColor" ) ), + mBgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedBGColor") ), + mBgStripeColor( LLUI::sColorsGroup->getColor("ScrollBGStripeColor") ), + mFgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedFGColor") ), + mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ), + mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ), + mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), + mSearchColumn(0), + mColumnPadding(5) { mItemListRect.setOriginAndSize( mBorderThickness, @@ -690,8 +723,6 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, updateLineHeight(); - mPageLines = mLineHeight? (mItemListRect.getHeight()) / mLineHeight : 0; - // Init the scrollbar LLRect scroll_rect; scroll_rect.setOriginAndSize( @@ -703,7 +734,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, LLScrollbar::VERTICAL, getItemCount(), mScrollLines, - mPageLines, + getLinesPerPage(), &LLScrollListCtrl::onScrollChange, this ); mScrollbar->setFollowsRight(); mScrollbar->setFollowsTop(); @@ -721,9 +752,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, addChild(mBorder); } - mColumnPadding = 5; - mLastSelected = NULL; } S32 LLScrollListCtrl::getSearchColumn() @@ -750,7 +779,10 @@ S32 LLScrollListCtrl::getSearchColumn() LLScrollListCtrl::~LLScrollListCtrl() { + delete mSortCallback; + std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); + std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); } @@ -786,7 +818,7 @@ void LLScrollListCtrl::clearRows() mScrollLines = 0; mLastSelected = NULL; updateLayout(); - mDirty = FALSE; + mDirty = false; } @@ -831,10 +863,10 @@ std::vector LLScrollListCtrl::getAllSelected() const return ret; } -LLDynamicArray LLScrollListCtrl::getSelectedIDs() +uuid_vec_t LLScrollListCtrl::getSelectedIDs() { LLUUID selected_id; - LLDynamicArray ids; + uuid_vec_t ids; std::vector selected = this->getAllSelected(); for(std::vector::iterator itr = selected.begin(); itr != selected.end(); ++itr) { @@ -843,6 +875,27 @@ LLDynamicArray LLScrollListCtrl::getSelectedIDs() return ids; } +S32 LLScrollListCtrl::getNumSelected() const +{ + if (!getCanSelect()) + { + return 0; + } + + S32 numSelected = 0; + + for(item_list::const_iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter) + { + LLScrollListItem* item = *iter; + if (item->getSelected()) + { + ++numSelected; + } + } + + return numSelected; +} + S32 LLScrollListCtrl::getFirstSelectedIndex() const { if (!getCanSelect()) @@ -852,6 +905,10 @@ S32 LLScrollListCtrl::getFirstSelectedIndex() const S32 CurSelectedIndex = 0; + + // make sure sort is up to date before returning an index + updateSort(); + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -887,6 +944,7 @@ LLScrollListItem* LLScrollListCtrl::getLastData() const std::vector LLScrollListCtrl::getAllData() const { std::vector ret; + ret.reserve(mItemList.size()); //Optimization item_list::const_iterator iter; for(iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -932,17 +990,26 @@ void LLScrollListCtrl::updateLayout() getRect().getWidth() - 2 * mBorderThickness, getRect().getHeight() - (2 * mBorderThickness ) - heading_size ); + if (mCommentTextView == NULL) + { + mCommentTextView = getChildView("comment_text"); + } + + mCommentTextView->setShape(mItemListRect); + // how many lines of content in a single "page" - mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; - BOOL scrollbar_visible = getItemCount() > mPageLines; + S32 page_lines = getLinesPerPage(); + + BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight(); if (scrollbar_visible) { // provide space on the right for scrollbar mItemListRect.mRight = getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE; } + mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE, mItemListRect.mBottom); mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); - mScrollbar->setPageSize( mPageLines ); + mScrollbar->setPageSize(page_lines); mScrollbar->setDocSize( getItemCount() ); mScrollbar->setVisible(scrollbar_visible); @@ -954,6 +1021,9 @@ void LLScrollListCtrl::updateLayout() void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height) { S32 height = llmin( getRequiredRect().getHeight(), max_height ); + if(mPageLines) + height = llmin( mPageLines * mLineHeight + 2*mBorderThickness + (mDisplayColumnHeaders ? mHeadingHeight : 0), height ); + S32 width = getRect().getWidth(); reshape( width, height ); @@ -981,7 +1051,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r { case ADD_TOP: mItemList.push_front(item); - setSorted(FALSE); + setNeedsSort(); break; case ADD_SORTED: @@ -994,22 +1064,22 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(single_sort_column)); + SortScrollListItem(single_sort_column,mSortCallback)); // ADD_SORTED just sorts by first column... // this might not match user sort criteria, so flag list as being in unsorted state - setSorted(FALSE); + setNeedsSort(); break; - } + } case ADD_BOTTOM: mItemList.push_back(item); - setSorted(FALSE); + setNeedsSort(); break; default: llassert(0); mItemList.push_back(item); - setSorted(FALSE); + setNeedsSort(); break; } @@ -1034,15 +1104,43 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r // NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame // while receiving a long list of names. // *TODO: Use bookkeeping to make this an incramental cost with item additions -void LLScrollListCtrl::calcColumnWidths() +S32 LLScrollListCtrl::calcMaxContentWidth() { const S32 HEADING_TEXT_PADDING = 25; const S32 COLUMN_TEXT_PADDING = 10; - mMaxContentWidth = 0; - S32 max_item_width = 0; + ordered_columns_t::iterator column_itor; + for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) + { + LLScrollListColumn* column = *column_itor; + if (!column) continue; + + if (mColumnWidthsDirty) + { + mColumnWidthsDirty = false; + // update max content width for this column, by looking at all items + column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); + if (!cellp) continue; + + column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + } + } + max_item_width += column->mMaxContentWidth; + } + + mMaxContentWidth = max_item_width; + return max_item_width; +} + +bool LLScrollListCtrl::updateColumnWidths() +{ + bool width_changed = false; ordered_columns_t::iterator column_itor; for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) { @@ -1060,23 +1158,14 @@ void LLScrollListCtrl::calcColumnWidths() new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns; } - column->setWidth(new_width); - - // update max content width for this column, by looking at all items - column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (column->getWidth() != new_width) { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); - if (!cellp) continue; - - column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + column->setWidth(new_width); + width_changed = true; } - - max_item_width += column->mMaxContentWidth; } - - mMaxContentWidth = max_item_width; + calcMaxContentWidth(); + return width_changed; } const S32 SCROLL_LIST_ROW_PAD = 2; @@ -1112,12 +1201,17 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) void LLScrollListCtrl::updateColumns() { - calcColumnWidths(); + if (!mColumnsDirty) + return; + + mColumnsDirty = false; + + bool columns_changed_width = updateColumnWidths(); // update column headers std::vector::iterator column_ordered_it; S32 left = mItemListRect.mLeft; - LLColumnHeader* last_header = NULL; + LLScrollColumnHeader* last_header = NULL; for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it) { if ((*column_ordered_it)->getWidth() < 0) @@ -1161,20 +1255,22 @@ void LLScrollListCtrl::updateColumns() } // propagate column widths to individual cells - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (columns_changed_width) { - LLScrollListItem *itemp = *iter; - S32 num_cols = itemp->getNumColumns(); - S32 i = 0; - for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { - if (i >= (S32)mColumnsIndexed.size()) break; + LLScrollListItem *itemp = *iter; + S32 num_cols = itemp->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; - cell->setWidth(mColumnsIndexed[i]->getWidth()); + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } } } - } void LLScrollListCtrl::setDisplayHeading(BOOL display) @@ -1191,6 +1287,12 @@ void LLScrollListCtrl::setHeadingHeight(S32 heading_height) updateLayout(); } +void LLScrollListCtrl::setPageLines(S32 new_page_lines) +{ + mPageLines = new_page_lines; + + updateLayout(); +} BOOL LLScrollListCtrl::selectFirstItem() { @@ -1216,7 +1318,7 @@ BOOL LLScrollListCtrl::selectFirstItem() { deselectItem(itemp); } - first_item = FALSE; + first_item = false; } if (mCommitOnSelectionChange) { @@ -1240,6 +1342,9 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) return FALSE; } + // make sure sort is up to date + updateSort(); + S32 listlen = (S32)mItemList.size(); first_index = llclamp(first_index, 0, listlen-1); @@ -1293,6 +1398,7 @@ void LLScrollListCtrl::swapWithNext(S32 index) // At end of list, doesn't do anything return; } + updateSort(); LLScrollListItem *cur_itemp = mItemList[index]; mItemList[index] = mItemList[index + 1]; mItemList[index + 1] = cur_itemp; @@ -1307,6 +1413,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) return; } + updateSort(); LLScrollListItem *cur_itemp = mItemList[index]; mItemList[index] = mItemList[index - 1]; mItemList[index - 1] = cur_itemp; @@ -1332,6 +1439,8 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index) return; } + updateSort(); + LLScrollListItem *itemp; itemp = mItemList[target_index]; if (itemp == mLastSelected) @@ -1388,7 +1497,7 @@ void LLScrollListCtrl::deleteSelectedItems() dirtyColumns(); } -void LLScrollListCtrl::highlightNthItem(S32 target_index) +void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index) { if (mHighlightedItem != target_index) { @@ -1396,14 +1505,14 @@ void LLScrollListCtrl::highlightNthItem(S32 target_index) } } -S32 LLScrollListCtrl::selectMultiple( LLDynamicArray ids ) +S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) { item_list::iterator iter; S32 count = 0; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; - LLDynamicArray::iterator iditr; + uuid_vec_t::iterator iditr; for(iditr = ids.begin(); iditr != ids.end(); ++iditr) { if (item->getEnabled() && (item->getUUID() == (*iditr))) @@ -1425,6 +1534,8 @@ S32 LLScrollListCtrl::selectMultiple( LLDynamicArray ids ) S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const { + updateSort(); + S32 index = 0; item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -1441,6 +1552,8 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const { + updateSort(); + S32 index = 0; item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -1466,6 +1579,8 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) } else { + updateSort(); + item_list::iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -1508,6 +1623,8 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) } else { + updateSort(); + item_list::reverse_iterator iter; for (iter = mItemList.rbegin(); iter != mItemList.rend(); iter++) { @@ -1559,16 +1676,10 @@ void LLScrollListCtrl::deselectAllItems(BOOL no_commit_on_change) /////////////////////////////////////////////////////////////////////////////////////////////////// // Use this to add comment text such as "Searching", which ignores column settings of list -LLScrollListItem* LLScrollListCtrl::addCommentText(const std::string& comment_text, EAddPosition pos) + +void LLScrollListCtrl::setCommentText(const std::string& comment_text) { - LLScrollListItem* item = NULL; - if (getItemCount() < mMaxItemCount) - { - // always draw comment text with "enabled" color - item = new LLScrollListItemComment( comment_text, mFgUnselectedColor ); - addItem( item, pos, FALSE ); - } - return item; + getChild("comment_text")->setValue(comment_text); } LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) @@ -1582,40 +1693,13 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) // Returns false if item not found. BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive) { - // ensure that no stale items are selected, even if we don't find a match - deselectAllItems(TRUE); - //RN: assume no empty items - if (label.empty()) - { - return FALSE; - } + deselectAllItems(TRUE); // ensure that no stale items are selected, even if we don't find a match + LLScrollListItem* item = getItemByLabel(label, case_sensitive); - std::string target_text = label; - if (!case_sensitive) + bool found = NULL != item; + if(found) { - LLStringUtil::toLower(target_text); - } - - BOOL found = FALSE; - - item_list::iterator iter; - S32 index = 0; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) - { - LLScrollListItem* item = *iter; - // Only select enabled items with matching names - std::string item_text = item->getColumn(0)->getValue().asString(); - if (!case_sensitive) - { - LLStringUtil::toLower(item_text); - } - BOOL select = !found && item->getEnabled() && item_text == target_text; - if (select) - { - selectItem(item); - } - found = found || select; - index++; + selectItem(item); } if (mCommitOnSelectionChange) @@ -1626,6 +1710,36 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen return found; } +LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOOL case_sensitive, S32 column) +{ + if (label.empty()) //RN: assume no empty items + { + return NULL; + } + + std::string target_text = label; + if (!case_sensitive) + { + LLStringUtil::toLower(target_text); + } + + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListItem* item = *iter; + std::string item_text = item->getColumn(column)->getValue().asString(); // Only select enabled items with matching names + if (!case_sensitive) + { + LLStringUtil::toLower(item_text); + } + if(item_text == target_text) + { + return item; + } + } + return NULL; +} + BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive) { @@ -1822,7 +1936,7 @@ void LLScrollListCtrl::drawItems() S32 y = mItemListRect.mTop - mLineHeight; // allow for partial line at bottom - S32 num_page_lines = mPageLines + 1; + S32 num_page_lines = getLinesPerPage(); LLRect item_rect; @@ -1832,34 +1946,34 @@ void LLScrollListCtrl::drawItems() LLLocalClipRect clip(mItemListRect); S32 cur_y = y; - - mDrewSelected = FALSE; - S32 line = 0; S32 max_columns = 0; LLColor4 highlight_color = LLColor4::white; F32 type_ahead_timeout = LLUI::sConfigGroup->getF32("TypeAheadTimeout"); highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + S32 first_line = mScrollLines; + S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage()); + + if ((item_list::size_type)first_line >= mItemList.size()) { - LLScrollListItem* item = *iter; + return; + } + item_list::iterator iter; + for (S32 line = first_line; line <= last_line; line++) + { + LLScrollListItem* item = mItemList[line]; item_rect.setOriginAndSize( x, cur_y, mItemListRect.getWidth(), mLineHeight ); + item->setRect(item_rect); //llinfos << item_rect.getWidth() << llendl; - if (item->getSelected()) - { - mDrewSelected = TRUE; - } - max_columns = llmax(max_columns, item->getNumColumns()); LLColor4 fg_color; @@ -1894,7 +2008,6 @@ void LLScrollListCtrl::drawItems() cur_y -= mLineHeight; } - line++; } } } @@ -1905,15 +2018,12 @@ void LLScrollListCtrl::draw() LLLocalClipRect clip(getLocalRect()); // if user specifies sort, make sure it is maintained - if (needsSorting() && !isSorted()) - { - sortItems(); - } + updateSort(); if (mNeedsScroll) { scrollToShowSelected(); - mNeedsScroll = FALSE; + mNeedsScroll = false; } LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background @@ -1924,17 +2034,14 @@ void LLScrollListCtrl::draw() gl_rect_2d(background); } - if (mColumnsDirty) - { - updateColumns(); - mColumnsDirty = FALSE; - } + updateColumns(); + drawItems(); if (mBorder) { - mBorder->setKeyboardFocusHighlight(gFocusMgr.getKeyboardFocus() == this); + mBorder->setKeyboardFocusHighlight(hasFocus()); } LLUICtrl::draw(); @@ -1961,6 +2068,18 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +// *NOTE: Requires a valid row_index and column_index +LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index) +{ + LLRect cell_rect; + S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; + S32 rect_bottom = getRowOffsetFromIndex(row_index); + LLScrollListColumn* columnp = getColumn(column_index); + cell_rect.setOriginAndSize(rect_left, rect_bottom, + /*rect_left + */columnp->getWidth(), mLineHeight); + return cell_rect; +} + BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) { S32 column_index = getColumnIndexFromOffset(x); @@ -1988,18 +2107,11 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti if (hit_cell && hit_cell->isText()) { - - S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; - S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item)); - LLRect cell_rect; - cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight); + S32 row_index = getItemIndex(hit_item); + LLRect cell_rect = getCellRect(row_index, column_index); // Convert rect local to screen coordinates - localPointToScreen( - cell_rect.mLeft, cell_rect.mBottom, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - cell_rect.mRight, cell_rect.mTop, - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); + LLRect sticky_rect; + localRectToScreen(cell_rect, sticky_rect_screen); msg = hit_cell->getValue().asString(); } @@ -2007,7 +2119,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti } // otherwise, look for a tooltip associated with this column - LLColumnHeader* headerp = columnp->mHeader; + LLScrollColumnHeader* headerp = columnp->mHeader; if (headerp && !handled) { headerp->handleToolTip(x, y, msg, sticky_rect_screen); @@ -2133,7 +2245,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) setFocus(TRUE); // clear selection changed flag because user is starting a selection operation - mSelectionChanged = FALSE; + mSelectionChanged = false; handleClick(x, y, mask); @@ -2153,15 +2265,15 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } // always commit when mouse operation is completed inside list if (mItemListRect.pointInRect(x,y)) { - mDirty |= mSelectionChanged; - mSelectionChanged = FALSE; + mDirty = mDirty || mSelectionChanged; + mSelectionChanged = false; onCommit(); } @@ -2179,7 +2291,8 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) // so the scroll bars will work. if (NULL == LLView::childrenHandleDoubleClick(x, y, mask)) { - if( mCanSelect && mOnDoubleClickCallback ) + // Run the callback only if an item is being double-clicked. + if( mCanSelect && hitItem(x, y) && mOnDoubleClickCallback ) { mOnDoubleClickCallback(); } @@ -2208,7 +2321,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) { selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; } // propagate state of cell to rest of selected column @@ -2237,7 +2350,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) // treat this as a normal single item selection selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; // do not eat click (allow double click callback) return FALSE; } @@ -2248,6 +2361,8 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) // Excludes disabled items. LLScrollListItem* hit_item = NULL; + updateSort(); + LLRect item_rect; item_rect.setLeftTopAndSize( mItemListRect.mLeft, @@ -2256,7 +2371,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) mLineHeight ); // allow for partial line at bottom - S32 num_page_lines = mPageLines + 1; + S32 num_page_lines = getLinesPerPage(); S32 line = 0; item_list::iterator iter; @@ -2327,8 +2442,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index) S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index) { - S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight) - - mLineHeight; + S32 row_bottom = (mItemListRect.mTop - ((index - mScrollLines + 1) * mLineHeight) ); return row_bottom; } @@ -2342,7 +2456,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } else @@ -2351,11 +2465,11 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) LLScrollListItem* item = hitItem(x, y); if (item) { - highlightNthItem(getItemIndex(item)); + mouseOverHighlightNthItem(getItemIndex(item)); } else { - highlightNthItem(-1); + mouseOverHighlightNthItem(-1); } } @@ -2384,7 +2498,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectPrevItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2393,7 +2507,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectNextItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2401,7 +2515,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2414,7 +2528,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2427,7 +2541,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectFirstItem(); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2440,7 +2554,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getItemCount() - 1); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2479,7 +2593,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) } else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) { - mNeedsScroll = TRUE; + mNeedsScroll = true; // update search string only on successful match mSearchTimer.reset(); @@ -2519,7 +2633,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) { // update search string only on successful match - mNeedsScroll = TRUE; + mNeedsScroll = true; mSearchString += uni_char; mSearchTimer.reset(); @@ -2565,7 +2679,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { selectItem(item); - mNeedsScroll = TRUE; + mNeedsScroll = true; cellp->highlightText(0, 1); mSearchTimer.reset(); @@ -2636,7 +2750,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it } itemp->setSelected(TRUE); mLastSelected = itemp; - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2657,7 +2771,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) { cellp->highlightText(0, 0); } - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2665,7 +2779,7 @@ void LLScrollListCtrl::commitIfChanged() { if (mSelectionChanged) { - mDirty = TRUE; + mDirty = true; mSelectionChanged = FALSE; onCommit(); } @@ -2684,9 +2798,11 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) LLScrollListColumn* sort_column = getColumn(column_idx); if (!sort_column) return FALSE; - sort_column->mSortAscending = ascending; + sort_column->mSortDirection = ascending ? LLScrollListColumn::ASCENDING : LLScrollListColumn::DESCENDING; sort_column_t new_sort_column(column_idx, ascending); + + setNeedsSort(); if (mSortColumns.empty()) { @@ -2708,6 +2824,19 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) } } +S32 LLScrollListCtrl::getLinesPerPage() +{ + //if mPageLines is NOT provided display all item + if(mPageLines) + { + return mPageLines; + } + else + { + return mLineHeight ? mItemListRect.getHeight() / mLineHeight : getItemCount(); + } +} + // Called by scrollbar //static void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata ) @@ -2719,31 +2848,32 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) { - std::map::iterator itor = mColumns.find(name); + column_map_t::iterator itor = mColumns.find(name); if (itor != mColumns.end()) { - sortByColumnIndex((*itor).second.mIndex, ascending); + sortByColumnIndex((*itor).second->mIndex, ascending); } } // First column is column 0 void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending) { - if (setSort(column, ascending)) - { - sortItems(); - } + setSort(column, ascending); + updateSort(); } -void LLScrollListCtrl::sortItems() +void LLScrollListCtrl::updateSort() const { - // do stable sort to preserve any previous sorts - std::stable_sort( - mItemList.begin(), - mItemList.end(), - SortScrollListItem(mSortColumns)); + if (hasSortOrder() && !isSorted()) + { + // do stable sort to preserve any previous sorts + std::stable_sort( + mItemList.begin(), + mItemList.end(), + SortScrollListItem(mSortColumns,mSortCallback)); - setSorted(TRUE); + mSorted = true; + } } // for one-shot sorts, does not save sort column/order @@ -2756,22 +2886,23 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending) std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(sort_column)); + SortScrollListItem(sort_column,mSortCallback)); } void LLScrollListCtrl::dirtyColumns() { - mColumnsDirty = TRUE; + mColumnsDirty = true; + mColumnWidthsDirty = true; // need to keep mColumnsIndexed up to date // just in case someone indexes into it immediately mColumnsIndexed.resize(mColumns.size()); - std::map::iterator column_itor; + column_map_t::iterator column_itor; for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) { - LLScrollListColumn *column = &column_itor->second; - mColumnsIndexed[column_itor->second.mIndex] = column; + LLScrollListColumn *column = column_itor->second; + mColumnsIndexed[column_itor->second->mIndex] = column; } } @@ -2799,6 +2930,8 @@ void LLScrollListCtrl::scrollToShowSelected() return; } + updateSort(); + S32 index = getFirstSelectedIndex(); if (index < 0) { @@ -2813,7 +2946,8 @@ void LLScrollListCtrl::scrollToShowSelected() } S32 lowest = mScrollLines; - S32 highest = mScrollLines + mPageLines; + S32 page_lines = getLinesPerPage(); + S32 highest = mScrollLines + page_lines; if (index < lowest) { @@ -2822,7 +2956,7 @@ void LLScrollListCtrl::scrollToShowSelected() } else if (highest <= index) { - setScrollPos(index - mPageLines + 1); + setScrollPos(index - page_lines + 1); } } @@ -2869,9 +3003,9 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const std::map::const_iterator itor; std::vector sorted_list; sorted_list.resize(mColumns.size()); - for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) + for (column_map_t::const_iterator itor = mColumns.begin(); itor != mColumns.end(); ++itor) { - sorted_list[itor->second.mIndex] = &itor->second; + sorted_list[itor->second->mIndex] = itor->second; } std::vector::iterator itor2; @@ -2993,9 +3127,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac callback, NULL, multi_select, - draw_border); + draw_border, + draw_heading); - scroll_list->setDisplayHeading(draw_heading); if (node->hasAttribute("heading_height")) { S32 heading_height; @@ -3217,8 +3351,8 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) if (mColumns.find(name) == mColumns.end()) { // Add column - mColumns[name] = LLScrollListColumn(column, this); - LLScrollListColumn* new_column = &mColumns[name]; + LLScrollListColumn* new_column = new LLScrollListColumn(column, this); + mColumns[name] = new_column; new_column->mParentCtrl = this; new_column->mIndex = mColumns.size()-1; @@ -3239,18 +3373,19 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) new_column->setWidth((mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns); } S32 top = mItemListRect.mTop; + S32 left = mItemListRect.mLeft; + for (column_map_t::iterator itor = mColumns.begin(); + itor != mColumns.end(); + ++itor) { - std::map::iterator itor; - for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) + if (itor->second->mIndex < new_column->mIndex && + itor->second->getWidth() > 0) { - if (itor->second.mIndex < new_column->mIndex && - itor->second.getWidth() > 0) - { - left += itor->second.getWidth() + mColumnPadding; - } + left += itor->second->getWidth() + mColumnPadding; } } + std::string button_name = "btn_" + name; S32 right = left+new_column->getWidth(); if (new_column->mIndex != (S32)mColumns.size()-1) @@ -3258,7 +3393,7 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) right += mColumnPadding; } LLRect temp_rect = LLRect(left,top+mHeadingHeight,right,top); - new_column->mHeader = new LLColumnHeader(button_name, temp_rect, new_column); + new_column->mHeader = new LLScrollColumnHeader(button_name, temp_rect, new_column); if(column["image"].asString() != "") { //new_column->mHeader->setScaleImage(false); @@ -3301,12 +3436,12 @@ void LLScrollListCtrl::onClickColumn(void *userdata) S32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; - bool ascending = column->mSortAscending; + bool ascending = column->mSortDirection == LLScrollListColumn::ASCENDING; if (column->mSortingColumn != column->mName && parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end()) { - LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn]; - column_index = info_redir.mIndex; + LLScrollListColumn* info_redir = parent->mColumns[column->mSortingColumn]; + column_index = info_redir->mIndex; } // if this column is the primary sort key, reverse the direction @@ -3332,23 +3467,29 @@ std::string LLScrollListCtrl::getSortColumnName() else return ""; } -BOOL LLScrollListCtrl::needsSorting() +BOOL LLScrollListCtrl::hasSortOrder() const { return !mSortColumns.empty(); } +void LLScrollListCtrl::clearSortOrder() +{ + mSortColumns.clear(); +} + void LLScrollListCtrl::clearColumns() { - std::map::iterator itor; + column_map_t::iterator itor; for (itor = mColumns.begin(); itor != mColumns.end(); ++itor) { - LLColumnHeader *header = itor->second.mHeader; + LLScrollColumnHeader *header = itor->second->mHeader; if (header) { removeChild(header); delete header; } } + std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); mColumns.clear(); mSortColumns.clear(); mTotalStaticColumnWidth = 0; @@ -3357,13 +3498,13 @@ void LLScrollListCtrl::clearColumns() void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label) { - std::map::iterator itor = mColumns.find(column); - if (itor != mColumns.end()) + LLScrollListColumn* columnp = getColumn(column); + if (columnp) { - itor->second.mLabel = label; - if (itor->second.mHeader) + columnp->mLabel = label; + if (columnp->mHeader) { - itor->second.mHeader->setLabel(label); + columnp->mHeader->setLabel(label); } } } @@ -3377,6 +3518,16 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(S32 index) return mColumnsIndexed[index]; } +LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name) +{ + column_map_t::iterator column_itor = mColumns.find(name); + if (column_itor != mColumns.end()) + { + return column_itor->second; + } + return NULL; +} + void LLScrollListCtrl::setColumnHeadings(LLSD headings) { mColumns.clear(); @@ -3387,6 +3538,15 @@ void LLScrollListCtrl::setColumnHeadings(LLSD headings) } } +/* "id" + "enabled" + "columns" + "column" + "name" + "label" + "width" + "dynamic_width" +*/ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata) { // ID @@ -3423,11 +3583,10 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p column = new_name.str(); } - std::map::iterator column_itor; - column_itor = mColumns.find(column); + column_map_t::iterator column_itor = mColumns.find(column); if (column_itor != mColumns.end()) { - columnp = &column_itor->second; + columnp = column_itor->second; } // create new column on demand @@ -3447,7 +3606,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p new_column["dynamicwidth"] = true; } addColumn(new_column); - columnp = &mColumns[column]; + columnp = mColumns[column]; new_item->setNumColumns(mColumns.size()); } @@ -3561,10 +3720,10 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p // add dummy cells for missing columns for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it) { - S32 column_idx = column_it->second.mIndex; + S32 column_idx = column_it->second->mIndex; if (new_item->getColumn(column_idx) == NULL) { - LLScrollListColumn* column_ptr = &column_it->second; + LLScrollListColumn* column_ptr = column_it->second; new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL)); } } @@ -3643,7 +3802,6 @@ BOOL LLScrollListCtrl::operateOnAll(EOperation op) //virtual void LLScrollListCtrl::setFocus(BOOL b) { - mSearchString.clear(); // for tabbing into pristine scroll lists (Finder) if (!getFirstSelected()) { @@ -3677,7 +3835,7 @@ void LLScrollListCtrl::resetDirty() void LLScrollListCtrl::onFocusReceived() { // forget latent selection changes when getting focus - mSelectionChanged = FALSE; + mSelectionChanged = false; LLUICtrl::onFocusReceived(); } @@ -3688,10 +3846,13 @@ void LLScrollListCtrl::onFocusLost() { gFocusMgr.setMouseCapture(NULL); } + + mSearchString.clear(); + LLUICtrl::onFocusLost(); } -LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) : +LLScrollColumnHeader::LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) : LLComboBox(label, rect, label, NULL, NULL), mColumn(column), mOrigLabel(label), @@ -3704,9 +3865,9 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS mButton->setTabStop(FALSE); // require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2); - mButton->setHeldDownCallback(boost::bind(&LLColumnHeader::onHeldDown, this)); - mButton->setClickedCallback(boost::bind(&LLColumnHeader::onClick, this)); - mButton->setMouseDownCallback(boost::bind(&LLColumnHeader::onMouseDown, this)); + mButton->setHeldDownCallback(boost::bind(&LLScrollColumnHeader::onHeldDown, this)); + mButton->setClickedCallback(boost::bind(&LLScrollColumnHeader::onClick, this)); + mButton->setMouseDownCallback(boost::bind(&LLScrollColumnHeader::onMouseDown, this)); mButton->setCallbackUserData(this); mButton->setToolTip(label); @@ -3731,11 +3892,11 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS mImageOverlayColor = LLColor4::white; } -LLColumnHeader::~LLColumnHeader() +LLScrollColumnHeader::~LLScrollColumnHeader() { } -void LLColumnHeader::draw() +void LLScrollColumnHeader::draw() { BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; @@ -3848,7 +4009,7 @@ void LLColumnHeader::draw() } } -BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) +BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) { if (canResize() && mResizeBar->getRect().pointInRect(x, y)) { @@ -3864,7 +4025,7 @@ BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } -void LLColumnHeader::setImage(const std::string &image_name) +void LLScrollColumnHeader::setImage(const std::string &image_name) { if (mButton) { @@ -3873,7 +4034,7 @@ void LLColumnHeader::setImage(const std::string &image_name) } } -void LLColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) +void LLScrollColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) { if (image_name.empty()) { @@ -3888,9 +4049,9 @@ void LLColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HA } //static -void LLColumnHeader::onClick(void* user_data) +void LLScrollColumnHeader::onClick(void* user_data) { - LLColumnHeader* headerp = (LLColumnHeader*)user_data; + LLScrollColumnHeader* headerp = (LLScrollColumnHeader*)user_data; if (!headerp) return; LLScrollListColumn* column = headerp->mColumn; @@ -3910,20 +4071,20 @@ void LLColumnHeader::onClick(void* user_data) } //static -void LLColumnHeader::onMouseDown(void* user_data) +void LLScrollColumnHeader::onMouseDown(void* user_data) { // for now, do nothing but block the normal showList() behavior return; } //static -void LLColumnHeader::onHeldDown(void* user_data) +void LLScrollColumnHeader::onHeldDown(void* user_data) { - LLColumnHeader* headerp = (LLColumnHeader*)user_data; + LLScrollColumnHeader* headerp = (LLScrollColumnHeader*)user_data; headerp->showList(); } -void LLColumnHeader::showList() +void LLScrollColumnHeader::showList() { if (mShowSortOptions) { @@ -3996,8 +4157,8 @@ void LLColumnHeader::showList() text_width = llmax(text_width, getRect().getWidth() - 30); mList->getColumn(0)->setWidth(text_width); - ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string); - ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string); + mList->getFirstData()->getColumn(0)->setValue(ascending_string); + mList->getLastData()->getColumn(0)->setValue(descending_string); mList->reshape(llmax(text_width + 30, 110, getRect().getWidth()), mList->getRect().getHeight()); @@ -4006,9 +4167,9 @@ void LLColumnHeader::showList() } //static -void LLColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data) +void LLScrollColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data) { - LLColumnHeader* headerp = (LLColumnHeader*)user_data; + LLScrollColumnHeader* headerp = (LLScrollColumnHeader*)user_data; if (!headerp) return; LLScrollListColumn* column = headerp->mColumn; @@ -4031,7 +4192,7 @@ void LLColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data) headerp->setLabel(headerp->mOrigLabel); } -LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) +LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) { // this logic assumes dragging on right llassert(snap_edge == SNAP_RIGHT); @@ -4069,7 +4230,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d return this; } -void LLColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) +void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) { S32 new_width = new_rect.getWidth(); S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); @@ -4151,7 +4312,7 @@ void LLColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) } } -void LLColumnHeader::setHasResizableElement(BOOL resizable) +void LLScrollColumnHeader::setHasResizableElement(BOOL resizable) { // for now, dynamically spaced columns can't be resized // if (mColumn->mDynamicWidth) return; @@ -4163,7 +4324,7 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable) } } -void LLColumnHeader::updateResizeBars() +void LLScrollColumnHeader::updateResizeBars() { S32 num_resizable_columns = 0; S32 col; @@ -4192,7 +4353,7 @@ void LLColumnHeader::updateResizeBars() } } -void LLColumnHeader::enableResizeBar(BOOL enable) +void LLScrollColumnHeader::enableResizeBar(BOOL enable) { // for now, dynamically spaced columns can't be resized //if (!mColumn->mDynamicWidth) @@ -4201,25 +4362,16 @@ void LLColumnHeader::enableResizeBar(BOOL enable) } } -BOOL LLColumnHeader::canResize() +BOOL LLScrollColumnHeader::canResize() { return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth); } -void LLScrollListColumn::setWidth(S32 width) -{ - if (!mDynamicWidth && mRelWidth <= 0.f) - { - mParentCtrl->updateStaticColumnWidth(this, width); - } - mWidth = width; -} - // Default constructor LLScrollListColumn::LLScrollListColumn() : mName(), mSortingColumn(), - mSortAscending(TRUE), + mSortDirection(ASCENDING), mLabel(), mWidth(-1), mRelWidth(-1.0), @@ -4246,10 +4398,13 @@ LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) { mSortingColumn = sd.get("sort").asString(); } - mSortAscending = TRUE; if (sd.has("sort_ascending")) { - mSortAscending = sd.get("sort_ascending").asBoolean(); + mSortDirection = sd.get("sort_ascending").asBoolean() ? ASCENDING : DESCENDING; + } + else + { + mSortDirection = ASCENDING; } mLabel = sd.get("label").asString(); if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0) @@ -4266,7 +4421,6 @@ LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) } else { - setWidth(sd.get("width").asInteger()); } @@ -4280,3 +4434,12 @@ LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) } } + +void LLScrollListColumn::setWidth(S32 width) +{ + if (!mDynamicWidth && mRelWidth <= 0.f) + { + mParentCtrl->updateStaticColumnWidth(this, width); + } + mWidth = width; +} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 5c678f601..9ea4d82b8 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -51,6 +51,7 @@ #include "lldate.h" // #include "lllineeditor.h" +#include // /* @@ -69,13 +70,13 @@ public: virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible virtual S32 getWidth() const {return mWidth;} virtual S32 getContentWidth() const { return 0; } - virtual S32 getHeight() const = 0; + virtual S32 getHeight() const { return 0; } virtual const LLSD getValue() const { return LLStringUtil::null; } virtual void setValue(const LLSD& value) { } virtual BOOL getVisible() const { return TRUE; } virtual void setWidth(S32 width) { mWidth = width; } virtual void highlightText(S32 offset, S32 num_chars) {} - virtual BOOL isText() const = 0; + virtual BOOL isText() const { return FALSE; } virtual void setColor(const LLColor4&) {} virtual void onCommit() {}; @@ -86,19 +87,6 @@ private: S32 mWidth; }; -/* - * Draws a horizontal line. - */ -class LLScrollListSeparator : public LLScrollListCell -{ -public: - LLScrollListSeparator(S32 width); - virtual ~LLScrollListSeparator() {}; - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible - virtual S32 getHeight() const; - virtual BOOL isText() const { return FALSE; } -}; - /* * Cell displaying a text label. */ @@ -108,22 +96,27 @@ public: LLScrollListText( const std::string& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); /*virtual*/ ~LLScrollListText(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getContentWidth() const; - virtual S32 getHeight() const; - virtual void setValue(const LLSD& value); - virtual const LLSD getValue() const; - virtual BOOL getVisible() const; - virtual void highlightText(S32 offset, S32 num_chars); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getContentWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ const LLSD getValue() const; + /*virtual*/ BOOL getVisible() const; + /*virtual*/ void highlightText(S32 offset, S32 num_chars); - virtual void setColor(const LLColor4&); - virtual BOOL isText() const; + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ BOOL isText() const; + + S32 getTextWidth() const { return mTextWidth;} + void setTextWidth(S32 value) { mTextWidth = value;} + virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; } void setText(const LLStringExplicit& text); - void setFontStyle(const U8 font_style) { mFontStyle = font_style; } + void setFontStyle(const U8 font_style); private: LLUIString mText; + S32 mTextWidth; const LLFontGL* mFont; LLColor4 mColor; U8 mUseColor; @@ -138,18 +131,6 @@ private: static U32 sCount; }; - -class LLScrollListDate : public LLScrollListText -{ -public: - LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); - virtual void setValue(const LLSD& value); - virtual const LLSD getValue() const; - -private: - LLDate mDate; -}; - /* * Cell displaying an image. */ @@ -159,24 +140,22 @@ public: LLScrollListIcon( LLUIImagePtr icon, S32 width = 0); LLScrollListIcon(const LLSD& value, S32 width = 0); /*virtual*/ ~LLScrollListIcon(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getWidth() const; - virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; } - virtual const LLSD getValue() const { return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); } - virtual void setColor(const LLColor4&); - virtual BOOL isText()const { return FALSE; } - virtual void setValue(const LLSD& value); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ void setValue(const LLSD& value); // - void setClickCallback(BOOL (*callback)(void*), void* user_data); + void setClickCallback(boost::function cb); virtual BOOL handleClick(); // private: - LLUIImagePtr mIcon; + LLPointer mIcon; LLColor4 mColor; // - BOOL (*mCallback)(void*); - void* mUserData; + boost::function mCallback; // }; @@ -188,22 +167,33 @@ class LLScrollListCheck : public LLScrollListCell public: LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0); /*virtual*/ ~LLScrollListCheck(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getHeight() const { return 0; } - virtual const LLSD getValue() const { return mCheckBox->getValue(); } - virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); } - virtual void onCommit() { mCheckBox->onCommit(); } + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getHeight() const { return 0; } + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ void onCommit(); - virtual BOOL handleClick(); - virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); } + /*virtual*/ BOOL handleClick(); + /*virtual*/ void setEnabled(BOOL enable); LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } - virtual BOOL isText() const { return FALSE; } private: LLCheckBoxCtrl* mCheckBox; }; + +class LLScrollListDate : public LLScrollListText +{ +public: + LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); + virtual void setValue(const LLSD& value); + virtual const LLSD getValue() const; + +private: + LLDate mDate; +}; + // class LLScrollListLineEditor : public LLScrollListCell { @@ -228,43 +218,12 @@ private: }; // -/* - * A simple data class describing a column within a scroll list. - */ -class LLScrollListColumn +class LLScrollListColumn; +class LLScrollColumnHeader : public LLComboBox { public: - LLScrollListColumn(); - LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent); - - void setWidth(S32 width); - S32 getWidth() const { return mWidth; } - - // Public data is fine so long as this remains a simple struct-like data class. - // If it ever gets any smarter than that, these should all become private - // with protected or public accessor methods added as needed. -MG - std::string mName; - std::string mSortingColumn; - BOOL mSortAscending; - std::string mLabel; - F32 mRelWidth; - BOOL mDynamicWidth; - S32 mMaxContentWidth; - S32 mIndex; - LLScrollListCtrl* mParentCtrl; - class LLColumnHeader* mHeader; - LLFontGL::HAlign mFontAlignment; - -private: - S32 mWidth; - -}; - -class LLColumnHeader : public LLComboBox -{ -public: - LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL); - ~LLColumnHeader(); + LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL); + ~LLScrollColumnHeader(); /*virtual*/ void draw(); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); @@ -301,7 +260,44 @@ private: LLColor4 mImageOverlayColor; }; -class LLScrollListItem +/* + * A simple data class describing a column within a scroll list. + */ +class LLScrollListColumn +{ +public: + typedef enum e_sort_direction + { + DESCENDING, + ASCENDING + } ESortDirection; + LLScrollListColumn(); + LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent); + + void setWidth(S32 width); + S32 getWidth() const { return mWidth; } + + // Public data is fine so long as this remains a simple struct-like data class. + // If it ever gets any smarter than that, these should all become private + // with protected or public accessor methods added as needed. -MG + std::string mName; + std::string mSortingColumn; + ESortDirection mSortDirection; + std::string mLabel; + F32 mRelWidth; + BOOL mDynamicWidth; + S32 mMaxContentWidth; + S32 mIndex; + LLScrollListCtrl* mParentCtrl; + LLScrollColumnHeader* mHeader; + LLFontGL::HAlign mFontAlignment; + +private: + S32 mWidth; + +}; + +class LLScrollListItem : public LLHandleProvider { public: LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null ) @@ -314,7 +310,7 @@ public: void setSelected( BOOL b ) { mSelected = b; } BOOL getSelected() const { return mSelected; } - void setEnabled( BOOL b ); + void setEnabled( BOOL b ) { mEnabled = b; } BOOL getEnabled() const { return mEnabled; } void setUserdata( void* userdata ) { mUserdata = userdata; } @@ -323,9 +319,12 @@ public: void setToolTip(const std::string tool_tip) { mToolTip=tool_tip; } std::string getToolTip() { return mToolTip; } - LLUUID getUUID() const { return mItemValue.asUUID(); } + virtual LLUUID getUUID() const { return mItemValue.asUUID(); } LLSD getValue() const { return mItemValue; } + void setRect(LLRect rect) { mRectangle = rect; } + LLRect getRect() const { return mRectangle; } + // If width = 0, just use the width of the text. Otherwise override with // specified width in pixels. void addColumn( const std::string& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE) @@ -341,9 +340,9 @@ public: void setColumn( S32 column, LLScrollListCell *cell ); - S32 getNumColumns() const { return mColumns.size(); } + S32 getNumColumns() const; - LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; } + LLScrollListCell *getColumn(const S32 i) const; std::string getContentsCSV() const; @@ -356,29 +355,7 @@ private: LLSD mItemValue; std::string mToolTip; std::vector mColumns; -}; - -/* - * A graphical control representing a scrollable table. - * Cells in the table can be simple text or more complicated things - * such as icons or even interactive elements like check boxes. - */ -class LLScrollListItemComment : public LLScrollListItem -{ -public: - LLScrollListItemComment(const std::string& comment_string, const LLColor4& color); - - /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); -private: - LLColor4 mColor; -}; - -class LLScrollListItemSeparator : public LLScrollListItem -{ -public: - LLScrollListItemSeparator(); - - /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); + LLRect mRectangle; }; class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, @@ -386,13 +363,37 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, { public: typedef boost::function callback_t; + + template struct maximum + { + typedef T result_type; + + template + T operator()(InputIterator first, InputIterator last) const + { + // If there are no slots to call, just return the + // default-constructed value + if(first == last ) return T(); + T max_value = *first++; + while (first != last) { + if (max_value < *first) + max_value = *first; + ++first; + } + + return max_value; + } + }; + + + typedef boost::signals2::signal > sort_signal_t; LLScrollListCtrl( const std::string& name, const LLRect& rect, void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata, BOOL allow_multiple_selection, - BOOL draw_border = TRUE); + BOOL draw_border = TRUE, bool draw_heading = false); virtual ~LLScrollListCtrl(); @@ -416,6 +417,7 @@ public: virtual void setColumnLabel(const std::string& column, const std::string& label); virtual LLScrollListColumn* getColumn(S32 index); + virtual LLScrollListColumn* getColumn(const std::string& name); virtual S32 getNumColumns() const { return mColumnsIndexed.size(); } // Adds a single element, from an array of: @@ -466,7 +468,12 @@ public: void deleteSelectedItems(); void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change - void highlightNthItem( S32 index ); + void clearHighlightedItems(); + + virtual void mouseOverHighlightNthItem( S32 index ); + + S32 getHighlightedItemInx() const { return mHighlightedItem; } + void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; } void setMaximumSelectCallback( callback_t cb ) { mOnMaximumSelectCallback = cb; } void setSortChangedCallback( callback_t cb ) { mOnSortChangedCallback = cb; } @@ -483,7 +490,7 @@ public: S32 getItemIndex( LLScrollListItem* item ) const; S32 getItemIndex( const LLUUID& item_id ) const; - LLScrollListItem* addCommentText( const std::string& comment_text, EAddPosition pos = ADD_BOTTOM); + void setCommentText( const std::string& comment_text); LLScrollListItem* addSeparator(EAddPosition pos); // "Simple" interface: use this when you're creating a list that contains only unique strings, only @@ -494,6 +501,7 @@ public: BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); + LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); @@ -506,7 +514,8 @@ public: LLScrollListItem* getFirstSelected() const; virtual S32 getFirstSelectedIndex() const; std::vector getAllSelected() const; - LLDynamicArray getSelectedIDs(); + uuid_vec_t getSelectedIDs(); //Helper. Much like getAllSelected, but just provides a LLUUID vec + S32 getNumSelected() const; LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } // iterate over all items @@ -581,17 +590,26 @@ public: LLRect getItemListRect() { return mItemListRect; } + /// Returns rect, in local coords, of a given row/column + LLRect getCellRect(S32 row_index, S32 column_index); + // Used "internally" by the scroll bar. static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata ); static void onClickColumn(void *userdata); - void updateColumns(); - void calcColumnWidths(); + virtual void updateColumns(); + S32 calcMaxContentWidth(); + bool updateColumnWidths(); S32 getMaxContentWidth() { return mMaxContentWidth; } void setDisplayHeading(BOOL display); void setHeadingHeight(S32 heading_height); + /** + * Sets max visible lines without scroolbar, if this value equals to 0, + * then display all items. + */ + void setPageLines(S32 page_lines ); void setCollapseEmptyColumns(BOOL collapse); LLScrollListItem* hitItem(S32 x,S32 y); @@ -613,17 +631,25 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } - BOOL needsSorting(); + BOOL hasSortOrder() const; + void clearSortOrder(); - S32 selectMultiple( LLDynamicArray ids ); - void sortItems(); + S32 selectMultiple( uuid_vec_t ids ); + // conceptually const, but mutates mItemList + void updateSort() const; // sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example) void sortOnce(S32 column, BOOL ascending); // manually call this whenever editing list items in place to flag need for resorting - void setSorted(BOOL sorted) { mSorted = sorted; } + void setNeedsSort(bool val = true) { mSorted = !val; } void dirtyColumns(); // some operation has potentially affected column layout or ordering + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) + { + if (!mSortCallback) mSortCallback = new sort_signal_t(); + return mSortCallback->connect(cb); + } + protected: // "Full" interface: use this when you're creating a list that has one or more of the following: // * contains icons @@ -645,11 +671,13 @@ protected: typedef std::deque item_list; item_list& getItemList() { return mItemList; } + void updateLineHeight(); + private: void selectPrevItem(BOOL extend_selection); void selectNextItem(BOOL extend_selection); void drawItems(); - void updateLineHeight(); + void updateLineHeightInsert(LLScrollListItem* item); void reportInvalidInput(); BOOL isRepeatedChars(const LLWString& string) const; @@ -657,10 +685,7 @@ private: void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); - - - S32 mCurIndex; // For get[First/Next]Data - S32 mCurSelectedIndex; // For get[First/Next]Selected + S32 getLinesPerPage(); S32 mLineHeight; // the max height of a single line S32 mScrollLines; // how many lines we've scrolled down @@ -668,18 +693,19 @@ private: S32 mHeadingHeight; // the height of the column header buttons, if visible U32 mMaxSelectable; LLScrollbar* mScrollbar; - BOOL mAllowMultipleSelection; - BOOL mAllowKeyboardMovement; - BOOL mCommitOnKeyboardMovement; - BOOL mCommitOnSelectionChange; - BOOL mSelectionChanged; - BOOL mNeedsScroll; - BOOL mMouseWheelOpaque; - BOOL mCanSelect; - BOOL mDisplayColumnHeaders; - BOOL mColumnsDirty; + bool mAllowMultipleSelection; + bool mAllowKeyboardMovement; + bool mCommitOnKeyboardMovement; + bool mCommitOnSelectionChange; + bool mSelectionChanged; + bool mNeedsScroll; + bool mMouseWheelOpaque; + bool mCanSelect; + bool mDisplayColumnHeaders; + bool mColumnsDirty; + bool mColumnWidthsDirty; - item_list mItemList; + mutable item_list mItemList; LLScrollListItem *mLastSelected; @@ -709,6 +735,8 @@ private: S32 mHighlightedItem; class LLViewBorder* mBorder; + + LLView *mCommentTextView; LLWString mSearchString; LLFrameTimer mSearchTimer; @@ -718,12 +746,12 @@ private: S32 mTotalStaticColumnWidth; S32 mTotalColumnPadding; - BOOL mSorted; + mutable bool mSorted; - typedef std::map column_map_t; + typedef std::map column_map_t; column_map_t mColumns; - BOOL mDirty; + bool mDirty; S32 mOriginalSelection; typedef std::vector ordered_columns_t; @@ -732,8 +760,7 @@ private: typedef std::pair sort_column_t; std::vector mSortColumns; - // HACK: Did we draw one selected item this frame? - BOOL mDrewSelected; + sort_signal_t* mSortCallback; }; // end class LLScrollListCtrl diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index d0de1a4a1..0a988c7a7 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -41,7 +41,7 @@ #include "llviewmodel.h" // *TODO move dependency to .cpp file class LLUICtrl -: public LLView +: public LLView { public: typedef boost::function commit_callback_t; diff --git a/indra/newview/ascentfloatercontactgroups.cpp b/indra/newview/ascentfloatercontactgroups.cpp index d4097493d..f1d867fca 100644 --- a/indra/newview/ascentfloatercontactgroups.cpp +++ b/indra/newview/ascentfloatercontactgroups.cpp @@ -30,7 +30,7 @@ #include "llfloaterchat.h" ASFloaterContactGroups* ASFloaterContactGroups::sInstance = NULL; -LLDynamicArray ASFloaterContactGroups::mSelectedUUIDs; +uuid_vec_t ASFloaterContactGroups::mSelectedUUIDs; LLSD ASFloaterContactGroups::mContactGroupData; ASFloaterContactGroups::ASFloaterContactGroups() @@ -40,7 +40,7 @@ ASFloaterContactGroups::ASFloaterContactGroups() } // static -void ASFloaterContactGroups::show(LLDynamicArray ids) +void ASFloaterContactGroups::show(const uuid_vec_t& ids) { if (!sInstance) sInstance = new ASFloaterContactGroups(); @@ -84,7 +84,8 @@ void ASFloaterContactGroups::onBtnAdd(void* userdata) self->createContactGroup(name); combo->selectByValue(name); } - for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i) + uuid_vec_t::reverse_iterator it = self->mSelectedUUIDs.rbegin(); + for (;it != self->mSelectedUUIDs.rend();++it) { //self->addContactMember(combo->getSimple(), self->mSelectedUUIDs.get(i)); } @@ -98,19 +99,21 @@ void ASFloaterContactGroups::onBtnRemove(void* userdata) if(self) { - if (self->mSelectedUUIDs.count() > 0) + if (!self->mSelectedUUIDs.empty()) { LLScrollListCtrl* scroller = self->getChild("group_scroll_list"); if(scroller != NULL) { - for (S32 i = (self->mSelectedUUIDs.count() - 1); i >= 0; --i) + uuid_vec_t::size_type i = self->mSelectedUUIDs.size(); + uuid_vec_t::reverse_iterator it = self->mSelectedUUIDs.rbegin(); + for (;it != self->mSelectedUUIDs.rend();++it) { std::string i_str; - LLResMgr::getInstance()->getIntegerString(i_str, i); - LLChat msg("Adding index " + i_str + ": " + self->mSelectedUUIDs.get(i).asString()); + LLResMgr::getInstance()->getIntegerString(i_str, --i); + LLChat msg("Adding index " + i_str + ": " + it->asString()); LLFloaterChat::addChat(msg); - self->addContactMember(scroller->getValue().asString(), self->mSelectedUUIDs.get(i)); + self->addContactMember(scroller->getValue().asString(), *it); } } } diff --git a/indra/newview/ascentfloatercontactgroups.h b/indra/newview/ascentfloatercontactgroups.h index 809dce781..e20a67d38 100644 --- a/indra/newview/ascentfloatercontactgroups.h +++ b/indra/newview/ascentfloatercontactgroups.h @@ -29,7 +29,7 @@ public: virtual ~ASFloaterContactGroups(); // by convention, this shows the floater and does instance management - static void show(LLDynamicArray ids); + static void show(const uuid_vec_t& ids); void populateGroupList(); void populateActiveGroupList(LLUUID to_add); @@ -47,7 +47,7 @@ public: private: //assuming we just need one, which is typical static ASFloaterContactGroups* sInstance; - static LLDynamicArray mSelectedUUIDs; + static uuid_vec_t mSelectedUUIDs; static LLSD mContactGroupData; }; diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 5f416241c..7dcd34a59 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -300,8 +300,6 @@ bool cmd_line_chat(std::string revised_text, EChatType type) if(LLUUID::parseUUID(avatarKey, &tempUUID)) { char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ - LLDynamicArray ids; - ids.push_back(tempUUID); std::string tpMsg="Join me!"; LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_StartLure); @@ -312,11 +310,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type) msg->addU8Fast(_PREHASH_LureType, (U8)0); msg->addStringFast(_PREHASH_Message, tpMsg); - for(LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - msg->nextBlockFast(_PREHASH_TargetData); - msg->addUUIDFast(_PREHASH_TargetID, *itr); - } + msg->nextBlockFast(_PREHASH_TargetData); + msg->addUUIDFast(_PREHASH_TargetID, tempUUID); gAgent.sendReliableMessage(); snprintf(buffer,sizeof(buffer),"Offered TP to key %s",tempUUID.asString().c_str()); cmdline_printchat(std::string(buffer)); diff --git a/indra/newview/jcfloaterareasearch.cpp b/indra/newview/jcfloaterareasearch.cpp index e4ecb7b53..8479b9a3b 100644 --- a/indra/newview/jcfloaterareasearch.cpp +++ b/indra/newview/jcfloaterareasearch.cpp @@ -234,7 +234,7 @@ void JCFloaterAreaSearch::results() if (!(sInstance->getVisible())) return; if (sRequested > 0 && sInstance->mLastUpdateTimer.getElapsedTimeF32() < min_refresh_interval) return; //llinfos << "results()" << llendl; - LLDynamicArray selected = sInstance->mResultList->getSelectedIDs(); + uuid_vec_t selected = sInstance->mResultList->getSelectedIDs(); S32 scrollpos = sInstance->mResultList->getScrollPos(); sInstance->mResultList->deleteAllItems(); S32 i; @@ -302,7 +302,7 @@ void JCFloaterAreaSearch::results() } } - sInstance->mResultList->sortItems(); + sInstance->mResultList->updateSort(); sInstance->mResultList->selectMultiple(selected); sInstance->mResultList->setScrollPos(scrollpos); sInstance->mCounterText->setText(llformat("%d listed/%d pending/%d total", sInstance->mResultList->getItemCount(), sRequested, sObjectDetails.size())); diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 874299df3..858c26909 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -208,7 +208,7 @@ BOOL LLFloaterScriptQueue::start() buffer = getString ("Starting", args); LLScrollListCtrl* list = getChild("queue output"); - list->addCommentText(buffer); + list->setCommentText(buffer); return nextObject(); } @@ -244,7 +244,7 @@ BOOL LLFloaterScriptQueue::nextObject() LLScrollListCtrl* list = getChild("queue output"); mDone = TRUE; - list->addCommentText(getString("Done")); + list->setCommentText(getString("Done")); childSetEnabled("close",TRUE); } return successful_start; @@ -325,7 +325,7 @@ LLFloaterCompileQueue* LLFloaterCompileQueue::create(BOOL mono) } LLScrollListCtrl* list = queue->getChild("queue output"); - list->addCommentText(message.c_str()); + list->setCommentText(message.c_str()); } private: @@ -520,7 +520,7 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, if(queue && (buffer.size() > 0)) { LLScrollListCtrl* list = queue->getChild("queue output"); - list->addCommentText(buffer); + list->setCommentText(buffer); } delete data; } @@ -707,7 +707,7 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild("queue output"); std::string buffer; buffer = getString("Resetting") + LLTrans::getString(":") + " " + item->getName(); - list->addCommentText(buffer); + list->setCommentText(buffer); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ScriptReset); msg->nextBlockFast(_PREHASH_AgentData); @@ -769,7 +769,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild("queue output"); std::string buffer; buffer = getString("Running") + LLTrans::getString(":") + " " + item->getName(); - list->addCommentText(buffer); + list->setCommentText(buffer); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -833,7 +833,7 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj, LLScrollListCtrl* list = getChild("queue output"); std::string buffer; buffer = getString("NotRunning") + LLTrans::getString(":") + " " + item->getName(); - list->addCommentText(buffer); + list->setCommentText(buffer); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp index 7934fda10..6c16dc94f 100644 --- a/indra/newview/llfloateractivespeakers.cpp +++ b/indra/newview/llfloateractivespeakers.cpp @@ -610,7 +610,7 @@ void LLPanelActiveSpeakers::refreshSpeakers() } // we potentially modified the sort order by touching the list items - mSpeakerList->setSorted(FALSE); + mSpeakerList->setNeedsSort(); LLPointer selected_speakerp = mSpeakerMgr->findSpeaker(selected_id); // update UI for selected participant diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index ed54b156f..8b02f06d9 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -631,9 +631,9 @@ void LLFloaterAvatarList::expireAvatarList() (it++)->getAlive(); else { - std::swap(*it,mAvatars.back()); + *it = mAvatars.back(); mAvatars.pop_back(); - if(!mAvatars.size()) + if(mAvatars.empty()) return; } } @@ -674,7 +674,7 @@ void LLFloaterAvatarList::refreshAvatarList() // We rebuild the list fully each time it's refreshed // The assumption is that it's faster to refill it and sort than // to rebuild the whole list. - LLDynamicArray selected = mAvatarList->getSelectedIDs(); + uuid_vec_t selected = mAvatarList->getSelectedIDs(); S32 scrollpos = mAvatarList->getScrollPos(); mAvatarList->deleteAllItems(); @@ -961,7 +961,7 @@ void LLFloaterAvatarList::refreshAvatarList() } // finish - mAvatarList->sortItems(); + mAvatarList->updateSort(); mAvatarList->selectMultiple(selected); mAvatarList->setScrollPos(scrollpos); @@ -974,8 +974,8 @@ void LLFloaterAvatarList::refreshAvatarList() void LLFloaterAvatarList::onClickIM() { //llinfos << "LLFloaterFriends::onClickIM()" << llendl; - LLDynamicArray ids = mAvatarList->getSelectedIDs(); - if (ids.size() > 0) + const uuid_vec_t ids = mAvatarList->getSelectedIDs(); + if (!ids.empty()) { if (ids.size() == 1) { @@ -1004,7 +1004,7 @@ void LLFloaterAvatarList::onClickIM() void LLFloaterAvatarList::onClickTeleportOffer() { - LLDynamicArray ids = mAvatarList->getSelectedIDs(); + uuid_vec_t ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { handle_lure(ids); @@ -1106,7 +1106,7 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) if (( KEY_RETURN == key ) && (MASK_SHIFT == mask)) { - LLDynamicArray ids = self->mAvatarList->getSelectedIDs(); + uuid_vec_t ids = self->mAvatarList->getSelectedIDs(); if (ids.size() > 0) { if (ids.size() == 1) @@ -1425,12 +1425,12 @@ static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateInfo:: void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/) { - LLDynamicArray ids; + uuid_vec_t ids; if(!single) ids = mAvatarList->getSelectedIDs(); else - ids.put(getSelectedID()); - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) + ids.push_back(getSelectedID()); + for (uuid_vec_t::iterator itr = ids.begin(); itr != ids.end(); ++itr) { LLUUID& avid = *itr; if(avid.isNull()) @@ -1565,10 +1565,10 @@ void LLFloaterAvatarList::onClickEject() void LLFloaterAvatarList::onClickMute() { - LLDynamicArray ids = mAvatarList->getSelectedIDs(); + uuid_vec_t ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { - for (LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) + for (uuid_vec_t::iterator itr = ids.begin(); itr != ids.end(); ++itr) { LLUUID agent_id = *itr; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index b7d465ed9..99f6b49f9 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -499,6 +499,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* } LLSD element; element["id"] = avatar_id; // value + element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = avatar_name; search_results->addElement(element); } diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 287b799bd..926caee95 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -95,7 +95,7 @@ void LLFloaterBulkPermission::doApply() LLSelectMgr::getInstance()->getSelection()->applyToNodes(&gatherer); if(mObjectIDs.empty()) { - list->addCommentText(getString("nothing_to_modify_text")); + list->setCommentText(getString("nothing_to_modify_text")); } else { @@ -180,7 +180,7 @@ void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data) BOOL LLFloaterBulkPermission::start() { // note: number of top-level objects to modify is mObjectIDs.count(). - getChild("queue output")->addCommentText(getString("start_text")); + getChild("queue output")->setCommentText(getString("start_text")); return nextObject(); } @@ -203,7 +203,7 @@ BOOL LLFloaterBulkPermission::nextObject() if(isDone() && !mDone) { - getChild("queue output")->addCommentText(getString("done_text")); + getChild("queue output")->setCommentText(getString("done_text")); mDone = TRUE; } return successful_start; @@ -349,7 +349,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInv status_text.setArg("[STATUS]", ""); } - list->addCommentText(status_text.getString()); + list->setCommentText(status_text.getString()); //TODO if we are an object inside an object we should check a recuse flag and if set //open the inventory of the object and recurse - Michelle2 Zenovka diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index aa14a4953..d44e6f7cb 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -78,8 +78,7 @@ const F32 CONTEXT_FADE_TIME = 0.08f; ////////////////////////////////////////////////////////////////////////////// // default ctor -LLFloaterColorPicker:: -LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) +LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) : LLFloater (std::string("Color Picker Floater")), mComponents ( 3 ), mMouseDownInLumRegion ( FALSE ), @@ -124,10 +123,7 @@ LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate ) } } -////////////////////////////////////////////////////////////////////////////// -// dtor -LLFloaterColorPicker:: -~LLFloaterColorPicker() +LLFloaterColorPicker::~LLFloaterColorPicker() { // destroy the UI we created destroyUI (); @@ -135,9 +131,7 @@ LLFloaterColorPicker:: ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -createUI () +void LLFloaterColorPicker::createUI () { // build the majority of the gui using the factory builder LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml" ); @@ -184,9 +178,7 @@ createUI () ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -showUI () +void LLFloaterColorPicker::showUI () { setVisible ( TRUE ); setFocus ( TRUE ); @@ -219,26 +211,24 @@ showUI () ////////////////////////////////////////////////////////////////////////////// // called after the dialog is rendered -BOOL -LLFloaterColorPicker:: -postBuild() +BOOL LLFloaterColorPicker::postBuild() { mCancelBtn = getChild( "cancel_btn" ); - mCancelBtn->setClickedCallback ( boost::bind(&LLFloaterColorPicker::onClickCancel,this) ); + mCancelBtn->setClickedCallback ( onClickCancel, this ); mSelectBtn = getChild( "select_btn"); - mSelectBtn->setClickedCallback ( boost::bind(&LLFloaterColorPicker::onClickSelect,this) ); + mSelectBtn->setClickedCallback ( onClickSelect, this ); mSelectBtn->setFocus ( TRUE ); mPipetteBtn = getChild("color_pipette" ); mPipetteBtn->setImages(std::string("eye_button_inactive.tga"), std::string("eye_button_active.tga")); - mPipetteBtn->setClickedCallback( boost::bind(&LLFloaterColorPicker::onClickPipette,this) ); + mPipetteBtn->setClickedCallback( boost::bind(&LLFloaterColorPicker::onClickPipette,this )); mApplyImmediateCheck = getChild("apply_immediate"); mApplyImmediateCheck->set(gSavedSettings.getBOOL("ApplyColorImmediately")); - mApplyImmediateCheck->setCommitCallback(boost::bind(&LLFloaterColorPicker::onImmediateCheck,this)); + mApplyImmediateCheck->setCommitCallback(onImmediateCheck, this); childSetCommitCallback("rspin", onTextCommit, (void*)this ); childSetCommitCallback("gspin", onTextCommit, (void*)this ); @@ -248,14 +238,14 @@ postBuild() childSetCommitCallback("lspin", onTextCommit, (void*)this ); childSetCommitCallback("hexval", onHexCommit, (void*)this ); + LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterColorPicker::onColorSelect, this, _1)); + return TRUE; } ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -initUI ( F32 rValIn, F32 gValIn, F32 bValIn ) +void LLFloaterColorPicker::initUI ( F32 rValIn, F32 gValIn, F32 bValIn ) { // start catching lose-focus events from entry widgets enableTextCallbacks ( TRUE ); @@ -277,9 +267,7 @@ initUI ( F32 rValIn, F32 gValIn, F32 bValIn ) ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -destroyUI () +void LLFloaterColorPicker::destroyUI () { // shut down pipette tool if active stopUsingPipette(); @@ -295,7 +283,7 @@ destroyUI () if ( mSwatchView ) { this->removeChild ( mSwatchView ); - delete mSwatchView; + mSwatchView->die();; mSwatchView = NULL; } } @@ -303,9 +291,7 @@ destroyUI () ////////////////////////////////////////////////////////////////////////////// // -F32 -LLFloaterColorPicker:: -hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) +F32 LLFloaterColorPicker::hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) { if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; @@ -317,9 +303,7 @@ hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut ) +void LLFloaterColorPicker::hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut ) { if ( sValIn < 0.00001f ) { @@ -347,9 +331,7 @@ hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& ////////////////////////////////////////////////////////////////////////////// // mutator for original RGB value -void -LLFloaterColorPicker:: -setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn ) +void LLFloaterColorPicker::setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn ) { origR = origRIn; origG = origGIn; @@ -358,9 +340,7 @@ setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn ) ////////////////////////////////////////////////////////////////////////////// // accessor for original RGB value -void -LLFloaterColorPicker:: -getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut ) +void LLFloaterColorPicker::getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut ) { origROut = origR; origGOut = origG; @@ -369,9 +349,7 @@ getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut ) ////////////////////////////////////////////////////////////////////////////// // mutator for current RGB value -void -LLFloaterColorPicker:: -setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ) +void LLFloaterColorPicker::setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ) { // save current RGB curR = curRIn; @@ -391,9 +369,7 @@ setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn ) ////////////////////////////////////////////////////////////////////////////// // accessor for current RGB value -void -LLFloaterColorPicker:: -getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut ) +void LLFloaterColorPicker::getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut ) { curROut = curR; curGOut = curG; @@ -402,9 +378,7 @@ getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut ) ////////////////////////////////////////////////////////////////////////////// // mutator for current HSL value -void -LLFloaterColorPicker:: -setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn ) +void LLFloaterColorPicker::setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn ) { // save current HSL curH = curHIn; @@ -417,9 +391,7 @@ setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn ) ////////////////////////////////////////////////////////////////////////////// // accessor for current HSL value -void -LLFloaterColorPicker:: -getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut ) +void LLFloaterColorPicker::getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut ) { curHOut = curH; curSOut = curS; @@ -428,9 +400,7 @@ getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut ) ////////////////////////////////////////////////////////////////////////////// // called when 'cancel' clicked -void -LLFloaterColorPicker:: -onClickCancel ( void* data ) +void LLFloaterColorPicker::onClickCancel ( void* data ) { if (data) { @@ -446,9 +416,7 @@ onClickCancel ( void* data ) ////////////////////////////////////////////////////////////////////////////// // called when 'select' clicked -void -LLFloaterColorPicker:: -onClickSelect ( void* data ) +void LLFloaterColorPicker::onClickSelect ( void* data ) { if (data) { @@ -463,31 +431,23 @@ onClickSelect ( void* data ) } } -void LLFloaterColorPicker::onClickPipette( void* data ) +void LLFloaterColorPicker::onClickPipette() { - LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data; - - if ( self) + BOOL pipette_active = mPipetteBtn->getToggleState(); + pipette_active = !pipette_active; + if (pipette_active) { - BOOL pipette_active = self->mPipetteBtn->getToggleState(); - pipette_active = !pipette_active; - if (pipette_active) - { - LLToolPipette::getInstance()->setSelectCallback(onColorSelect, self); - LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); - } - else - { - LLToolMgr::getInstance()->clearTransientTool(); - } + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); + } + else + { + LLToolMgr::getInstance()->clearTransientTool(); } } ////////////////////////////////////////////////////////////////////////////// // called when 'text is committed' - i,e. focus moves from a text field -void -LLFloaterColorPicker:: -onTextCommit ( LLUICtrl* ctrl, void* data ) +void LLFloaterColorPicker::onTextCommit ( LLUICtrl* ctrl, void* data ) { if ( data ) { @@ -499,22 +459,13 @@ onTextCommit ( LLUICtrl* ctrl, void* data ) } } -void LLFloaterColorPicker::onImmediateCheck() +void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data) { - gSavedSettings.setBOOL("ApplyColorImmediately", mApplyImmediateCheck->get()); - - if (mApplyImmediateCheck->get()) - { - LLColorSwatchCtrl::onColorChanged ( getSwatch(), LLColorSwatchCtrl::COLOR_CHANGE ); - } -} - -void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te, void *data ) -{ - LLFloaterColorPicker* self = (LLFloaterColorPicker*)data; + LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data; if (self) { - self->setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]); + gSavedSettings.setBOOL("ApplyColorImmediately", self->mApplyImmediateCheck->get()); + if (self->mApplyImmediateCheck->get()) { LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); @@ -522,6 +473,15 @@ void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te, void *data ) } } +void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te) +{ + setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]); + if (mApplyImmediateCheck->get()) + { + LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); + } +} + void LLFloaterColorPicker::onMouseCaptureLost() { setMouseDownInHueRegion(FALSE); @@ -673,9 +633,7 @@ void LLFloaterColorPicker::draw() ////////////////////////////////////////////////////////////////////////////// // find a complimentary color to the one passed in that can be used to highlight -const LLColor4& -LLFloaterColorPicker:: -getComplimentaryColor ( const LLColor4& backgroundColor ) +const LLColor4& LLFloaterColorPicker::getComplimentaryColor ( const LLColor4& backgroundColor ) { // going to base calculation on luminance F32 hVal, sVal, lVal; @@ -695,9 +653,7 @@ getComplimentaryColor ( const LLColor4& backgroundColor ) ////////////////////////////////////////////////////////////////////////////// // draw color palette -void -LLFloaterColorPicker:: -drawPalette () +void LLFloaterColorPicker::drawPalette () { S32 curEntry = 0; @@ -759,9 +715,7 @@ std::string RGBToHex(int rNum, int gNum, int bNum) } //Called when a hex value is entered into the Hex field - Convert and set values. -void -LLFloaterColorPicker:: -onHexCommit ( LLUICtrl* ctrl, void* data ) +void LLFloaterColorPicker::onHexCommit ( LLUICtrl* ctrl, void* data ) { if ( data ) { @@ -834,9 +788,7 @@ enableTextCallbacks ( BOOL stateIn ) ////////////////////////////////////////////////////////////////////////////// // -void -LLFloaterColorPicker:: -onTextEntryChanged ( LLUICtrl* ctrl ) +void LLFloaterColorPicker::onTextEntryChanged ( LLUICtrl* ctrl ) { // value in RGB boxes changed std::string name = ctrl->getName(); @@ -905,9 +857,7 @@ onTextEntryChanged ( LLUICtrl* ctrl ) ////////////////////////////////////////////////////////////////////////////// // -BOOL -LLFloaterColorPicker:: -updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn ) +BOOL LLFloaterColorPicker::updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn ) { if ( xPosIn >= mRGBViewerImageLeft && xPosIn <= mRGBViewerImageLeft + mRGBViewerImageWidth && @@ -943,9 +893,7 @@ updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn ) ////////////////////////////////////////////////////////////////////////////// // -BOOL -LLFloaterColorPicker:: -handleMouseDown ( S32 x, S32 y, MASK mask ) +BOOL LLFloaterColorPicker::handleMouseDown ( S32 x, S32 y, MASK mask ) { // make it the frontmost gFloaterView->bringToFront(this); @@ -1047,9 +995,7 @@ handleMouseDown ( S32 x, S32 y, MASK mask ) ////////////////////////////////////////////////////////////////////////////// // -BOOL -LLFloaterColorPicker:: -handleHover ( S32 x, S32 y, MASK mask ) +BOOL LLFloaterColorPicker::handleHover ( S32 x, S32 y, MASK mask ) { // if we're the front most window if ( isFrontmost () ) @@ -1125,9 +1071,7 @@ void LLFloaterColorPicker::onClose(bool app_quitting) ////////////////////////////////////////////////////////////////////////////// // reverts state once mouse button is released -BOOL -LLFloaterColorPicker:: -handleMouseUp ( S32 x, S32 y, MASK mask ) +BOOL LLFloaterColorPicker::handleMouseUp ( S32 x, S32 y, MASK mask ) { getWindow()->setCursor ( UI_CURSOR_ARROW ); @@ -1202,9 +1146,7 @@ handleMouseUp ( S32 x, S32 y, MASK mask ) ////////////////////////////////////////////////////////////////////////////// // cancel current color selection, revert to original and close picker -void -LLFloaterColorPicker:: -cancelSelection () +void LLFloaterColorPicker::cancelSelection () { // restore the previous color selection setCurRgb ( getOrigR (), getOrigG (), getOrigB () ); diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 6e9e75e3a..185b2a400 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -123,11 +123,11 @@ class LLFloaterColorPicker // callbacks static void onClickCancel ( void* data ); static void onClickSelect ( void* data ); - static void onClickPipette ( void* data ); + void onClickPipette ( ); static void onTextCommit ( LLUICtrl* ctrl, void* data ); + static void onImmediateCheck ( LLUICtrl* ctrl, void* data ); static void onHexCommit ( LLUICtrl* ctrl, void* data ); - void onImmediateCheck(); - static void onColorSelect( const LLTextureEntry& te, void *data ); + void onColorSelect( const LLTextureEntry& te ); private: // turns on or off text entry commit call backs void enableTextCallbacks ( BOOL stateIn ); diff --git a/indra/newview/llfloaterexploresounds.cpp b/indra/newview/llfloaterexploresounds.cpp index 00cbcab59..4ce0cf111 100644 --- a/indra/newview/llfloaterexploresounds.cpp +++ b/indra/newview/llfloaterexploresounds.cpp @@ -166,13 +166,7 @@ BOOL LLFloaterExploreSounds::tick() // Save scroll pos and selection so they can be restored S32 scroll_pos = list->getScrollPos(); - LLDynamicArray selected_ids; - std::vector selected_items = list->getAllSelected(); - std::vector::iterator selection_iter = selected_items.begin(); - std::vector::iterator selection_end = selected_items.end(); - for(; selection_iter != selection_end; ++selection_iter) - selected_ids.push_back((*selection_iter)->getUUID()); - + uuid_vec_t selected_ids = list->getSelectedIDs(); list->clearRows(); std::list unique_asset_list; diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 276e29d47..f5786c46c 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -168,7 +168,7 @@ void LLPanelFriends::updateFriends(U32 changed_mask) // if the maximum amount of friends are selected mShowMaxSelectWarning = false; - LLDynamicArray selected_friends = getSelectedIDs(); + const uuid_vec_t selected_friends = mFriendsList->getSelectedIDs(); if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) { refreshNames(changed_mask); @@ -187,13 +187,13 @@ void LLPanelFriends::updateFriends(U32 changed_mask) tick(); } } - if(selected_friends.size() > 0) + if(!selected_friends.empty()) { // only non-null if friends was already found. This may fail, // but we don't really care here, because refreshUI() will // clean up the interface. friends_list->setCurrentByID(selected_id); - for(LLDynamicArray::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr) + for(uuid_vec_t::const_iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr) { friends_list->setSelectedByValue(*itr, true); } @@ -587,7 +587,7 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh void LLPanelFriends::refreshRightsChangeList() { - LLDynamicArray friends = getSelectedIDs(); + const uuid_vec_t friends = mFriendsList->getSelectedIDs(); S32 num_selected = friends.size(); bool can_offer_teleport = num_selected >= 1; @@ -610,7 +610,7 @@ void LLPanelFriends::refreshRightsChangeList() processing_label->setVisible(false); } Making Dummy View -HgB */ const LLRelationship* friend_status = NULL; - for(LLDynamicArray::iterator itr = friends.begin(); itr != friends.end(); ++itr) + for(uuid_vec_t::const_iterator itr = friends.begin(); itr != friends.end(); ++itr) { friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr); if (friend_status) @@ -659,7 +659,7 @@ struct SortFriendsByID void LLPanelFriends::refreshNames(U32 changed_mask) { - LLDynamicArray selected_ids = getSelectedIDs(); + const uuid_vec_t selected_ids = mFriendsList->getSelectedIDs(); S32 pos = mFriendsList->getScrollPos(); // get all buddies we know about @@ -685,7 +685,7 @@ void LLPanelFriends::refreshNames(U32 changed_mask) // Changed item in place, need to request sort and update columns // because we might have changed data in a column on which the user // has already sorted. JC - mFriendsList->sortItems(); + mFriendsList->updateSort(); // re-select items mFriendsList->selectMultiple(selected_ids); @@ -787,18 +787,6 @@ void LLPanelFriends::refreshUI() refreshRightsChangeList(); } -LLDynamicArray LLPanelFriends::getSelectedIDs() -{ - LLUUID selected_id; - LLDynamicArray friend_ids; - std::vector selected = mFriendsList->getAllSelected(); - for(std::vector::iterator itr = selected.begin(); itr != selected.end(); ++itr) - { - friend_ids.push_back((*itr)->getUUID()); - } - return friend_ids; -} - // static void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data) { @@ -818,8 +806,8 @@ void LLPanelFriends::onClickProfile(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; //llinfos << "LLPanelFriends::onClickProfile()" << llendl; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() > 0) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { LLUUID agent_id = ids[0]; BOOL online; @@ -834,7 +822,7 @@ void LLPanelFriends::onClickAssign(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; if (panelp) { - LLDynamicArray ids = panelp->getSelectedIDs(); + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); ASFloaterContactGroups::show(ids); } } @@ -885,8 +873,8 @@ void LLPanelFriends::onClickIM(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; //llinfos << "LLPanelFriends::onClickIM()" << llendl; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() > 0) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { if(ids.size() == 1) { @@ -959,13 +947,12 @@ bool LLPanelFriends::callbackAddFriend(const LLSD& notification, const LLSD& res } // static -void LLPanelFriends::onPickAvatar(const std::vector& names, - const std::vector& ids, - void* ) +void LLPanelFriends::onPickAvatar( const uuid_vec_t& ids, + const std::vector& names ) { if (names.empty()) return; if (ids.empty()) return; - requestFriendshipDialog(ids[0], names[0]); + requestFriendshipDialog(ids[0], names[0].getCompleteName()); } // static @@ -1001,7 +988,7 @@ void LLPanelFriends::onClickAddFriend(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; LLFloater* root_floater = gFloaterView->getParentFloater(panelp); - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelFriends::onPickAvatar, _1, _2), FALSE, TRUE); if (root_floater) { root_floater->addDependentFloater(picker); @@ -1014,9 +1001,9 @@ void LLPanelFriends::onClickRemove(void* user_data) LLPanelFriends* panelp = (LLPanelFriends*)user_data; //llinfos << "LLPanelFriends::onClickRemove()" << llendl; - LLDynamicArray ids = panelp->getSelectedIDs(); + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); LLSD args; - if(ids.size() > 0) + if(!ids.empty()) { std::string msgType = "RemoveFromFriends"; if(ids.size() == 1) @@ -1053,7 +1040,7 @@ void LLPanelFriends::onClickRemove(void* user_data) } LLSD payload; - for (LLDynamicArray::iterator it = ids.begin(); + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -1257,8 +1244,8 @@ void LLPanelFriends::onClickOfferTeleport(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() > 0) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { handle_lure(ids); } @@ -1269,8 +1256,8 @@ void LLPanelFriends::onClickPay(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; - LLDynamicArray ids = panelp->getSelectedIDs(); - if(ids.size() == 1) + const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); + if(!ids.empty()) { handle_pay_by_id(ids[0]); } @@ -1281,7 +1268,7 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command if (ids.empty()) return; LLSD args; - if(ids.size() > 0) + if(!ids.empty()) { rights_map_t* rights = new rights_map_t(ids); diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h index e97aecc0f..94bfe17b0 100644 --- a/indra/newview/llfloaterfriends.h +++ b/indra/newview/llfloaterfriends.h @@ -41,6 +41,7 @@ #include "lleventtimer.h" #include "llcallingcard.h" +class LLAvatarName; class LLFriendObserver; class LLRelationship; class LLScrollListItem; @@ -126,15 +127,12 @@ private: void confirmModifyRights(rights_map_t& ids, EGrantRevoke command); void sendRightsGrant(rights_map_t& ids); - // return LLUUID::null if nothing is selected - LLDynamicArray getSelectedIDs(); - // callback methods static void onSelectName(LLUICtrl* ctrl, void* user_data); static void onChangeContactGroup(LLUICtrl* ctrl, void* user_data); static bool callbackAddFriend(const LLSD& notification, const LLSD& response); static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); - static void onPickAvatar(const std::vector& names, const std::vector& ids, void* user_data); + static void onPickAvatar(const uuid_vec_t& ids, const std::vector& names ); static void onContactSearchEdit(const std::string& search_string, void* user_data); static void onClickIM(void* user_data); static void onClickAssign(void* user_data); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 08425f69b..398151373 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1499,7 +1499,7 @@ void LLPanelLandObjects::onClickRefresh(void* userdata) // ready the list for results self->mOwnerList->deleteAllItems(); - self->mOwnerList->addCommentText(LLTrans::getString("Searching")); + self->mOwnerList->setCommentText(LLTrans::getString("Searching")); self->mOwnerList->setEnabled(FALSE); self->mFirstReply = TRUE; @@ -1526,8 +1526,6 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo return; } - const LLFontGL* FONT = LLFontGL::getFontSansSerif(); - // Extract all of the owners. S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data); //uuid_list_t return_ids; @@ -1568,44 +1566,64 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo BOOL in_sim = (std::find(avatar_ids.begin(), avatar_ids.end(), owner_id) != avatar_ids.end()); - LLScrollListItem *row = new LLScrollListItem( TRUE, NULL, owner_id); + LLSD item; + item["id"] = owner_id; + LLSD& row = item["columns"]; + LLSD icon_column; + LLSD status_column; + icon_column["type"] = "icon"; + icon_column["column"] = "type"; + status_column["font"] = "SANSSERIF"; + status_column["column"] = "online_status"; + if (is_group_owned) { - row->addColumn(self->mIconGroup); - row->addColumn(OWNER_GROUP, FONT); + icon_column["value"] = self->mIconGroup->getName(); + status_column["value"] = OWNER_GROUP; } else if (in_sim) { - row->addColumn(self->mIconAvatarInSim); - row->addColumn(OWNER_INSIM, FONT); + icon_column["value"] = self->mIconAvatarInSim->getName(); + status_column["value"] = OWNER_INSIM; } else if (is_online) { - row->addColumn(self->mIconAvatarOnline); - row->addColumn(OWNER_ONLINE, FONT); + icon_column["value"] = self->mIconAvatarOnline->getName(); + status_column["value"] = OWNER_ONLINE; } else // offline { - row->addColumn(self->mIconAvatarOffline); - row->addColumn(OWNER_OFFLINE, FONT); + icon_column["value"] = self->mIconAvatarOffline->getName(); + status_column["value"] = OWNER_OFFLINE; } + row.append(icon_column); + row.append(status_column); + // Placeholder for name. - row->addColumn(LLStringUtil::null, FONT); + LLAvatarName av_name; + LLAvatarNameCache::get(owner_id, &av_name); + LLSD name_column; + name_column["value"] = av_name.getCompleteName(); + name_column["font"] = "SANSSERIF"; + name_column["column"] = "name"; + row.append(name_column); - object_count_str = llformat("%d", object_count); - row->addColumn(object_count_str, FONT); + LLSD count_column; + count_column["value"] = llformat("%d", object_count); + count_column["font"] = "SANSSERIF"; + count_column["column"] = "count"; + row.append(count_column); - row->addColumn(formatted_time((time_t)most_recent_time), FONT); + LLSD time_column; + time_column["value"] = formatted_time((time_t)most_recent_time); + time_column["font"] = "SANSSERIF"; + time_column["column"] = "mostrecent"; + row.append(time_column); - - if (is_group_owned) - { + if( is_group_owned ) self->mOwnerList->addGroupNameItem(row, ADD_BOTTOM); - } else - { self->mOwnerList->addNameItem(row, ADD_BOTTOM); - } lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") << ") owns " << object_count << " objects." << llendl; @@ -1613,7 +1631,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo // check for no results if (0 == self->mOwnerList->getItemCount()) { - self->mOwnerList->addCommentText(LLTrans::getString("NoneFound")); + self->mOwnerList->setCommentText(LLTrans::getString("NoneFound")); } else { @@ -2439,7 +2457,11 @@ void LLPanelLandAccess::refresh() childSetLabelArg("GroupCheck", "[GROUP]", group_name ); // Allow list + if (mListAccess) { + // Clear the sort order so we don't re-sort on every add. + mListAccess->clearSortOrder(); + mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",count)); childSetToolTipArg("AccessList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2475,13 +2497,17 @@ void LLPanelLandAccess::refresh() } suffix.append(" " + getString("remaining") + ")"); } - if (mListAccess) - mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); + mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); } + mListAccess->sortByName(TRUE); } // Ban List + if(mListBanned) { + // Clear the sort order so we don't re-sort on every add. + mListBanned->clearSortOrder(); + mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); childSetToolTipArg("BannedList", "[LISTED]", llformat("%d",count)); @@ -2520,6 +2546,7 @@ void LLPanelLandAccess::refresh() } mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); } + mListBanned->sortByName(TRUE); } if(parcel->getRegionDenyAnonymousOverride()) diff --git a/indra/newview/llfloatermessagelog.cpp b/indra/newview/llfloatermessagelog.cpp index ac1ecd99c..230a4b15a 100644 --- a/indra/newview/llfloatermessagelog.cpp +++ b/indra/newview/llfloatermessagelog.cpp @@ -636,18 +636,18 @@ void LLFloaterMessageLog::refreshNetList() { LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); icon->setValue("icon_net_close_circuit.tga"); - icon->setClickCallback(onClickCloseCircuit, itemp); + icon->setClickCallback(boost::bind(&LLFloaterMessageLog::onClickCloseCircuit, itemp)); } else { LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); icon->setValue("icon_net_close_circuit_gray.tga"); - icon->setClickCallback(NULL, NULL); + //icon->setClickCallback(NULL); } // Event queue isn't even supported yet... FIXME LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2); icon->setValue("icon_net_close_eventpoll_gray.tga"); - icon->setClickCallback(NULL, NULL); + //icon->setClickCallback(NULL); } if(selected_id.notNull()) scrollp->selectByID(selected_id); if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos); diff --git a/indra/newview/llfloaternewim.cpp b/indra/newview/llfloaternewim.cpp index 8bff4f17f..3acca6e38 100644 --- a/indra/newview/llfloaternewim.cpp +++ b/indra/newview/llfloaternewim.cpp @@ -92,7 +92,7 @@ void LLFloaterNewIM::addSpecial(const LLUUID& uuid, const std::string& name, LLSD row; row["id"] = uuid; row["name"] = name; - row["target"] = "SPECIAL"; + row["target"] = LLNameListCtrl::SPECIAL; row["columns"][0]["value"] = name; row["columns"][0]["width"] = COL_1_WIDTH; row["columns"][0]["font"] = "SANSSERIF"; @@ -113,7 +113,7 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on { LLSD row; row["id"] = uuid; - row["target"] = "GROUP"; + row["target"] = LLNameListCtrl::GROUP; row["columns"][0]["value"] = ""; // name will be looked up row["columns"][0]["width"] = COL_1_WIDTH; row["columns"][0]["font"] = "SANSSERIF"; @@ -132,12 +132,10 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online) { - std::string fullname; - gCacheName->getFullName(uuid, fullname); - LLSD row; row["id"] = uuid; - row["columns"][0]["value"] = fullname; + row["target"] = LLNameListCtrl::INDIVIDUAL; + row["columns"][0]["value"] = ""; row["columns"][0]["width"] = COL_1_WIDTH; row["columns"][0]["font"] = "SANSSERIF"; row["columns"][0]["font-style"] = online ? "BOLD" : "NORMAL"; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 0a6b234f0..f9a4d3908 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -3200,7 +3200,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_agent_name_list) { - //allowed_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + allowed_agent_name_list->clearSortOrder(); for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; @@ -3208,7 +3209,7 @@ bool LLDispatchSetEstateAccess::operator()( allowed_agent_name_list->addNameItem(id); } panel->childSetEnabled("remove_allowed_avatar_btn", allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); + allowed_agent_name_list->sortByName(TRUE); } } @@ -3225,6 +3226,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_group_name_list) { + // Don't sort these as we add them, sort them when we are done. + allowed_group_name_list->clearSortOrder(); allowed_group_name_list->deleteAllItems(); for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) { @@ -3233,7 +3236,7 @@ bool LLDispatchSetEstateAccess::operator()( allowed_group_name_list->addGroupNameItem(id); } panel->childSetEnabled("remove_allowed_group_btn", allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); + allowed_group_name_list->sortByName(TRUE); } } @@ -3257,7 +3260,9 @@ bool LLDispatchSetEstateAccess::operator()( if (banned_agent_name_list) { - //banned_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + banned_agent_name_list->clearSortOrder(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; @@ -3265,7 +3270,7 @@ bool LLDispatchSetEstateAccess::operator()( banned_agent_name_list->addNameItem(id); } panel->childSetEnabled("remove_banned_avatar_btn", banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); + banned_agent_name_list->sortByName(TRUE); } } @@ -3280,6 +3285,9 @@ bool LLDispatchSetEstateAccess::operator()( panel->getChild("estate_manager_name_list"); if (estate_manager_name_list) { + // Don't sort these as we add them, sort them when we are done. + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); // Clear existing entries // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't @@ -3292,7 +3300,7 @@ bool LLDispatchSetEstateAccess::operator()( estate_manager_name_list->addNameItem(id); } panel->childSetEnabled("remove_estate_manager_btn", estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); + estate_manager_name_list->sortByName(TRUE); } } diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index c230aef4c..e737b3d56 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -250,7 +250,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) if (total_count == 0 && list->getItemCount() == 0) { - list->addCommentText(getString("none_descriptor")); + list->setCommentText(getString("none_descriptor")); } else { diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index feef951f2..f21bb2902 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -1593,7 +1593,7 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) else { // if we found nothing, say "none" - list->addCommentText(LLTrans::getString("worldmap_results_none_found")); + list->setCommentText(LLTrans::getString("worldmap_results_none_found")); list->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 852ad01b8..e5d1bb259 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -792,7 +792,7 @@ void LLGestureMgr::update() if (gesture->mDoneCallback) { - gesture->mDoneCallback(gesture, gesture->mCallbackData); + gesture->mDoneCallback(gesture); // callback might have deleted gesture, can't // rely on this pointer any more @@ -1299,7 +1299,7 @@ void LLGestureMgr::stopGesture(LLMultiGesture* gesture) if (gesture->mDoneCallback) { - gesture->mDoneCallback(gesture, gesture->mCallbackData); + gesture->mDoneCallback(gesture); // callback might have deleted gesture, can't // rely on this pointer any more diff --git a/indra/newview/llinventorybackup.cpp b/indra/newview/llinventorybackup.cpp index 412404944..6963d4ff9 100644 --- a/indra/newview/llinventorybackup.cpp +++ b/indra/newview/llinventorybackup.cpp @@ -619,11 +619,11 @@ BOOL LLFloaterInventoryBackup::postBuild(void) status_column["column"] = "status"; status_column["value"] = "Pending"; - LLScrollListItem* scroll_itemp = list->addElement(element, ADD_BOTTOM); + /*LLScrollListItem* scroll_itemp = */list->addElement(element, ADD_BOTTOM); //hack to stop crashing - LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(LIST_TYPE); - icon->setClickCallback(NULL, NULL); + //LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(LIST_TYPE); + //icon->setClickCallback(NULL); } // Setup and go! diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 60eafcd4a..0ec781e40 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -32,13 +32,16 @@ #include "llviewerprecompiledheaders.h" +#include "llnamelistctrl.h" + #include -#include "llnamelistctrl.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "llagent.h" #include "llinventory.h" +#include "lltrans.h" static LLRegisterWidget r("name_list"); @@ -51,12 +54,14 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name, void* userdata, BOOL allow_multiple_selection, BOOL draw_border, + bool draw_heading, S32 name_column_index, const std::string& tooltip) : LLScrollListCtrl(name, rect, cb, userdata, allow_multiple_selection, - draw_border), + draw_border,draw_heading), mNameColumnIndex(name_column_index), - mAllowCallingCardDrop(FALSE) + mAllowCallingCardDrop(FALSE), + mShortNames(FALSE) { setToolTip(tooltip); LLNameListCtrl::sInstances.insert(this); @@ -71,19 +76,22 @@ LLNameListCtrl::~LLNameListCtrl() // public -BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, - BOOL enabled, std::string const& suffix) +LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, + BOOL enabled, const std::string& suffix) { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; - std::string fullname; - BOOL result = gCacheName->getFullName(agent_id, fullname); - - fullname.append(suffix); - - addStringUUIDItem(fullname, agent_id, pos, enabled); - - return result; + LLSD item; + item["id"] = agent_id; + item["enabled"] = enabled; + item["target"] = INDIVIDUAL; + item["suffix"] = suffix; + LLSD& column = item["columns"][0]; + column["value"] = ""; + column["font"] = "SANSSERIF"; + column["column"] = "name"; + + return addNameItemRow(item, pos); } // virtual, public @@ -134,79 +142,99 @@ BOOL LLNameListCtrl::handleDragAndDrop( return handled; } + // public void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, BOOL enabled) { - //llinfos << "LLNameListCtrl::addGroupNameItem " << group_id << llendl; - std::string group_name; - gCacheName->getGroupName(group_id, group_name); - addStringUUIDItem(group_name, group_id, pos, enabled); + LLSD item; + item["id"] = group_id; + item["enabled"] = enabled; + item["target"] = GROUP; + LLSD& column = item["columns"][0]; + column["value"] = ""; + column["font"] = "SANSSERIF"; + column["column"] = "name"; + + addNameItemRow(item, pos); } // public -void LLNameListCtrl::addGroupNameItem(LLScrollListItem* item, EAddPosition pos) - +void LLNameListCtrl::addGroupNameItem(LLSD& item, EAddPosition pos) { - //llinfos << "LLNameListCtrl::addGroupNameItem " << item->getUUID() << llendl; - - std::string group_name; - gCacheName->getGroupName(item->getUUID(), group_name); - - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - ((LLScrollListText*)cell)->setText( std::string(group_name) ); - - addItem(item, pos); + item["target"] = GROUP; + addNameItemRow(item, pos); } -BOOL LLNameListCtrl::addNameItem(LLScrollListItem* item, EAddPosition pos) +LLScrollListItem* LLNameListCtrl::addNameItem(LLSD& item, EAddPosition pos) { - //llinfos << "LLNameListCtrl::addNameItem " << item->getUUID() << llendl; - - std::string fullname; - BOOL result = gCacheName->getFullName(item->getUUID(), fullname); - - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - ((LLScrollListText*)cell)->setText( fullname ); - - addItem(item, pos); - - // this column is resizable - LLScrollListColumn* columnp = getColumn(mNameColumnIndex); - if (columnp && columnp->mHeader) - { - columnp->mHeader->setHasResizableElement(TRUE); - } - - return result; + item["target"] = INDIVIDUAL; + return addNameItemRow(item, pos); } LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata) { + return addNameItemRow(value, pos, userdata); +} +LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLSD& value, EAddPosition pos, void* userdata) +{ + LLScrollListItem* item = LLScrollListCtrl::addElement(value, pos, userdata); + if (!item) return NULL; + + LLUUID id = item->getUUID(); // use supplied name by default std::string fullname = value["name"].asString(); - if (value["target"].asString() == "GROUP") + switch(value["target"].asInteger()) { - gCacheName->getGroupName(item->getUUID(), fullname); + case GROUP: + gCacheName->getGroupName(id, fullname); // fullname will be "nobody" if group not found - } - else if (value["target"].asString() == "SPECIAL") - { + break; + case SPECIAL: // just use supplied name - } - else // normal resident + break; + case INDIVIDUAL: { - std::string name; - if (gCacheName->getFullName(item->getUUID(), name)) + LLAvatarName av_name; + if (id.isNull()) { - fullname = name; + fullname = LLTrans::getString("AvatarNameNobody"); } + else if (LLAvatarNameCache::get(id, &av_name)) + { + if (mShortNames) + fullname = av_name.mDisplayName; + else + fullname = av_name.getCompleteName(); + } + else + { + fullname = " ( " + LLTrans::getString("LoadingData") + " ) "; + // ...schedule a callback + LLAvatarNameCache::get(id, + boost::bind(&LLNameListCtrl::onAvatarNameCache, + this, _1, _2, item->getHandle())); + } + break; + } + default: + break; } - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - ((LLScrollListText*)cell)->setText( fullname ); + // Append optional suffix. + std::string suffix = value["suffix"]; + if(!suffix.empty()) + { + fullname.append(suffix); + } + + LLScrollListCell* cell = item->getColumn(mNameColumnIndex); + if (cell && !fullname.empty() && cell->getValue().asString().empty()) + { + cell->setValue(fullname); + } dirtyColumns(); @@ -223,54 +251,53 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos // public void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) { - BOOL item_exists = selectByID( agent_id ); - if(item_exists) + // Find the item specified with agent_id. + S32 idx = -1; + for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++) { - S32 index = getItemIndex(getFirstSelected()); - if(index >= 0) + LLScrollListItem* item = *it; + if (item->getUUID() == agent_id) { - deleteSingleItem(index); + idx = getItemIndex(item); + break; } } + + // Remove it. + if (idx >= 0) + { + selectNthItem(idx); // not sure whether this is needed, taken from previous implementation + deleteSingleItem(idx); + } } -// public -void LLNameListCtrl::refresh(const LLUUID& agent_id, const std::string& full_name) +void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + LLHandle item) { - //llinfos << "LLNameListCtrl::refresh " << id << " '" << first << " " - // << last << "'" << llendl; + std::string name; + if (mShortNames) + name = av_name.mDisplayName; + else + name = av_name.getCompleteName(); - - // TODO: scan items for that ID, fix if necessary - item_list::iterator iter; - for (iter = getItemList().begin(); iter != getItemList().end(); iter++) + LLScrollListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == agent_id) { - LLScrollListItem* item = *iter; - if (item->getUUID() == agent_id) + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) { - LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); - if (cell) - { - ((LLScrollListText*)cell)->setText( full_name ); - } + cell->setValue(name); + setNeedsSort(); } } dirtyColumns(); } - -// static -void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& full_name) +void LLNameListCtrl::sortByName(BOOL ascending) { - std::set::iterator it; - for (it = LLNameListCtrl::sInstances.begin(); - it != LLNameListCtrl::sInstances.end(); - ++it) - { - LLNameListCtrl* ctrl = *it; - ctrl->refresh(id, full_name); - } + sortByColumnIndex(mNameColumnIndex,ascending); } // virtual @@ -320,9 +347,9 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto NULL, multi_select, draw_border, - name_column_index); - - name_list->setDisplayHeading(draw_heading); + draw_heading, + name_column_index + ); if (node->hasAttribute("heading_height")) { S32 heading_height; @@ -439,7 +466,7 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto while(token_iter != tokens.end()) { const std::string& line = *token_iter; - name_list->addCommentText(line); + name_list->setCommentText(line); ++token_iter; } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 0ff74423d..8a4f4141d 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -37,17 +37,26 @@ #include "llscrolllistctrl.h" +class LLAvatarName; class LLNameListCtrl -: public LLScrollListCtrl +: public LLScrollListCtrl, public LLInstanceTracker { public: + typedef enum e_name_type + { + INDIVIDUAL, + GROUP, + SPECIAL + } ENameType; + LLNameListCtrl(const std::string& name, const LLRect& rect, LLUICtrlCallback callback, void* userdata, BOOL allow_multiple_selection, BOOL draw_border = TRUE, + bool draw_heading = false, S32 name_column_index = 0, const std::string& tooltip = LLStringUtil::null); virtual ~LLNameListCtrl(); @@ -57,36 +66,38 @@ public: // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. - BOOL addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, + LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, std::string const& suffix = LLStringUtil::null); - BOOL addNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM); + LLScrollListItem* addNameItem(LLSD& item, EAddPosition pos = ADD_BOTTOM); - virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + LLScrollListItem* addNameItemRow(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. void addGroupNameItem(const LLUUID& group_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); - void addGroupNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM); + + void addGroupNameItem(LLSD& item, EAddPosition pos = ADD_BOTTOM); void removeNameItem(const LLUUID& agent_id); - void refresh(const LLUUID& agent_id, const std::string& full_name); - - static void refreshAll(const LLUUID& id, const std::string& full_name); - - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + // LLView interface + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } + void sortByName(BOOL ascending); private: static std::set sInstances; + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle item); S32 mNameColumnIndex; BOOL mAllowCallingCardDrop; + bool mShortNames; // display name only, no SLID }; #endif diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index b068adfe0..0ffd26e0f 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -320,7 +320,7 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType // } if (0 == pAvatarGroups->group_list.size()) { - group_list->addCommentText(getString("None")); + group_list->setCommentText(getString("None")); } for(LLAvatarGroups::group_list_t::const_iterator it = pAvatarGroups->group_list.begin(); diff --git a/indra/newview/llpaneldirbrowser.cpp b/indra/newview/llpaneldirbrowser.cpp index 1af94ef4e..5dee332b3 100644 --- a/indra/newview/llpaneldirbrowser.cpp +++ b/indra/newview/llpaneldirbrowser.cpp @@ -212,7 +212,7 @@ void LLPanelDirBrowser::updateResultCount() // add none found response if (list->getItemCount() == 0) { - list->addCommentText(LLTrans::getString("NoneFound")); + list->setCommentText(LLTrans::getString("NoneFound")); list->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } @@ -1222,7 +1222,7 @@ void LLPanelDirBrowser::setupNewSearch() // ready the list for results list->operateOnAll(LLCtrlListInterface::OP_DELETE); - list->addCommentText(LLTrans::getString("Searching")); + list->setCommentText(LLTrans::getString("Searching")); childDisable("results"); mResultsReceived = 0; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index d19d14a4b..ca19b2caa 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -544,7 +544,7 @@ void LLPanelFace::getState() bool identical; LLTextureCtrl* texture_ctrl = getChild("texture control"); - + texture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. // Texture { LLUUID id; @@ -552,8 +552,14 @@ void LLPanelFace::getState() { LLUUID get(LLViewerObject* object, S32 te) { - LLViewerTexture* image = object->getTEImage(te); + //LLViewerTexture* image = object->getTEImage(te); + LLTextureEntry* image = object->getTE(te); //Singu Note: Use this instead of the above. + //The above actually returns LLViewerFetchedTexture::sDefaultImagep when + //the texture id is null, which gives us IMG_DEFAULT, not LLUUID::null + //Such behavior prevents the 'None' button from ever greying out in the face panel. return image ? image->getID() : LLUUID::null; + + } } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index b0dfb3704..6f099f483 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -854,6 +854,7 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) LLSD row; row["columns"][0]["value"] = pending.str(); + row["columns"][0]["column"] = "name"; mListVisibleMembers->setEnabled(FALSE); mListVisibleMembers->addElement(row); @@ -918,7 +919,7 @@ void LLPanelGroupGeneral::updateMembers() sSDTime += sd_timer.getElapsedTimeF32(); element_timer.reset(); - mListVisibleMembers->addElement(row);//, ADD_SORTED); + mListVisibleMembers->addNameItem(row); sElementTime += element_timer.getElapsedTimeF32(); } sAllTime += all_timer.getElapsedTimeF32(); diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 35f405340..f84da5d10 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -138,9 +138,10 @@ void LLPanelGroupInvite::impl::addUsers(const std::vector& names, //add the name to the names list LLSD row; row["id"] = id; + row["columns"][0]["column"] = "name"; row["columns"][0]["value"] = name; - mInvitees->addElement(row); + mInvitees->addNameItem(row); } } diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 64aefdbbf..5ad7ad7a1 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -676,7 +676,7 @@ BOOL LLPanelGroupLandMoney::postBuild() { if ( mImplementationp->mGroupParcelsp ) { - mImplementationp->mGroupParcelsp->addCommentText( + mImplementationp->mGroupParcelsp->setCommentText( mImplementationp->mCantViewParcelsText); mImplementationp->mGroupParcelsp->setEnabled(FALSE); } diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 13786d9e4..ffec84e7d 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -450,7 +450,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) if (1 == count && id.isNull()) { // Only one entry, the dummy entry. - mNoticesList->addCommentText(mNoNoticesStr); + mNoticesList->setCommentText(mNoNoticesStr); mNoticesList->setEnabled(FALSE); return; } @@ -493,7 +493,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) mNoticesList->addElement(row, ADD_BOTTOM); } - mNoticesList->sortItems(); + mNoticesList->updateSort(); } void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index d0a878877..8ffae0c64 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1615,7 +1615,7 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) retrieved << "Retrieving role member mappings..."; } mMembersList->setEnabled(FALSE); - mMembersList->addCommentText(retrieved.str()); + mMembersList->setCommentText(retrieved.str()); } } @@ -1680,7 +1680,7 @@ void LLPanelGroupMembersSubTab::updateMembers() row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); row["columns"][2]["font"] = "SANSSERIF_SMALL"; - mMembersList->addElement(row);//, ADD_SORTED); + mMembersList->addNameItem(row); mHasMatch = TRUE; } } @@ -1694,7 +1694,7 @@ void LLPanelGroupMembersSubTab::updateMembers() else { mMembersList->setEnabled(FALSE); - mMembersList->addCommentText(std::string("No match.")); + mMembersList->setCommentText(std::string("No match.")); } } else diff --git a/indra/newview/llpanelgroupvoting.cpp b/indra/newview/llpanelgroupvoting.cpp index 73b00c509..3af05adc6 100644 --- a/indra/newview/llpanelgroupvoting.cpp +++ b/indra/newview/llpanelgroupvoting.cpp @@ -916,19 +916,19 @@ void LLPanelGroupVoting::impl::addPendingActiveScrollListItem(unsigned int curre << current << "\\" << expected << ")"; - mProposals->addCommentText(pending.str()); + mProposals->setCommentText(pending.str()); } void LLPanelGroupVoting::impl::addNoActiveScrollListItem(EAddPosition pos) { // *TODO: translate - mProposals->addCommentText(std::string("There are currently no active proposals"), pos); + mProposals->setCommentText(std::string("There are currently no active proposals")); } void LLPanelGroupVoting::impl::addNoHistoryScrollListItem(EAddPosition pos) { // *TODO: translate - mVotesHistory->addCommentText(std::string("There are currently no archived proposals"), pos); + mVotesHistory->setCommentText(std::string("There are currently no archived proposals")); } void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(unsigned int current, @@ -941,7 +941,7 @@ void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(unsigned int curr << current << "\\" << expected << ")"; - mVotesHistory->addCommentText(pending.str()); + mVotesHistory->setCommentText(pending.str()); } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 31e686adb..16eef86fd 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1321,8 +1321,8 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect, void LLPreviewLSL::callbackLSLCompileSucceeded() { llinfos << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->addCommentText(LLTrans::getString("CompileSuccessful")); - mScriptEd->mErrorList->addCommentText(LLTrans::getString("SaveComplete")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -1931,8 +1931,8 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, bool is_script_running) { lldebugs << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->addCommentText(LLTrans::getString("CompileSuccessful")); - mScriptEd->mErrorList->addCommentText(LLTrans::getString("SaveComplete")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -2518,7 +2518,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, else { llinfos << "Compile worked!" << llendl; - mScriptEd->mErrorList->addCommentText(LLTrans::getString("CompileSuccessfulSaving")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessfulSaving")); if(gAssetStorage) { llinfos << "LLLiveLSLEditor::saveAsset " @@ -2593,7 +2593,7 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use if(self) { // Tell the user that the compile worked. - self->mScriptEd->mErrorList->addCommentText(LLTrans::getString("SaveComplete")); + self->mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); // close the window if this completes both uploads self->getWindow()->decBusyCount(); self->mPendingUploads--; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7b9e2dfe5..afc63690f 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1593,7 +1593,10 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) // Texture picker defaults aren't inventory items // * Don't need to worry about permissions for them // * Can just apply the texture and be done with it. - objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + //objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + objectp->setTETexture(te, mImageID); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. } return true; } @@ -1756,7 +1759,10 @@ BOOL LLSelectMgr::selectionRevertTextures() } else { - object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + //object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + object->setTETexture(te, id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. } } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index c99fa08e2..cb82d8722 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -307,7 +307,6 @@ bool process_login_success_response(std::string &password); void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group) { - LLNameListCtrl::refreshAll(id, full_name); LLNameBox::refreshAll(id, full_name, is_group); LLNameEditor::refreshAll(id, full_name, is_group); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 18493bd7c..12fcfc77d 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -161,18 +161,19 @@ public: static void onBtnSetToDefault( void* userdata ); static void onBtnSelect( void* userdata ); static void onBtnCancel( void* userdata ); - static void onBtnPipette( void* userdata ); + void onBtnPipette( ); static void onBtnUUID( void* userdata ); //static void onBtnRevert( void* userdata ); static void onBtnWhite( void* userdata ); + static void onBtnNone( void* userdata ); static void onBtnInvisible( void* userdata ); static void onBtnAlpha( void* userdata ); static void onBtnClear( void* userdata ); - static void onSelectionChange(const std::deque &items, BOOL user_action, void* data); + void onSelectionChange(const std::deque &items, BOOL user_action); static void onShowFolders(LLUICtrl* ctrl, void* userdata); static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); static void onSearchEdit(const std::string& search_string, void* user_data ); - static void onTextureSelect( const LLTextureEntry& te, void *data ); + void onTextureSelect( const LLTextureEntry& te ); // tag: vaa emerald local_asset_browser [begin] // static void onBtnLocal( void* userdata ); @@ -250,81 +251,9 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), mContextConeOpacity(0.f) { + mCanApplyImmediately = can_apply_immediately; LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml"); - mTentativeLabel = getChild("Multiple"); - - mResolutionLabel = getChild("unknown"); - - - childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this); - childSetAction("Alpha", LLFloaterTexturePicker::onBtnAlpha,this); - childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); - childSetAction("Invisible", LLFloaterTexturePicker::onBtnInvisible,this); - - // tag: vaa emerald local_asset_browser [begin] -// childSetAction("Local", LLFloaterTexturePicker::onBtnLocal, this); -// childSetAction("Server", LLFloaterTexturePicker::onBtnServer, this); - childSetAction("Add", LLFloaterTexturePicker::onBtnAdd, this); - childSetAction("Remove", LLFloaterTexturePicker::onBtnRemove, this); - childSetAction("Browser", LLFloaterTexturePicker::onBtnBrowser, this); - - mLocalScrollCtrl = getChild("local_name_list"); - mLocalScrollCtrl->setCallbackUserData(this); - mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit); - LocalAssetBrowser::UpdateTextureCtrlList( mLocalScrollCtrl ); - // tag: vaa emerald local_asset_browser [end] - - childSetCommitCallback("show_folders_check", onShowFolders, this); - childSetVisible("show_folders_check", FALSE); - - mSearchEdit = getChild("inventory search editor"); - mSearchEdit->setSearchCallback(onSearchEdit, this); - - mInventoryPanel = getChild("inventory panel"); - - if(mInventoryPanel) - { - U32 filter_types = 0x0; - filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; - filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; - - mInventoryPanel->setFilterTypes(filter_types); - //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss. - mInventoryPanel->setFilterPermMask(immediate_filter_perm_mask); - mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, _1, _2, (void*)this)); - mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - mInventoryPanel->setAllowMultiSelect(FALSE); - - // store this filter as the default one - mInventoryPanel->getRootFolder()->getFilter()->markDefault(); - - // Commented out to stop opening all folders with textures - // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE); - - // don't put keyboard focus on selected item, because the selection callback - // will assume that this was user input - mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); - } - - mCanApplyImmediately = can_apply_immediately; - mNoCopyTextureSelected = FALSE; - - childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately")); - childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); - - if (!can_apply_immediately) - { - childSetEnabled("show_folders_check", FALSE); - } - - childSetAction("Pipette", LLFloaterTexturePicker::onBtnPipette,this); - childSetAction("ApplyUUID", LLFloaterTexturePicker::onBtnUUID,this); - childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); - childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this); - - // update permission filter once UI is fully initialized - updateFilterPermMask(); setCanMinimize(FALSE); @@ -532,7 +461,80 @@ BOOL LLFloaterTexturePicker::postBuild() setTitle(pick + mLabel); } + mTentativeLabel = getChild("Multiple"); + mResolutionLabel = getChild("unknown"); + + + childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this); + childSetAction("None", LLFloaterTexturePicker::onBtnNone,this); + childSetAction("Alpha", LLFloaterTexturePicker::onBtnAlpha,this); + childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); + childSetAction("Invisible", LLFloaterTexturePicker::onBtnInvisible,this); + + // tag: vaa emerald local_asset_browser [begin] +// childSetAction("Local", LLFloaterTexturePicker::onBtnLocal, this); +// childSetAction("Server", LLFloaterTexturePicker::onBtnServer, this); + childSetAction("Add", LLFloaterTexturePicker::onBtnAdd, this); + childSetAction("Remove", LLFloaterTexturePicker::onBtnRemove, this); + childSetAction("Browser", LLFloaterTexturePicker::onBtnBrowser, this); + + mLocalScrollCtrl = getChild("local_name_list"); + mLocalScrollCtrl->setCallbackUserData(this); + mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit); + LocalAssetBrowser::UpdateTextureCtrlList( mLocalScrollCtrl ); + // tag: vaa emerald local_asset_browser [end] + + childSetCommitCallback("show_folders_check", onShowFolders, this); + childSetVisible("show_folders_check", FALSE); + + mSearchEdit = getChild("inventory search editor"); + mSearchEdit->setSearchCallback(onSearchEdit, this); + + mInventoryPanel = getChild("inventory panel"); + + if(mInventoryPanel) + { + U32 filter_types = 0x0; + filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; + filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; + + mInventoryPanel->setFilterTypes(filter_types); + //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss. + mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask); + mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); + mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + mInventoryPanel->setAllowMultiSelect(FALSE); + + // store this filter as the default one + mInventoryPanel->getRootFolder()->getFilter()->markDefault(); + + // Commented out to stop opening all folders with textures + // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE); + + // don't put keyboard focus on selected item, because the selection callback + // will assume that this was user input + mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); + } + + mNoCopyTextureSelected = FALSE; + + childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately")); + childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); + + if (!mCanApplyImmediately) + { + childSetEnabled("show_folders_check", FALSE); + } + + getChild("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this)); + childSetAction("ApplyUUID", LLFloaterTexturePicker::onBtnUUID,this); + childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); + childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this); + + // update permission filter once UI is fully initialized + updateFilterPermMask(); + LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); return TRUE; } @@ -624,6 +626,7 @@ void LLFloaterTexturePicker::draw() childSetEnabled("Default", mImageAssetID != mOwner->getDefaultImageAssetID()); childSetEnabled("Blank", mImageAssetID != mWhiteImageAssetID ); + childSetEnabled("None", mOwner->getAllowNoTexture() && !mImageAssetID.isNull() ); childSetEnabled("Invisible", mOwner->getAllowInvisibleTexture() && mImageAssetID != mInvisibleImageAssetID ); childSetEnabled("Alpha", mImageAssetID != mAlphaImageAssetID ); @@ -758,6 +761,13 @@ void LLFloaterTexturePicker::onBtnWhite(void* userdata) self->commitIfImmediateSet(); } +// static +void LLFloaterTexturePicker::onBtnNone(void* userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setImageID( LLUUID::null ); + self->commitIfImmediateSet(); +} // static void LLFloaterTexturePicker::onBtnInvisible(void* userdata) @@ -876,26 +886,18 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl *ctrl, void *userdata) // tag: vaa emerald local_asset_browser [end] -// static -void LLFloaterTexturePicker::onBtnPipette( void* userdata ) +void LLFloaterTexturePicker::onBtnPipette() { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - - if ( self) + BOOL pipette_active = getChild("Pipette")->getValue().asBoolean(); + pipette_active = !pipette_active; + if (pipette_active) { - BOOL pipette_active = self->childGetValue("Pipette").asBoolean(); - pipette_active = !pipette_active; - if (pipette_active) - { - LLToolPipette::getInstance()->setSelectCallback(onTextureSelect, self); - LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); - } - else - { - LLToolMgr::getInstance()->clearTransientTool(); - } + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); + } + else + { + LLToolMgr::getInstance()->clearTransientTool(); } - } // static @@ -916,33 +918,32 @@ void LLFloaterTexturePicker::onBtnUUID( void* userdata ) } // static -void LLFloaterTexturePicker::onSelectionChange(const std::deque &items, BOOL user_action, void* data) +void LLFloaterTexturePicker::onSelectionChange(const std::deque &items, BOOL user_action) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data; if (items.size()) { LLFolderViewItem* first_item = items.front(); LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID()); - self->mNoCopyTextureSelected = FALSE; + mNoCopyTextureSelected = FALSE; if (itemp) { // if (itemp->getPermissions().getMaskOwner() & PERM_ALL) - self->childSetValue("texture_uuid", self->mImageAssetID); + childSetValue("texture_uuid", mImageAssetID); else - self->childSetValue("texture_uuid", LLUUID::null.asString()); + childSetValue("texture_uuid", LLUUID::null.asString()); // if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) { - self->mNoCopyTextureSelected = TRUE; + mNoCopyTextureSelected = TRUE; } - self->mImageAssetID = itemp->getAssetUUID(); - self->mIsDirty = TRUE; + mImageAssetID = itemp->getAssetUUID(); + mIsDirty = TRUE; if (user_action) { // only commit intentional selections, not implicit ones - self->commitIfImmediateSet(); + commitIfImmediateSet(); } } } @@ -1017,32 +1018,28 @@ void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string, void picker->mInventoryPanel->setFilterSubString(upper_case_search_string); } -//static -void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te, void *data ) +void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data; - - LLUUID inventory_item_id = self->findItemID(te.getID(), TRUE); - if (self && inventory_item_id.notNull()) + LLUUID inventory_item_id = findItemID(te.getID(), TRUE); + if (inventory_item_id.notNull()) { LLToolPipette::getInstance()->setResult(TRUE, ""); - self->setImageID(te.getID()); - - self->mNoCopyTextureSelected = FALSE; + setImageID(te.getID()); + mNoCopyTextureSelected = FALSE; LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) { // no copy texture - self->mNoCopyTextureSelected = TRUE; + mNoCopyTextureSelected = TRUE; } else { - self->childSetValue("texture_uuid", inventory_item_id.asString()); + childSetValue("texture_uuid", inventory_item_id.asString()); } - self->commitIfImmediateSet(); + commitIfImmediateSet(); } else { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index d39061bb4..a49674550 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1089,14 +1089,17 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, { return; } - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); + //LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) { // update viewer side image in anticipation of update from simulator - hit_obj->setTEImage(face, image); + //hit_obj->setTEImage(face, image); + hit_obj->setTETexture(face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. dialog_refresh_all(); } // send the update to the simulator @@ -1157,9 +1160,12 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, return; } // update viewer side image in anticipation of update from simulator - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); + //LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); - hit_obj->setTEImage(hit_face, image); + //hit_obj->setTEImage(hit_face, image); + hit_obj->setTETexture(hit_face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. dialog_refresh_all(); // send the update to the simulator diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp index 9d95ccc06..878ed0f9a 100644 --- a/indra/newview/lltoolpipette.cpp +++ b/indra/newview/lltoolpipette.cpp @@ -55,8 +55,6 @@ LLToolPipette::LLToolPipette() : LLTool(std::string("Pipette")), mSuccess(TRUE) { - mSelectCallback = NULL; - mUserData = NULL; } @@ -106,6 +104,15 @@ BOOL LLToolPipette::handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky return TRUE; } +void LLToolPipette::setTextureEntry(const LLTextureEntry* entry) +{ + if (entry) + { + mTextureEntry = *entry; + mSignal(mTextureEntry); + } +} + void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); @@ -118,20 +125,11 @@ void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { //TODO: this should highlight the selected face only LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj); - LLToolPipette::getInstance()->mTextureEntry = *hit_obj->getTE(pick_info.mObjectFace); - if (LLToolPipette::getInstance()->mSelectCallback) - { - LLToolPipette::getInstance()->mSelectCallback(LLToolPipette::getInstance()->mTextureEntry, LLToolPipette::getInstance()->mUserData); - } + const LLTextureEntry* entry = hit_obj->getTE(pick_info.mObjectFace); + LLToolPipette::getInstance()->setTextureEntry(entry); } } -void LLToolPipette::setSelectCallback(select_callback callback, void* user_data) -{ - mSelectCallback = callback; - mUserData = user_data; -} - void LLToolPipette::setResult(BOOL success, const std::string& msg) { mTooltipMsg = msg; diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index 54c24e946..b9d53623f 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -56,18 +56,19 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky_rect_screen); - typedef void (*select_callback)(const LLTextureEntry& te, void *data); - void setSelectCallback(select_callback callback, void* user_data); + // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots + typedef boost::signals2::signal signal_t; + void setToolSelectCallback(const signal_t::slot_type& cb) { mSignal.connect(cb); } void setResult(BOOL success, const std::string& msg); - + + void setTextureEntry(const LLTextureEntry* entry); static void pickCallback(const LLPickInfo& pick_info); protected: LLTextureEntry mTextureEntry; - select_callback mSelectCallback; + signal_t mSignal; BOOL mSuccess; std::string mTooltipMsg; - void* mUserData; }; #endif //LL_LLTOOLPIPETTE_H diff --git a/indra/newview/skins/default/xui/en-us/floater_about_land.xml b/indra/newview/skins/default/xui/en-us/floater_about_land.xml index f40659986..ae6c96de5 100644 --- a/indra/newview/skins/default/xui/en-us/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en-us/floater_about_land.xml @@ -773,7 +773,7 @@ Only large parcels can be listed in search. mouse_opaque="true" name="Snapshot:" v_pad="0" width="278"> Snapshot: - diff --git a/indra/newview/skins/default/xui/en-us/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en-us/floater_texture_ctrl.xml index 83a0d1b16..4ab70c46a 100644 --- a/indra/newview/skins/default/xui/en-us/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en-us/floater_texture_ctrl.xml @@ -30,6 +30,9 @@