diff options
| author | Dave Parks <davep@lindenlab.com> | 2012-06-28 13:22:04 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2012-06-28 13:22:04 -0500 | 
| commit | ed72fd0ae98671f1cfce3c975b93e1f760fc40f0 (patch) | |
| tree | 10596d0f2040e9a0414e8a9f14d1269b58942264 /indra/newview | |
| parent | 90547ff411db177bf6424ca553449a81a808fc0f (diff) | |
| parent | a1d0d67e05c45bdc1a7a8bb0aad79772a2a94f6e (diff) | |
merge
Diffstat (limited to 'indra/newview')
110 files changed, 4692 insertions, 2325 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c9b4de0140..1928e53699 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -148,7 +148,7 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>ApplyTextureImmediately</key> +    <key>TextureLivePreview</key>      <map>        <key>Comment</key>        <string>Preview selections in texture picker immediately</string> @@ -7274,7 +7274,7 @@      <key>WebContentWindowLimit</key>      <map>        <key>Comment</key> -      <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string> +      <string>Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit)</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -8093,6 +8093,18 @@      <real>0</real>    </map> +  <key>RenderDepthPrePass</key> +  <map> +    <key>Comment</key> +    <string>EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +      <key>RenderDepthOfField</key>    <map>      <key>Comment</key> @@ -9172,7 +9184,7 @@      <key>RenderUseVAO</key>      <map>        <key>Comment</key> -      <string>Use GL Vertex Array Objects</string> +      <string>[EXPERIMENTAL] Use GL Vertex Array Objects</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -9180,7 +9192,19 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>RenderVBOMappingDisable</key> +  <key>RenderUseTransformFeedback</key> +  <map> +    <key>Comment</key> +    <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> + +  <key>RenderVBOMappingDisable</key>      <map>        <key>Comment</key>        <string>Disable VBO glMapBufferARB</string> @@ -12227,6 +12251,17 @@        <key>Value</key>        <integer>1</integer>      </map> +  <key>RenderSynchronousOcclusion</key> +  <map> +    <key>Comment</key> +    <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>RenderDelayVBUpdate</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl index cb87b754b4..1113a9845b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl @@ -31,6 +31,8 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif +uniform float minimum_alpha; +  uniform sampler2DRect depthMap;  uniform sampler2D diffuseMap; @@ -70,9 +72,15 @@ void main()  	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy); +	if (diff.a < minimum_alpha) +	{ +		discard; +	} +  	vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);  	vec4 color = diff * col; +	  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 75de47614c..bff87cb6aa 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -55,8 +55,6 @@ uniform float far_clip;  uniform vec3 proj_origin; //origin of projection to be used for angular attenuation  uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade;  uniform vec3 center;  uniform vec3 color; @@ -143,7 +141,8 @@ void main()  		discard;  	} -	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0, norm.z);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 19800a8b8e..f671d5b750 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -42,12 +42,13 @@ uniform sampler2DRect depthMap;  uniform vec3 env_mat[3];  uniform float sun_wash; -uniform vec3 center;  uniform vec3 color;  uniform float falloff;  uniform float size;  VARYING vec4 vary_fragcoord; +VARYING vec3 trans_center; +  uniform vec2 screen_res;  uniform mat4 inv_proj; @@ -74,7 +75,7 @@ void main()  	frag.xy *= screen_res;  	vec3 pos = getPosition(frag.xy).xyz; -	vec3 lv = center.xyz-pos; +	vec3 lv = trans_center.xyz-pos;  	float dist2 = dot(lv,lv);  	dist2 /= size;  	if (dist2 > 1.0) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index cb14e6d4e8..9491421236 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -24,16 +24,22 @@   */  uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix;  ATTRIBUTE vec3 position; +uniform vec3 center; +uniform float size; +  VARYING vec4 vary_fragcoord; +VARYING vec3 trans_center;  void main()  {  	//transform vertex -	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vec3 p = position*sqrt(size)+center; +	vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);  	vary_fragcoord = pos; -		 +	trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;  	gl_Position = pos;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl new file mode 100644 index 0000000000..6195e2f1ec --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl @@ -0,0 +1,44 @@ +/**  + * @file shadowCubeV.glsl + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec4 post_pos; + +uniform vec3 box_center; +uniform vec3 box_size; + +void main() +{ +	//transform vertex +	vec3 p = position*box_size+box_center; +	vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0); +	 +	post_pos = pos; +	 +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 7ed8ed3370..cca63872de 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -24,18 +24,21 @@   */ -#extension GL_ARB_texture_rectangle : enable -  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color;  #else  #define frag_color gl_FragColor  #endif +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable +  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap; +uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; @@ -46,6 +49,7 @@ uniform vec3 proj_n;  uniform float proj_focus; //distance from plane to begin blurring  uniform float proj_lod;  //(number of mips in proj map)  uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod;  uniform float proj_ambiance;  uniform float near_clip;  uniform float far_clip; @@ -53,19 +57,66 @@ uniform float far_clip;  uniform vec3 proj_origin; //origin of projection to be used for angular attenuation  uniform float sun_wash; -uniform vec3 center;  uniform vec3 color;  uniform float falloff;  uniform float size;  VARYING vec4 vary_fragcoord; +VARYING vec3 trans_center; +  uniform vec2 screen_res;  uniform mat4 inv_proj; +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + +  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -84,16 +135,16 @@ void main()  	frag.xy *= screen_res;  	vec3 pos = getPosition(frag.xy).xyz; -	vec3 lv = center.xyz-pos.xyz; +	vec3 lv = trans_center.xyz-pos.xyz;  	float dist2 = dot(lv,lv);  	dist2 /= size;  	if (dist2 > 1.0)  	{  		discard;  	} -	 +		  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	norm = vec3((norm.xy-0.5)*2.0, norm.z);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -107,7 +158,11 @@ void main()  	proj_tc.xyz /= proj_tc.w;  	float fa = falloff+1.0; -	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	if (dist_atten <= 0.0) +	{ +		discard; +	}  	lv = proj_origin-pos.xyz;  	lv = normalize(lv); @@ -125,32 +180,32 @@ void main()  		proj_tc.y > 0.0)  	{  		float lit = 0.0; +		float amb_da = proj_ambiance; +		  		if (da > 0.0)  		{  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod; -			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); +			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);  			vec3 lcol = color.rgb * plcol.rgb * plcol.a;  			lit = da * dist_atten * noise;  			col = lcol*lit*diff_tex; +			amb_da += (da*0.5)*proj_ambiance;  		} -		float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -		float lod = diff * proj_lod; -		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); -		//float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); -		float amb_da = proj_ambiance; -		 +		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							  		amb_da += (da*da*0.5+0.5)*proj_ambiance; -			 +				  		amb_da *= dist_atten * noise; -		 +			  		amb_da = min(amb_da, 1.0-lit); -		 +			  		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;  	} @@ -168,18 +223,22 @@ void main()  		{  			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; -			vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; +			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));  			if (stc.z > 0.0)  			{ -				stc.xy /= stc.z+proj_near; -					 +				stc.xy /= stc.w; + +				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								  				if (stc.x < 1.0 &&  					stc.y < 1.0 &&  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);  					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;  				}  			} diff --git a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl new file mode 100644 index 0000000000..ac2bc8703b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl @@ -0,0 +1,46 @@ +/**  + * @file debugF.glsl + * + * $LicenseInfo:firstyear=2007&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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform vec4 color; +uniform vec4 clip_plane; + +VARYING vec3 vary_position; + + +void main()  +{ +	if (dot(vary_position,clip_plane.xyz)+clip_plane.w < 0.0) +	{ +		discard; +	} + +	frag_color = color; +} diff --git a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl new file mode 100644 index 0000000000..e376b25a71 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl @@ -0,0 +1,38 @@ +/**  + * @file debugV.glsl + * + * $LicenseInfo:firstyear=2007&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$ + */ + +uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec3 vary_position; + +void main() +{ +	vary_position = (modelview_matrix*vec4(position.xyz,1.0)).xyz; +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl new file mode 100644 index 0000000000..5c479d27a9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl @@ -0,0 +1,38 @@ +/**  + * @file occlusionCubeV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +uniform vec3 box_center; +uniform vec3 box_size; + +void main() +{ +	vec3 p = position*box_size+box_center; +	gl_Position = modelview_projection_matrix * vec4(p.xyz, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl new file mode 100644 index 0000000000..44f1aa34a0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl @@ -0,0 +1,36 @@ +/** + * @file binormalV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat3 normal_matrix; + +ATTRIBUTE vec3 binormal; + +VARYING vec4 binormal_out; + +void main() +{ +	binormal_out = vec4(normal_matrix * binormal, 0.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl new file mode 100644 index 0000000000..59c4a7d895 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl @@ -0,0 +1,36 @@ +/** + * @file colorV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform int color_in; + +ATTRIBUTE vec3 position; + +VARYING int color_out; + +void main() +{ +	color_out = color_in; +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl new file mode 100644 index 0000000000..a213aa0ae8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl @@ -0,0 +1,36 @@ +/** + * @file normalV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat3 normal_matrix; + +ATTRIBUTE vec3 normal; + +VARYING vec4 normal_out; + +void main() +{ +	normal_out = vec4(normalize(normal_matrix * normal), 0.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl new file mode 100644 index 0000000000..01eed18de4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl @@ -0,0 +1,40 @@ +/** + * @file positionV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_matrix; + +uniform int texture_index_in; + +ATTRIBUTE vec3 position; + +VARYING vec3 position_out; +VARYING int texture_index_out; + +void main() +{ +	texture_index_out = texture_index_in; +	position_out = (modelview_matrix*vec4(position, 1.0)).xyz; +} + diff --git a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl new file mode 100644 index 0000000000..0e074f3cec --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl @@ -0,0 +1,35 @@ +/** + * @file texcoordV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + + +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 texcoord_out; + +void main() +{ +	texcoord_out = texcoord0; +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index ba6f3ace53..2093fc37dc 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -31,6 +31,8 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif +uniform float minimum_alpha; +  uniform sampler2DRectShadow shadowMap0;  uniform sampler2DRectShadow shadowMap1;  uniform sampler2DRectShadow shadowMap2; @@ -97,6 +99,13 @@ void main()  	float shadow = 0.0;  	vec4 pos = vec4(vary_position, 1.0); +	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); + +	if (diff.a < minimum_alpha) +	{ +		discard; +	} +	  	vec4 spos = pos;  	if (spos.z > -shadow_clip.w) @@ -164,8 +173,6 @@ void main()  		shadow = 1.0;  	} -	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); -  	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);  	vec4 color = diff * col; diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 99a277fbfc..ab077d9e02 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -31,8 +31,6 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif -VARYING vec4 vertex_color; -  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect depthMap; @@ -49,6 +47,7 @@ uniform vec3 proj_n;  uniform float proj_focus; //distance from plane to begin blurring  uniform float proj_lod;  //(number of mips in proj map)  uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod;  uniform float proj_ambiance;  uniform float near_clip;  uniform float far_clip; @@ -58,16 +57,65 @@ uniform float sun_wash;  uniform int proj_shadow_idx;  uniform float shadow_fade; -VARYING vec4 vary_light; +uniform float size; +uniform vec3 color; +uniform float falloff; +VARYING vec3 trans_center;  VARYING vec4 vary_fragcoord;  uniform vec2 screen_res;  uniform mat4 inv_proj; +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + +  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -85,6 +133,15 @@ void main()  	frag.xyz = frag.xyz*0.5+0.5;  	frag.xy *= screen_res; +	vec3 pos = getPosition(frag.xy).xyz; +	vec3 lv = trans_center.xyz-pos.xyz; +	float dist2 = dot(lv,lv); +	dist2 /= size; +	if (dist2 > 1.0) +	{ +		discard; +	} +	  	float shadow = 1.0;  	if (proj_shadow_idx >= 0) @@ -96,15 +153,6 @@ void main()  		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);  	} -	vec3 pos = getPosition(frag.xy).xyz; -	vec3 lv = vary_light.xyz-pos.xyz; -	float dist2 = dot(lv,lv); -	dist2 /= vary_light.w; -	if (dist2 > 1.0) -	{ -		discard; -	} -	  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz;  	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm @@ -119,8 +167,12 @@ void main()  	proj_tc.xyz /= proj_tc.w; -	float fa = vertex_color.a+1.0; -	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +	float fa = falloff+1.0; +	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	if (dist_atten <= 0.0) +	{ +		discard; +	}  	lv = proj_origin-pos.xyz;  	lv = normalize(lv); @@ -138,37 +190,33 @@ void main()  		proj_tc.y > 0.0)  	{  		float lit = 0.0; +		float amb_da = proj_ambiance; +		  		if (da > 0.0)  		{  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod; -			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); +			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = vertex_color.rgb * plcol.rgb * plcol.a; +			vec3 lcol = color.rgb * plcol.rgb * plcol.a;  			lit = da * dist_atten * noise;  			col = lcol*lit*diff_tex*shadow; -		} -		 -		float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -		float lod = diff * proj_lod; -		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); -		//float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); -		float amb_da = proj_ambiance; -		if (da > 0.0) -		{  			amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} +		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							  		amb_da += (da*da*0.5+0.5)*proj_ambiance; -			 +				  		amb_da *= dist_atten * noise; -		 +			  		amb_da = min(amb_da, 1.0-lit); -		 -		col += amb_da*vertex_color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +			 +		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;  	} @@ -185,19 +233,23 @@ void main()  		{  			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; -			vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; +			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));  			if (stc.z > 0.0)  			{ -				stc.xy /= stc.z+proj_near; -					 +				stc.xy /= stc.w; + +				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								  				if (stc.x < 1.0 &&  					stc.y < 1.0 &&  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*vertex_color.rgb*scol.a*spec.rgb*shadow; +					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;  				}  			}  		} diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index e8a109e661..eeb632acaf 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -520,6 +520,7 @@ Disregard128DefaultDrawDistance	1	0  list ATIOldDriver  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 +RenderVBOEnable				1	0  // ATI cards generally perform better when not using VBOs for streaming data diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 398a64378e..a945f7a693 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -517,6 +517,7 @@ Disregard128DefaultDrawDistance	1	0  list ATIOldDriver  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 +RenderVBOEnable				1	0  // ATI cards generally perform better when not using VBOs for streaming data diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ed04b5bf38..062551a3e8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -89,6 +89,7 @@  #include "lllogininstance.h"  #include "llprogressview.h"  #include "llvocache.h" +#include "llvopartgroup.h"  #include "llweb.h"  #include "llsecondlifeurls.h"  #include "llupdaterservice.h" @@ -675,6 +676,9 @@ bool LLAppViewer::init()  	// initialize SSE options  	LLVector4a::initClass(); +	//initialize particle index pool +	LLVOPartGroup::initClass(); +  	// Need to do this initialization before we do anything else, since anything  	// that touches files should really go through the lldir API  	gDirUtilp->initAppDirs("SecondLife"); @@ -1162,6 +1166,8 @@ void LLAppViewer::checkMemory()  static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");  static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep"); +static LLFastTimer::DeclareTimer FTM_YIELD("Yield"); +  static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache");  static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode");  static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread"); @@ -1347,6 +1353,7 @@ bool LLAppViewer::mainLoop()  				// yield some time to the os based on command line option  				if(mYieldTime >= 0)  				{ +					LLFastTimer t(FTM_YIELD);  					ms_sleep(mYieldTime);  				} diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index f530d10ddc..84e73e96fa 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -495,7 +495,7 @@ protected:  	void showInfoCtrl()  	{ -		if (mAvatarID.isNull() || mFrom.empty() || SYSTEM_FROM == mFrom) return; +		if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return;  		if (!sInfoCtrl)  		{ @@ -689,8 +689,11 @@ void LLChatHistory::clear()  	mLastFromID = LLUUID::null;  } +static LLFastTimer::DeclareTimer FTM_APPEND_MESSAGE("Append Chat Message"); +  void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params)  { +	LLFastTimer _(FTM_APPEND_MESSAGE);  	bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();  	llassert(mEditor); @@ -783,7 +786,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  			timestamp_style.color(timestamp_color);  			timestamp_style.readonly_color(timestamp_color);  		} -		mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style); +		mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getLength() != 0, timestamp_style);  		if (utf8str_trim(chat.mFromName).size() != 0)  		{ @@ -842,7 +845,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  		else  		{  			view = getHeader(chat, style_params, args); -			if (mEditor->getText().size() == 0) +			if (mEditor->getLength() == 0)  				p.top_pad = 0;  			else  				p.top_pad = mTopHeaderPad; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 21b21c152a..563b9b9cab 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -57,6 +57,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;  static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +extern bool gShiftFrame; +  ////////////////////////  // @@ -108,6 +110,8 @@ void LLDrawable::init()  	mGeneration = -1;  	mBinRadius = 1.f; +	mBinIndex = -1; +  	mSpatialBridge = NULL;  } @@ -450,7 +454,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)  {  	if (isState(ACTIVE))  	{ -		clearState(ACTIVE); +		clearState(ACTIVE | ANIMATED_CHILD);  		if (mParent.notNull() && mParent->isActive() && warning_enabled)  		{ @@ -538,9 +542,9 @@ F32 LLDrawable::updateXform(BOOL undamped)  			target_rot = new_rot;  			target_scale = new_scale;  		} -		else +		else if (mVObjp->getAngularVelocity().isExactlyZero())  		{ -			// snap to final position +			// snap to final position (only if no target omega is applied)  			dist_squared = 0.0f;  			if (getVOVolume() && !isRoot())  			{ //child prim snapping to some position, needs a rebuild @@ -549,15 +553,25 @@ F32 LLDrawable::updateXform(BOOL undamped)  		}  	} -	if ((mCurrentScale != target_scale) || -		(!isRoot() &&  -		 (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED ||  -		 !mVObjp->getAngularVelocity().isExactlyZero() || -		 target_pos != mXform.getPosition() || -		 target_rot != mXform.getRotation()))) -	{ //child prim moving or scale change requires immediate rebuild +	LLVector3 vec = mCurrentScale-target_scale; +	 +	if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED) +	{ //scale change requires immediate rebuild +		mCurrentScale = target_scale;  		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);  	} +	else if (!isRoot() &&  +		 (!mVObjp->getAngularVelocity().isExactlyZero() || +			dist_squared > 0.f)) +	{ //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild +		dist_squared = 1.f; //keep this object on the move list +		if (!isState(LLDrawable::ANIMATED_CHILD)) +		{			 +			setState(LLDrawable::ANIMATED_CHILD); +			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); +			mVObjp->dirtySpatialGroup(); +		} +	}  	else if (!getVOVolume() && !isAvatar())  	{  		movePartition(); @@ -568,9 +582,7 @@ F32 LLDrawable::updateXform(BOOL undamped)  	mXform.setRotation(target_rot);  	mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)  	mXform.updateMatrix(); -	 -	mCurrentScale = target_scale; -	 +  	if (mSpatialBridge)  	{  		gPipeline.markMoved(mSpatialBridge, FALSE); @@ -596,7 +608,11 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)  	// Update the face centers.  	for (S32 i = 0; i < getNumFaces(); i++)  	{ -		getFace(i)->updateCenterAgent(); +		LLFace* face = getFace(i); +		if (face) +		{ +			face->updateCenterAgent(); +		}  	}  } @@ -651,7 +667,6 @@ BOOL LLDrawable::updateMoveUndamped()  	}  	mVObjp->clearChanged(LLXform::MOVED); -	  	return TRUE;  } @@ -703,6 +718,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(); @@ -727,7 +747,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)  				for (S32 i = 0; i < getNumFaces(); i++)  				{  					LLFace* facep = getFace(i); -					if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) +					if (facep &&  +						(force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))  					{  						LLVector4a box;  						box.setSub(facep->mExtents[1], facep->mExtents[0]); @@ -811,14 +832,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);  		} @@ -826,13 +852,16 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)  		for (S32 i = 0; i < getNumFaces(); i++)  		{  			LLFace *facep = getFace(i); -			facep->mCenterAgent += LLVector3(shift_vector.getF32ptr()); -			facep->mExtents[0].add(shift_vector); -			facep->mExtents[1].add(shift_vector); -			 -			if (!volume && facep->hasGeometry()) +			if (facep)  			{ -				facep->clearVertexBuffer(); +				facep->mCenterAgent += LLVector3(shift_vector.getF32ptr()); +				facep->mExtents[0].add(shift_vector); +				facep->mExtents[1].add(shift_vector); +			 +				if (rebuild && facep->hasGeometry()) +				{ +					facep->clearVertexBuffer(); +				}  			}  		} @@ -940,6 +969,12 @@ void LLDrawable::updateUVMinMax()  {  } +LLSpatialGroup* LLDrawable::getSpatialGroup() const +{  +	llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); +	return mSpatialGroupp;  +} +  void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)  {  /*if (mSpatialGroupp && (groupp != mSpatialGroupp)) @@ -954,11 +989,16 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)  		for (S32 i = 0; i < getNumFaces(); ++i)  		{  			LLFace* facep = getFace(i); -			facep->clearVertexBuffer(); +			if (facep) +			{ +				facep->clearVertexBuffer(); +			}  		}  	}  	mSpatialGroupp = groupp; + +	llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);  }  LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1081,6 +1121,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat  	mDrawable = root;  	root->setSpatialBridge(this); +	mBinIndex = -1; +  	mRenderType = mDrawable->mRenderType;  	mDrawableType = mDrawable->mRenderType; @@ -1384,6 +1426,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)  		markDead();  		return;  	} +	 +	if (gShiftFrame) +	{ +		return; +	}  	if (mDrawable->getVObj())  	{ @@ -1462,7 +1509,13 @@ void LLSpatialBridge::cleanupReferences()  	LLDrawable::cleanupReferences();  	if (mDrawable)  	{ -		mDrawable->setSpatialGroup(NULL); +		LLSpatialGroup* group = mDrawable->getSpatialGroup(); +		if (group) +		{ +			group->mOctreeNode->remove(mDrawable); +			mDrawable->setSpatialGroup(NULL); +		} +		  		if (mDrawable->getVObj())  		{  			LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1473,7 +1526,12 @@ void LLSpatialBridge::cleanupReferences()  				LLDrawable* drawable = child->mDrawable;					  				if (drawable)  				{ -					drawable->setSpatialGroup(NULL); +					LLSpatialGroup* group = drawable->getSpatialGroup(); +					if (group) +					{ +						group->mOctreeNode->remove(drawable); +						drawable->setSpatialGroup(NULL); +					}  				}  			}  		} @@ -1529,10 +1587,10 @@ BOOL LLDrawable::isAnimating() const  		return TRUE;  	} -	if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero()) -	{ +	/*if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero()) +	{ //target omega  		return TRUE; -	} +	}*/  	return FALSE;  } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index e268640a21..bc4b301ebb 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -109,6 +109,9 @@ public:  	F32			          getIntensity() const			{ return llmin(mXform.getScale().mV[0], 4.f); }  	S32					  getLOD() const				{ return mVObjp ? mVObjp->getLOD() : 1; }  	F32					  getBinRadius() const			{ return mBinRadius; } +	S32					  getBinIndex() const			{ return mBinIndex; } +	void				  setBinIndex(S32 index) const	{ mBinIndex = index; } +  	void  getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }  	LLXformMatrix*		getXform() { return &mXform; } @@ -194,7 +197,7 @@ public:  	S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...  	void setSpatialGroup(LLSpatialGroup *groupp); -	LLSpatialGroup *getSpatialGroup() const			{ return mSpatialGroupp; } +	LLSpatialGroup *getSpatialGroup() const;  	LLSpatialPartition* getSpatialPartition();  	// Statics @@ -277,6 +280,7 @@ public:  		HAS_ALPHA		= 0x04000000,  		RIGGED			= 0x08000000,  		PARTITION_MOVE	= 0x10000000, +		ANIMATED_CHILD  = 0x20000000,  	} EDrawableFlags;  private: //aligned members @@ -314,6 +318,7 @@ private:  	mutable U32		mVisible;  	F32				mRadius;  	F32				mBinRadius; +	mutable S32		mBinIndex;  	S32				mGeneration;  	LLVector3		mCurrentScale; @@ -333,12 +338,14 @@ inline LLFace* LLDrawable::getFace(const S32 i) const  	if ((U32) i >= mFaces.size())  	{ -		llerrs << "Invalid face index." << llendl; +		llwarns << "Invalid face index." << llendl; +		return NULL;  	}  	if (!mFaces[i])  	{ -		llerrs << "Null face found." << llendl; +		llwarns << "Null face found." << llendl; +		return NULL;  	}  	return mFaces[i]; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 35f8a85796..6c0be0a5c2 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -253,48 +253,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures  {  } -// static -S32 LLFacePool::drawLoop(face_array_t& face_list) -{ -	S32 res = 0; -	if (!face_list.empty()) -	{ -		for (std::vector<LLFace*>::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<LLFace*>::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); @@ -442,7 +400,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)  void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  { -	for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	 +	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)  diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 64774d06df..e0f2da41d7 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -186,10 +186,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/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 5b62dbc560..313b310e1e 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -348,7 +348,7 @@ void LLDrawPoolAlpha::render(S32 pass)  void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)  { -	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) +	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i;  		if (group->mSpatialPartition->mRenderByGroup && @@ -385,7 +385,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  	BOOL use_shaders = gPipeline.canUseVertexShaders(); -	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) +	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i;  		llassert(group); @@ -405,6 +405,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  			{  				LLDrawInfo& params = **k; +				if ((params.mVertexBuffer->getTypeMask() & mask) != mask) +				{ //FIXME! +					llwarns << "Missing required components, skipping render batch." << llendl; +					continue; +				} +  				LLRenderPass::applyModelMatrix(params); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 0103373fd2..730ad1a364 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -261,7 +261,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()  	sRenderingSkinned = TRUE;  	gPipeline.bindDeferredShader(*sVertexProgram); -	 + +	sVertexProgram->setMinimumAlpha(0.2f); +  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  } @@ -1034,9 +1036,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++) @@ -1193,15 +1199,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	if (pass >= 7 && pass < 9)  	{ -		LLGLEnable blend(GL_BLEND); - -		gGL.setColorMask(true, true); -		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, -					  LLRender::BF_ONE_MINUS_SOURCE_ALPHA, -					  LLRender::BF_ZERO, -					  LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - -		  		if (pass == 7)  		{  			renderRiggedAlpha(avatarp); @@ -1217,20 +1214,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	if (pass == 9)  	{ -		LLGLEnable blend(GL_BLEND); -		LLGLDisable test(GL_ALPHA_TEST); -		gGL.flush(); - -		LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); -		glPolygonOffset(-1.0f, -1.0f); -		gGL.setSceneBlendType(LLRender::BT_ADD); - -		LLGLDepthTest depth(GL_TRUE, GL_FALSE); -		gGL.setColorMask(false, true); -  		renderRiggedGlow(avatarp); -		gGL.setColorMask(true, false); -		gGL.setSceneBlendType(LLRender::BT_ALPHA); +		  		return;  	} @@ -1428,7 +1413,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  { -	if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled()) +	if (avatar->isSelf() && !gAgent.needsRenderAvatar())  	{  		return;  	} @@ -1557,8 +1542,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)  	{ @@ -1630,17 +1619,56 @@ void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar)  void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)  { -	renderRigged(avatar, RIGGED_ALPHA); +	if (!mRiggedFace[RIGGED_ALPHA].empty()) +	{ +		LLGLEnable blend(GL_BLEND); + +		gGL.setColorMask(true, true); +		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, +						LLRender::BF_ONE_MINUS_SOURCE_ALPHA, +						LLRender::BF_ZERO, +						LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + +		renderRigged(avatar, RIGGED_ALPHA); +	}  }  void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)  { -	renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); +	if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) +	{ +		LLGLEnable blend(GL_BLEND); + +		gGL.setColorMask(true, true); +		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, +						LLRender::BF_ONE_MINUS_SOURCE_ALPHA, +						LLRender::BF_ZERO, +						LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + +		renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); +	}  }  void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)  { -	renderRigged(avatar, RIGGED_GLOW, true); +	if (!mRiggedFace[RIGGED_GLOW].empty()) +	{ +		LLGLEnable blend(GL_BLEND); +		LLGLDisable test(GL_ALPHA_TEST); +		gGL.flush(); + +		LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); +		glPolygonOffset(-1.0f, -1.0f); +		gGL.setSceneBlendType(LLRender::BT_ADD); + +		LLGLDepthTest depth(GL_TRUE, GL_FALSE); +		gGL.setColorMask(false, true); + +		renderRigged(avatar, RIGGED_GLOW, true); + +		gGL.setColorMask(true, false); +		gGL.setSceneBlendType(LLRender::BT_ALPHA); +	}  } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 6f71e6ebc8..a264eae302 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -847,12 +847,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  	LLFastTimer ftm(FTM_RENDER_BUMP);  	U32 type = LLRenderPass::PASS_BUMP; -	LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); -	LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); +	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); +	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);  	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; -	for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)	 +	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{  		LLDrawInfo& params = **i; @@ -1448,10 +1448,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  void LLDrawPoolBump::renderBump(U32 type, U32 mask)  {	 -	LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); -	LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); +	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); +	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -	for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)	 +	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{  		LLDrawInfo& params = **i; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b95d8296fa..7fc78fb382 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -294,6 +294,34 @@ void LLDrawPoolTerrain::renderShadow(S32 pass)  	//glCullFace(GL_BACK);  } + +void LLDrawPoolTerrain::drawLoop() +{ +	if (!mDrawFace.empty()) +	{ +		for (std::vector<LLFace*>::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 283ed87f1a..2163d087e1 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -83,6 +83,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 3165a3516c..83f04e45a8 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -37,6 +37,7 @@  #include "llviewershadermgr.h"  #include "llrender.h"  #include "llviewercontrol.h" +#include "llviewerregion.h"  S32 LLDrawPoolTree::sDiffTex = 0;  static LLGLSLShader* shader = NULL; @@ -104,8 +105,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/lldriverparam.cpp b/indra/newview/lldriverparam.cpp index 64eb11fc9b..885cae1737 100644 --- a/indra/newview/lldriverparam.cpp +++ b/indra/newview/lldriverparam.cpp @@ -155,6 +155,7 @@ LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :  	mAvatarp(avatarp),   	mWearablep(NULL)  { +	mDefaultVec.clear();  }  LLDriverParam::LLDriverParam(LLWearable *wearablep) :  @@ -162,6 +163,7 @@ LLDriverParam::LLDriverParam(LLWearable *wearablep) :  	mAvatarp(NULL),   	mWearablep(wearablep)  { +	mDefaultVec.clear();  }  LLDriverParam::~LLDriverParam() @@ -341,18 +343,19 @@ F32	LLDriverParam::getTotalDistortion()  	return sum;   } -const LLVector3	&LLDriverParam::getAvgDistortion()	 +const LLVector4a	&LLDriverParam::getAvgDistortion()	  {  	// It's not actually correct to take the average of averages, but it good enough here. -	LLVector3 sum; +	LLVector4a sum; +	sum.clear();  	S32 count = 0;  	for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )  	{  		LLDrivenEntry* driven = &(*iter); -		sum += driven->mParam->getAvgDistortion(); +		sum.add(driven->mParam->getAvgDistortion());  		count++;  	} -	sum /= (F32)count; +	sum.mul( 1.f/(F32)count);  	mDefaultVec = sum;  	return mDefaultVec;  @@ -375,21 +378,22 @@ F32	LLDriverParam::getMaxDistortion()  } -LLVector3	LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) +LLVector4a	LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)  { -	LLVector3 sum; +	LLVector4a sum; +	sum.clear();  	for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )  	{  		LLDrivenEntry* driven = &(*iter); -		sum += driven->mParam->getVertexDistortion( index, poly_mesh ); +		sum.add(driven->mParam->getVertexDistortion( index, poly_mesh ));  	}  	return sum;  } -const LLVector3*	LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a*	LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)  {  	mCurrentDistortionParam = NULL; -	const LLVector3* v = NULL; +	const LLVector4a* v = NULL;  	for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )  	{  		LLDrivenEntry* driven = &(*iter); @@ -404,7 +408,7 @@ const LLVector3*	LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly  	return v;  }; -const LLVector3*	LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a*	LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)  {  	llassert( mCurrentDistortionParam );  	if( !mCurrentDistortionParam ) @@ -432,7 +436,7 @@ const LLVector3*	LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_  	}  	// We're already in the middle of a param's distortions, so get the next one. -	const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh ); +	const LLVector4a* v = driven->mParam->getNextDistortion( index, poly_mesh );  	if( (!v) && (iter != mDriven.end()) )  	{  		// This param is finished, so start the next param.  It might not have any diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h index fb1b44458c..7a4d711d4e 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/newview/lldriverparam.h @@ -105,18 +105,18 @@ public:  	// LLViewerVisualParam Virtual functions  	/*virtual*/ F32					getTotalDistortion(); -	/*virtual*/ const LLVector3&	getAvgDistortion(); +	/*virtual*/ const LLVector4a&	getAvgDistortion();  	/*virtual*/ F32					getMaxDistortion(); -	/*virtual*/ LLVector3			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); -	/*virtual*/ const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); -	/*virtual*/ const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);  protected:  	F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);  	void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake); -	LLVector3	mDefaultVec; // temp holder +	LLVector4a	mDefaultVec; // temp holder  	typedef std::vector<LLDrivenEntry> entry_list_t;  	entry_list_t mDriven;  	LLViewerVisualParam* mCurrentDistortionParam; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4108d69e82..f5b217d539 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -44,11 +44,14 @@  #include "llsky.h"  #include "llviewercamera.h"  #include "llviewertexturelist.h" +#include "llvopartgroup.h"  #include "llvosky.h"  #include "llvovolume.h"  #include "pipeline.h"  #include "llviewerregion.h"  #include "llviewerwindow.h" +#include "llviewershadermgr.h" +  #define LL_MAX_INDICES_COUNT 1000000 @@ -56,7 +59,6 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE  #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) -  /*  For each vertex, given:  	B - binormal @@ -161,7 +163,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mGeomCount		= 0;  	mGeomIndex		= 0;  	mIndicesCount	= 0; -	mIndicesIndex	= 0; + +	//special value to indicate uninitialized position +	mIndicesIndex	= 0xFFFFFFFF; +	  	mIndexInTex = 0;  	mTexture		= NULL;  	mTEOffset		= -1; @@ -177,12 +182,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mFaceColor = LLColor4(1,0,0,1); -	mLastVertexBuffer = mVertexBuffer; -	mLastGeomCount = mGeomCount; -	mLastGeomIndex = mGeomIndex; -	mLastIndicesCount = mIndicesCount; -	mLastIndicesIndex = mIndicesIndex; -  	mImportanceToCamera = 0.f ;  	mBoundingSphereRadius = 0.0f ; @@ -203,6 +202,12 @@ void LLFace::destroy()  		mTexture->removeFace(this) ;  	} +	if (isState(LLFace::PARTICLE)) +	{ +		LLVOPartGroup::freeVBSlot(getGeomIndex()/4); +		clearState(LLFace::PARTICLE); +	} +  	if (mDrawPoolp)  	{  		if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR) @@ -372,7 +377,6 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)  		mGeomCount    = num_vertices;  		mIndicesCount = num_indices;  		mVertexBuffer = NULL; -		mLastVertexBuffer = NULL;  	}  	llassert(verify()); @@ -765,12 +769,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		LLMatrix4a mat_normal;  		mat_normal.loadu(mat_normal_in); -		//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) -		//{ //vertex buffer no longer valid -		//	mVertexBuffer = NULL; -		//	mLastVertexBuffer = NULL; -		//} -  		//VECTORIZE THIS  		LLVector4a min,max; @@ -1032,30 +1030,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to,  LLVector2* res_st_offs  void LLFace::updateRebuildFlags()  { -	if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) -	{ -		BOOL moved = TRUE; -		if (mLastVertexBuffer == mVertexBuffer &&  -			!mVertexBuffer->isEmpty()) -		{	//this face really doesn't need to be regenerated, try real hard not to do so -			if (mLastGeomCount == mGeomCount && -				mLastGeomIndex == mGeomIndex && -				mLastIndicesCount == mIndicesCount && -				mLastIndicesIndex == mIndicesIndex) -			{ //data is in same location in vertex buffer -				moved = FALSE; -			} -		} -		mLastMoveTime = gFrameTimeSeconds; -		 -		if (moved) -		{ -			mDrawablep->setState(LLDrawable::REBUILD_VOLUME); -		} +	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) +	{ //this rebuild is zero overhead (direct consequence of some change that affects this face) +		mLastUpdateTime = gFrameTimeSeconds;  	}  	else -	{ -		mLastUpdateTime = gFrameTimeSeconds; +	{ //this rebuild is overhead (side effect of some change that does not affect this face) +		mLastMoveTime = gFrameTimeSeconds;  	}  } @@ -1094,6 +1075,73 @@ bool LLFace::canRenderAsMask()  } +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_VOLUME("Volume VB Cache"); + +//static  +void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) +{ +	LLFastTimer t(FTM_FACE_GEOM_VOLUME); +	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | +				LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL; +	 +	if (vf.mWeights) +	{ +		mask |= LLVertexBuffer::MAP_WEIGHT4; +	} + +	LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB); +	vf.mVertexBuffer = buff; + +	buff->allocateBuffer(vf.mNumVertices, 0, true); + +	LLStrider<LLVector4a> f_vert; +	LLStrider<LLVector3> f_binorm; +	LLStrider<LLVector3> f_norm; +	LLStrider<LLVector2> f_tc; + +	buff->getBinormalStrider(f_binorm); +	buff->getVertexStrider(f_vert); +	buff->getNormalStrider(f_norm); +	buff->getTexCoord0Strider(f_tc); + +	for (U32 i = 0; i < vf.mNumVertices; ++i) +	{ +		*f_vert++ = vf.mPositions[i]; +		(*f_binorm++).set(vf.mBinormals[i].getF32ptr()); +		*f_tc++ = vf.mTexCoords[i]; +		(*f_norm++).set(vf.mNormals[i].getF32ptr()); +	} + +	if (vf.mWeights) +	{ +		LLStrider<LLVector4> f_wght; +		buff->getWeight4Strider(f_wght); +		for (U32 i = 0; i < vf.mNumVertices; ++i) +		{ +			(*f_wght++).set(vf.mWeights[i].getF32ptr()); +		} +	} + +	buff->flush(); +} + +//helper function for pushing primitives for transform shaders and cleaning up +//uninitialized data on the tail, plus tracking number of expected primitives +void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count) +{ +	if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping +	{ +		//push source primitives +		buff->drawArrays(LLRender::POINTS, 0, source_count); +		U32 tail = dest_count-source_count; +		for (U32 i = 0; i < tail; ++i) +		{ //copy last source primitive into each element in tail +			buff->drawArrays(LLRender::POINTS, source_count-1, 1); +		} +		gPipeline.mTransformFeedbackPrimitives += dest_count; +	} +} +  static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal"); @@ -1111,7 +1159,6 @@ static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default");  static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick");  static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform");  static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform"); -  static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");  BOOL LLFace::getGeometryVolume(const LLVolume& volume, @@ -1139,21 +1186,25 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	{  		if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())  		{ -			llwarns	<< "Index buffer overflow!" << llendl; -			llwarns << "Indices Count: " << mIndicesCount -					<< " VF Num Indices: " << num_indices -					<< " Indices Index: " << mIndicesIndex -					<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl; -			llwarns	<< "Last Indices Count: " << mLastIndicesCount -					<< " Last Indices Index: " << mLastIndicesIndex -					<< " Face Index: " << f -					<< " Pool Type: " << mPoolType << llendl; +			if (gDebugGL) +			{ +				llwarns	<< "Index buffer overflow!" << llendl; +				llwarns << "Indices Count: " << mIndicesCount +						<< " VF Num Indices: " << num_indices +						<< " Indices Index: " << mIndicesIndex +						<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl; +				llwarns	<< " Face Index: " << f +						<< " Pool Type: " << mPoolType << llendl; +			}  			return FALSE;  		}  		if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())  		{ -			llwarns << "Vertex buffer overflow!" << llendl; +			if (gDebugGL) +			{ +				llwarns << "Vertex buffer overflow!" << llendl; +			}  			return FALSE;  		}  	} @@ -1284,17 +1335,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	LLMatrix4a mat_normal;  	mat_normal.loadu(mat_norm_in); -	//if it's not fullbright and has no normals, bake sunlight based on face normal -	//bool bake_sunlight = !getTextureEntry()->getFullbright() && -	//  !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -  	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; - +	bool do_xform = false;  	if (rebuild_tcoord)  	{ -		LLFastTimer t(FTM_FACE_GEOM_TEXTURE); -		bool do_xform; -			  		if (tep)  		{  			r  = tep->getRotation(); @@ -1323,599 +1367,759 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		{  			do_xform = false;  		} +	} +	 +	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + +#ifdef GL_TRANSFORM_FEEDBACK_BUFFER +	if (use_transform_feedback && +		gTransformPositionProgram.mProgramObject && //transform shaders are loaded +		mVertexBuffer->useVBOs() && //target buffer is in VRAM +		!rebuild_weights && //TODO: add support for weights +		!volume.isUnique()) //source volume is NOT flexi +	{ //use transform feedback to pack vertex buffer + +		LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); + +		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) +		{ +			mVObjp->getVolume()->genBinormals(f); +			LLFace::cacheFaceInVRAM(vf); +			buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); +		}		 + +		LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; +		 +		gGL.pushMatrix(); +		gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix); + +		if (rebuild_pos) +		{ +			LLFastTimer t(FTM_FACE_GEOM_POSITION); +			gTransformPositionProgram.bind(); + +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); + +			U8 index = mTextureIndex < 255 ? mTextureIndex : 0; + +			S32 val = 0; +			U8* vp = (U8*) &val; +			vp[0] = index; +			vp[1] = 0; +			vp[2] = 0; +			vp[3] = 0; +			 +			gTransformPositionProgram.uniform1i("texture_index_in", val); +			glBeginTransformFeedback(GL_POINTS); +			buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + +			push_for_transform(buff, vf.mNumVertices, mGeomCount); + +			glEndTransformFeedback(); +		} + +		if (rebuild_color) +		{ +			LLFastTimer t(FTM_FACE_GEOM_COLOR); +			gTransformColorProgram.bind(); +			 +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); + +			S32 val = *((S32*) color.mV); + +			gTransformColorProgram.uniform1i("color_in", val); +			glBeginTransformFeedback(GL_POINTS); +			buff->setBuffer(LLVertexBuffer::MAP_VERTEX); +			push_for_transform(buff, vf.mNumVertices, mGeomCount); +			glEndTransformFeedback(); +		} + +		if (rebuild_emissive) +		{ +			LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); +			gTransformColorProgram.bind(); +			 +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); + +			U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); + +			S32 glow32 = glow | +						 (glow << 8) | +						 (glow << 16) | +						 (glow << 24); + +			gTransformColorProgram.uniform1i("color_in", glow32); +			glBeginTransformFeedback(GL_POINTS); +			buff->setBuffer(LLVertexBuffer::MAP_VERTEX); +			push_for_transform(buff, vf.mNumVertices, mGeomCount); +			glEndTransformFeedback(); +		} + +		if (rebuild_normal) +		{ +			LLFastTimer t(FTM_FACE_GEOM_NORMAL); +			gTransformNormalProgram.bind(); +			 +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); -		//bump setup -		LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); -		LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); -		LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); +			glBeginTransformFeedback(GL_POINTS); +			buff->setBuffer(LLVertexBuffer::MAP_NORMAL); +			push_for_transform(buff, vf.mNumVertices, mGeomCount); +			glEndTransformFeedback(); +		} -		LLQuaternion bump_quat; -		if (mDrawablep->isActive()) +		if (rebuild_binormal)  		{ -			bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); +			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); +			gTransformBinormalProgram.bind(); +			 +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); +						 +			glBeginTransformFeedback(GL_POINTS); +			buff->setBuffer(LLVertexBuffer::MAP_BINORMAL); +			push_for_transform(buff, vf.mNumVertices, mGeomCount); +			glEndTransformFeedback();  		} -		 -		if (bump_code) + +		if (rebuild_tcoord)  		{ -			mVObjp->getVolume()->genBinormals(f); -			F32 offset_multiple;  -			switch( bump_code ) -			{ -				case BE_NO_BUMP: -				offset_multiple = 0.f; -				break; -				case BE_BRIGHTNESS: -				case BE_DARKNESS: -				if( mTexture.notNull() && mTexture->hasGLTexture()) -				{ -					// Offset by approximately one texel -					S32 cur_discard = mTexture->getDiscardLevel(); -					S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); -					max_size <<= cur_discard; -					const F32 ARTIFICIAL_OFFSET = 2.f; -					offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; -				} -				else -				{ -					offset_multiple = 1.f/256; -				} -				break; +			LLFastTimer t(FTM_FACE_GEOM_TEXTURE); +			gTransformTexCoordProgram.bind(); +			 +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); +						 +			glBeginTransformFeedback(GL_POINTS); +			buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); +			push_for_transform(buff, vf.mNumVertices, mGeomCount); +			glEndTransformFeedback(); -				default:  // Standard bumpmap textures.  Assumed to be 256x256 -				offset_multiple = 1.f / 256; -				break; -			} +			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); -			F32 s_scale = 1.f; -			F32 t_scale = 1.f; -			if( tep ) +			if (do_bump)  			{ -				tep->getScale( &s_scale, &t_scale ); -			} -			// Use the nudged south when coming from above sun angle, such -			// that emboss mapping always shows up on the upward faces of cubes when  -			// it's noon (since a lot of builders build with the sun forced to noon). -			LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir; -			LLVector3   moon_ray = gSky.getMoonDirection(); -			LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; - -			bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); -			bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); +				mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount); +				glBeginTransformFeedback(GL_POINTS); +				buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); +				push_for_transform(buff, vf.mNumVertices, mGeomCount); +				glEndTransformFeedback(); +			}				  		} -		U8 texgen = getTextureEntry()->getTexGen(); -		if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) -		{ //planar texgen needs binormals -			mVObjp->getVolume()->genBinormals(f); +		glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0); + +		gGL.popMatrix(); + +		if (cur_shader) +		{ +			cur_shader->bind();  		} +	} +	else +#endif +	{ +		//if it's not fullbright and has no normals, bake sunlight based on face normal +		//bool bake_sunlight = !getTextureEntry()->getFullbright() && +		//  !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -		U8 tex_mode = 0; -	 -		if (isState(TEXTURE_ANIM)) +		if (rebuild_tcoord)  		{ -			LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	 -			tex_mode = vobj->mTexAnimMode; +			LLFastTimer t(FTM_FACE_GEOM_TEXTURE); +									 +			//bump setup +			LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); +			LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); +			LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); -			if (!tex_mode) +			LLQuaternion bump_quat; +			if (mDrawablep->isActive())  			{ -				clearState(TEXTURE_ANIM); +				bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());  			} -			else +		 +			if (bump_code)  			{ -				os = ot = 0.f; -				r = 0.f; -				cos_ang = 1.f; -				sin_ang = 0.f; -				ms = mt = 1.f; +				mVObjp->getVolume()->genBinormals(f); +				F32 offset_multiple;  +				switch( bump_code ) +				{ +					case BE_NO_BUMP: +					offset_multiple = 0.f; +					break; +					case BE_BRIGHTNESS: +					case BE_DARKNESS: +					if( mTexture.notNull() && mTexture->hasGLTexture()) +					{ +						// Offset by approximately one texel +						S32 cur_discard = mTexture->getDiscardLevel(); +						S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); +						max_size <<= cur_discard; +						const F32 ARTIFICIAL_OFFSET = 2.f; +						offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; +					} +					else +					{ +						offset_multiple = 1.f/256; +					} +					break; -				do_xform = false; +					default:  // Standard bumpmap textures.  Assumed to be 256x256 +					offset_multiple = 1.f / 256; +					break; +				} + +				F32 s_scale = 1.f; +				F32 t_scale = 1.f; +				if( tep ) +				{ +					tep->getScale( &s_scale, &t_scale ); +				} +				// Use the nudged south when coming from above sun angle, such +				// that emboss mapping always shows up on the upward faces of cubes when  +				// it's noon (since a lot of builders build with the sun forced to noon). +				LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir; +				LLVector3   moon_ray = gSky.getMoonDirection(); +				LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; + +				bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); +				bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);  			} -			if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) -			{ //don't override texture transform during tc bake -				tex_mode = 0; +			U8 texgen = getTextureEntry()->getTexGen(); +			if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) +			{ //planar texgen needs binormals +				mVObjp->getVolume()->genBinormals(f);  			} -		} -		LLVector4a scalea; -		scalea.load3(scale.mV); +			U8 tex_mode = 0; +	 +			if (isState(TEXTURE_ANIM)) +			{ +				LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	 +				tex_mode = vobj->mTexAnimMode; + +				if (!tex_mode) +				{ +					clearState(TEXTURE_ANIM); +				} +				else +				{ +					os = ot = 0.f; +					r = 0.f; +					cos_ang = 1.f; +					sin_ang = 0.f; +					ms = mt = 1.f; + +					do_xform = false; +				} -		bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); -		bool do_tex_mat = tex_mode && mTextureMatrix; +				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) +				{ //don't override texture transform during tc bake +					tex_mode = 0; +				} +			} -		if (!in_atlas && !do_bump) -		{ //not in atlas or not bump mapped, might be able to do a cheap update -			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); +			LLVector4a scalea; +			scalea.load3(scale.mV); -			if (texgen != LLTextureEntry::TEX_GEN_PLANAR) -			{ -				LLFastTimer t(FTM_FACE_TEX_QUICK); -				if (!do_tex_mat) +			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); +			bool do_tex_mat = tex_mode && mTextureMatrix; + +			if (!in_atlas && !do_bump) +			{ //not in atlas or not bump mapped, might be able to do a cheap update +				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); + +				if (texgen != LLTextureEntry::TEX_GEN_PLANAR)  				{ -					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)); -					} -					else +					LLFastTimer t(FTM_FACE_TEX_QUICK); +					if (!do_tex_mat)  					{ -						LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); -						F32* dst = (F32*) tex_coords.get(); -						LLVector4a* src = (LLVector4a*) vf.mTexCoords; +						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)); +						} +						else +						{ +							LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); +							F32* dst = (F32*) tex_coords.get(); +							LLVector4a* src = (LLVector4a*) vf.mTexCoords; -						LLVector4a trans; -						trans.splat(-0.5f); +							LLVector4a trans; +							trans.splat(-0.5f); -						LLVector4a rot0; -						rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang); +							LLVector4a rot0; +							rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang); -						LLVector4a rot1; -						rot1.set(sin_ang, cos_ang, sin_ang, cos_ang); +							LLVector4a rot1; +							rot1.set(sin_ang, cos_ang, sin_ang, cos_ang); -						LLVector4a scale; -						scale.set(ms, mt, ms, mt); +							LLVector4a scale; +							scale.set(ms, mt, ms, mt); -						LLVector4a offset; -						offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f); +							LLVector4a offset; +							offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f); -						LLVector4Logical mask; -						mask.clear(); -						mask.setElement<2>(); -						mask.setElement<3>(); +							LLVector4Logical mask; +							mask.clear(); +							mask.setElement<2>(); +							mask.setElement<3>(); -						U32 count = num_vertices/2 + num_vertices%2; +							U32 count = num_vertices/2 + num_vertices%2; -						for (S32 i = 0; i < count; i++) +							for (S32 i = 0; i < count; i++) +							{	 +								LLVector4a res = *src++; +								xform4a(res, trans, mask, rot0, rot1, offset, scale); +								res.store4a(dst); +								dst += 4; +							} +						} +					} +					else +					{ //do tex mat, no texgen, no atlas, no bump +						for (S32 i = 0; i < num_vertices; i++)  						{	 -							LLVector4a res = *src++; -							xform4a(res, trans, mask, rot0, rot1, offset, scale); -							res.store4a(dst); -							dst += 4; +							LLVector2 tc(vf.mTexCoords[i]); +							//LLVector4a& norm = vf.mNormals[i]; +							//LLVector4a& center = *(vf.mCenter); + +							LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +							tmp = tmp * *mTextureMatrix; +							tc.mV[0] = tmp.mV[0]; +							tc.mV[1] = tmp.mV[1]; +							*tex_coords++ = tc;	  						}  					}  				}  				else -				{ //do tex mat, no texgen, no atlas, no bump -					for (S32 i = 0; i < num_vertices; i++) -					{	 -						LLVector2 tc(vf.mTexCoords[i]); -						//LLVector4a& norm = vf.mNormals[i]; -						//LLVector4a& center = *(vf.mCenter); - -						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); -						tmp = tmp * *mTextureMatrix; -						tc.mV[0] = tmp.mV[0]; -						tc.mV[1] = tmp.mV[1]; -						*tex_coords++ = tc;	 -					} -				} -			} -			else -			{ //no bump, no atlas, tex gen planar -				LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR); -				if (do_tex_mat) -				{ -					for (S32 i = 0; i < num_vertices; i++) -					{	 -						LLVector2 tc(vf.mTexCoords[i]); -						LLVector4a& norm = vf.mNormals[i]; -						LLVector4a& center = *(vf.mCenter); -						LLVector4a vec = vf.mPositions[i];	 -						vec.mul(scalea); -						planarProjection(tc, norm, center, vec); +				{ //no bump, no atlas, tex gen planar +					LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR); +					if (do_tex_mat) +					{ +						for (S32 i = 0; i < num_vertices; i++) +						{	 +							LLVector2 tc(vf.mTexCoords[i]); +							LLVector4a& norm = vf.mNormals[i]; +							LLVector4a& center = *(vf.mCenter); +							LLVector4a vec = vf.mPositions[i];	 +							vec.mul(scalea); +							planarProjection(tc, norm, center, vec); -						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); -						tmp = tmp * *mTextureMatrix; -						tc.mV[0] = tmp.mV[0]; -						tc.mV[1] = tmp.mV[1]; +							LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +							tmp = tmp * *mTextureMatrix; +							tc.mV[0] = tmp.mV[0]; +							tc.mV[1] = tmp.mV[1]; -						*tex_coords++ = tc;	 +							*tex_coords++ = tc;	 +						}  					} -				} -				else -				{ -					for (S32 i = 0; i < num_vertices; i++) -					{	 -						LLVector2 tc(vf.mTexCoords[i]); -						LLVector4a& norm = vf.mNormals[i]; -						LLVector4a& center = *(vf.mCenter); -						LLVector4a vec = vf.mPositions[i];	 -						vec.mul(scalea); -						planarProjection(tc, norm, center, vec); +					else +					{ +						for (S32 i = 0; i < num_vertices; i++) +						{	 +							LLVector2 tc(vf.mTexCoords[i]); +							LLVector4a& norm = vf.mNormals[i]; +							LLVector4a& center = *(vf.mCenter); +							LLVector4a vec = vf.mPositions[i];	 +							vec.mul(scalea); +							planarProjection(tc, norm, center, vec); -						xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +							xform(tc, cos_ang, sin_ang, os, ot, ms, mt); -						*tex_coords++ = tc;	 +							*tex_coords++ = tc;	 +						}  					}  				} -			} -			if (map_range) -			{ -				mVertexBuffer->flush(); +				if (map_range) +				{ +					mVertexBuffer->flush(); +				}  			} -		} -		else -		{ //either bump mapped or in atlas, just do the whole expensive loop -			LLFastTimer t(FTM_FACE_TEX_DEFAULT); -			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); +			else +			{ //either bump mapped or in atlas, just do the whole expensive loop +				LLFastTimer t(FTM_FACE_TEX_DEFAULT); +				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); -			std::vector<LLVector2> bump_tc; +				std::vector<LLVector2> bump_tc; -			for (S32 i = 0; i < num_vertices; i++) -			{	 -				LLVector2 tc(vf.mTexCoords[i]); +				for (S32 i = 0; i < num_vertices; i++) +				{	 +					LLVector2 tc(vf.mTexCoords[i]); -				LLVector4a& norm = vf.mNormals[i]; +					LLVector4a& norm = vf.mNormals[i]; -				LLVector4a& center = *(vf.mCenter); +					LLVector4a& center = *(vf.mCenter); -				if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) -				{ -					LLVector4a vec = vf.mPositions[i]; +					if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) +					{ +						LLVector4a vec = vf.mPositions[i]; -					vec.mul(scalea); +						vec.mul(scalea); -					switch (texgen) +						switch (texgen) +						{ +							case LLTextureEntry::TEX_GEN_PLANAR: +								planarProjection(tc, norm, center, vec); +								break; +							case LLTextureEntry::TEX_GEN_SPHERICAL: +								sphericalProjection(tc, norm, center, vec); +								break; +							case LLTextureEntry::TEX_GEN_CYLINDRICAL: +								cylindricalProjection(tc, norm, center, vec); +								break; +							default: +								break; +						}		 +					} + +					if (tex_mode && mTextureMatrix)  					{ -						case LLTextureEntry::TEX_GEN_PLANAR: -							planarProjection(tc, norm, center, vec); +						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +						tmp = tmp * *mTextureMatrix; +						tc.mV[0] = tmp.mV[0]; +						tc.mV[1] = tmp.mV[1]; +					} +					else +					{ +						xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +					} + +					if(in_atlas) +					{ +						// +						//manually calculate tex-coord per vertex for varying address modes. +						//should be removed if shader can handle this. +						// + +						S32 int_part = 0 ; +						switch(mTexture->getAddressMode()) +						{ +						case LLTexUnit::TAM_CLAMP: +							if(tc.mV[0] < 0.f) +							{ +								tc.mV[0] = 0.f ; +							} +							else if(tc.mV[0] > 1.f) +							{ +								tc.mV[0] = 1.f; +							} + +							if(tc.mV[1] < 0.f) +							{ +								tc.mV[1] = 0.f ; +							} +							else if(tc.mV[1] > 1.f) +							{ +								tc.mV[1] = 1.f; +							}  							break; -						case LLTextureEntry::TEX_GEN_SPHERICAL: -							sphericalProjection(tc, norm, center, vec); +						case LLTexUnit::TAM_MIRROR: +							if(tc.mV[0] < 0.f) +							{ +								tc.mV[0] = -tc.mV[0] ; +							} +							int_part = (S32)tc.mV[0] ; +							if(int_part & 1) //odd number +							{ +								tc.mV[0] = int_part + 1 - tc.mV[0] ; +							} +							else //even number +							{ +								tc.mV[0] -= int_part ; +							} + +							if(tc.mV[1] < 0.f) +							{ +								tc.mV[1] = -tc.mV[1] ; +							} +							int_part = (S32)tc.mV[1] ; +							if(int_part & 1) //odd number +							{ +								tc.mV[1] = int_part + 1 - tc.mV[1] ; +							} +							else //even number +							{ +								tc.mV[1] -= int_part ; +							}  							break; -						case LLTextureEntry::TEX_GEN_CYLINDRICAL: -							cylindricalProjection(tc, norm, center, vec); +						case LLTexUnit::TAM_WRAP: +							if(tc.mV[0] > 1.f) +								tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; +							else if(tc.mV[0] < -1.f) +								tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; + +							if(tc.mV[1] > 1.f) +								tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; +							else if(tc.mV[1] < -1.f) +								tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; + +							if(tc.mV[0] < 0.f) +							{ +								tc.mV[0] = 1.0f + tc.mV[0] ; +							} +							if(tc.mV[1] < 0.f) +							{ +								tc.mV[1] = 1.0f + tc.mV[1] ; +							}  							break;  						default:  							break; -					}		 -				} +						} +				 +						tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; +						tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; +					} +				 -				if (tex_mode && mTextureMatrix) -				{ -					LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); -					tmp = tmp * *mTextureMatrix; -					tc.mV[0] = tmp.mV[0]; -					tc.mV[1] = tmp.mV[1]; +					*tex_coords++ = tc; +					if (do_bump) +					{ +						bump_tc.push_back(tc); +					}  				} -				else + +				if (map_range)  				{ -					xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +					mVertexBuffer->flush();  				} -				if(in_atlas) +				if (do_bump)  				{ -					// -					//manually calculate tex-coord per vertex for varying address modes. -					//should be removed if shader can handle this. -					// - -					S32 int_part = 0 ; -					switch(mTexture->getAddressMode()) +					mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); +		 +					for (S32 i = 0; i < num_vertices; i++)  					{ -					case LLTexUnit::TAM_CLAMP: -						if(tc.mV[0] < 0.f) -						{ -							tc.mV[0] = 0.f ; -						} -						else if(tc.mV[0] > 1.f) -						{ -							tc.mV[0] = 1.f; -						} - -						if(tc.mV[1] < 0.f) -						{ -							tc.mV[1] = 0.f ; -						} -						else if(tc.mV[1] > 1.f) -						{ -							tc.mV[1] = 1.f; -						} -						break; -					case LLTexUnit::TAM_MIRROR: -						if(tc.mV[0] < 0.f) -						{ -							tc.mV[0] = -tc.mV[0] ; -						} -						int_part = (S32)tc.mV[0] ; -						if(int_part & 1) //odd number -						{ -							tc.mV[0] = int_part + 1 - tc.mV[0] ; -						} -						else //even number +						LLVector4a tangent; +						tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + +						LLMatrix4a tangent_to_object; +						tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); +						LLVector4a t; +						tangent_to_object.rotate(binormal_dir, t); +						LLVector4a binormal; +						mat_normal.rotate(t, binormal); +						 +						//VECTORIZE THIS +						if (mDrawablep->isActive())  						{ -							tc.mV[0] -= int_part ; +							LLVector3 t; +							t.set(binormal.getF32ptr()); +							t *= bump_quat; +							binormal.load3(t.mV);  						} -						if(tc.mV[1] < 0.f) -						{ -							tc.mV[1] = -tc.mV[1] ; -						} -						int_part = (S32)tc.mV[1] ; -						if(int_part & 1) //odd number -						{ -							tc.mV[1] = int_part + 1 - tc.mV[1] ; -						} -						else //even number -						{ -							tc.mV[1] -= int_part ; -						} -						break; -					case LLTexUnit::TAM_WRAP: -						if(tc.mV[0] > 1.f) -							tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; -						else if(tc.mV[0] < -1.f) -							tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - -						if(tc.mV[1] > 1.f) -							tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; -						else if(tc.mV[1] < -1.f) -							tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - -						if(tc.mV[0] < 0.f) -						{ -							tc.mV[0] = 1.0f + tc.mV[0] ; -						} -						if(tc.mV[1] < 0.f) -						{ -							tc.mV[1] = 1.0f + tc.mV[1] ; -						} -						break; -					default: -						break; +						binormal.normalize3fast(); +						LLVector2 tc = bump_tc[i]; +						tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); +					 +						*tex_coords2++ = tc;  					} -				 -					tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; -					tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; -				} -				 -				*tex_coords++ = tc; -				if (do_bump) -				{ -					bump_tc.push_back(tc); -				} -			} - -			if (map_range) -			{ -				mVertexBuffer->flush(); -			} - -			if (do_bump) -			{ -				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); -		 -				for (S32 i = 0; i < num_vertices; i++) -				{ -					LLVector4a tangent; -					tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); - -					LLMatrix4a tangent_to_object; -					tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); -					LLVector4a t; -					tangent_to_object.rotate(binormal_dir, t); -					LLVector4a binormal; -					mat_normal.rotate(t, binormal); -						 -					//VECTORIZE THIS -					if (mDrawablep->isActive()) +					if (map_range)  					{ -						LLVector3 t; -						t.set(binormal.getF32ptr()); -						t *= bump_quat; -						binormal.load3(t.mV); +						mVertexBuffer->flush();  					} - -					binormal.normalize3fast(); -					LLVector2 tc = bump_tc[i]; -					tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); -					 -					*tex_coords2++ = tc; -				} - -				if (map_range) -				{ -					mVertexBuffer->flush();  				}  			}  		} -	} -	if (rebuild_pos) -	{ -		LLFastTimer t(FTM_FACE_GEOM_POSITION); -		llassert(num_vertices > 0); +		if (rebuild_pos) +		{ +			LLFastTimer t(FTM_FACE_GEOM_POSITION); +			llassert(num_vertices > 0); -		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); +			mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); -		LLMatrix4a mat_vert; -		mat_vert.loadu(mat_vert_in); +			LLMatrix4a mat_vert; +			mat_vert.loadu(mat_vert_in); -		LLVector4a* src = vf.mPositions; -		volatile F32* dst = (volatile F32*) vert.get(); +			LLVector4a* src = vf.mPositions; +			volatile F32* dst = (volatile F32*) vert.get(); -		volatile F32* end = dst+num_vertices*4; -		LLVector4a res; +			volatile F32* end = dst+num_vertices*4; +			LLVector4a res; -		LLVector4a texIdx; +			LLVector4a texIdx; -		U8 index = mTextureIndex < 255 ? mTextureIndex : 0; +			U8 index = mTextureIndex < 255 ? mTextureIndex : 0; -		F32 val = 0.f; -		U8* vp = (U8*) &val; -		vp[0] = index; -		vp[1] = 0; -		vp[2] = 0; -		vp[3] = 0; +			F32 val = 0.f; +			U8* vp = (U8*) &val; +			vp[0] = index; +			vp[1] = 0; +			vp[2] = 0; +			vp[3] = 0; -		llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); +			llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); -		LLVector4Logical mask; -		mask.clear(); -		mask.setElement<3>(); +			LLVector4Logical mask; +			mask.clear(); +			mask.setElement<3>(); -		texIdx.set(0,0,0,val); +			texIdx.set(0,0,0,val); -		{ -			LLFastTimer t(FTM_FACE_POSITION_STORE); -			LLVector4a tmp; - -			do -			{	 -				mat_vert.affineTransform(*src++, res); -				tmp.setSelectWithMask(mask, texIdx, res); -				tmp.store4a((F32*) dst); -				dst += 4; +			{ +				LLFastTimer t(FTM_FACE_POSITION_STORE); +				LLVector4a tmp; + +				do +				{	 +					mat_vert.affineTransform(*src++, res); +					tmp.setSelectWithMask(mask, texIdx, res); +					tmp.store4a((F32*) dst); +					dst += 4; +				} +				while(dst < end);  			} -			while(dst < end); -		} -		{ -			LLFastTimer t(FTM_FACE_POSITION_PAD); -			S32 aligned_pad_vertices = mGeomCount - num_vertices; -			res.set(res[0], res[1], res[2], 0.f); +			{ +				LLFastTimer t(FTM_FACE_POSITION_PAD); +				S32 aligned_pad_vertices = mGeomCount - num_vertices; +				res.set(res[0], res[1], res[2], 0.f); -			while (aligned_pad_vertices > 0) +				while (aligned_pad_vertices > 0) +				{ +					--aligned_pad_vertices; +					res.store4a((F32*) dst); +					dst += 4; +				} +			} + +			if (map_range)  			{ -				--aligned_pad_vertices; -				res.store4a((F32*) dst); -				dst += 4; +				mVertexBuffer->flush();  			}  		} -		if (map_range) -		{ -			mVertexBuffer->flush(); -		} -	} -	if (rebuild_normal) -	{ -		LLFastTimer t(FTM_FACE_GEOM_NORMAL); -		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); -		F32* normals = (F32*) norm.get(); +		if (rebuild_normal) +		{ +			LLFastTimer t(FTM_FACE_GEOM_NORMAL); +			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); +			F32* normals = (F32*) norm.get(); -		for (S32 i = 0; i < num_vertices; i++) -		{	 -			LLVector4a normal; -			mat_normal.rotate(vf.mNormals[i], normal); -			normal.normalize3fast(); -			normal.store4a(normals); -			normals += 4; -		} +			for (S32 i = 0; i < num_vertices; i++) +			{	 +				LLVector4a normal; +				mat_normal.rotate(vf.mNormals[i], normal); +				normal.normalize3fast(); +				normal.store4a(normals); +				normals += 4; +			} -		if (map_range) -		{ -			mVertexBuffer->flush(); +			if (map_range) +			{ +				mVertexBuffer->flush(); +			}  		} -	} -	if (rebuild_binormal) -	{ -		LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); -		F32* binormals = (F32*) binorm.get(); +		if (rebuild_binormal) +		{ +			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); +			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); +			F32* binormals = (F32*) binorm.get(); -		for (S32 i = 0; i < num_vertices; i++) -		{	 -			LLVector4a binormal; -			mat_normal.rotate(vf.mBinormals[i], binormal); -			binormal.normalize3fast(); -			binormal.store4a(binormals); -			binormals += 4; -		} +			for (S32 i = 0; i < num_vertices; i++) +			{	 +				LLVector4a binormal; +				mat_normal.rotate(vf.mBinormals[i], binormal); +				binormal.normalize3fast(); +				binormal.store4a(binormals); +				binormals += 4; +			} -		if (map_range) -		{ -			mVertexBuffer->flush(); +			if (map_range) +			{ +				mVertexBuffer->flush(); +			}  		} -	} -	if (rebuild_weights && vf.mWeights) -	{ -		LLFastTimer t(FTM_FACE_GEOM_WEIGHTS); -		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); -		F32* weights = (F32*) wght.get(); -		LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); -		if (map_range) +		if (rebuild_weights && vf.mWeights)  		{ -			mVertexBuffer->flush(); +			LLFastTimer t(FTM_FACE_GEOM_WEIGHTS); +			mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); +			F32* weights = (F32*) wght.get(); +			LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); +			if (map_range) +			{ +				mVertexBuffer->flush(); +			}  		} -	} -	if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) -	{ -		LLFastTimer t(FTM_FACE_GEOM_COLOR); -		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); +		if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) +		{ +			LLFastTimer t(FTM_FACE_GEOM_COLOR); +			mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); -		LLVector4a src; +			LLVector4a src; -		U32 vec[4]; -		vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; +			U32 vec[4]; +			vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; -		src.loadua((F32*) vec); +			src.loadua((F32*) vec); -		F32* dst = (F32*) colors.get(); -		S32 num_vecs = num_vertices/4; -		if (num_vertices%4 > 0) -		{ -			++num_vecs; -		} +			F32* dst = (F32*) colors.get(); +			S32 num_vecs = num_vertices/4; +			if (num_vertices%4 > 0) +			{ +				++num_vecs; +			} -		for (S32 i = 0; i < num_vecs; i++) -		{	 -			src.store4a(dst); -			dst += 4; -		} +			for (S32 i = 0; i < num_vecs; i++) +			{	 +				src.store4a(dst); +				dst += 4; +			} -		if (map_range) -		{ -			mVertexBuffer->flush(); +			if (map_range) +			{ +				mVertexBuffer->flush(); +			}  		} -	} -	if (rebuild_emissive) -	{ -		LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); -		LLStrider<LLColor4U> emissive; -		mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range); +		if (rebuild_emissive) +		{ +			LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); +			LLStrider<LLColor4U> emissive; +			mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range); -		U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); +			U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); -		LLVector4a src; +			LLVector4a src; -		U32 glow32 = glow | -					 (glow << 8) | -					 (glow << 16) | -					 (glow << 24); +			U32 glow32 = glow | +						 (glow << 8) | +						 (glow << 16) | +						 (glow << 24); -		U32 vec[4]; -		vec[0] = vec[1] = vec[2] = vec[3] = glow32; +			U32 vec[4]; +			vec[0] = vec[1] = vec[2] = vec[3] = glow32; -		src.loadua((F32*) vec); +			src.loadua((F32*) vec); -		F32* dst = (F32*) emissive.get(); -		S32 num_vecs = num_vertices/4; -		if (num_vertices%4 > 0) -		{ -			++num_vecs; -		} +			F32* dst = (F32*) emissive.get(); +			S32 num_vecs = num_vertices/4; +			if (num_vertices%4 > 0) +			{ +				++num_vecs; +			} -		for (S32 i = 0; i < num_vecs; i++) -		{	 -			src.store4a(dst); -			dst += 4; -		} +			for (S32 i = 0; i < num_vecs; i++) +			{	 +				src.store4a(dst); +				dst += 4; +			} -		if (map_range) -		{ -			mVertexBuffer->flush(); +			if (map_range) +			{ +				mVertexBuffer->flush(); +			}  		}  	} +  	if (rebuild_tcoord)  	{  		mTexExtents[0].setVec(0,0); @@ -1932,12 +2136,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	} -	mLastVertexBuffer = mVertexBuffer; -	mLastGeomCount = mGeomCount; -	mLastGeomIndex = mGeomIndex; -	mLastIndicesCount = mIndicesCount; -	mLastIndicesIndex = mIndicesIndex; -  	return TRUE;  } @@ -2516,7 +2714,6 @@ void LLFace::setVertexBuffer(LLVertexBuffer* buffer)  void LLFace::clearVertexBuffer()  {  	mVertexBuffer = NULL; -	mLastVertexBuffer = NULL;  }  //static diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 82e4ab61b7..3babc13c2e 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -79,10 +79,13 @@ public:  		USE_FACE_COLOR	= 0x0010,  		TEXTURE_ANIM	= 0x0020,   		RIGGED			= 0x0040, +		PARTICLE		= 0x0080,  	};  	static void initClass(); +	static void cacheFaceInVRAM(const LLVolumeFace& vf); +  public:  	LLFace(LLDrawable* drawablep, LLViewerObject* objp)   { init(drawablep, objp); }  	~LLFace()  { destroy(); } @@ -222,7 +225,7 @@ public:  	//vertex buffer tracking  	void setVertexBuffer(LLVertexBuffer* buffer); -	void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL +	void clearVertexBuffer(); //sets mVertexBuffer to NULL  	LLVertexBuffer* getVertexBuffer()	const	{ return mVertexBuffer; }  	U32 getRiggedVertexBufferDataMask() const;  	S32 getRiggedIndex(U32 type) const; @@ -255,8 +258,7 @@ public:  private:  	LLPointer<LLVertexBuffer> mVertexBuffer; -	LLPointer<LLVertexBuffer> mLastVertexBuffer; -	 +		  	U32			mState;  	LLFacePool*	mDrawPoolp;  	U32			mPoolType; @@ -269,12 +271,6 @@ private:  	U32			mIndicesIndex;		// index into draw pool for indices (yeah, I know!)  	S32         mIndexInTex ; -	//previous rebuild's geometry info -	U16			mLastGeomCount; -	U16			mLastGeomIndex; -	U32			mLastIndicesCount; -	U32			mLastIndicesIndex; -  	LLXformMatrix* mXform;  	LLPointer<LLViewerTexture> mTexture;  	LLPointer<LLDrawable> mDrawablep; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 575b613ccf..4cbc9cab4a 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -1191,7 +1191,7 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)  	}  	else if (action == "paste")  	{ -		pastFromClipboard(); +		pasteFromClipboard();  	}  	else if (action == "delete")  	{ @@ -1239,7 +1239,7 @@ BOOL LLFavoritesBarCtrl::isClipboardPasteable() const  	return TRUE;  } -void LLFavoritesBarCtrl::pastFromClipboard() const +void LLFavoritesBarCtrl::pasteFromClipboard() const  {  	LLInventoryModel* model = &gInventory;  	if(model && isClipboardPasteable()) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 2f75b3bb0e..447d30f1f4 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -90,7 +90,7 @@ protected:  	bool enableSelected(const LLSD& userdata);  	void doToSelected(const LLSD& userdata);  	BOOL isClipboardPasteable() const; -	void pastFromClipboard() const; +	void pasteFromClipboard() const;  	void showDropDownMenu(); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 32a533570a..c4dca4cb79 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -65,7 +65,7 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD  	mFrameNum = 0;  	mCollisionSphereRadius = 0.f;  	mRenderRes = 1; - +	  	if(mVO->mDrawable.notNull())  	{  		mVO->mDrawable->makeActive() ; @@ -255,50 +255,28 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons  {  } -//--------------------------------------------------------------------------------- -// This calculates the physics of the flexible object. Note that it has to be 0 -// updated every time step. In the future, perhaps there could be an  -// optimization similar to what Havok does for objects that are stationary.  -//--------------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); -BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ -	if (mVO->mDrawable.isNull()) -	{ -		// Don't do anything until we have a drawable -		return FALSE; // (we are not initialized or updated) -	} - -	BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; -	//flexible objects never go static -	mVO->mDrawable->mQuietCount = 0; -	if (!mVO->mDrawable->isRoot()) -	{ -		LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); -		parent->mDrawable->mQuietCount = 0; -	} +void LLVolumeImplFlexible::updateRenderRes() +{ +	LLDrawable* drawablep = mVO->mDrawable; -	LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); -		  	S32 new_res = mAttributes->getSimulateLOD(); -	//number of segments only cares about z axis -	F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); +#if 1 //optimal approximation of previous behavior that doesn't rely on atan2 +	F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera;  	// Rendering sections increases with visible angle on the screen -	mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView()); -	if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS) -	{ -		mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS; -	} - +	mRenderRes = (S32) (12.f*app_angle); +#else //legacy behavior +	//number of segments only cares about z axis +	F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); -	// Bottom cap at 1/4 the original number of sections -	if (mRenderRes < mAttributes->getSimulateLOD()-1) -	{ -		mRenderRes = mAttributes->getSimulateLOD()-1; -	} + 	// Rendering sections increases with visible angle on the screen +	mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView()); +#endif +		 +	mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS); +		  	// Throttle back simulation of segments we're not rendering  	if (mRenderRes < new_res)  	{ @@ -311,43 +289,65 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6  		setAttributesOfAllSections();  		mInitialized = TRUE;  	} -	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) -	{ -		return FALSE; // (we are not initialized or updated) -	} - -	bool visible = mVO->mDrawable->isVisible(); +} +//--------------------------------------------------------------------------------- +// This calculates the physics of the flexible object. Note that it has to be 0 +// updated every time step. In the future, perhaps there could be an  +// 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) +{ +	LLDrawable* drawablep = mVO->mDrawable; -	if (force_update && visible) +	if (drawablep)  	{ -		gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); -	} -	else if	(visible && -		!mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) && -		mVO->getPixelArea() > 256.f) -	{ -		U32 id; -		F32 pixel_area = mVO->getPixelArea(); +		//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); -		if (mVO->isRootEdit()) +		//flexible objects never go static +		drawablep->mQuietCount = 0; +		if (!drawablep->isRoot())  		{ -			id = mID; +			LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); +			parent->mDrawable->mQuietCount = 0;  		} -		else + +		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))  		{ -			LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); -			id = parent->getVolumeInterfaceID(); -		} +			bool visible = drawablep->isVisible(); -		U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; +			if ((mSimulateRes == 0) && visible) +			{ +				updateRenderRes(); +				gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); +			} +			else if	(visible && +				!drawablep->isState(LLDrawable::IN_REBUILD_Q1) && +				mVO->getPixelArea() > 256.f) +			{ +				U32 id; +				F32 pixel_area = mVO->getPixelArea(); -		if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) -		{ -			gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); +				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) +				{ +					updateRenderRes(); +					gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); +				} +			}  		}  	} -	 -	return force_update;  }  inline S32 log2(S32 x) @@ -368,8 +368,10 @@ void LLVolumeImplFlexible::doFlexibleUpdate()  	LLPath *path = &volume->getPath();  	if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())   	{ -		mVO->markForUpdate(TRUE); -		if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) +		//mVO->markForUpdate(TRUE); +		doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0); + +		if (mSimulateRes == 0)  		{  			return;	// we did not get updated or initialized, proceeding without can be dangerous  		} @@ -729,7 +731,11 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)  	else if (!mUpdated || rotated)  	{  		volume->mDrawable->setState(LLDrawable::REBUILD_POSITION); -		volume->dirtyMesh(); +		LLSpatialGroup* group = volume->mDrawable->getSpatialGroup(); +		if (group) +		{ +			group->dirtyMesh(); +		}  		volume->genBBoxes(isVolumeGlobal());  	} @@ -814,15 +820,17 @@ LLQuaternion LLVolumeImplFlexible::getEndRotation()  }//------------------------------------------------------------------ -void LLVolumeImplFlexible::updateRelativeXform() +void LLVolumeImplFlexible::updateRelativeXform(bool force_identity)  {  	LLQuaternion delta_rot;  	LLVector3 delta_pos, delta_scale;  	LLVOVolume* vo = (LLVOVolume*) mVO; +	bool use_identity = vo->mDrawable->isSpatialRoot() || force_identity; +  	//matrix from local space to parent relative/global space -	delta_rot = vo->mDrawable->isSpatialRoot() ? LLQuaternion() : vo->mDrawable->getRotation(); -	delta_pos = vo->mDrawable->isSpatialRoot() ? LLVector3(0,0,0) : vo->mDrawable->getPosition(); +	delta_rot = use_identity ? LLQuaternion() : vo->mDrawable->getRotation(); +	delta_pos = use_identity ? LLVector3(0,0,0) : vo->mDrawable->getPosition();  	delta_scale = LLVector3(1,1,1);  	// Vertex transform (4x4) diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index fef43d464d..56d579d86f 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -78,7 +78,8 @@ class LLVolumeImplFlexible : public LLVolumeInterface  		LLVector3 getFramePosition() const;  		LLQuaternion getFrameRotation() const;  		LLVolumeInterfaceType getInterfaceType() const		{ return INTERFACE_FLEXIBLE; } -		BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); +		void updateRenderRes(); +		void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);  		BOOL doUpdateGeometry(LLDrawable *drawable);  		LLVector3 getPivotPosition() const;  		void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); @@ -89,7 +90,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface  		bool isVolumeGlobal() const { return true; }  		bool isActive() const { return true; }  		const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; -		void updateRelativeXform(); +		void updateRelativeXform(bool force_identity);  		void doFlexibleUpdate(); // Called to update the simulation  		void doFlexibleRebuild(); // Called to rebuild the geometry  		void preRebuild(); @@ -128,7 +129,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface  		LLVector3					mCollisionSpherePosition;  		F32							mCollisionSphereRadius;  		U32							mID; - +		  		//--------------------------------------  		// private methods  		//-------------------------------------- diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index bca4b5e447..809d344d01 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -211,8 +211,8 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,  		BOOL item_is_multi = FALSE;  		if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED -			|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) -			&& !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK)) +		     || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) +		     && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))  		{  			item_is_multi = TRUE;  		} diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index ac33a05f42..fa0ad20fdb 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1124,9 +1124,13 @@ BOOL	LLPreviewAnimation::render()  		LLVertexBuffer::unbind();  		LLGLDepthTest gls_depth(GL_TRUE); -		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); -		avatarp->dirtyMesh(); -		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar +		LLFace* face = avatarp->mDrawable->getFace(0); +		if (face) +		{ +			LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); +			avatarp->dirtyMesh(); +			avatarPoolp->renderAvatars(avatarp);  // renders only one avatar +		}  	}  	gGL.color4f(1,1,1,1); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 92ee8ddac6..6b2492d927 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -704,9 +704,13 @@ BOOL LLImagePreviewAvatar::render()  		// make sure alpha=0 shows avatar material color  		LLGLDisable no_blend(GL_BLEND); -		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); -		gPipeline.enableLightsPreview(); -		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar +		LLFace* face = avatarp->mDrawable->getFace(0); +		if (face) +		{ +			LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); +			gPipeline.enableLightsPreview(); +			avatarPoolp->renderAvatars(avatarp);  // renders only one avatar +		}  	}  	gGL.popUIMatrix(); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index ee18c95b34..cc7c9a5bda 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1901,6 +1901,7 @@ BOOL LLPanelLandOptions::postBuild()  		mSnapshotCtrl->setCommitCallback( onCommitAny, this );  		mSnapshotCtrl->setAllowNoTexture ( TRUE );  		mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); +		mSnapshotCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);  		mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);  	}  	else @@ -2226,8 +2227,8 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)  	BOOL allow_damage		= !self->mCheckSafe->get();  	BOOL allow_fly			= self->mCheckFly->get();  	BOOL allow_landmark		= TRUE; // cannot restrict landmark creation -	BOOL allow_group_scripts	= self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get();  	BOOL allow_other_scripts	= self->mCheckOtherScripts->get(); +	BOOL allow_group_scripts	= self->mCheckGroupScripts->get() || allow_other_scripts;  	BOOL allow_publish		= FALSE;  	BOOL mature_publish		= self->mMatureCtrl->get();  	BOOL push_restriction	= self->mPushRestrictionCtrl->get(); @@ -2240,11 +2241,16 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)  	LLViewerRegion* region;  	region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); -	if (!allow_other_scripts && region && region->getAllowDamage()) -	{ - -		LLNotificationsUtil::add("UnableToDisableOutsideScripts"); -		return; +	if (region && region->getAllowDamage()) +	{	// Damage is allowed on the region - server will always allow scripts +		if ( (!allow_other_scripts && parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)) || +			 (!allow_group_scripts && parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)) ) +		{	// Don't allow turning off "Run Scripts" if damage is allowed in the region +			self->mCheckOtherScripts->set(parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS));	// Restore UI to actual settings +			self->mCheckGroupScripts->set(parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)); +			LLNotificationsUtil::add("UnableToDisableOutsideScripts"); +			return; +		}  	}  	// Push data into current parcel diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 7448f2bb2a..40d2157e28 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -396,7 +396,6 @@ mCalculateBtn(NULL)  	sInstance = this;  	mLastMouseX = 0;  	mLastMouseY = 0; -	mGLName = 0;  	mStatusLock = new LLMutex(NULL);  	mModelPreview = NULL; @@ -538,11 +537,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview()  		delete mModelPreview;  	} -	if (mGLName) -	{ -		LLImageGL::deleteTextures(1, &mGLName ); -	} -  	delete mStatusLock;  	mStatusLock = NULL;  } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 64324854a5..981f9b0f72 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -256,7 +256,6 @@ protected:  	S32				mLastMouseX;  	S32				mLastMouseY;  	LLRect			mPreviewRect; -	U32				mGLName;  	static S32		sUploadAmount;  	std::set<LLPointer<DecompRequest> > mCurRequest; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 1fa194ab19..0965b7b533 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -2236,12 +2236,16 @@ void LLFolderView::doIdle()  		arrangeAll();  	} +	mNeedsAutoSelect = mFilter->hasFilterString() && +							!(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture()); + +		  	if (mFilter->isModified() && mFilter->isNotDefault())  	{  		mNeedsAutoSelect = TRUE;  	}  	mFilter->clearModified(); - +			  	// filter to determine visibility before arranging  	filterFromRoot(); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 8092f3bf36..6e23d7c701 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -822,6 +822,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)  			{  				parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);  				new_item->setParent(parent_id); +				LLInventoryModel::update_list_t update; +				LLInventoryModel::LLCategoryUpdate new_folder(parent_id, 1); +				update.push_back(new_folder); +				accountForUpdate(update); +  			}  			item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, parent_id);  			if(item_array) diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 3a88fbd96d..f8088d04b4 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -60,6 +60,7 @@  #include "llworld.h"  #include "llui.h"  #include "pipeline.h" +#include "llviewershadermgr.h"  const S32 NUM_AXES = 3;  const S32 MOUSE_DRAG_SLOP = 2;       // pixels @@ -1580,7 +1581,11 @@ void LLManipTranslate::renderSnapGuides()  					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);  					LLGLEnable stipple(GL_LINE_STIPPLE);  					gGL.flush(); -					glLineStipple(1, 0x3333); + +					if (!LLGLSLShader::sNoFixedFunction) +					{ +						glLineStipple(1, 0x3333); +					}  					switch (mManipPart)  					{ @@ -1645,17 +1650,28 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,  											 LLQuaternion grid_rotation,   											 LLColor4 inner_color)  { -	if (!gSavedSettings.getBOOL("GridCrossSections")) +	if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction)  	{  		return;  	} +	 +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + +	  	U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };  	U32 num_types = LL_ARRAY_SIZE(types);  	GLuint stencil_mask = 0xFFFFFFFF;  	//stencil in volumes +  	gGL.flush(); + +	if (shader) +	{ +		gClipProgram.bind(); +	} +		  	{  		glStencilMask(stencil_mask);  		glClearStencil(1); @@ -1666,6 +1682,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,  		glStencilFunc(GL_ALWAYS, 0, stencil_mask);  		gGL.setColorMask(false, false);  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +  		gGL.diffuseColor4f(1,1,1,1);  		//setup clip plane @@ -1675,10 +1692,12 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,  			normal = -normal;  		}  		F32 d = -(selection_center * normal); -		F64 plane[] = { normal.mV[0], normal.mV[1], normal.mV[2], d }; -		LLGLEnable clip(GL_CLIP_PLANE0); -		glClipPlane(GL_CLIP_PLANE0, plane); +		glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d ); + +		gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane); +		gClipProgram.uniform4fv("clip_plane", 1, plane.v); +		  		BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);  		BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS); @@ -1729,6 +1748,11 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,  	F32 sz = mGridSizeMeters;  	F32 tiles = sz; +	if (shader) +	{ +		shader->bind(); +	} +  	//draw volume/plane intersections  	{  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index c899e8991e..bc7f522848 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1659,7 +1659,7 @@ void LLMeshUploadThread::requestWholeModelFee()  		mCurlRequest->process();  		//sleep for 10ms to prevent eating a whole core  		apr_sleep(10000); -	} while (mCurlRequest->getQueued() > 0); +	} while (!LLApp::isQuitting() && mCurlRequest->getQueued() > 0);  	delete mCurlRequest;  	mCurlRequest = NULL; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 03404e816b..d58d6d536c 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -574,6 +574,7 @@ static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const L                  texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);                  // Don't allow (no copy) or (notransfer) textures to be selected.                  texture_ctrl->setImmediateFilterPermMask(PERM_NONE); +                texture_ctrl->setDnDFilterPermMask(PERM_NONE);                  texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);          }  } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7301b305b2..3e29805446 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,6 +38,7 @@  #include "llfontgl.h"  // project includes +#include "llagentdata.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcolorswatch.h" @@ -46,6 +47,7 @@  #include "llface.h"  #include "lllineeditor.h"  #include "llmediaentry.h" +#include "llnotificationsutil.h"  #include "llresmgr.h"  #include "llselectmgr.h"  #include "llspinctrl.h" @@ -104,27 +106,11 @@ BOOL	LLPanelFace::postBuild()  		mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );  		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );  		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); +		mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));  		mTextureCtrl->setFollowsTop();  		mTextureCtrl->setFollowsLeft(); -		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode -		mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); -		// Allow any texture to be used during non-immediate mode. -		mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE); -		LLAggregatePermissions texture_perms; -		if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) -		{ -			BOOL can_copy =  -				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||  -				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; -			BOOL can_transfer =  -				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||  -				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; -			mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer); -		} -		else -		{ -			mTextureCtrl->setCanApplyImmediately(FALSE); -		} +		mTextureCtrl->setImmediateFilterPermMask(PERM_NONE); +		mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);  	}  	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); @@ -595,28 +581,6 @@ void LLPanelFace::getState()  		} -		LLAggregatePermissions texture_perms; -		if(texture_ctrl) -		{ -// 			texture_ctrl->setValid( editable ); -		 -			if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) -			{ -				BOOL can_copy =  -					texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||  -					texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; -				BOOL can_transfer =  -					texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||  -					texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; -				texture_ctrl->setCanApplyImmediately(can_copy && can_transfer); -			} -			else -			{ -				texture_ctrl->setCanApplyImmediately(FALSE); -			} -		} - -  		// planar align  		bool align_planar = false;  		bool identical_planar_aligned = false; @@ -1190,3 +1154,35 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)  	self->sendTextureInfo();  } +void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) +{ +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); +	if (texture_ctrl) +	{ +		LLUUID obj_owner_id; +		std::string obj_owner_name; +		LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name); + +		LLSaleInfo sale_info; +		LLSelectMgr::instance().selectGetSaleInfo(sale_info); + +		bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? +		bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? +		bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent? +		bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale? + +		if (can_copy && can_transfer) +		{ +			texture_ctrl->setCanApply(true, true); +			return; +		} + +		// if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale +		texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale); + +		if (gSavedSettings.getBOOL("TextureLivePreview")) +		{ +			LLNotificationsUtil::add("LivePreviewUnavailable"); +		} +	} +} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 42be9b257f..3b5a9b1398 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -91,6 +91,15 @@ protected:  	static void		onClickAutoFix(void*);  	static F32      valueGlow(LLViewerObject* object, S32 face); +private: + +	/* +	 * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. +	 * If agent selects texture which is not allowed to be applied for the currently selected object, +	 * all controls of the floater texture picker which allow to apply the texture will be disabled. +	 */ +	void onTextureSelectionChanged(LLInventoryItem* itemp); +  };  #endif diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp index b3adfac8a2..26cd3ff1c1 100644 --- a/indra/newview/llpanellandmedia.cpp +++ b/indra/newview/llpanellandmedia.cpp @@ -85,6 +85,7 @@ BOOL LLPanelLandMedia::postBuild()  	mMediaTextureCtrl->setCommitCallback( onCommitAny, this );  	mMediaTextureCtrl->setAllowNoTexture ( TRUE );  	mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); +	mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);  	mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);  	mMediaAutoScaleCheck = getChild<LLCheckBoxCtrl>("media_auto_scale"); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 1f77e7a602..7dfe529b73 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -245,6 +245,7 @@ BOOL	LLPanelObject::postBuild()  		mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));  		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode  		mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); +		mCtrlSculptTexture->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);  		// Allow any texture to be used during non-immediate mode.  		mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);  		LLAggregatePermissions texture_perms; diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index e124916c48..cb6989c9dd 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -67,6 +67,19 @@ inline F64 llsgn(const F64 a)  class LLPhysicsMotion  {  public: +	typedef enum +	{ +		SMOOTHING = 0, +		MASS, +		GRAVITY, +		SPRING, +		GAIN, +		DAMPING, +		DRAG, +		MAX_EFFECT, +		NUM_PARAMS +	} eParamName; +          /*            param_driver_name: The param that controls the params that are being affected by the physics.            joint_name: The joint that the body part is attached to.  The joint is @@ -98,6 +111,11 @@ public:                  mPositionLastUpdate_local(0)          {                  mJointState = new LLJointState; + +				for (U32 i = 0; i < NUM_PARAMS; ++i) +				{ +					mParamCache[i] = NULL; +				}          }          BOOL initialize(); @@ -111,16 +129,43 @@ public:                  return mJointState;          }  protected: -        F32 getParamValue(const std::string& controller_key) -        { -                const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); + +		F32 getParamValue(eParamName param) +		{ +			static std::string controller_key[] =  +			{ +				"Smoothing", +				"Mass", +				"Gravity", +				"Spring", +				"Gain", +				"Damping", +				"Drag", +				"MaxEffect" +			}; + +			if (!mParamCache[param]) +			{ +				const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key[param]);                  if (entry == mParamControllers.end())                  { -                        return sDefaultController[controller_key]; +                        return sDefaultController[controller_key[param]];                  }                  const std::string& param_name = (*entry).second.c_str(); -                return mCharacter->getVisualParamWeight(param_name.c_str()); -        } +                mParamCache[param] = mCharacter->getVisualParam(param_name.c_str()); +			} +				 +			if (mParamCache[param]) +			{ +				return mParamCache[param]->getWeight(); +			} +			else +			{ +				return sDefaultController[controller_key[param]]; +			} +		} + +                  void setParamValue(LLViewerVisualParam *param,                             const F32 new_value_local,                                                     F32 behavior_maxeffect); @@ -150,6 +195,8 @@ private:          F32 mLastTime; +		LLVisualParam* mParamCache[NUM_PARAMS]; +          static default_controller_map_t sDefaultController;  }; @@ -427,7 +474,6 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask)          return TRUE;  } -  // Return TRUE if character has to update visual params.  BOOL LLPhysicsMotion::onUpdate(F32 time)  { @@ -471,15 +517,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)          LLJoint *joint = mJointState->getJoint(); -        const F32 behavior_mass = getParamValue("Mass"); -        const F32 behavior_gravity = getParamValue("Gravity"); -        const F32 behavior_spring = getParamValue("Spring"); -        const F32 behavior_gain = getParamValue("Gain"); -        const F32 behavior_damping = getParamValue("Damping"); -        const F32 behavior_drag = getParamValue("Drag"); -        const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts. +		const F32 behavior_mass = getParamValue(MASS); +		const F32 behavior_gravity = getParamValue(GRAVITY); +		const F32 behavior_spring = getParamValue(SPRING); +		const F32 behavior_gain = getParamValue(GAIN); +		const F32 behavior_damping = getParamValue(DAMPING); +		const F32 behavior_drag = getParamValue(DRAG); +		F32 behavior_maxeffect = getParamValue(MAX_EFFECT); +		 +		const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts. -        F32 behavior_maxeffect = getParamValue("MaxEffect");          if (physics_test)                  behavior_maxeffect = 1.0f; diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 450f9b2be7..3baa1eccc8 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -229,15 +229,18 @@ U32 LLPolyMeshSharedData::getNumKB()  BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )  {          U32 i; -        mBaseCoords = new LLVector3[ numVertices ]; -        mBaseNormals = new LLVector3[ numVertices ]; -        mBaseBinormals = new LLVector3[ numVertices ]; +        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++)          { -                mWeights[i] = 0.f; +			mBaseCoords[i].clear(); +			mBaseNormals[i].clear(); +			mBaseBinormals[i].clear(); +            mWeights[i] = 0.f;          }          mNumVertices = numVertices;          return TRUE; @@ -408,39 +411,47 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )                          allocateVertexData( numVertices );       -                        //---------------------------------------------------------------- -                        // Coords -                        //---------------------------------------------------------------- -                        numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp); -                        llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices); -                        if (numRead != numVertices) -                        { -                                llerrs << "can't read Coordinates from " << fileName << llendl; -                                return FALSE; -                        } - -                        //---------------------------------------------------------------- -                        // Normals -                        //---------------------------------------------------------------- -                        numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp); -                        llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices); -                        if (numRead != numVertices) -                        { -                                llerrs << " can't read Normals from " << fileName << llendl; -                                return FALSE; -                        } - -                        //---------------------------------------------------------------- -                        // Binormals -                        //---------------------------------------------------------------- -                        numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp); -                        llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices); -                        if (numRead != numVertices) -                        { -                                llerrs << " can't read Binormals from " << fileName << llendl; -                                return FALSE; -                        } - +						for (U16 i = 0; i < numVertices; ++i) +						{ +							//---------------------------------------------------------------- +							// Coords +							//---------------------------------------------------------------- +							numRead = fread(&mBaseCoords[i], sizeof(float), 3, fp); +							llendianswizzle(&mBaseCoords[i], sizeof(float), 3); +							if (numRead != 3) +							{ +									llerrs << "can't read Coordinates from " << fileName << llendl; +									return FALSE; +							} +						} + +						for (U16 i = 0; i < numVertices; ++i) +						{ +							//---------------------------------------------------------------- +							// Normals +							//---------------------------------------------------------------- +							numRead = fread(&mBaseNormals[i], sizeof(float), 3, fp); +							llendianswizzle(&mBaseNormals[i], sizeof(float), 3); +							if (numRead != 3) +							{ +									llerrs << " can't read Normals from " << fileName << llendl; +									return FALSE; +							} +						} + +						for (U16 i = 0; i < numVertices; ++i) +						{ +							//---------------------------------------------------------------- +							// Binormals +							//---------------------------------------------------------------- +							numRead = fread(&mBaseBinormals[i], sizeof(float), 3, fp); +							llendianswizzle(&mBaseBinormals[i], sizeof(float), 3); +							if (numRead != 3) +							{ +									llerrs << " can't read Binormals from " << fileName << llendl; +									return FALSE; +							} +						}                          //----------------------------------------------------------------                          // TexCoords @@ -767,21 +778,28 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_  	{  		// Allocate memory without initializing every vector  		// NOTE: This makes asusmptions about the size of LLVector[234] -		int nverts = mSharedData->mNumVertices; -		int nfloats = nverts * (2*4 + 3*3 + 2 + 4); +		S32 nverts = mSharedData->mNumVertices; +		//make sure it's an even number of verts for alignment +		nverts += nverts%2; +		S32 nfloats = nverts * ( +					4 + //coords +					4 + //normals +					4 + //weights +					2 + //coords +					4 + //scaled normals +					4 + //binormals +					4); //scaled binormals +  		//use 16 byte aligned vertex data to make LLPolyMesh SSE friendly  		mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4); -		int offset = 0; -		mCoords				= 	(LLVector4*)(mVertexData + offset); offset += 4*nverts; -		mNormals			=	(LLVector4*)(mVertexData + offset); offset += 4*nverts; -		mClothingWeights	= 	(LLVector4*)(mVertexData + offset); offset += 4*nverts; -		mTexCoords			= 	(LLVector2*)(mVertexData + offset); offset += 2*nverts; - -		// these members don't need to be 16-byte aligned, but the first one might be -		// read during an aligned memcpy of mTexCoords -		mScaledNormals =                (LLVector3*)(mVertexData + offset); offset += 3*nverts; -		mBinormals =                    (LLVector3*)(mVertexData + offset); offset += 3*nverts; -		mScaledBinormals =              (LLVector3*)(mVertexData + offset); offset += 3*nverts;  +		S32 offset = 0; +		mCoords				= 	(LLVector4a*)(mVertexData + offset); offset += 4*nverts; +		mNormals			=	(LLVector4a*)(mVertexData + offset); offset += 4*nverts; +		mClothingWeights	= 	(LLVector4a*)(mVertexData + offset); offset += 4*nverts; +		mTexCoords			= 	(LLVector2*)(mVertexData + offset);  offset += 2*nverts; +		mScaledNormals		=   (LLVector4a*)(mVertexData + offset); offset += 4*nverts; +		mBinormals			=   (LLVector4a*)(mVertexData + offset); offset += 4*nverts; +		mScaledBinormals	=   (LLVector4a*)(mVertexData + offset); offset += 4*nverts;   		initializeForMorph();  	}  } @@ -906,7 +924,7 @@ void LLPolyMesh::dumpDiagInfo()  //-----------------------------------------------------------------------------  // getWritableCoords()  //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableCoords() +LLVector4a *LLPolyMesh::getWritableCoords()  {          return mCoords;  } @@ -914,7 +932,7 @@ LLVector4 *LLPolyMesh::getWritableCoords()  //-----------------------------------------------------------------------------  // getWritableNormals()  //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableNormals() +LLVector4a *LLPolyMesh::getWritableNormals()  {          return mNormals;  } @@ -922,7 +940,7 @@ LLVector4 *LLPolyMesh::getWritableNormals()  //-----------------------------------------------------------------------------  // getWritableBinormals()  //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableBinormals() +LLVector4a *LLPolyMesh::getWritableBinormals()  {          return mBinormals;  } @@ -931,7 +949,7 @@ LLVector3 *LLPolyMesh::getWritableBinormals()  //-----------------------------------------------------------------------------  // getWritableClothingWeights()  //----------------------------------------------------------------------------- -LLVector4       *LLPolyMesh::getWritableClothingWeights() +LLVector4a       *LLPolyMesh::getWritableClothingWeights()  {          return mClothingWeights;  } @@ -947,7 +965,7 @@ LLVector2       *LLPolyMesh::getWritableTexCoords()  //-----------------------------------------------------------------------------  // getScaledNormals()  //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getScaledNormals() +LLVector4a *LLPolyMesh::getScaledNormals()  {          return mScaledNormals;  } @@ -955,7 +973,7 @@ LLVector3 *LLPolyMesh::getScaledNormals()  //-----------------------------------------------------------------------------  // getScaledBinormals()  //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getScaledBinormals() +LLVector4a *LLPolyMesh::getScaledBinormals()  {          return mScaledBinormals;  } @@ -966,17 +984,17 @@ LLVector3 *LLPolyMesh::getScaledBinormals()  //-----------------------------------------------------------------------------  void LLPolyMesh::initializeForMorph()  { -    for (U32 i = 0; i < mSharedData->mNumVertices; ++i) +    LLVector4a::memcpyNonAliased16((F32*) mCoords, (F32*) mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices); +	LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); +	LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2)); + +	for (U32 i = 0; i < mSharedData->mNumVertices; ++i)  	{ -		mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]); -		mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]); +		mClothingWeights[i].clear();  	} - -	memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices);	/*Flawfinder: ignore*/ -	memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices);	/*Flawfinder: ignore*/ -	memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices);		/*Flawfinder: ignore*/ -	memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices);		/*Flawfinder: ignore*/ -	memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);  }  //----------------------------------------------------------------------------- @@ -1098,7 +1116,7 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)  LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)  {          mAvatar = avatarp; -        mDefaultVec.setVec(0.001f, 0.001f, 0.001f); +        mDefaultVec.splat(0.001f);  }  //----------------------------------------------------------------------------- @@ -1171,8 +1189,12 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)  //-----------------------------------------------------------------------------  // apply()  //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); +  void LLPolySkeletalDistortion::apply( ESex avatar_sex )  { +	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY); +          F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();          LLJoint* joint; @@ -1228,11 +1250,14 @@ LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,  {          LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);          cloned_morph_data->mName = name; +		LLVector4a dir; +		dir.load3(direction.mV); +          for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)          { -                cloned_morph_data->mCoords[v] = direction; -                cloned_morph_data->mNormals[v] = LLVector3(0,0,0); -                cloned_morph_data->mBinormals[v] = LLVector3(0,0,0); +                cloned_morph_data->mCoords[v] = dir; +                cloned_morph_data->mNormals[v].clear(); +                cloned_morph_data->mBinormals[v].clear();          }          return cloned_morph_data;  } @@ -1243,17 +1268,27 @@ LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,  {          LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);          cloned_morph_data->mName = name; + +		LLVector4a sc; +		sc.splat(scale); + +		LLVector4a nsc; +		nsc.set(scale, -scale, scale, scale); +          for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)          { -                cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale; -                cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale; -                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale; -                if (cloned_morph_data->mCoords[v][1] < 0) -                { -                        cloned_morph_data->mCoords[v][1] *= -1; -                        cloned_morph_data->mNormals[v][1] *= -1; -                        cloned_morph_data->mBinormals[v][1] *= -1; -                } +            if (cloned_morph_data->mCoords[v][1] < 0) +            { +                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); +				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); +				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); +			} +			else +			{ +				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); +				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); +				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); +			}          }          return cloned_morph_data;  } diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index ba2bf85570..ffb11a3f7e 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -73,9 +73,9 @@ private:  	// vertex data			  	S32						mNumVertices; -	LLVector3				*mBaseCoords; -	LLVector3				*mBaseNormals; -	LLVector3				*mBaseBinormals; +	LLVector4a				*mBaseCoords; +	LLVector4a				*mBaseNormals; +	LLVector4a				*mBaseBinormals;  	LLVector2				*mTexCoords;  	LLVector2				*mDetailTexCoords;  	F32						*mWeights; @@ -217,41 +217,41 @@ public:  	}  	// Get coords -	const LLVector4	*getCoords() const{ +	const LLVector4a	*getCoords() const{  		return mCoords;  	}  	// non const version -	LLVector4 *getWritableCoords(); +	LLVector4a *getWritableCoords();  	// Get normals -	const LLVector4	*getNormals() const{  +	const LLVector4a	*getNormals() const{   		return mNormals;   	}  	// Get normals -	const LLVector3	*getBinormals() const{  +	const LLVector4a	*getBinormals() const{   		return mBinormals;   	}  	// Get base mesh normals -	const LLVector3 *getBaseNormals() const{ +	const LLVector4a *getBaseNormals() const{  		llassert(mSharedData);  		return mSharedData->mBaseNormals;  	}  	// Get base mesh normals -	const LLVector3 *getBaseBinormals() const{ +	const LLVector4a *getBaseBinormals() const{  		llassert(mSharedData);  		return mSharedData->mBaseBinormals;  	}  	// intermediate morphed normals and output normals -	LLVector4 *getWritableNormals(); -	LLVector3 *getScaledNormals(); +	LLVector4a *getWritableNormals(); +	LLVector4a *getScaledNormals(); -	LLVector3 *getWritableBinormals(); -	LLVector3 *getScaledBinormals(); +	LLVector4a *getWritableBinormals(); +	LLVector4a *getScaledBinormals();  	// Get texCoords  	const LLVector2	*getTexCoords() const {  @@ -275,9 +275,9 @@ public:  	F32			*getWritableWeights() const; -	LLVector4	*getWritableClothingWeights(); +	LLVector4a	*getWritableClothingWeights(); -	const LLVector4		*getClothingWeights() +	const LLVector4a		*getClothingWeights()  	{  		return mClothingWeights;	  	} @@ -341,17 +341,17 @@ protected:  	// Single array of floats for allocation / deletion  	F32						*mVertexData;  	// deformed vertices (resulting from application of morph targets) -	LLVector4				*mCoords; +	LLVector4a				*mCoords;  	// deformed normals (resulting from application of morph targets) -	LLVector3				*mScaledNormals; +	LLVector4a				*mScaledNormals;  	// output normals (after normalization) -	LLVector4				*mNormals; +	LLVector4a				*mNormals;  	// deformed binormals (resulting from application of morph targets) -	LLVector3				*mScaledBinormals; +	LLVector4a				*mScaledBinormals;  	// output binormals (after normalization) -	LLVector3				*mBinormals; +	LLVector4a				*mBinormals;  	// weight values that mark verts as clothing/skin -	LLVector4				*mClothingWeights; +	LLVector4a				*mClothingWeights;  	// output texture coordinates  	LLVector2				*mTexCoords; @@ -419,17 +419,17 @@ public:  	// LLViewerVisualParam Virtual functions  	/*virtual*/ F32					getTotalDistortion() { return 0.1f; } -	/*virtual*/ const LLVector3&	getAvgDistortion()	{ return mDefaultVec; } +	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; }  	/*virtual*/ F32					getMaxDistortion() { return 0.1f; } -	/*virtual*/ LLVector3			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);} -	/*virtual*/ const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; -	/*virtual*/ const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};  protected:  	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;  	joint_vec_map_t mJointScales;  	joint_vec_map_t mJointOffsets; -	LLVector3	mDefaultVec; +	LLVector4a	mDefaultVec;  	// Backlink only; don't make this an LLPointer.  	LLVOAvatar *mAvatar;  }; diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index cefd7df3fe..d25d1420ee 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -48,7 +48,7 @@ LLPolyMorphData::LLPolyMorphData(const std::string& morph_name)  	mNumIndices = 0;  	mCurrentIndex = 0;  	mTotalDistortion = 0.f; -	mAvgDistortion.zeroVec(); +	mAvgDistortion.clear();  	mMaxDistortion = 0.f;  	mVertexIndices = NULL;  	mCoords = NULL; @@ -73,9 +73,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :  {  	const S32 numVertices = mNumIndices; -	mCoords = new LLVector3[numVertices]; -	mNormals = new LLVector3[numVertices]; -	mBinormals = new LLVector3[numVertices]; +	mCoords = new LLVector4a[numVertices]; +	mNormals = new LLVector4a[numVertices]; +	mBinormals = new LLVector4a[numVertices];  	mTexCoords = new LLVector2[numVertices];  	mVertexIndices = new U32[numVertices]; @@ -121,16 +121,16 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)  	//-------------------------------------------------------------------------  	// allocate vertices  	//------------------------------------------------------------------------- -	mCoords = new LLVector3[numVertices]; -	mNormals = new LLVector3[numVertices]; -	mBinormals = new LLVector3[numVertices]; +	mCoords = new LLVector4a[numVertices]; +	mNormals = new LLVector4a[numVertices]; +	mBinormals = new LLVector4a[numVertices];  	mTexCoords = new LLVector2[numVertices];  	// Actually, we are allocating more space than we need for the skiplist  	mVertexIndices = new U32[numVertices];  	mNumIndices = 0;  	mTotalDistortion = 0.f;  	mMaxDistortion = 0.f; -	mAvgDistortion.zeroVec(); +	mAvgDistortion.clear();  	mMesh = mesh;  	//------------------------------------------------------------------------- @@ -152,36 +152,36 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)  		} -		numRead = fread(&mCoords[v].mV, sizeof(F32), 3, fp); -		llendianswizzle(&mCoords[v].mV, sizeof(F32), 3); +		numRead = fread(&mCoords[v], sizeof(F32), 3, fp); +		llendianswizzle(&mCoords[v], sizeof(F32), 3);  		if (numRead != 3)  		{  			llwarns << "Can't read morph target vertex coordinates" << llendl;  			return FALSE;  		} -		F32 magnitude = mCoords[v].magVec(); +		F32 magnitude = mCoords[v].getLength3().getF32();  		mTotalDistortion += magnitude; -		mAvgDistortion.mV[VX] += fabs(mCoords[v].mV[VX]); -		mAvgDistortion.mV[VY] += fabs(mCoords[v].mV[VY]); -		mAvgDistortion.mV[VZ] += fabs(mCoords[v].mV[VZ]); +		LLVector4a t; +		t.setAbs(mCoords[v]); +		mAvgDistortion.add(t);  		if (magnitude > mMaxDistortion)  		{  			mMaxDistortion = magnitude;  		} -		numRead = fread(&mNormals[v].mV, sizeof(F32), 3, fp); -		llendianswizzle(&mNormals[v].mV, sizeof(F32), 3); +		numRead = fread(&mNormals[v], sizeof(F32), 3, fp); +		llendianswizzle(&mNormals[v], sizeof(F32), 3);  		if (numRead != 3)  		{  			llwarns << "Can't read morph target normal" << llendl;  			return FALSE;  		} -		numRead = fread(&mBinormals[v].mV, sizeof(F32), 3, fp); -		llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3); +		numRead = fread(&mBinormals[v], sizeof(F32), 3, fp); +		llendianswizzle(&mBinormals[v], sizeof(F32), 3);  		if (numRead != 3)  		{  			llwarns << "Can't read morph target binormal" << llendl; @@ -200,8 +200,8 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)  		mNumIndices++;  	} -	mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices); -	mAvgDistortion.normVec(); +	mAvgDistortion.mul(1.f/(F32)mNumIndices); +	mAvgDistortion.normalize3fast();  	return TRUE;  } @@ -367,9 +367,9 @@ BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node)  //-----------------------------------------------------------------------------  // getVertexDistortion()  //----------------------------------------------------------------------------- -LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) +LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)  { -	if (!mMorphData || mMesh != mesh) return LLVector3::zero; +	if (!mMorphData || mMesh != mesh) return LLVector4a::getZero();  	for(U32 index = 0; index < mMorphData->mNumIndices; index++)  	{ @@ -379,17 +379,17 @@ LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh  		}  	} -	return LLVector3::zero; +	return LLVector4a::getZero();  }  //-----------------------------------------------------------------------------  // getFirstDistortion()  //----------------------------------------------------------------------------- -const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)  { -	if (!mMorphData) return &LLVector3::zero; +	if (!mMorphData) return &LLVector4a::getZero(); -	LLVector3* resultVec; +	LLVector4a* resultVec;  	mMorphData->mCurrentIndex = 0;  	if (mMorphData->mNumIndices)  	{ @@ -411,11 +411,11 @@ const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **  //-----------------------------------------------------------------------------  // getNextDistortion()  //----------------------------------------------------------------------------- -const LLVector3 *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)  { -	if (!mMorphData) return &LLVector3::zero; +	if (!mMorphData) return &LLVector4a::getZero(); -	LLVector3* resultVec; +	LLVector4a* resultVec;  	mMorphData->mCurrentIndex++;  	if (mMorphData->mCurrentIndex < mMorphData->mNumIndices)  	{ @@ -451,7 +451,7 @@ F32	LLPolyMorphTarget::getTotalDistortion()  //-----------------------------------------------------------------------------  // getAvgDistortion()  //----------------------------------------------------------------------------- -const LLVector3& LLPolyMorphTarget::getAvgDistortion()	 +const LLVector4a& LLPolyMorphTarget::getAvgDistortion()	  {  	if (mMorphData)   	{ @@ -459,7 +459,7 @@ const LLVector3& LLPolyMorphTarget::getAvgDistortion()  	}  	else   	{ -		return LLVector3::zero; +		return LLVector4a::getZero();  	}  } @@ -481,6 +481,8 @@ F32	LLPolyMorphTarget::getMaxDistortion()  //-----------------------------------------------------------------------------  // apply()  //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph"); +  void LLPolyMorphTarget::apply( ESex avatar_sex )  {  	if (!mMorphData || mNumMorphMasksPending > 0) @@ -488,6 +490,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )  		return;  	} +	LLFastTimer t(FTM_APPLY_MORPH_TARGET); +  	mLastSex = avatar_sex;  	// Check for NaN condition (NaN is detected if a variable doesn't equal itself. @@ -508,15 +512,15 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )  	if (delta_weight != 0.f)  	{  		llassert(!mMesh->isLOD()); -		LLVector4 *coords = mMesh->getWritableCoords(); +		LLVector4a *coords = mMesh->getWritableCoords(); -		LLVector3 *scaled_normals = mMesh->getScaledNormals(); -		LLVector4 *normals = mMesh->getWritableNormals(); +		LLVector4a *scaled_normals = mMesh->getScaledNormals(); +		LLVector4a *normals = mMesh->getWritableNormals(); -		LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); -		LLVector3 *binormals = mMesh->getWritableBinormals(); +		LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); +		LLVector4a *binormals = mMesh->getWritableBinormals(); -		LLVector4 *clothing_weights = mMesh->getWritableClothingWeights(); +		LLVector4a *clothing_weights = mMesh->getWritableClothingWeights();  		LLVector2 *tex_coords = mMesh->getWritableTexCoords();  		F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; @@ -531,31 +535,38 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )  				maskWeight = maskWeightArray[vert_index_morph];  			} -			coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); + +			LLVector4a pos = mMorphData->mCoords[vert_index_morph]; +			pos.mul(delta_weight*maskWeight); +			coords[vert_index_mesh].add(pos);  			if (getInfo()->mIsClothingMorph && clothing_weights)  			{ -				LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; -				LLVector4* clothing_weight = &clothing_weights[vert_index_mesh]; -				clothing_weight->mV[VX] += clothing_offset.mV[VX]; -				clothing_weight->mV[VY] += clothing_offset.mV[VY]; -				clothing_weight->mV[VZ] += clothing_offset.mV[VZ]; -				clothing_weight->mV[VW] = maskWeight; +				LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph]; +				clothing_offset.mul(delta_weight * maskWeight); +				LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh]; +				clothing_weight->add(clothing_offset); +				clothing_weight->getF32ptr()[VW] = maskWeight;  			}  			// calculate new normals based on half angles -			scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; -			LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; -			normalized_normal.normVec(); -			normals[vert_index_mesh] = LLVector4(normalized_normal); +			LLVector4a norm = mMorphData->mNormals[vert_index_morph]; +			norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); +			scaled_normals[vert_index_mesh].add(norm); +			norm = scaled_normals[vert_index_mesh]; +			norm.normalize3fast(); +			normals[vert_index_mesh] = norm;  			// calculate new binormals -			scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; -			LLVector3 tangent = scaled_binormals[vert_index_mesh] % normalized_normal; -			LLVector3 normalized_binormal = normalized_normal % tangent;  -			normalized_binormal.normVec(); -			binormals[vert_index_mesh] = normalized_binormal; - +			LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; +			binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); +			scaled_binormals[vert_index_mesh].add(binorm); +			LLVector4a tangent; +			tangent.setCross3(scaled_binormals[vert_index_mesh], norm); +			LLVector4a& normalized_binormal = binormals[vert_index_mesh]; +			normalized_binormal.setCross3(norm, tangent);  +			normalized_binormal.normalize3fast(); +			  			tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;  		} @@ -582,7 +593,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )  //-----------------------------------------------------------------------------  void	LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)  { -	LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; +	LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;  	if (!mVertMask)  	{ @@ -596,29 +607,47 @@ void	LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3  		if (maskWeights)  		{ -			LLVector4 *coords = mMesh->getWritableCoords(); -			LLVector3 *scaled_normals = mMesh->getScaledNormals(); -			LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); +			LLVector4a *coords = mMesh->getWritableCoords(); +			LLVector4a *scaled_normals = mMesh->getScaledNormals(); +			LLVector4a *scaled_binormals = mMesh->getScaledBinormals();  			LLVector2 *tex_coords = mMesh->getWritableTexCoords(); +			LLVector4Logical clothing_mask; +			clothing_mask.clear(); +			clothing_mask.setElement<0>(); +			clothing_mask.setElement<1>(); +			clothing_mask.setElement<2>(); + +  			for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)  			{  				F32 lastMaskWeight = mLastWeight * maskWeights[vert];  				S32 out_vert = mMorphData->mVertexIndices[vert];  				// remove effect of existing masked morph -				coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight; -				scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; -				scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; +				LLVector4a t; +				t = mMorphData->mCoords[vert]; +				t.mul(lastMaskWeight); +				coords[out_vert].sub(t); + +				t = mMorphData->mNormals[vert]; +				t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); +				scaled_normals[out_vert].sub(t); + +				t = mMorphData->mBinormals[vert]; +				t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); +				scaled_binormals[out_vert].sub(t); +  				tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight;  				if (clothing_weights)  				{ -					LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight; -					LLVector4* clothing_weight = &clothing_weights[out_vert]; -					clothing_weight->mV[VX] -= clothing_offset.mV[VX]; -					clothing_weight->mV[VY] -= clothing_offset.mV[VY]; -					clothing_weight->mV[VZ] -= clothing_offset.mV[VZ]; +					LLVector4a clothing_offset = mMorphData->mCoords[vert]; +					clothing_offset.mul(lastMaskWeight); +					LLVector4a* clothing_weight = &clothing_weights[out_vert]; +					LLVector4a t; +					t.setSub(*clothing_weight, clothing_offset); +					clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight);  				}  			}  		} @@ -654,7 +683,7 @@ LLPolyVertexMask::~LLPolyVertexMask()  //-----------------------------------------------------------------------------  // generateMask()  //----------------------------------------------------------------------------- -void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights) +void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights)  {  // RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/)  //	BOOL debugImg = FALSE;  @@ -698,7 +727,7 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height,  		if (clothing_weights)  		{ -			clothing_weights[vertIndex].mV[VW] = mWeights[index]; +			clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index];  		}  	}  	mWeightsGenerated = TRUE; diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h index 8a024f2e9e..46e23b7792 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/newview/llpolymorph.h @@ -58,14 +58,14 @@ public:  	U32					mNumIndices;  	U32*				mVertexIndices;  	U32					mCurrentIndex; -	LLVector3*			mCoords; -	LLVector3*			mNormals; -	LLVector3*			mBinormals; +	LLVector4a*			mCoords; +	LLVector4a*			mNormals; +	LLVector4a*			mBinormals;  	LLVector2*			mTexCoords;  	F32					mTotalDistortion;	// vertex distortion summed over entire morph  	F32					mMaxDistortion;		// maximum single vertex distortion in a given morph -	LLVector3			mAvgDistortion;		// average vertex distortion, to infer directionality of the morph +	LLVector4a			mAvgDistortion;		// average vertex distortion, to infer directionality of the morph  	LLPolyMeshSharedData*	mMesh;  }; @@ -78,7 +78,7 @@ public:  	LLPolyVertexMask(LLPolyMorphData* morph_data);  	~LLPolyVertexMask(); -	void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights); +	void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);  	F32* getMorphMaskWeights(); @@ -157,11 +157,11 @@ public:  	// LLViewerVisualParam Virtual functions  	/*virtual*/ F32					getTotalDistortion(); -	/*virtual*/ const LLVector3&	getAvgDistortion(); +	/*virtual*/ const LLVector4a&	getAvgDistortion();  	/*virtual*/ F32					getMaxDistortion(); -	/*virtual*/ LLVector3			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); -	/*virtual*/ const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); -	/*virtual*/ const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);  	void	applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);  	void	addPendingMorphMask() { mNumMorphMasksPending++; } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index eec2c0a521..a55565909f 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1508,6 +1508,49 @@ struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor  	}  }; +void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) +{ +	if (!item) +	{ +		return; +	} +	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); + +	for (iterator iter = begin(); iter != end(); ++iter) +	{ +		LLSelectNode* node = *iter; +		LLViewerObject* object = (*iter)->getObject(); +		if (!object) +		{ +			continue; +		} + +		S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); +		bool texture_copied = false; +		for (S32 te = 0; te < num_tes; ++te) +		{ +			if (node->isTESelected(te)) +			{ +				//(no-copy) textures must be moved to the object's inventory only once +				// without making any copies +				if (!texture_copied) +				{ +					LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); +					texture_copied = true; +				} + +				// apply texture for the selected faces +				LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); +				object->setTEImage(te, image); +				dialog_refresh_all(); + +				// send the update to the simulator +				object->sendTEUpdate(); +			} +		} +	} +} +  //-----------------------------------------------------------------------------  // selectionSetImage()  //----------------------------------------------------------------------------- @@ -1559,8 +1602,18 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)  			}  			return true;  		} -	} setfunc(item, imageid); -	getSelection()->applyToTEs(&setfunc); +	}; + +	if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) +	{ +		getSelection()->applyNoCopyTextureToTEs(item); +	} +	else +	{ +		f setfunc(item, imageid); +		getSelection()->applyToTEs(&setfunc); +	} +  	struct g : public LLSelectedObjectFunctor  	{ @@ -5583,7 +5636,7 @@ void pushWireframe(LLDrawable* drawable)  			for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)  			{  				const LLVolumeFace& face = volume->getVolumeFace(i); -				LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices); +				LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);  			}  		} @@ -5610,7 +5663,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)  	if (shader)  	{ -		gHighlightProgram.bind(); +		gDebugProgram.bind();  	}  	gGL.matrixMode(LLRender::MM_MODELVIEW); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 87ada5ac6b..94606b9fba 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -307,6 +307,15 @@ public:  	bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);  	bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false); +	/* +	 * Used to apply (no-copy) textures to the selected object or +	 * selected face/faces of the object. +	 * This method moves (no-copy) texture to the object's inventory +	 * and doesn't make copy of the texture for each face. +	 * Then this only texture is used for all selected faces. +	 */ +	void applyNoCopyTextureToTEs(LLViewerInventoryItem* item); +  	ESelectType getSelectType() const { return mSelectType; }  private: diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index 1ce05da849..92c2863ffd 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -352,7 +352,7 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)  		getChildView("BtnCreator")->setEnabled(FALSE);  		getChildView("LabelCreatorTitle")->setEnabled(FALSE);  		getChildView("LabelCreatorName")->setEnabled(FALSE); -		getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown")); +		getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown_multiple"));  	}  	//////////////// diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 8e62b79d7f..bd335576ba 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -68,6 +68,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; @@ -85,12 +86,32 @@ static F32 sCurMaxTexPriority = 1.f;  class LLOcclusionQueryPool : public LLGLNamePool  { +public: +	LLOcclusionQueryPool() +	{ +		mCurQuery = 1; +	} +  protected: + +	std::list<GLuint> mAvailableName; +	GLuint mCurQuery; +		  	virtual GLuint allocateName()  	{ -		GLuint name; -		glGenQueriesARB(1, &name); -		return name; +		GLuint ret = 0; + +		if (!mAvailableName.empty()) +		{ +			ret = mAvailableName.front(); +			mAvailableName.pop_front(); +		} +		else +		{ +			ret = mCurQuery++; +		} + +		return ret;  	}  	virtual void releaseName(GLuint name) @@ -98,7 +119,8 @@ protected:  #if LL_TRACK_PENDING_OCCLUSION_QUERIES  		LLSpatialGroup::sPendingQueries.erase(name);  #endif -		glDeleteQueriesARB(1, &name); +		llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); +		mAvailableName.push_back(name);  	}  }; @@ -259,79 +281,39 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)  	return (U8*) (sOcclusionIndices+cypher*8);  } - -static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); - -void LLSpatialGroup::buildOcclusion() +//create a vertex buffer for efficiently rendering cubes +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)  { -	//if (mOcclusionVerts.isNull()) -	{ -		mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,  -			LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling. -		mOcclusionVerts->allocateBuffer(8, 64, true); -	 -		LLStrider<U16> idx; -		mOcclusionVerts->getIndexStrider(idx); -		for (U32 i = 0; i < 64; i++) -		{ -			*idx++ = sOcclusionIndices[i]; -		} -	} +	LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); -	LLVector4a fudge; -	fudge.splat(SG_OCCLUSION_FUDGE); - -	LLVector4a r; -	r.setAdd(mBounds[1], fudge); +	ret->allocateBuffer(8, 64, true);  	LLStrider<LLVector3> pos; -	 -	{ -		LLFastTimer t(FTM_BUILD_OCCLUSION); -		mOcclusionVerts->getVertexStrider(pos); -	} +	LLStrider<U16> idx; -	{ -		LLVector4a* v = (LLVector4a*) pos.get(); +	ret->getVertexStrider(pos); +	ret->getIndexStrider(idx); -		const LLVector4a& c = mBounds[0]; -		const LLVector4a& s = r; -		 -		static const LLVector4a octant[] = -		{ -			LLVector4a(-1.f, -1.f, -1.f), -			LLVector4a(-1.f, -1.f, 1.f), -			LLVector4a(-1.f, 1.f, -1.f), -			LLVector4a(-1.f, 1.f, 1.f), - -			LLVector4a(1.f, -1.f, -1.f), -			LLVector4a(1.f, -1.f, 1.f), -			LLVector4a(1.f, 1.f, -1.f), -			LLVector4a(1.f, 1.f, 1.f), -		}; - -		//vertex positions are encoded so the 3 bits of their vertex index  -		//correspond to their axis facing, with bit position 3,2,1 matching -		//axis facing x,y,z, bit set meaning positive facing, bit clear  -		//meaning negative facing -		 -		for (S32 i = 0; i < 8; ++i) -		{ -			LLVector4a p; -			p.setMul(s, octant[i]); -			p.add(c); -			v[i] = p; -		} -	} -	 +	pos[0] = LLVector3(-1,-1,-1); +	pos[1] = LLVector3(-1,-1, 1); +	pos[2] = LLVector3(-1, 1,-1); +	pos[3] = LLVector3(-1, 1, 1); +	pos[4] = LLVector3( 1,-1,-1); +	pos[5] = LLVector3( 1,-1, 1); +	pos[6] = LLVector3( 1, 1,-1); +	pos[7] = LLVector3( 1, 1, 1); + +	for (U32 i = 0; i < 64; i++)  	{ -		mOcclusionVerts->flush(); -		LLVertexBuffer::unbind(); +		idx[i] = sOcclusionIndices[i];  	} -	clearState(LLSpatialGroup::OCCLUSION_DIRTY); +	ret->flush(); + +	return ret;  } +static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");  BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); @@ -394,8 +376,6 @@ LLSpatialGroup::~LLSpatialGroup()  		}  	} -	mOcclusionVerts = NULL; -  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);  	clearDrawMap();  	clearAtlasList() ; @@ -562,7 +542,7 @@ void LLSpatialGroup::validate()  	validateDrawMap(); -	for (element_iter i = getData().begin(); i != getData().end(); ++i) +	for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)  	{  		LLDrawable* drawable = *i;  		sg_assert(drawable->getSpatialGroup() == this); @@ -687,6 +667,11 @@ void LLSpatialGroup::rebuildGeom()  	if (!isDead())  	{  		mSpatialPartition->rebuildGeom(this); + +		if (isState(LLSpatialGroup::MESH_DIRTY)) +		{ +			gPipeline.markMeshDirty(this); +		}  	}  } @@ -699,6 +684,9 @@ void LLSpatialGroup::rebuildMesh()  }  static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +static LLFastTimer::DeclareTimer FTM_ADD_GEOMETRY_COUNT("Add Geometry"); +static LLFastTimer::DeclareTimer FTM_CREATE_VB("Create VB"); +static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry");  void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)  { @@ -720,27 +708,36 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)  	//get geometry count  	U32 index_count = 0;  	U32 vertex_count = 0; -	 -	addGeometryCount(group, vertex_count, index_count); + +	{ +		LLFastTimer t(FTM_ADD_GEOMETRY_COUNT); +		addGeometryCount(group, vertex_count, index_count); +	}  	if (vertex_count > 0 && index_count > 0)  	{ //create vertex buffer containing volume geometry for this node -		group->mBuilt = 1.f; -		if (group->mVertexBuffer.isNull() || -			!group->mVertexBuffer->isWriteable() || -			(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))  		{ -			group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); -			group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); -			stop_glerror(); +			LLFastTimer t(FTM_CREATE_VB); +			group->mBuilt = 1.f; +			if (group->mVertexBuffer.isNull() || +				!group->mVertexBuffer->isWriteable() || +				(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) +			{ +				group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); +				group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); +				stop_glerror(); +			} +			else +			{ +				group->mVertexBuffer->resizeBuffer(vertex_count, index_count); +				stop_glerror(); +			}  		} -		else +  		{ -			group->mVertexBuffer->resizeBuffer(vertex_count, index_count); -			stop_glerror(); +			LLFastTimer t(FTM_GET_GEOMETRY); +			getGeometry(group);  		} -		 -		getGeometry(group);  	}  	else  	{ @@ -762,7 +759,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma  {	  	const OctreeNode* node = mOctreeNode; -	if (node->getData().empty()) +	if (node->isEmpty())  	{	//don't do anything if there are no objects  		if (empty && mOctreeNode->getParent())  		{	//only root is allowed to be empty @@ -779,14 +776,14 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma  		clearState(OBJECT_DIRTY);  		//initialize bounding box to first element -		OctreeNode::const_element_iter i = node->getData().begin(); +		OctreeNode::const_element_iter i = node->getDataBegin();  		LLDrawable* drawablep = *i;  		const LLVector4a* minMax = drawablep->getSpatialExtents();  		newMin = minMax[0];  		newMax = minMax[1]; -		for (++i; i != node->getData().end(); ++i) +		for (++i; i != node->getDataEnd(); ++i)  		{  			drawablep = *i;  			minMax = drawablep->getSpatialExtents(); @@ -927,16 +924,14 @@ 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);  	} - -	if (mOcclusionVerts.notNull()) -	{ -		setState(OCCLUSION_DIRTY); -	}  }  class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler @@ -1235,8 +1230,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :  		mVisible[i] = 0;  	} -	mOcclusionVerts = NULL; -  	mRadius = 1;  	mPixelArea = 1024.f;  } @@ -1249,13 +1242,18 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)  		return;  	} +	if (gShiftFrame) +	{ +		return; +	} +  #if !LL_RELEASE_FOR_DOWNLOAD  	if (isState(LLSpatialGroup::OBJECT_DIRTY))  	{  		llerrs << "Spatial group dirty on distance update." << llendl;  	}  #endif -	if (!getData().empty()) +	if (!isEmpty())  	{  		mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :  						(F32) mOctreeNode->getSize().getLength3().getF32(); @@ -1406,7 +1404,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);  	setState(DEAD); -	for (element_iter i = getData().begin(); i != getData().end(); ++i) +	for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)  	{  		LLDrawable* drawable = *i;  		if (drawable->getSpatialGroup() == this) @@ -1465,10 +1463,14 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo  	unbound();  } -void LLSpatialGroup::destroyGL()  +void LLSpatialGroup::destroyGL(bool keep_occlusion)   {  	setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); -	gPipeline.markRebuild(this, TRUE); + +	if (!keep_occlusion) +	{ //going to need a rebuild +		gPipeline.markRebuild(this, TRUE); +	}  	mLastUpdateTime = gFrameTimeSeconds;  	mVertexBuffer = NULL; @@ -1476,24 +1478,29 @@ void LLSpatialGroup::destroyGL()  	clearDrawMap(); -	for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) +	if (!keep_occlusion)  	{ -		if (mOcclusionQuery[i]) +		for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)  		{ -			sQueryPool.release(mOcclusionQuery[i]); -			mOcclusionQuery[i] = 0; +			if (mOcclusionQuery[i]) +			{ +				sQueryPool.release(mOcclusionQuery[i]); +				mOcclusionQuery[i] = 0; +			}  		}  	} -	mOcclusionVerts = NULL; -	for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) +	for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)  	{  		LLDrawable* drawable = *i;  		for (S32 j = 0; j < drawable->getNumFaces(); j++)  		{  			LLFace* facep = drawable->getFace(j); -			facep->clearVertexBuffer(); +			if (facep) +			{ +				facep->clearVertexBuffer(); +			}  		}  	}  } @@ -1556,15 +1563,13 @@ BOOL LLSpatialGroup::rebound()  		mBounds[1].mul(0.5f);  	} -	setState(OCCLUSION_DIRTY); -	  	clearState(DIRTY);  	return TRUE;  }  static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait");  void LLSpatialGroup::checkOcclusion()  { @@ -1584,7 +1589,9 @@ void LLSpatialGroup::checkOcclusion()  			{  				glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); -				if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) +				static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); + +				if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)  				{ //query was issued last frame, wait until it's available  					S32 max_loop = 1024;  					LLFastTimer t(FTM_OCCLUSION_WAIT); @@ -1635,7 +1642,9 @@ void LLSpatialGroup::checkOcclusion()  				else  				{  					assert_states_valid(this); +					  					setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); +					  					assert_states_valid(this);  				} @@ -1690,12 +1699,6 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)  						mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();  					} -					if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) -					{ -						LLFastTimer t(FTM_OCCLUSION_BUILD); -						buildOcclusion(); -					} -					  					// Depth clamp all water to avoid it being culled as a result of being  					// behind the far clip plane, and in the case of edge water to avoid  					// it being culled while still visible. @@ -1726,10 +1729,13 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)  							glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					  						} -						{ -							LLFastTimer t(FTM_OCCLUSION_SET_BUFFER); -							mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); -						} +						LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +						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);  						if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)  						{ @@ -1738,12 +1744,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)  							LLGLSquashToFarClip squash(glh_get_current_projection(), 1);  							if (camera->getOrigin().isExactlyZero())  							{ //origin is invalid, draw entire box -								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); -								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				 +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				  							}  							else  							{ -								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));  							}  						}  						else @@ -1751,12 +1757,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)  							LLFastTimer t(FTM_OCCLUSION_DRAW);  							if (camera->getOrigin().isExactlyZero())  							{ //origin is invalid, draw entire box -								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); -								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				 +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				  							}  							else  							{ -								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));  							}  						} @@ -1841,12 +1847,14 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -	drawablep->setSpatialGroup(NULL); -  	if (!curp->removeObject(drawablep))  	{  		OCT_ERRS << "Failed to remove drawable from octree!" << llendl;  	} +	else +	{ +		drawablep->setSpatialGroup(NULL); +	}  	assert_octree_valid(mOctree); @@ -2117,7 +2125,7 @@ public:  	virtual void processGroup(LLSpatialGroup* group)  	{ -		llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) +		llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty())  		if (mRes < 2)  		{ @@ -2184,7 +2192,7 @@ public:  	{  		LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) +		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)  		{  			LLDrawable* drawable = *i; @@ -2308,7 +2316,7 @@ public:  		LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);  		group->destroyGL(); -		for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +		for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  		{  			LLDrawable* drawable = *i;  			if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) @@ -2480,18 +2488,21 @@ void pushVerts(LLSpatialGroup* group, U32 mask)  void pushVerts(LLFace* face, U32 mask)  { -	llassert(face->verify()); +	if (face) +	{ +		llassert(face->verify()); -	LLVertexBuffer* buffer = face->getVertexBuffer(); +		LLVertexBuffer* buffer = face->getVertexBuffer(); -	if (buffer && (face->getGeomCount() >= 3)) -	{ -		buffer->setBuffer(mask); -		U16 start = face->getGeomStart(); -		U16 end = start + face->getGeomCount()-1; -		U32 count = face->getIndicesCount(); -		U16 offset = face->getIndicesStart(); -		buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); +		if (buffer && (face->getGeomCount() >= 3)) +		{ +			buffer->setBuffer(mask); +			U16 start = face->getGeomStart(); +			U16 end = start + face->getGeomCount()-1; +			U32 count = face->getIndicesCount(); +			U16 offset = face->getIndicesStart(); +			buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); +		}  	}  } @@ -2615,7 +2626,7 @@ void renderOctree(LLSpatialGroup* group)  			gGL.flush();  			glLineWidth(1.f);  			gGL.flush(); -			for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +			for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  			{  				LLDrawable* drawable = *i;  				if (!group->mSpatialPartition->isBridge()) @@ -2628,7 +2639,7 @@ void renderOctree(LLSpatialGroup* group)  				for (S32 j = 0; j < drawable->getNumFaces(); j++)  				{  					LLFace* face = drawable->getFace(j); -					if (face->getVertexBuffer()) +					if (face && face->getVertexBuffer())  					{  						if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)  						{ @@ -2661,7 +2672,7 @@ void renderOctree(LLSpatialGroup* group)  	}  	else  	{ -		if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty()  +		if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()   			&& group->mSpatialPartition->mRenderByGroup)  		{  			col.setVec(0.8f, 0.4f, 0.1f, 0.1f); @@ -2729,7 +2740,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)  	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  	BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && -							!group->getData().empty(); +							!group->isEmpty();  	if (render_objects)  	{ @@ -2757,19 +2768,6 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)  			gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);  			pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);  		} -		/*else if (camera && group->mOcclusionVerts.notNull()) -		{ -			LLVertexBuffer::unbind(); -			group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); -			 -			gGL.diffuseColor4f(1.0f, 0.f, 0.f, 0.5f); -			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); -			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -			 -			gGL.diffuseColor4f(1.0f, 1.f, 1.f, 1.0f); -			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); -			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -		}*/  	}  } @@ -2999,15 +2997,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)  	for (S32 i = 0; i < drawable->getNumFaces(); i++)  	{  		LLFace* facep = drawable->getFace(i); +		if (facep) +		{ +			ext = facep->mExtents; -		ext = facep->mExtents; - -		pos.setAdd(ext[0], ext[1]); -		pos.mul(0.5f); -		size.setSub(ext[1], ext[0]); -		size.mul(0.5f); +			pos.setAdd(ext[0], ext[1]); +			pos.mul(0.5f); +			size.setSub(ext[1], ext[0]); +			size.mul(0.5f); -		drawBoxOutline(pos,size); +			drawBoxOutline(pos,size); +		}  	}  	//render drawable bounding box @@ -3471,7 +3471,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)  void renderPhysicsShapes(LLSpatialGroup* group)  { -	for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +	for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{  		LLDrawable* drawable = *i;  		LLVOVolume* volume = drawable->getVOVolume(); @@ -3499,18 +3499,21 @@ void renderPhysicsShapes(LLSpatialGroup* group)  				for (S32 i = 0; i < drawable->getNumFaces(); ++i)  				{  					LLFace* face = drawable->getFace(i); -					LLVertexBuffer* buff = face->getVertexBuffer(); -					if (buff) +					if (face)  					{ -						glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +						LLVertexBuffer* buff = face->getVertexBuffer(); +						if (buff) +						{ +							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -						buff->setBuffer(LLVertexBuffer::MAP_VERTEX); -						gGL.diffuseColor3f(0.2f, 0.5f, 0.3f); -						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); +							buff->setBuffer(LLVertexBuffer::MAP_VERTEX); +							gGL.diffuseColor3f(0.2f, 0.5f, 0.3f); +							buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); -						gGL.diffuseColor3f(0.2f, 1.f, 0.3f); -						glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); +							gGL.diffuseColor3f(0.2f, 1.f, 0.3f); +							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +							buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); +						}  					}  				}  			} @@ -3534,6 +3537,7 @@ void renderTexturePriority(LLDrawable* drawable)  		//LLViewerTexture* imagep = facep->getTexture();  		//if (imagep) +		if (facep)  		{  			//F32 vsize = imagep->mMaxVirtualSize; @@ -3586,7 +3590,11 @@ void renderPoints(LLDrawable* drawablep)  		gGL.diffuseColor3f(1,1,1);  		for (S32 i = 0; i < drawablep->getNumFaces(); i++)  		{ -			gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); +			LLFace * face = drawablep->getFace(i); +			if (face) +			{ +				gGL.vertex3fv(face->mCenterLocal.mV); +			}  		}  		gGL.end();  	} @@ -3767,7 +3775,11 @@ void renderLights(LLDrawable* drawablep)  		for (S32 i = 0; i < drawablep->getNumFaces(); i++)  		{ -			pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); +			LLFace * face = drawablep->getFace(i); +			if (face) +			{ +				pushVerts(face, LLVertexBuffer::MAP_VERTEX); +			}  		}  		const LLVector4a* ext = drawablep->getSpatialExtents(); @@ -3808,7 +3820,7 @@ public:  		LLVector3 center, size; -		if (branch->getData().empty()) +		if (branch->isEmpty())  		{  			gGL.diffuseColor3f(1.f,0.2f,0.f);  			center.set(branch->getCenter().getF32ptr()); @@ -3844,8 +3856,8 @@ public:  			}  			gGL.begin(LLRender::TRIANGLES); -			for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin(); -					iter != branch->getData().end(); +			for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin(); +					iter != branch->getDataEnd();  					++iter)  			{  				const LLVolumeTriangle* tri = *iter; @@ -4082,7 +4094,7 @@ public:  		if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))  		{ -			if (!group->getData().empty()) +			if (!group->isEmpty())  			{  				gGL.diffuseColor3f(0,0,1);  				drawBoxOutline(group->mObjectBounds[0], @@ -4090,7 +4102,7 @@ public:  			}  		} -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) +		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)  		{  			LLDrawable* drawable = *i; @@ -4169,18 +4181,21 @@ public:  				for (U32 i = 0; i < drawable->getNumFaces(); ++i)  				{  					LLFace* facep = drawable->getFace(i); -					U8 index = facep->getTextureIndex(); -					if (facep->mDrawInfo) +					if (facep)  					{ -						if (index < 255) +						U8 index = facep->getTextureIndex(); +						if (facep->mDrawInfo)  						{ -							if (facep->mDrawInfo->mTextureList.size() <= index) -							{ -								llerrs << "Face texture index out of bounds." << llendl; -							} -							else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) +							if (index < 255)  							{ -								llerrs << "Face texture index incorrect." << llendl; +								if (facep->mDrawInfo->mTextureList.size()<= index) +								{ +									llerrs << "Face texture index out of bounds." << llendl; +								} +								else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) +								{ +									llerrs << "Face texture index incorrect." << llendl; +								}  							}  						}  					} @@ -4276,7 +4291,7 @@ public:  			return;  		} -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) +		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)  		{  			LLDrawable* drawable = *i; @@ -4500,7 +4515,7 @@ public:  	virtual void visit(const LLSpatialGroup::OctreeNode* branch)   	{	 -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) +		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)  		{  			check(*i);  		} @@ -4686,28 +4701,62 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 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.begin(); +	mVisibleGroupsEnd = mVisibleGroups;  	mAlphaGroupsSize = 0; -	mAlphaGroupsEnd = mAlphaGroups.begin(); +	mAlphaGroupsEnd = mAlphaGroups;  	mOcclusionGroupsSize = 0; -	mOcclusionGroupsEnd = mOcclusionGroups.begin(); +	mOcclusionGroupsEnd = mOcclusionGroups;  	mDrawableGroupsSize = 0; -	mDrawableGroupsEnd = mDrawableGroups.begin(); +	mDrawableGroupsEnd = mDrawableGroups;  	mVisibleListSize = 0; -	mVisibleListEnd = mVisibleList.begin(); +	mVisibleListEnd = mVisibleList;  	mVisibleBridgeSize = 0; -	mVisibleBridgeEnd = mVisibleBridge.begin(); +	mVisibleBridgeEnd = mVisibleBridge;  	for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) @@ -4717,176 +4766,176 @@ void LLCullResult::clear()  			mRenderMap[i][j] = 0;  		}  		mRenderMapSize[i] = 0; -		mRenderMapEnd[i] = mRenderMap[i].begin(); +		mRenderMapEnd[i] = mRenderMap[i];  	}  } -LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups() +LLCullResult::sg_iterator LLCullResult::beginVisibleGroups()  { -	return mVisibleGroups.begin(); +	return mVisibleGroups;  } -LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups() +LLCullResult::sg_iterator LLCullResult::endVisibleGroups()  {  	return mVisibleGroupsEnd;  } -LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() +LLCullResult::sg_iterator LLCullResult::beginAlphaGroups()  { -	return mAlphaGroups.begin(); +	return mAlphaGroups;  } -LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups() +LLCullResult::sg_iterator LLCullResult::endAlphaGroups()  {  	return mAlphaGroupsEnd;  } -LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() +LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups()  { -	return mOcclusionGroups.begin(); +	return mOcclusionGroups;  } -LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups() +LLCullResult::sg_iterator LLCullResult::endOcclusionGroups()  {  	return mOcclusionGroupsEnd;  } -LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() +LLCullResult::sg_iterator LLCullResult::beginDrawableGroups()  { -	return mDrawableGroups.begin(); +	return mDrawableGroups;  } -LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups() +LLCullResult::sg_iterator LLCullResult::endDrawableGroups()  {  	return mDrawableGroupsEnd;  } -LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() +LLCullResult::drawable_iterator LLCullResult::beginVisibleList()  { -	return mVisibleList.begin(); +	return mVisibleList;  } -LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList() +LLCullResult::drawable_iterator LLCullResult::endVisibleList()  {  	return mVisibleListEnd;  } -LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() +LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge()  { -	return mVisibleBridge.begin(); +	return mVisibleBridge;  } -LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge() +LLCullResult::bridge_iterator LLCullResult::endVisibleBridge()  {  	return mVisibleBridgeEnd;  } -LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type)  { -	return mRenderMap[type].begin(); +	return mRenderMap[type];  } -LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type)  {  	return mRenderMapEnd[type];  }  void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)  { -	if (mVisibleGroupsSize < mVisibleGroups.size()) +	if (mVisibleGroupsSize < mVisibleGroupsAllocated)  	{  		mVisibleGroups[mVisibleGroupsSize] = group;  	}  	else  	{ -		mVisibleGroups.push_back(group); +		pushBack((void**&) mVisibleGroups, mVisibleGroupsAllocated, (void*) group);  	}  	++mVisibleGroupsSize; -	mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize; +	mVisibleGroupsEnd = mVisibleGroups+mVisibleGroupsSize;  }  void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)  { -	if (mAlphaGroupsSize < mAlphaGroups.size()) +	if (mAlphaGroupsSize < mAlphaGroupsAllocated)  	{  		mAlphaGroups[mAlphaGroupsSize] = group;  	}  	else  	{ -		mAlphaGroups.push_back(group); +		pushBack((void**&) mAlphaGroups, mAlphaGroupsAllocated, (void*) group);  	}  	++mAlphaGroupsSize; -	mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize; +	mAlphaGroupsEnd = mAlphaGroups+mAlphaGroupsSize;  }  void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)  { -	if (mOcclusionGroupsSize < mOcclusionGroups.size()) +	if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)  	{  		mOcclusionGroups[mOcclusionGroupsSize] = group;  	}  	else  	{ -		mOcclusionGroups.push_back(group); +		pushBack((void**&) mOcclusionGroups, mOcclusionGroupsAllocated, (void*) group);  	}  	++mOcclusionGroupsSize; -	mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize; +	mOcclusionGroupsEnd = mOcclusionGroups+mOcclusionGroupsSize;  }  void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)  { -	if (mDrawableGroupsSize < mDrawableGroups.size()) +	if (mDrawableGroupsSize < mDrawableGroupsAllocated)  	{  		mDrawableGroups[mDrawableGroupsSize] = group;  	}  	else  	{ -		mDrawableGroups.push_back(group); +		pushBack((void**&) mDrawableGroups, mDrawableGroupsAllocated, (void*) group);  	}  	++mDrawableGroupsSize; -	mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize; +	mDrawableGroupsEnd = mDrawableGroups+mDrawableGroupsSize;  }  void LLCullResult::pushDrawable(LLDrawable* drawable)  { -	if (mVisibleListSize < mVisibleList.size()) +	if (mVisibleListSize < mVisibleListAllocated)  	{  		mVisibleList[mVisibleListSize] = drawable;  	}  	else  	{ -		mVisibleList.push_back(drawable); +		pushBack((void**&) mVisibleList, mVisibleListAllocated, (void*) drawable);  	}  	++mVisibleListSize; -	mVisibleListEnd = mVisibleList.begin()+mVisibleListSize; +	mVisibleListEnd = mVisibleList+mVisibleListSize;  }  void LLCullResult::pushBridge(LLSpatialBridge* bridge)  { -	if (mVisibleBridgeSize < mVisibleBridge.size()) +	if (mVisibleBridgeSize < mVisibleBridgeAllocated)  	{  		mVisibleBridge[mVisibleBridgeSize] = bridge;  	}  	else  	{ -		mVisibleBridge.push_back(bridge); +		pushBack((void**&) mVisibleBridge, mVisibleBridgeAllocated, (void*) bridge);  	}  	++mVisibleBridgeSize; -	mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize; +	mVisibleBridgeEnd = mVisibleBridge+mVisibleBridgeSize;  }  void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)  { -	if (mRenderMapSize[type] < mRenderMap[type].size()) +	if (mRenderMapSize[type] < mRenderMapAllocated[type])  	{  		mRenderMap[type][mRenderMapSize[type]] = draw_info;  	}  	else  	{ -		mRenderMap[type].push_back(draw_info); +		pushBack((void**&) mRenderMap[type], mRenderMapAllocated[type], (void*) draw_info);  	}  	++mRenderMapSize[type]; -	mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type]; +	mRenderMapEnd[type] = mRenderMap[type] + mRenderMapSize[type];  } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 1a93145cc5..e82c50b92b 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -263,11 +263,10 @@ public:  		SKIP_FRUSTUM_CHECK		= 0x00000020,  		IN_IMAGE_QUEUE			= 0x00000040,  		IMAGE_DIRTY				= 0x00000080, -		OCCLUSION_DIRTY			= 0x00000100, -		MESH_DIRTY				= 0x00000200, -		NEW_DRAWINFO			= 0x00000400, -		IN_BUILD_Q1				= 0x00000800, -		IN_BUILD_Q2				= 0x00001000, +		MESH_DIRTY				= 0x00000100, +		NEW_DRAWINFO			= 0x00000200, +		IN_BUILD_Q1				= 0x00000400, +		IN_BUILD_Q2				= 0x00000800,  		STATE_MASK				= 0x0000FFFF,  	} eSpatialState; @@ -313,10 +312,9 @@ public:  	BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);  	void unbound();  	BOOL rebound(); -	void buildOcclusion(); //rebuild mOcclusionVerts  	void checkOcclusion(); //read back last occlusion query (if any)  	void doOcclusion(LLCamera* camera); //issue occlusion query -	void destroyGL(); +	void destroyGL(bool keep_occlusion = false);  	void updateDistance(LLCamera& camera);  	BOOL needsUpdate(); @@ -327,8 +325,13 @@ public:  	void dirtyGeom() { setState(GEOM_DIRTY); }  	void dirtyMesh() { setState(MESH_DIRTY); } + +	//octree wrappers to make code more readable  	element_list& getData() { return mOctreeNode->getData(); } +	element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } +	element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }  	U32 getElementCount() const { return mOctreeNode->getElementCount(); } +	bool isEmpty() const { return mOctreeNode->isEmpty(); }  	void drawObjectBox(LLColor4 col); @@ -415,7 +418,6 @@ public:  	LLSpatialPartition* mSpatialPartition;  	LLPointer<LLVertexBuffer> mVertexBuffer; -	LLPointer<LLVertexBuffer> mOcclusionVerts;  	GLuint					mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];  	U32 mBufferUsage; @@ -545,34 +547,39 @@ class LLCullResult  public:  	LLCullResult(); -	typedef std::vector<LLSpatialGroup*> sg_list_t; -	typedef std::vector<LLDrawable*> drawable_list_t; -	typedef std::vector<LLSpatialBridge*> bridge_list_t; -	typedef std::vector<LLDrawInfo*> drawinfo_list_t; +	typedef LLSpatialGroup** sg_list_t; +	typedef LLDrawable** drawable_list_t; +	typedef LLSpatialBridge** bridge_list_t; +	typedef LLDrawInfo** drawinfo_list_t; + +	typedef LLSpatialGroup** sg_iterator; +	typedef LLSpatialBridge** bridge_iterator; +	typedef LLDrawInfo** drawinfo_iterator; +	typedef LLDrawable** drawable_iterator;  	void clear(); -	sg_list_t::iterator beginVisibleGroups(); -	sg_list_t::iterator endVisibleGroups(); +	sg_iterator beginVisibleGroups(); +	sg_iterator endVisibleGroups(); -	sg_list_t::iterator beginAlphaGroups(); -	sg_list_t::iterator endAlphaGroups(); +	sg_iterator beginAlphaGroups(); +	sg_iterator endAlphaGroups();  	bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } -	sg_list_t::iterator beginOcclusionGroups(); -	sg_list_t::iterator endOcclusionGroups(); +	sg_iterator beginOcclusionGroups(); +	sg_iterator endOcclusionGroups(); -	sg_list_t::iterator beginDrawableGroups(); -	sg_list_t::iterator endDrawableGroups(); +	sg_iterator beginDrawableGroups(); +	sg_iterator endDrawableGroups(); -	drawable_list_t::iterator beginVisibleList(); -	drawable_list_t::iterator endVisibleList(); +	drawable_iterator beginVisibleList(); +	drawable_iterator endVisibleList(); -	bridge_list_t::iterator beginVisibleBridge(); -	bridge_list_t::iterator endVisibleBridge(); +	bridge_iterator beginVisibleBridge(); +	bridge_iterator endVisibleBridge(); -	drawinfo_list_t::iterator beginRenderMap(U32 type); -	drawinfo_list_t::iterator endRenderMap(U32 type); +	drawinfo_iterator beginRenderMap(U32 type); +	drawinfo_iterator endRenderMap(U32 type);  	void pushVisibleGroup(LLSpatialGroup* group);  	void pushAlphaGroup(LLSpatialGroup* group); @@ -592,28 +599,41 @@ public:  	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_list_t::iterator mVisibleGroupsEnd; +	sg_iterator			mVisibleGroupsEnd;  	sg_list_t			mAlphaGroups; -	sg_list_t::iterator mAlphaGroupsEnd; +	sg_iterator			mAlphaGroupsEnd;  	sg_list_t			mOcclusionGroups; -	sg_list_t::iterator	mOcclusionGroupsEnd; +	sg_iterator			mOcclusionGroupsEnd;  	sg_list_t			mDrawableGroups; -	sg_list_t::iterator mDrawableGroupsEnd; +	sg_iterator			mDrawableGroupsEnd;  	drawable_list_t		mVisibleList; -	drawable_list_t::iterator mVisibleListEnd; +	drawable_iterator	mVisibleListEnd;  	bridge_list_t		mVisibleBridge; -	bridge_list_t::iterator mVisibleBridgeEnd; +	bridge_iterator		mVisibleBridgeEnd;  	drawinfo_list_t		mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; -	drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; +	U32					mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES]; +	drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; +  }; @@ -657,6 +677,7 @@ class LLParticlePartition : public LLSpatialPartition  {  public:  	LLParticlePartition(); +	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group);  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);  	virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); @@ -671,10 +692,14 @@ public:  };  //spatial partition for grass (implemented in LLVOGrass.cpp) -class LLGrassPartition : public LLParticlePartition +class LLGrassPartition : public LLSpatialPartition  {  public:  	LLGrassPartition(); +	virtual void getGeometry(LLSpatialGroup* group); +	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); +protected: +	U32 mRenderPass;  };  //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 66df7dae3e..230e871b49 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -56,6 +56,7 @@  #include "lldrawable.h"  extern LLPipeline gPipeline; +extern bool gShiftFrame;  LLColor4U MAX_WATER_COLOR(0, 48, 96, 240); @@ -294,7 +295,7 @@ void LLSurface::initTextures()  		mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);  		gPipeline.createObject(mWaterObjp);  		LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); -		water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); +		water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT);		// region doesn't have a valid water height yet  		mWaterObjp->setPositionGlobal(water_pos_global);  	}  } @@ -608,6 +609,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/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5077c2c7e1..a9ba2bce9c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -43,6 +43,7 @@  #include "lldrawpool.h"  #include "noise.h" +extern bool gShiftFrame;  extern U64 gFrameTime;  extern LLPipeline gPipeline; @@ -218,7 +219,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); @@ -366,10 +367,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/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 74c22b0cdf..2c0da60b48 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -76,11 +76,11 @@ public:  	// LLViewerVisualParam Virtual functions  	/*virtual*/ F32					getTotalDistortion()									{ return 1.f; } -	/*virtual*/ const LLVector3&	getAvgDistortion()										{ return mAvgDistortionVec; } +	/*virtual*/ const LLVector4a&	getAvgDistortion()										{ return mAvgDistortionVec; }  	/*virtual*/ F32					getMaxDistortion()										{ return 3.f; } -	/*virtual*/ LLVector3			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)	{ return LLVector3(1.f, 1.f, 1.f);} -	/*virtual*/ const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; -	/*virtual*/ const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return NULL;}; +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)	{ return LLVector4a(1.f, 1.f, 1.f);} +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return NULL;};  	// New functions  	BOOL					render( S32 x, S32 y, S32 width, S32 height ); @@ -94,7 +94,7 @@ private:  	LLPointer<LLImageRaw>	mStaticImageRaw;  	BOOL					mNeedsCreateTexture;  	BOOL					mStaticImageInvalid; -	LLVector3				mAvgDistortionVec; +	LLVector4a				mAvgDistortionVec;  	F32						mCachedEffectiveWeight;  public: @@ -155,18 +155,18 @@ public:  	// LLViewerVisualParam Virtual functions  	/*virtual*/ F32					getTotalDistortion()									{ return 1.f; } -	/*virtual*/ const LLVector3&	getAvgDistortion()										{ return mAvgDistortionVec; } +	/*virtual*/ const LLVector4a&	getAvgDistortion()										{ return mAvgDistortionVec; }  	/*virtual*/ F32					getMaxDistortion()										{ return 3.f; } -	/*virtual*/ LLVector3			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)	{ return LLVector3(1.f, 1.f, 1.f); } -	/*virtual*/ const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; -	/*virtual*/ const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return NULL;}; +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)	{ return LLVector4a(1.f, 1.f, 1.f); } +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)	{ index = 0; poly_mesh = NULL; return NULL;};  	// New functions  	LLColor4				getNetColor() const;  protected:  	virtual void onGlobalColorChanged(bool upload_bake) {}  private: -	LLVector3				mAvgDistortionVec; +	LLVector4a				mAvgDistortionVec;  };  class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp index d2e4b01732..f8c1bca8ae 100644 --- a/indra/newview/lltextureatlas.cpp +++ b/indra/newview/lltextureatlas.cpp @@ -116,7 +116,6 @@ LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_  		return 0 ;  	} -	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE);  	glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h,  						mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData()); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ed9faa0706..6703ef4a41 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -97,6 +97,7 @@ public:  		LLTextureCtrl* owner,  		const std::string& label,  		PermissionMask immediate_filter_perm_mask, +		PermissionMask dnd_filter_perm_mask,  		PermissionMask non_immediate_filter_perm_mask,  		BOOL can_apply_immediately,  		LLUIImagePtr fallback_image_name); @@ -134,6 +135,9 @@ public:  	void onFilterEdit(const std::string& search_string ); +	void setCanApply(bool can_preview, bool can_apply); +	void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;} +  	static void		onBtnSetToDefault( void* userdata );  	static void		onBtnSelect( void* userdata );  	static void		onBtnCancel( void* userdata ); @@ -175,6 +179,7 @@ protected:  	LLFilterEditor*		mFilterEdit;  	LLInventoryPanel*	mInventoryPanel;  	PermissionMask		mImmediateFilterPermMask; +	PermissionMask		mDnDFilterPermMask;  	PermissionMask		mNonImmediateFilterPermMask;  	BOOL				mCanApplyImmediately;  	BOOL				mNoCopyTextureSelected; @@ -184,12 +189,18 @@ protected:  	LLRadioGroup*		mModeSelector;  	LLScrollListCtrl*	mLocalScrollCtrl; + +private: +	bool mCanApply; +	bool mCanPreview; +	texture_selected_callback mTextureSelectedCallback;  };  LLFloaterTexturePicker::LLFloaterTexturePicker(	  	LLTextureCtrl* owner,  	const std::string& label,  	PermissionMask immediate_filter_perm_mask, +	PermissionMask dnd_filter_perm_mask,  	PermissionMask non_immediate_filter_perm_mask,  	BOOL can_apply_immediately,  	LLUIImagePtr fallback_image) @@ -205,9 +216,12 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(  	mActive( TRUE ),  	mFilterEdit(NULL),  	mImmediateFilterPermMask(immediate_filter_perm_mask), +	mDnDFilterPermMask(dnd_filter_perm_mask),  	mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),  	mContextConeOpacity(0.f), -	mSelectedItemPinned( FALSE ) +	mSelectedItemPinned( FALSE ), +	mCanApply(true), +	mCanPreview(true)  {  	buildFromFile("floater_texture_ctrl.xml");  	mCanApplyImmediately = can_apply_immediately; @@ -319,7 +333,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(  		if (xfer) item_perm_mask |= PERM_TRANSFER;  		//PermissionMask filter_perm_mask = getFilterPermMask();  Commented out due to no-copy texture loss. -		PermissionMask filter_perm_mask = mImmediateFilterPermMask; +		PermissionMask filter_perm_mask = mDnDFilterPermMask;  		if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )  		{  			if (drop) @@ -464,7 +478,7 @@ BOOL LLFloaterTexturePicker::postBuild()  	mNoCopyTextureSelected = FALSE; -	getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("ApplyTextureImmediately")); +	getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));  	childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);  	if (!mCanApplyImmediately) @@ -546,7 +560,7 @@ void LLFloaterTexturePicker::draw()  	// if we're inactive, gray out "apply immediate" checkbox  	getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected); -	getChildView("Select")->setEnabled(mActive); +	getChildView("Select")->setEnabled(mActive && mCanApply);  	getChildView("Pipette")->setEnabled(mActive);  	getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); @@ -702,8 +716,7 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask()  void LLFloaterTexturePicker::commitIfImmediateSet()  { -	bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean(); -	if (!mNoCopyTextureSelected && apply_immediate && mOwner) +	if (!mNoCopyTextureSelected && mOwner && mCanApply)  	{  		mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);  	} @@ -713,6 +726,7 @@ void LLFloaterTexturePicker::commitIfImmediateSet()  void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)  {  	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +	self->setCanApply(true, true);  	if (self->mOwner)  	{  		self->setImageID( self->mOwner->getDefaultImageAssetID() ); @@ -724,6 +738,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)  void LLFloaterTexturePicker::onBtnWhite(void* userdata)  {  	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; +	self->setCanApply(true, true);  	self->setImageID( self->mWhiteImageAssetID );  	self->commitIfImmediateSet();  } @@ -804,13 +819,14 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem  		mNoCopyTextureSelected = FALSE;  		if (itemp)  		{ +			mTextureSelectedCallback(itemp);  			if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))  			{  				mNoCopyTextureSelected = TRUE;  			}  			mImageAssetID = itemp->getAssetUUID();  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? -			if (user_action) +			if (user_action && mCanPreview)  			{  				// only commit intentional selections, not implicit ones  				commitIfImmediateSet(); @@ -947,7 +963,7 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da  	LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;  	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; -	gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get()); +	gSavedSettings.setBOOL("TextureLivePreview", check_box->get());  	picker->updateFilterPermMask();  	picker->commitIfImmediateSet(); @@ -958,6 +974,16 @@ void LLFloaterTexturePicker::updateFilterPermMask()  	//mInventoryPanel->setFilterPermMask( getFilterPermMask() );  Commented out due to no-copy texture loss.  } +void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply) +{ +	getChildRef<LLUICtrl>("Select").setEnabled(can_apply); +	getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview); +	getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview); + +	mCanApply = can_apply; +	mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false; +} +  void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )  {  	std::string upper_case_search_string = search_string; @@ -1108,6 +1134,15 @@ void LLTextureCtrl::setCanApplyImmediately(BOOL b)  	}  } +void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply) +{ +	LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get()); +	if( floaterp ) +	{ +		floaterp->setCanApply(can_preview, can_apply); +	} +} +  void LLTextureCtrl::setVisible( BOOL visible )   {  	if( !visible ) @@ -1188,12 +1223,19 @@ void LLTextureCtrl::showPicker(BOOL take_focus)  			this,  			mLabel,  			mImmediateFilterPermMask, +			mDnDFilterPermMask,  			mNonImmediateFilterPermMask,  			mCanApplyImmediately,  			mFallbackImage);  		mFloaterHandle = floaterp->getHandle(); +		LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp); +		if (texture_floaterp && mOnTextureSelectedCallback) +		{ +			texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback); +		} +  		LLFloater* root_floater = gFloaterView->getParentFloater(this);  		if (root_floater)  			root_floater->addDependentFloater(floaterp); @@ -1318,6 +1360,16 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)  	}  } +void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) +{ +	mOnTextureSelectedCallback = cb; +	LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get()); +	if (floaterp) +	{ +		floaterp->setTextureSelectedCallback(cb); +	} +} +  void	LLTextureCtrl::setImageAssetName(const std::string& name)  {  	LLPointer<LLUIImage> imagep = LLUI::getUIImage(name); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 3abe84dcc3..599d9c70c5 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -43,6 +43,7 @@ class LLViewerFetchedTexture;  // used for setting drag & drop callbacks.  typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback; +typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;  ////////////////////////////////////////////////////////////////////////////////////////// @@ -147,8 +148,12 @@ public:  	void			setCaption(const std::string& caption);  	void			setCanApplyImmediately(BOOL b); +	void			setCanApply(bool can_preview, bool can_apply); +  	void			setImmediateFilterPermMask(PermissionMask mask)  					{ mImmediateFilterPermMask = mask; } +	void			setDnDFilterPermMask(PermissionMask mask) +						{ mDnDFilterPermMask = mask; }  	void			setNonImmediateFilterPermMask(PermissionMask mask)  					{ mNonImmediateFilterPermMask = mask; }  	PermissionMask	getImmediateFilterPermMask() { return mImmediateFilterPermMask; } @@ -172,6 +177,11 @@ public:  	void setOnSelectCallback(commit_callback_t cb)	{ mOnSelectCallback = cb; } +	/* +	 * callback for changing texture selection in inventory list of texture floater +	 */ +	void setOnTextureSelectedCallback(texture_selected_callback cb); +  	void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);  	LLViewerFetchedTexture* getTexture() { return mTexturep; } @@ -185,6 +195,7 @@ private:  	drag_n_drop_callback	 	mDropCallback;  	commit_callback_t		 	mOnCancelCallback;  	commit_callback_t		 	mOnSelectCallback; +	texture_selected_callback	mOnTextureSelectedCallback;  	LLPointer<LLViewerFetchedTexture> mTexturep;  	LLUIColor				 	mBorderColor;  	LLUUID					 	mImageItemID; @@ -198,6 +209,7 @@ private:  	std::string				 	mLabel;  	BOOL					 	mAllowNoTexture; // If true, the user can select "none" as an option  	PermissionMask			 	mImmediateFilterPermMask; +	PermissionMask				mDnDFilterPermMask;  	PermissionMask			 	mNonImmediateFilterPermMask;  	BOOL					 	mCanApplyImmediately;  	BOOL					 	mCommitOnSelection; diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 245c2a23e6..41aee484db 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -93,6 +93,13 @@ public:  	static S32 getOperationId() { return sOperationId; } +	// deal with permissions of object, etc. returns TRUE if drop can +	// proceed, otherwise FALSE. +	static BOOL handleDropTextureProtections(LLViewerObject* hit_obj, +						 LLInventoryItem* item, +						 LLToolDragAndDrop::ESource source, +						 const LLUUID& src_id); +  protected:  	enum EDropTarget  	{ @@ -219,13 +226,6 @@ protected:  	// inventory items to determine if a drop would be ok.  	static EAcceptance willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item); -	// deal with permissions of object, etc. returns TRUE if drop can -	// proceed, otherwise FALSE. -	static BOOL handleDropTextureProtections(LLViewerObject* hit_obj, -						 LLInventoryItem* item, -						 LLToolDragAndDrop::ESource source, -						 const LLUUID& src_id); -  public:  	// helper functions  	static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); } diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 718201e381..0d5daf129f 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -225,7 +225,8 @@ BOOL LLVisualParamHint::render()  	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); -	if (gAgentAvatarp->mDrawable.notNull()) +	if (gAgentAvatarp->mDrawable.notNull() && +		gAgentAvatarp->mDrawable->getFace(0))  	{  		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();  		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index f2712e7590..0d361a2646 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -325,7 +325,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)  static bool handleUseOcclusionChanged(const LLSD& newvalue)  { -	LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery  +	LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction  		&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;  	return true;  } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 0adb187dd2..0ad2a6eb9b 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -79,6 +79,7 @@  #include "llpostprocess.h"  extern LLPointer<LLViewerTexture> gStartTexture; +extern bool gShiftFrame;  LLPointer<LLViewerTexture> gDisconnectedImagep = NULL; @@ -162,8 +163,11 @@ void display_startup()  	glClear(GL_DEPTH_BUFFER_BIT);  } +static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Update Camera"); +  void display_update_camera()  { +	LLFastTimer t(FTM_UPDATE_CAMERA);  	LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);  	// TODO: cut draw distance down if customizing avatar?  	// TODO: cut draw distance on per-parcel basis? @@ -217,6 +221,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete"); +static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window"); +static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update"); +static LLFastTimer::DeclareTimer FTM_DISPLAY_UPDATE_GEOM("Update Geom"); +static LLFastTimer::DeclareTimer FTM_TEXTURE_UNBIND("Texture Unbind"); +static LLFastTimer::DeclareTimer FTM_TELEPORT_DISPLAY("Teleport Display");  // Paint the display!  void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) @@ -226,6 +235,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	if (gWindowResized)  	{ //skip render on frames where window has been resized +		LLFastTimer t(FTM_RESIZE_WINDOW);  		gGL.flush();  		glClear(GL_COLOR_BUFFER_BIT);  		gViewerWindow->getWindow()->swapBuffers(); @@ -362,6 +372,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	if (gTeleportDisplay)  	{ +		LLFastTimer t(FTM_TELEPORT_DISPLAY);  		LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");  		const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. @@ -581,6 +592,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		// *TODO: merge these two methods  		{ +			LLFastTimer t(FTM_HUD_UPDATE);  			LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);  			LLHUDManager::getInstance()->updateEffects();  			LLHUDObject::updateAll(); @@ -588,6 +600,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		}  		{ +			LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM);  			LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);  			const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time  			gPipeline.createObjects(max_geom_update_time); @@ -597,6 +610,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		}  		gPipeline.updateGL(); +		  		stop_glerror();  		S32 water_clip = 0; @@ -622,11 +636,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		LLSpatialGroup::sNoDelete = TRUE;  		LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); -		/*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) -		{ //force occlusion on for all render types if doing deferred render (tighter shadow frustum) -			LLPipeline::sUseOcclusion = 3; -		}*/ -  		S32 occlusion = LLPipeline::sUseOcclusion;  		if (gDepthDirty)  		{ //depth buffer is invalid, don't overwrite occlusion state @@ -755,12 +764,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  				gTextureList.updateImages(max_image_decode_time);  			} -			{ +			/*{  				LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);  				//remove dead textures from GL  				LLImageGL::deleteDeadTextures();  				stop_glerror(); -			} +			}*/  		}  		LLGLState::checkStates(); @@ -889,6 +898,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		{  			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;  			LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM); + +			if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction) +			{ +				gGL.setColorMask(false, false); +				 +				U32 types[] = {  +					LLRenderPass::PASS_SIMPLE,  +					LLRenderPass::PASS_FULLBRIGHT,  +					LLRenderPass::PASS_SHINY  +				}; + +				U32 num_types = LL_ARRAY_SIZE(types); +				gOcclusionProgram.bind(); +				for (U32 i = 0; i < num_types; i++) +				{ +					gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); +				} + +				gOcclusionProgram.unbind(); +			} + +  			gGL.setColorMask(true, false);  			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)  			{ @@ -911,14 +942,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			stop_glerror();  		} -		for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) -		{ //dummy cleanup of any currently bound textures -			if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) -			{ -				gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); -				gGL.getTexUnit(i)->disable(); +		{ +			LLFastTimer t(FTM_TEXTURE_UNBIND); +			for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) +			{ //dummy cleanup of any currently bound textures +				if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +				{ +					gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +					gGL.getTexUnit(i)->disable(); +				}  			}  		} +  		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		  		if (to_texture) @@ -984,6 +1019,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	display_stats();  	LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); + +	gShiftFrame = false;  }  void render_hud_attachments() diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 4e14824e69..3a04bbed4f 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -127,7 +127,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)  	{  		for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)  		{ -			object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER); +			LLFace *face = object->mDrawable->getFace(face_num); +			if (face) +			{ +				face->setState(LLFace::HUD_RENDER); +			}  		}  	} @@ -146,7 +150,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)  			{  				for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)  				{ -					childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER); +					LLFace * face = childp->mDrawable->getFace(face_num); +					if (face) +					{ +						face->setState(LLFace::HUD_RENDER); +					}  				}  			}  		} @@ -254,7 +262,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)  		{  			for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)  			{ -				object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER); +				LLFace * face = object->mDrawable->getFace(face_num); +				if (face) +				{ +					face->clearState(LLFace::HUD_RENDER); +				}  			}  		}  	} @@ -272,7 +284,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)  			{  				for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)  				{ -					childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER); +					LLFace * face = childp->mDrawable->getFace(face_num); +					if (face) +					{ +						face->clearState(LLFace::HUD_RENDER); +					}  				}  			}  		} diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a9bff67f40..d790fbc31d 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -132,6 +132,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); @@ -2770,7 +2771,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			chat.mSourceType = CHAT_SOURCE_OBJECT; -			if(SYSTEM_FROM == name) +			// To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not +			// enough to check only from name (i.e. fromName = "Second Life"). For example +			// source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM. +			bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull(); +			if(chat_from_system)  			{  				// System's UUID is NULL (fixes EXT-4766)  				chat.mFromID = LLUUID::null; @@ -2795,7 +2800,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because  			// IMs from obejcts don't open IM sessions.  			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); -			if(SYSTEM_FROM != name && nearby_chat) +			if(!chat_from_system && nearby_chat)  			{  				chat.mOwnerID = from_id;  				LLSD args; @@ -2814,7 +2819,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590) -			if (SYSTEM_FROM != name) break; +			if (!chat_from_system) break;  			LLSD substitutions;  			substitutions["NAME"] = name; @@ -3734,6 +3739,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)  void process_agent_movement_complete(LLMessageSystem* msg, void**)  { +	gShiftFrame = true;  	gAgentMovementCompleted = true;  	LLUUID agent_id; @@ -4064,6 +4070,8 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  	head_rot_chg = dot(last_head_rot, head_rotation); +	//static S32 msg_number = 0;		// Used for diagnostic log messages +  	if (force_send ||   		(cam_center_chg.magVec() > TRANSLATE_THRESHOLD) ||   		(head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||	 @@ -4072,19 +4080,20 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  		control_flag_change != 0 ||  		flag_change != 0)    	{ -/* +		/* Diagnotics to show why we send the AgentUpdate message.  Also un-commment the msg_number code above and below this block +		msg_number += 1;  		if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)  		{ -			//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; -			LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL; +			//LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL; +			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL;  		}  		if (cam_rot_chg.magVec() > ROTATION_THRESHOLD)   		{ -			LL_INFOS("Messaging") << "cam rot " <<  cam_rot_chg.magVec() << LL_ENDL; +			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " <<  cam_rot_chg.magVec() << LL_ENDL;  		}  		if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)  		{ -			LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL; +			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL;  		}  //		if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)  //		{ @@ -4092,9 +4101,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  //		}  		if (control_flag_change)  		{ -			LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL; +			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL;  		} -*/ +		*/  		duplicate_count = 0;  	} @@ -4129,6 +4138,26 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  	if (duplicate_count < DUP_MSGS && !gDisconnected)  	{ +		/* More diagnostics to count AgentUpdate messages +		static S32 update_sec = 0; +		static S32 update_count = 0; +		static S32 max_update_count = 0; +		S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() ); +		update_count += 1; +		if (cur_sec != update_sec) +		{ +			if (update_sec != 0) +			{ +				update_sec = cur_sec; +				//msg_number = 0; +				max_update_count = llmax(max_update_count, update_count); +				llinfos << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << llendl; +			} +			update_sec = cur_sec; +			update_count = 0; +		} +		*/ +  		LLFastTimer t(FTM_AGENT_UPDATE_SEND);  		// Build the message  		msg->newMessageFast(_PREHASH_AgentUpdate); @@ -4297,8 +4326,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)  			LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;  		} -		LLSelectMgr::getInstance()->removeObjectFromSelections(id); -  		// ...don't kill the avatar  		if (!(id == gAgentID))  		{ @@ -4321,6 +4348,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)  				gObjectList.mNumUnknownKills++;  			}  		} + +		// We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab, +        // which is using the object, release the mouse capture correctly when the object dies. +        // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical(). +		LLSelectMgr::getInstance()->removeObjectFromSelections(id); +  	}  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cd300accb7..af007743bf 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -199,6 +199,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mID(id),  	mLocalID(0),  	mTotalCRC(0), +	mListIndex(-1),  	mTEImages(NULL),  	mGLName(0),  	mbCanSelect(TRUE), @@ -432,7 +433,9 @@ void LLViewerObject::dump() const  	llinfos << "PositionAgent: " << getPositionAgent() << llendl;  	llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;  	llinfos << "Velocity: " << getVelocity() << llendl; -	if (mDrawable.notNull() && mDrawable->getNumFaces()) +	if (mDrawable.notNull() &&  +		mDrawable->getNumFaces() &&  +		mDrawable->getFace(0))  	{  		LLFacePool *poolp = mDrawable->getFace(0)->getPool();  		if (poolp) @@ -2169,8 +2172,8 @@ BOOL LLViewerObject::isActive() const  BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  { -	static LLFastTimer::DeclareTimer ftm("Viewer Object"); -	LLFastTimer t(ftm); +	//static LLFastTimer::DeclareTimer ftm("Viewer Object"); +	//LLFastTimer t(ftm);  	if (mDead)  	{ @@ -2798,6 +2801,23 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS  	   (object = gObjectList.findObject(ft->mTaskID)))  	{  		object->loadTaskInvFile(ft->mFilename); + +		LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); +		LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); +		std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs; + +		for (; it != end && pending_lst.size(); ++it) +		{ +			LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get()); +			if(item && item->getType() != LLAssetType::AT_CATEGORY) +			{ +				std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); +				if (id_it != pending_lst.end()) +				{ +					pending_lst.erase(id_it); +				} +			} +		}  	}  	else  	{ @@ -2910,7 +2930,22 @@ void LLViewerObject::updateInventory(  	bool is_new)  {  	LLMemType mt(LLMemType::MTYPE_OBJECT); -	 + +	std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin(); +	std::list<LLUUID>::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. @@ -4477,7 +4512,11 @@ U32 LLViewerObject::getNumVertices() const  		num_faces = mDrawable->getNumFaces();  		for (i = 0; i < num_faces; i++)  		{ -			num_vertices += mDrawable->getFace(i)->getGeomCount(); +			LLFace * facep = mDrawable->getFace(i); +			if (facep) +			{ +				num_vertices += facep->getGeomCount(); +			}  		}  	}  	return num_vertices; @@ -4492,7 +4531,11 @@ U32 LLViewerObject::getNumIndices() const  		num_faces = mDrawable->getNumFaces();  		for (i = 0; i < num_faces; i++)  		{ -			num_indices += mDrawable->getFace(i)->getIndicesCount(); +			LLFace * facep = mDrawable->getFace(i); +			if (facep) +			{ +				num_indices += facep->getIndicesCount(); +			}  		}  	}  	return num_indices; @@ -4769,9 +4812,11 @@ void LLViewerObject::deleteParticleSource()  // virtual  void LLViewerObject::updateDrawable(BOOL force_damped)  { -	if (mDrawable.notNull() &&  -		!mDrawable->isState(LLDrawable::ON_MOVE_LIST) && -		isChanged(MOVED)) +	if (!isChanged(MOVED)) +	{ //most common case, having an empty if case here makes for better branch prediction +	} +	else if (mDrawable.notNull() &&  +		!mDrawable->isState(LLDrawable::ON_MOVE_LIST))  	{  		BOOL damped_motion =   			!isChanged(SHIFTED) &&										// not shifted between regions this frame and... diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index c8152e1539..30c3d03635 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -229,6 +229,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; } @@ -589,6 +591,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<LLViewerTexture> *mTEImages;  	// Selection, picking and rendering variables @@ -684,6 +689,10 @@ protected:  	F32				mAppAngle;	// Apparent visual arc in degrees  	F32				mPixelArea; // Apparent area in pixels +	// IDs of of all items in the object's content which are added to the object's content, +	// but not updated on the server yet. After item was updated, its ID will be removed from this list. +	std::list<LLUUID> mPendingInventoryItemsIDs; +  	// This is the object's inventory from the viewer's perspective.  	LLInventoryObject::object_list_t* mInventory;  	class LLInventoryCallbackInfo diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 54ccfb9aae..2fd8c87fc2 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -931,21 +931,30 @@ 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<LLViewerObject*> idle_list; -	 +	static std::vector<LLViewerObject*> idle_list; + +	U32 idle_count = 0; +		  	static LLFastTimer::DeclareTimer idle_copy("Idle Copy");  	{  		LLFastTimer t(idle_copy); -		idle_list.reserve( mActiveObjects.size() ); - - 		for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin(); +		 + 		for (std::vector<LLPointer<LLViewerObject> >::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 @@ -955,10 +964,13 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  		}  	} +	std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count; +  	if (gSavedSettings.getBOOL("FreezeTime"))  	{ +		  		for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin(); -			iter != idle_list.end(); iter++) +			iter != idle_end; iter++)  		{  			objectp = *iter;  			if (objectp->isAvatar()) @@ -970,17 +982,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	else  	{  		for (std::vector<LLViewerObject*>::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<LLViewerObject*>::iterator kill_iter = kill_list.begin(); @@ -1218,7 +1230,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()) @@ -1395,6 +1407,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); @@ -1409,13 +1441,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 >= 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);  		}  	} @@ -1489,6 +1537,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... @@ -1500,6 +1552,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)  	{ @@ -1516,8 +1570,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() @@ -1721,7 +1782,10 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)  			LLViewerObject* last_objectp = NULL;  			for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)  			{ -				LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject(); +				LLFace * facep = drawablep->getFace(face_num); +				if (!facep) continue; + +				LLViewerObject* objectp = facep->getViewerObject();  				if (objectp && objectp != last_objectp)  				{ diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 64925f46ae..9936432a71 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -118,7 +118,9 @@ public:  	void dirtyAllObjectInventory(); +	void removeFromActiveList(LLViewerObject* objectp);  	void updateActive(LLViewerObject *objectp); +	  	void updateAvatarVisibility();  	// Selection related stuff @@ -197,7 +199,7 @@ protected:  	typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;  	vobj_list_t mObjects; -	std::set<LLPointer<LLViewerObject> > mActiveObjects; +	std::vector<LLPointer<LLViewerObject> > mActiveObjects;  	vobj_list_t mMapObjects; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6b3e04348a..345023dbfa 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -476,7 +476,7 @@ void LLViewerPartSim::checkParticleCount(U32 size)  LLViewerPartSim::LLViewerPartSim()  {  	LLMemType mt(LLMemType::MTYPE_PARTICLES); -	sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); +	sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT);  	static U32 id_seed = 0;  	mID = ++id_seed;  } diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 3e20f999c0..c9959c63ec 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -39,6 +39,8 @@ class LLViewerRegion;  class LLViewerTexture;  class LLVOPartGroup; +#define LL_MAX_PARTICLE_COUNT 8192 +  typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);  /////////////////// diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e3cb985ddb..e4108e2cd1 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1461,7 +1461,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/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 10c61c01d5..a6c564a6a1 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -63,8 +63,16 @@ bool				LLViewerShaderMgr::sSkipReload = false;  LLVector4			gShinyOrigin; +//transform shaders +LLGLSLShader			gTransformPositionProgram; +LLGLSLShader			gTransformTexCoordProgram; +LLGLSLShader			gTransformNormalProgram; +LLGLSLShader			gTransformColorProgram; +LLGLSLShader			gTransformBinormalProgram; +  //utility shaders  LLGLSLShader	gOcclusionProgram; +LLGLSLShader	gOcclusionCubeProgram;  LLGLSLShader	gCustomAlphaProgram;  LLGLSLShader	gGlowCombineProgram;  LLGLSLShader	gSplatTextureRectProgram; @@ -72,6 +80,7 @@ LLGLSLShader	gGlowCombineFXAAProgram;  LLGLSLShader	gTwoTextureAddProgram;  LLGLSLShader	gOneTextureNoColorProgram;  LLGLSLShader	gDebugProgram; +LLGLSLShader	gClipProgram;  LLGLSLShader	gAlphaMaskProgram;  //object shaders @@ -178,6 +187,7 @@ LLGLSLShader			gDeferredSunProgram;  LLGLSLShader			gDeferredBlurLightProgram;  LLGLSLShader			gDeferredSoftenProgram;  LLGLSLShader			gDeferredShadowProgram; +LLGLSLShader			gDeferredShadowCubeProgram;  LLGLSLShader			gDeferredShadowAlphaMaskProgram;  LLGLSLShader			gDeferredAvatarShadowProgram;  LLGLSLShader			gDeferredAttachmentShadowProgram; @@ -437,7 +447,8 @@ void LLViewerShaderMgr::setShaders()  		S32 wl_class = 2;  		S32 water_class = 2;  		S32 deferred_class = 0; -		 +		S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; +  		if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&  		    gSavedSettings.getBOOL("RenderDeferred") &&  			gSavedSettings.getBOOL("RenderAvatarVP") && @@ -475,6 +486,7 @@ void LLViewerShaderMgr::setShaders()  			gSky.mVOSkyp->forceSkyUpdate();  		} +		  		// Load lighting shaders  		mVertexShaderLevel[SHADER_LIGHTING] = light_class;  		mVertexShaderLevel[SHADER_INTERFACE] = light_class; @@ -484,6 +496,7 @@ void LLViewerShaderMgr::setShaders()  		mVertexShaderLevel[SHADER_EFFECT] = effect_class;  		mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;  		mVertexShaderLevel[SHADER_DEFERRED] = deferred_class; +		mVertexShaderLevel[SHADER_TRANSFORM] = transform_class;  		BOOL loaded = loadBasicShaders(); @@ -493,65 +506,109 @@ void LLViewerShaderMgr::setShaders()  			gPipeline.mVertexShadersLoaded = 1;  			// Load all shaders to set max levels -			loadShadersEnvironment(); -			loadShadersWater(); -			loadShadersWindLight(); -			loadShadersEffects(); -			loadShadersInterface(); +			loaded = loadShadersEnvironment(); + +			if (loaded) +			{ +				loaded = loadShadersWater(); +			} + +			if (loaded) +			{ +				loaded = loadShadersWindLight(); +			} + +			if (loaded) +			{ +				loaded = loadShadersEffects(); +			} + +			if (loaded) +			{ +				loaded = loadShadersInterface(); +			} -			// Load max avatar shaders to set the max level -			mVertexShaderLevel[SHADER_AVATAR] = 3; -			mMaxAvatarShaderLevel = 3; -						 -			if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) -			{ //hardware skinning is enabled and rigged attachment shaders loaded correctly -				BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); -				S32 avatar_class = 1; -				 -				// cloth is a class3 shader -				if(avatar_cloth) -				{ -					avatar_class = 3; -				} +			if (loaded) +			{ +				loaded = loadTransformShaders(); +			} -				// Set the actual level -				mVertexShaderLevel[SHADER_AVATAR] = avatar_class; -				loadShadersAvatar(); -				if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class) -				{ -					if (mVertexShaderLevel[SHADER_AVATAR] == 0) +			if (loaded) +			{ +				// Load max avatar shaders to set the max level +				mVertexShaderLevel[SHADER_AVATAR] = 3; +				mMaxAvatarShaderLevel = 3; +				 +				if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) +				{ //hardware skinning is enabled and rigged attachment shaders loaded correctly +					BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); +					S32 avatar_class = 1; +				 +					// cloth is a class3 shader +					if(avatar_cloth)  					{ -						gSavedSettings.setBOOL("RenderAvatarVP", FALSE); +						avatar_class = 3;  					} -					if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) + +					// Set the actual level +					mVertexShaderLevel[SHADER_AVATAR] = avatar_class; +					loadShadersAvatar(); +					if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)  					{ -						avatar_cloth = true; +						if (mVertexShaderLevel[SHADER_AVATAR] == 0) +						{ +							gSavedSettings.setBOOL("RenderAvatarVP", FALSE); +						} +						if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) +						{ +							avatar_cloth = true; +						} +						else +						{ +							avatar_cloth = false; +						} +						gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);  					} -					else +				} +				else +				{ //hardware skinning not possible, neither is deferred rendering +					mVertexShaderLevel[SHADER_AVATAR] = 0; +					mVertexShaderLevel[SHADER_DEFERRED] = 0; + +					if (gSavedSettings.getBOOL("RenderAvatarVP"))  					{ -						avatar_cloth = false; +						gSavedSettings.setBOOL("RenderDeferred", FALSE); +						gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); +						gSavedSettings.setBOOL("RenderAvatarVP", FALSE);  					} -					gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); + +					loadShadersAvatar(); // unloads + +					loaded = loadShadersObject();  				}  			} -			else -			{ //hardware skinning not possible, neither is deferred rendering -				mVertexShaderLevel[SHADER_AVATAR] = 0; -				mVertexShaderLevel[SHADER_DEFERRED] = 0; - -				if (gSavedSettings.getBOOL("RenderAvatarVP")) -				{ -					gSavedSettings.setBOOL("RenderDeferred", FALSE); -					gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); -					gSavedSettings.setBOOL("RenderAvatarVP", FALSE); + +			if (!loaded) +			{ //some shader absolutely could not load, try to fall back to a simpler setting +				if (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) +				{ //disable windlight and try again +					gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE); +					reentrance = false; +					setShaders(); +					return;  				} -				loadShadersAvatar(); // unloads -				loadShadersObject(); -			} +				if (gSavedSettings.getBOOL("VertexShaderEnable")) +				{ //disable shaders outright and try again +					gSavedSettings.setBOOL("VertexShaderEnable", FALSE); +					reentrance = false; +					setShaders(); +					return; +				} +			}		 -			if (!loadShadersDeferred()) -			{ +			if (loaded && !loadShadersDeferred()) +			{ //everything else succeeded but deferred failed, disable deferred and try again  				gSavedSettings.setBOOL("RenderDeferred", FALSE);  				reentrance = false;  				setShaders(); @@ -600,7 +657,9 @@ void LLViewerShaderMgr::setShaders()  void LLViewerShaderMgr::unloadShaders()  {  	gOcclusionProgram.unload(); +	gOcclusionCubeProgram.unload();  	gDebugProgram.unload(); +	gClipProgram.unload();  	gAlphaMaskProgram.unload();  	gUIProgram.unload();  	gCustomAlphaProgram.unload(); @@ -692,6 +751,12 @@ void LLViewerShaderMgr::unloadShaders()  	gDeferredSkinnedBumpProgram.unload();  	gDeferredSkinnedAlphaProgram.unload(); +	gTransformPositionProgram.unload(); +	gTransformTexCoordProgram.unload(); +	gTransformNormalProgram.unload(); +	gTransformColorProgram.unload(); +	gTransformBinormalProgram.unload(); +  	mVertexShaderLevel[SHADER_LIGHTING] = 0;  	mVertexShaderLevel[SHADER_OBJECT] = 0;  	mVertexShaderLevel[SHADER_AVATAR] = 0; @@ -700,6 +765,7 @@ void LLViewerShaderMgr::unloadShaders()  	mVertexShaderLevel[SHADER_INTERFACE] = 0;  	mVertexShaderLevel[SHADER_EFFECT] = 0;  	mVertexShaderLevel[SHADER_WINDLIGHT] = 0; +	mVertexShaderLevel[SHADER_TRANSFORM] = 0;  	gPipeline.mVertexShadersLoaded = 0;  } @@ -828,7 +894,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()  	if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0)  	{  		gTerrainProgram.unload(); -		return FALSE; +		return TRUE;  	}  	if (success) @@ -868,7 +934,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gWaterProgram.unload();  		gUnderWaterProgram.unload();  		gTerrainWaterProgram.unload(); -		return FALSE; +		return TRUE;  	}  	if (success) @@ -953,7 +1019,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowExtractProgram.unload();  		gPostColorFilterProgram.unload();	  		gPostNightVisionProgram.unload(); -		return FALSE; +		return TRUE;  	}  	if (success) @@ -1013,6 +1079,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredBlurLightProgram.unload();  		gDeferredSoftenProgram.unload();  		gDeferredShadowProgram.unload(); +		gDeferredShadowCubeProgram.unload();  		gDeferredShadowAlphaMaskProgram.unload();  		gDeferredAvatarShadowProgram.unload();  		gDeferredAttachmentShadowProgram.unload(); @@ -1200,7 +1267,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";  		gDeferredSpotLightProgram.mShaderFiles.clear();  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);  	} @@ -1209,7 +1276,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";  		gDeferredMultiSpotLightProgram.mShaderFiles.clear(); -		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); @@ -1368,6 +1435,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; +		gDeferredShadowCubeProgram.mShaderFiles.clear(); +		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredShadowCubeProgram.createShader(NULL, NULL); +	} + +	if (success) +	{  		gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";  		gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); @@ -2410,7 +2487,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarWaterProgram.unload();  		gAvatarEyeballProgram.unload();  		gAvatarPickProgram.unload(); -		return FALSE; +		return TRUE;  	}  	if (success) @@ -2504,7 +2581,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	if (mVertexShaderLevel[SHADER_INTERFACE] == 0)  	{  		gHighlightProgram.unload(); -		return FALSE; +		return TRUE;  	}  	if (success) @@ -2647,6 +2724,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	if (success)  	{ +		gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; +		gOcclusionCubeProgram.mShaderFiles.clear(); +		gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB)); +		gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gOcclusionCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gOcclusionCubeProgram.createShader(NULL, NULL); +	} + +	if (success) +	{  		gDebugProgram.mName = "Debug Shader";  		gDebugProgram.mShaderFiles.clear();  		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2657,6 +2744,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	if (success)  	{ +		gClipProgram.mName = "Clip Shader"; +		gClipProgram.mShaderFiles.clear(); +		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB)); +		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gClipProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gClipProgram.createShader(NULL, NULL); +	} + +	if (success) +	{  		gAlphaMaskProgram.mName = "Alpha Mask Shader";  		gAlphaMaskProgram.mShaderFiles.clear();  		gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2682,7 +2779,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  	{  		gWLSkyProgram.unload();  		gWLCloudProgram.unload(); -		return FALSE; +		return TRUE;  	}  	if (success) @@ -2712,6 +2809,95 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  	return success;  } +BOOL LLViewerShaderMgr::loadTransformShaders() +{ +	BOOL success = TRUE; +	 +	if (mVertexShaderLevel[SHADER_TRANSFORM] < 1) +	{ +		gTransformPositionProgram.unload(); +		gTransformTexCoordProgram.unload(); +		gTransformNormalProgram.unload(); +		gTransformColorProgram.unload(); +		gTransformBinormalProgram.unload(); +		return TRUE; +	} + +	if (success) +	{ +		gTransformPositionProgram.mName = "Position Transform Shader"; +		gTransformPositionProgram.mShaderFiles.clear(); +		gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + +		const char* varyings[] = { +			"position_out", +			"texture_index_out", +		}; +	 +		success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); +	} + +	if (success) +	{ +		gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; +		gTransformTexCoordProgram.mShaderFiles.clear(); +		gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + +		const char* varyings[] = { +			"texcoord_out", +		}; +	 +		success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); +	} + +	if (success) +	{ +		gTransformNormalProgram.mName = "Normal Transform Shader"; +		gTransformNormalProgram.mShaderFiles.clear(); +		gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + +		const char* varyings[] = { +			"normal_out", +		}; +	 +		success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); +	} + +	if (success) +	{ +		gTransformColorProgram.mName = "Color Transform Shader"; +		gTransformColorProgram.mShaderFiles.clear(); +		gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + +		const char* varyings[] = { +			"color_out", +		}; +	 +		success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); +	} + +	if (success) +	{ +		gTransformBinormalProgram.mName = "Binormal Transform Shader"; +		gTransformBinormalProgram.mShaderFiles.clear(); +		gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + +		const char* varyings[] = { +			"binormal_out", +		}; +	 +		success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings); +	} + +	 +	return success; +} +  std::string LLViewerShaderMgr::getShaderDirPrefix(void)  {  	return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 95eb551bf1..8f7ff8dd2f 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -54,6 +54,7 @@ public:  	BOOL loadShadersWater();  	BOOL loadShadersInterface();  	BOOL loadShadersWindLight(); +	BOOL loadTransformShaders();  	std::vector<S32> mVertexShaderLevel;  	S32	mMaxAvatarShaderLevel; @@ -69,6 +70,7 @@ public:  		SHADER_WINDLIGHT,  		SHADER_WATER,  		SHADER_DEFERRED, +		SHADER_TRANSFORM,  		SHADER_COUNT  	}; @@ -209,13 +211,24 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade  extern LLVector4			gShinyOrigin; +//transform shaders +extern LLGLSLShader			gTransformPositionProgram; +extern LLGLSLShader			gTransformTexCoordProgram; +extern LLGLSLShader			gTransformNormalProgram; +extern LLGLSLShader			gTransformColorProgram; +extern LLGLSLShader			gTransformBinormalProgram; + + +  //utility shaders  extern LLGLSLShader			gOcclusionProgram; +extern LLGLSLShader			gOcclusionCubeProgram;  extern LLGLSLShader			gCustomAlphaProgram;  extern LLGLSLShader			gGlowCombineProgram;  extern LLGLSLShader			gSplatTextureRectProgram;  extern LLGLSLShader			gGlowCombineFXAAProgram;  extern LLGLSLShader			gDebugProgram; +extern LLGLSLShader			gClipProgram;  extern LLGLSLShader			gAlphaMaskProgram;  //output tex0[tc0] + tex1[tc1] @@ -328,6 +341,7 @@ extern LLGLSLShader			gDeferredBlurLightProgram;  extern LLGLSLShader			gDeferredAvatarProgram;  extern LLGLSLShader			gDeferredSoftenProgram;  extern LLGLSLShader			gDeferredShadowProgram; +extern LLGLSLShader			gDeferredShadowCubeProgram;  extern LLGLSLShader			gDeferredShadowAlphaMaskProgram;  extern LLGLSLShader			gDeferredPostProgram;  extern LLGLSLShader			gDeferredCoFProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 497e95c5e3..28f4ec72f3 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -789,6 +789,24 @@ void send_stats()  	system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();  	system["gpu_vendor"] = gGLManager.mGLVendorShort;  	system["gpu_version"] = gGLManager.mDriverVersionVendorString; +	system["opengl_version"] = gGLManager.mGLVersionString; + +	S32 shader_level = 0; +	if (LLPipeline::sRenderDeferred) +	{ +		shader_level = 3; +	} +	else if (gPipeline.canUseWindLightShadersOnObjects()) +	{ +		shader_level = 2; +	} +	else if (gPipeline.canUseVertexShaders()) +	{ +		shader_level = 1; +	} + + +	system["shader_level"] = shader_level;  	LLSD &download = body["downloads"]; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index d844aeb12a..7f638a24bf 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1398,10 +1398,10 @@ void LLViewerFetchedTexture::dump()  // ONLY called from LLViewerFetchedTextureList  void LLViewerFetchedTexture::destroyTexture()   { -	if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory. -	{ -		return ; -	} +	//if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory. +	//{ +	//	return ; +	//}  	if (mNeedsCreateTexture)//return if in the process of generating a new texture.  	{  		return ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 528e0080b7..9a6c0569a9 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -705,7 +705,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			// Flush formatted images using a lazy flush  			//  			const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding -			const F32 MAX_INACTIVE_TIME  = 50.f; // actually delete +			const F32 MAX_INACTIVE_TIME  = 20.f; // actually delete  			S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference  			S32 num_refs = imagep->getNumRefs(); diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h index dd7751acd7..3bc95cbfbf 100644 --- a/indra/newview/llviewervisualparam.h +++ b/indra/newview/llviewervisualparam.h @@ -83,11 +83,11 @@ public:  	// New Virtual functions  	virtual F32					getTotalDistortion() = 0; -	virtual const LLVector3&	getAvgDistortion() = 0; +	virtual const LLVector4a&	getAvgDistortion() = 0;  	virtual F32					getMaxDistortion() = 0; -	virtual LLVector3			getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0; -	virtual const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0; -	virtual const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0; +	virtual LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0; +	virtual const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0; +	virtual const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;  	// interface methods  	F32					getDisplayOrder() const		{ return getInfo()->mEditGroupDisplayOrder; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 39e330ad66..862d53c613 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -175,6 +175,7 @@  #include "llviewershadermgr.h"  #include "llviewerstats.h"  #include "llvoavatarself.h" +#include "llvopartgroup.h"  #include "llvovolume.h"  #include "llworld.h"  #include "llworldmapview.h" @@ -4660,6 +4661,8 @@ void LLViewerWindow::stopGL(BOOL save_state)  		LLVOAvatar::destroyGL();  		stop_glerror(); +		LLVOPartGroup::destroyGL(); +  		LLViewerDynamicTexture::destroyGL();  		stop_glerror(); @@ -4713,7 +4716,8 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)  		gBumpImageList.restoreGL();  		LLViewerDynamicTexture::restoreGL();  		LLVOAvatar::restoreGL(); -		 +		LLVOPartGroup::restoreGL(); +  		gResizeScreenTexture = TRUE;  		gWindowResized = TRUE; @@ -4759,8 +4763,11 @@ void LLViewerWindow::requestResolutionUpdate()  	mResDirty = true;  } +static LLFastTimer::DeclareTimer FTM_WINDOW_CHECK_SETTINGS("Window Settings"); +  void LLViewerWindow::checkSettings()  { +	LLFastTimer t(FTM_WINDOW_CHECK_SETTINGS);  	if (mStatesDirty)  	{  		gGL.refreshState(); @@ -5196,8 +5203,10 @@ void LLPickInfo::getSurfaceInfo()  			if (objectp->mDrawable.notNull() && mObjectFace > -1)  			{  				LLFace* facep = objectp->mDrawable->getFace(mObjectFace); - -				mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); +				if (facep) +				{ +					mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); +				}  			}  			// and XY coords: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index eada77156e..28a25f744b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -817,6 +817,7 @@ LLVOAvatar::~LLVOAvatar()  	lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;  	mRoot.removeAllChildren(); +	mJointMap.clear();  	deleteAndClearArray(mSkeleton);  	deleteAndClearArray(mCollisionVolumes); @@ -961,7 +962,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)  		}  		if (mBakedTextureDatas[i].mMaskTexName)  		{ -			glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName)); +			LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));  			mBakedTextureDatas[i].mMaskTexName = 0 ;  		}  	} @@ -1459,8 +1460,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector)  	const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);  	mLastAnimExtents[0] += shift;  	mLastAnimExtents[1] += shift; -	mNeedsImpostorUpdate = TRUE; -	mNeedsAnimUpdate = TRUE;  }  void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) @@ -1934,6 +1933,7 @@ void LLVOAvatar::buildCharacter()  	// remove all of mRoot's children  	//-------------------------------------------------------------------------  	mRoot.removeAllChildren(); +	mJointMap.clear();  	mIsBuilt = FALSE;  	//------------------------------------------------------------------------- @@ -2094,11 +2094,17 @@ void LLVOAvatar::releaseMeshData()  	if (mDrawable.notNull())  	{  		LLFace* facep = mDrawable->getFace(0); -		facep->setSize(0, 0); -		for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) +		if (facep)  		{ -			facep = mDrawable->getFace(i);  			facep->setSize(0, 0); +			for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) +			{ +				facep = mDrawable->getFace(i); +				if (facep) +				{ +					facep->setSize(0, 0); +				} +			}  		}  	} @@ -2183,15 +2189,20 @@ void LLVOAvatar::updateMeshData()  				part_index-- ;  			} -			LLFace* facep ; +			LLFace* facep = NULL;  			if(f_num < mDrawable->getNumFaces())   			{  				facep = mDrawable->getFace(f_num);  			}  			else  			{ -				facep = mDrawable->addFace(mDrawable->getFace(0)->getPool(), mDrawable->getFace(0)->getTexture()) ; +				facep = mDrawable->getFace(0); +				if (facep) +				{ +					facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ; +				}  			} +			if (!facep) continue;  			// resize immediately  			facep->setSize(num_vertices, num_indices); @@ -2379,7 +2390,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)  	}  } -static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar"); +static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update");  static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints");  //------------------------------------------------------------------------ @@ -4236,10 +4247,14 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  			mNeedsSkin = FALSE;  			mLastSkinTime = gFrameTimeSeconds; -			LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer(); -			if (vb) +			LLFace * face = mDrawable->getFace(0); +			if (face)  			{ -				vb->flush(); +				LLVertexBuffer* vb = face->getVertexBuffer(); +				if (vb) +				{ +					vb->flush(); +				}  			}  		}  	} @@ -5122,7 +5137,20 @@ const LLUUID& LLVOAvatar::getID() const  // RN: avatar joints are multi-rooted to include screen-based attachments  LLJoint *LLVOAvatar::getJoint( const std::string &name )  { -	LLJoint* jointp = mRoot.findJoint(name); +	joint_map_t::iterator iter = mJointMap.find(name); + +	LLJoint* jointp = NULL; + +	if (iter == mJointMap.end() || iter->second == NULL) +	{ //search for joint and cache found joint in lookup table +		jointp = mRoot.findJoint(name); +		mJointMap[name] = jointp; +	} +	else +	{ //return cached pointer +		jointp = iter->second; +	} +  	return jointp;  } @@ -7492,7 +7520,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  			}  			U32 gl_name; -			LLImageGL::generateTextures(1, &gl_name ); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name );  			stop_glerror();  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name); @@ -7529,7 +7557,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  						maskData->mLastDiscardLevel = discard_level;  						if (self->mBakedTextureDatas[baked_index].mMaskTexName)  						{ -							LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); +							LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));  						}  						self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;  						found_texture_id = true; @@ -8395,7 +8423,7 @@ BOOL LLVOAvatar::updateLOD()  	BOOL res = updateJointLODs();  	LLFace* facep = mDrawable->getFace(0); -	if (!facep->getVertexBuffer()) +	if (!facep || !facep->getVertexBuffer())  	{  		dirtyMesh(2);  	} diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 6fb56a4c0b..fab15c200d 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -356,6 +356,10 @@ public:  	LLVector3			mHeadOffset; // current head position  	LLViewerJoint		mRoot; + +	typedef std::map<std::string, LLJoint*> joint_map_t; +	joint_map_t			mJointMap; +  protected:  	static BOOL			parseSkeletonFile(const std::string& filename);  	void				buildCharacter(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d2609e5587..98f7245f8d 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2751,7 +2751,7 @@ void LLVOAvatarSelf::deleteScratchTextures()  		 namep;   		 namep = sScratchTexNames.getNextData() )  	{ -		LLImageGL::deleteTextures(1, (U32 *)namep ); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep );  		stop_glerror();  	} diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 8a79d564d3..5ad9ccc9af 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -34,6 +34,7 @@  #include "llagentcamera.h"  #include "llnotificationsutil.h"  #include "lldrawable.h" +#include "lldrawpoolalpha.h"  #include "llface.h"  #include "llsky.h"  #include "llsurface.h" @@ -380,8 +381,10 @@ BOOL LLVOGrass::updateLOD()  		{  			mNumBlades <<= 1;  		} - -		face->setSize(mNumBlades*8, mNumBlades*12); +		if (face) +		{ +			face->setSize(mNumBlades*8, mNumBlades*12); +		}  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);  	}  	else if (num_blades <= (mNumBlades >> 1)) @@ -391,7 +394,10 @@ BOOL LLVOGrass::updateLOD()  			mNumBlades >>=1;  		} -		face->setSize(mNumBlades*8, mNumBlades*12); +		if (face) +		{ +			face->setSize(mNumBlades*8, mNumBlades*12); +		}  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);  		return TRUE;  	} @@ -449,14 +455,16 @@ void LLVOGrass::plantBlades()  	}  	LLFace *face = mDrawable->getFace(0); +	if (face) +	{ +		face->setTexture(getTEImage(0)); +		face->setState(LLFace::GLOBAL); +		face->setSize(mNumBlades * 8, mNumBlades * 12); +		face->setVertexBuffer(NULL); +		face->setTEOffset(0); +		face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); +	} -	face->setTexture(getTEImage(0)); -	face->setState(LLFace::GLOBAL); -	face->setSize(mNumBlades * 8, mNumBlades * 12); -	face->setVertexBuffer(NULL); -	face->setTEOffset(0); -	face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); -	  	mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();  	mDrawable->setPosition(face->mCenterLocal);  	mDrawable->movePartition(); @@ -486,6 +494,8 @@ void LLVOGrass::getGeometry(S32 idx,  	LLColor4U color(255,255,255,255);  	LLFace *face = mDrawable->getFace(idx); +	if (!face) +		return;  	F32 width  = sSpeciesTable[mSpecies]->mBladeSizeX;  	F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; @@ -594,6 +604,7 @@ U32 LLVOGrass::getPartitionType() const  }  LLGrassPartition::LLGrassPartition() +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)  {  	mDrawableType = LLPipeline::RENDER_TYPE_GRASS;  	mPartitionType = LLViewerRegion::PARTITION_GRASS; @@ -604,6 +615,143 @@ LLGrassPartition::LLGrassPartition()  	mBufferUsage = GL_DYNAMIC_DRAW_ARB;  } +void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) +{ +	group->mBufferUsage = mBufferUsage; + +	mFaceList.clear(); + +	LLViewerCamera* camera = LLViewerCamera::getInstance(); +	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) +	{ +		LLDrawable* drawablep = *i; +		 +		if (drawablep->isDead()) +		{ +			continue; +		} + +		LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get(); +		obj->mDepth = 0.f; +		 +		if (drawablep->isAnimating()) +		{ +			group->mBufferUsage = GL_STREAM_DRAW_ARB; +		} + +		U32 count = 0; +		for (S32 j = 0; j < drawablep->getNumFaces(); ++j) +		{ +			drawablep->updateFaceSize(j); + +			LLFace* facep = drawablep->getFace(j); +			if ( !facep || !facep->hasGeometry()) +			{ +				continue; +			} +			 +			if ((facep->getGeomCount() + vertex_count) <= 65536) +			{ +				count++; +				facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis(); +				obj->mDepth += facep->mDistance; +			 +				mFaceList.push_back(facep); +				vertex_count += facep->getGeomCount(); +				index_count += facep->getIndicesCount(); +				llassert(facep->getIndicesCount() < 65536); +			} +			else +			{ +				facep->clearVertexBuffer(); +			} +		} +		 +		obj->mDepth /= count; +	} +} + +static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB"); + +void LLGrassPartition::getGeometry(LLSpatialGroup* group) +{ +	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); +	LLFastTimer ftm(FTM_REBUILD_GRASS_VB); + +	std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); + +	U32 index_count = 0; +	U32 vertex_count = 0; + +	group->clearDrawMap(); + +	LLVertexBuffer* buffer = group->mVertexBuffer; + +	LLStrider<U16> indicesp; +	LLStrider<LLVector4a> verticesp; +	LLStrider<LLVector3> normalsp; +	LLStrider<LLVector2> texcoordsp; +	LLStrider<LLColor4U> colorsp; + +	buffer->getVertexStrider(verticesp); +	buffer->getNormalStrider(normalsp); +	buffer->getColorStrider(colorsp); +	buffer->getTexCoord0Strider(texcoordsp); +	buffer->getIndexStrider(indicesp); + +	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];	 + +	for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) +	{ +		LLFace* facep = *i; +		LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); +		facep->setGeomIndex(vertex_count); +		facep->setIndicesIndex(index_count); +		facep->setVertexBuffer(buffer); +		facep->setPoolType(LLDrawPool::POOL_ALPHA); +		object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); +		 +		vertex_count += facep->getGeomCount(); +		index_count += facep->getIndicesCount(); + +		S32 idx = draw_vec.size()-1; + +		BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); +		F32 vsize = facep->getVirtualSize(); + +		if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && +			draw_vec[idx]->mTexture == facep->getTexture() && +			(U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && +			//draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && +			draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 && +			draw_vec[idx]->mFullbright == fullbright) +		{ +			draw_vec[idx]->mCount += facep->getIndicesCount(); +			draw_vec[idx]->mEnd += facep->getGeomCount(); +			draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); +		} +		else +		{ +			U32 start = facep->getGeomIndex(); +			U32 end = start + facep->getGeomCount()-1; +			U32 offset = facep->getIndicesStart(); +			U32 count = facep->getIndicesCount(); +			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),  +				//facep->getTexture(), +				buffer, fullbright);  +			info->mExtents[0] = group->mObjectExtents[0]; +			info->mExtents[1] = group->mObjectExtents[1]; +			info->mVSize = vsize; +			draw_vec.push_back(info); +			//for alpha sorting +			facep->setDrawInfo(info); +		} +	} + +	buffer->flush(); +	mFaceList.clear(); +} +  // virtual  void LLVOGrass::updateDrawable(BOOL force_damped)  { diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 0060f81ab5..6da54435e3 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -82,6 +82,7 @@ LLDrawable *LLVOGround::createDrawable(LLPipeline *pipeline)  	return mDrawable;  } +// TO DO - this always returns TRUE,   BOOL LLVOGround::updateGeometry(LLDrawable *drawable)  {  	LLStrider<LLVector3> verticesp; @@ -96,6 +97,8 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)  	if (drawable->getNumFaces() < 1)  		drawable->addFace(poolp, NULL);  	face = drawable->getFace(0);  +	if (!face) +		return TRUE;  	if (!face->getVertexBuffer())  	{ diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 5c10a80b07..9cce68fff6 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -48,6 +48,120 @@ const F32 MAX_PART_LIFETIME = 120.f;  extern U64 gFrameTime; +LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL; +S32 LLVOPartGroup::sVBSlotFree[]; +S32* LLVOPartGroup::sVBSlotCursor = NULL; + +void LLVOPartGroup::initClass() +{ +	for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i) +	{ +		sVBSlotFree[i] = i; +	} + +	sVBSlotCursor = sVBSlotFree; +} + +//static +void LLVOPartGroup::restoreGL() +{ +	sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); +	U32 count = LL_MAX_PARTICLE_COUNT; +	sVB->allocateBuffer(count*4, count*6, true); + +	//indices and texcoords are always the same, set once +	LLStrider<U16> indicesp; + +	LLStrider<LLVector4a> verticesp; + +	sVB->getIndexStrider(indicesp); +	sVB->getVertexStrider(verticesp); + +	LLVector4a v; +	v.set(0,0,0,0); + +	 +	U16 vert_offset = 0; + +	for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++) +	{ +		*indicesp++ = vert_offset + 0; +		*indicesp++ = vert_offset + 1; +		*indicesp++ = vert_offset + 2; + +		*indicesp++ = vert_offset + 1; +		*indicesp++ = vert_offset + 3; +		*indicesp++ = vert_offset + 2; + +		*verticesp++ = v; + +		vert_offset += 4; +	} + +	LLStrider<LLVector2> texcoordsp; +	sVB->getTexCoord0Strider(texcoordsp); + +	for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++) +	{ +		*texcoordsp++ = LLVector2(0.f, 1.f); +		*texcoordsp++ = LLVector2(0.f, 0.f); +		*texcoordsp++ = LLVector2(1.f, 1.f); +		*texcoordsp++ = LLVector2(1.f, 0.f); +	} + +	sVB->flush(); + +} + +//static +void LLVOPartGroup::destroyGL() +{ +	sVB = NULL; +} + +//static +S32 LLVOPartGroup::findAvailableVBSlot() +{ +	if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT) +	{ //no more available slots +		return -1; +	} + +	S32 ret = *sVBSlotCursor; +	sVBSlotCursor++; + +	return ret; +} + +bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) +{ +	while (start < end) +	{ +		if (*start == idx) +		{ //not allocated (in free list) +			return false; +		} +		++start; +	} + +	//allocated (not in free list) +	return true; +} + +//static +void LLVOPartGroup::freeVBSlot(S32 idx) +{ +	llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); +	llassert(sVBSlotCursor > sVBSlotFree); +	llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); + +	if (sVBSlotCursor > sVBSlotFree) +	{ +		sVBSlotCursor--; +		*sVBSlotCursor = idx; +	} +} +  LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  	:	LLAlphaObject(id, pcode, regionp),  		mViewerPartGroupp(NULL) @@ -62,7 +176,6 @@ LLVOPartGroup::~LLVOPartGroup()  {  } -  BOOL LLVOPartGroup::isActive() const  {  	return FALSE; @@ -287,9 +400,6 @@ void LLVOPartGroup::getGeometry(S32 idx,  	const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx])); -	U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex(); - -	  	LLVector4a part_pos_agent;  	part_pos_agent.load3(part.mPosAgent.mV);  	LLVector4a camera_agent; @@ -361,33 +471,18 @@ void LLVOPartGroup::getGeometry(S32 idx,  	verticesp->setAdd(ppamu, right);  	(*verticesp++).getF32ptr()[3] = 0.f; -	//*verticesp++ = part_pos_agent + up - right; -	//*verticesp++ = part_pos_agent - up - right; -	//*verticesp++ = part_pos_agent + up + right; -	//*verticesp++ = part_pos_agent - up + right; -  	*colorsp++ = part.mColor;  	*colorsp++ = part.mColor;  	*colorsp++ = part.mColor;  	*colorsp++ = part.mColor; -	*texcoordsp++ = LLVector2(0.f, 1.f); -	*texcoordsp++ = LLVector2(0.f, 0.f); -	*texcoordsp++ = LLVector2(1.f, 1.f); -	*texcoordsp++ = LLVector2(1.f, 0.f); - -	*normalsp++   = normal; -	*normalsp++   = normal; -	*normalsp++   = normal; -	*normalsp++   = normal; - -	*indicesp++ = vert_offset + 0; -	*indicesp++ = vert_offset + 1; -	*indicesp++ = vert_offset + 2; - -	*indicesp++ = vert_offset + 1; -	*indicesp++ = vert_offset + 3; -	*indicesp++ = vert_offset + 2; +	if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)) +	{ //not fullbright, needs normal +		*normalsp++   = normal; +		*normalsp++   = normal; +		*normalsp++   = normal; +		*normalsp++   = normal; +	}  }  U32 LLVOPartGroup::getPartitionType() const @@ -412,6 +507,49 @@ LLHUDParticlePartition::LLHUDParticlePartition() :  	mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;  } +static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO"); + +void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) +{ +	if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) +	{ +		return; +	} + +	if (group->changeLOD()) +	{ +		group->mLastUpdateDistance = group->mDistance; +		group->mLastUpdateViewAngle = group->mViewAngle; +	} +	 +	LLFastTimer ftm(FTM_REBUILD_PARTICLE_VBO);	 + +	group->clearDrawMap(); +	 +	//get geometry count +	U32 index_count = 0; +	U32 vertex_count = 0; + +	addGeometryCount(group, vertex_count, index_count); +	 + +	if (vertex_count > 0 && index_count > 0) +	{  +		group->mBuilt = 1.f; +		//use one vertex buffer for all groups +		group->mVertexBuffer = LLVOPartGroup::sVB; +		getGeometry(group); +	} +	else +	{ +		group->mVertexBuffer = NULL; +		group->mBufferMap.clear(); +	} + +	group->mLastUpdateTime = gFrameTimeSeconds; +	group->clearState(LLSpatialGroup::GEOM_DIRTY); +} +  void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)  {  	group->mBufferUsage = mBufferUsage; @@ -419,7 +557,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  	mFaceList.clear();  	LLViewerCamera* camera = LLViewerCamera::getInstance(); -	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{  		LLDrawable* drawablep = *i; @@ -431,11 +569,6 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  		LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();  		obj->mDepth = 0.f; -		if (drawablep->isAnimating()) -		{ -			group->mBufferUsage = GL_STREAM_DRAW_ARB; -		} -  		U32 count = 0;  		for (S32 j = 0; j < drawablep->getNumFaces(); ++j)  		{ @@ -447,13 +580,14 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  				continue;  			} +			vertex_count += facep->getGeomCount(); +			index_count += facep->getIndicesCount(); +  			count++;  			facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();  			obj->mDepth += facep->mDistance;  			mFaceList.push_back(facep); -			vertex_count += facep->getGeomCount(); -			index_count += facep->getIndicesCount();  			llassert(facep->getIndicesCount() < 65536);  		} @@ -461,15 +595,13 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  	}  } -static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB"); -static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB"); + +static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_GEOM("Particle Geom");  void LLParticlePartition::getGeometry(LLSpatialGroup* group)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -	LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ? -					FTM_REBUILD_GRASS_VB : -					FTM_REBUILD_PARTICLE_VB); +	LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);  	std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); @@ -489,21 +621,45 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  	buffer->getVertexStrider(verticesp);  	buffer->getNormalStrider(normalsp);  	buffer->getColorStrider(colorsp); -	buffer->getTexCoord0Strider(texcoordsp); -	buffer->getIndexStrider(indicesp); - +	  	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];	  	for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)  	{  		LLFace* facep = *i;  		LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); -		facep->setGeomIndex(vertex_count); -		facep->setIndicesIndex(index_count); -		facep->setVertexBuffer(buffer); -		facep->setPoolType(LLDrawPool::POOL_ALPHA); -		object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); + +		if (!facep->isState(LLFace::PARTICLE)) +		{ //set the indices of this face +			S32 idx = LLVOPartGroup::findAvailableVBSlot(); +			if (idx >= 0) +			{ +				facep->setGeomIndex(idx*4); +				facep->setIndicesIndex(idx*6); +				facep->setVertexBuffer(LLVOPartGroup::sVB); +				facep->setPoolType(LLDrawPool::POOL_ALPHA); +				facep->setState(LLFace::PARTICLE); +			} +			else +			{ +				continue; //out of space in particle buffer +			}		 +		} + +		S32 geom_idx = (S32) facep->getGeomIndex(); + +		LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart(); +		LLStrider<LLVector4a> cur_vert = verticesp + geom_idx; +		LLStrider<LLVector3> cur_norm = normalsp + geom_idx; +		LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx; +		LLStrider<LLColor4U> cur_col = colorsp + geom_idx; + +		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx); +		llassert(facep->getGeomCount() == 4); +		llassert(facep->getIndicesCount() == 6); + +  		vertex_count += facep->getGeomCount();  		index_count += facep->getIndicesCount(); @@ -512,18 +668,31 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  		BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);  		F32 vsize = facep->getVirtualSize(); -		if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && +		bool batched = false; +	 +		if (idx >= 0 &&  			draw_vec[idx]->mTexture == facep->getTexture() && -			(U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && -			//draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && -			draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&  			draw_vec[idx]->mFullbright == fullbright)  		{ -			draw_vec[idx]->mCount += facep->getIndicesCount(); -			draw_vec[idx]->mEnd += facep->getGeomCount(); -			draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); +			if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1) +			{ +				batched = true; +				draw_vec[idx]->mCount += facep->getIndicesCount(); +				draw_vec[idx]->mEnd += facep->getGeomCount(); +				draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); +			} +			else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1) +			{ +				batched = true; +				draw_vec[idx]->mCount += facep->getIndicesCount(); +				draw_vec[idx]->mStart -= facep->getGeomCount(); +				draw_vec[idx]->mOffset = facep->getIndicesStart(); +				draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); +			}  		} -		else + + +		if (!batched)  		{  			U32 start = facep->getGeomIndex();  			U32 end = start + facep->getGeomCount()-1; @@ -541,7 +710,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  		}  	} -	buffer->flush();  	mFaceList.clear();  } diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index e58fed86d9..43b2844f07 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -31,18 +31,33 @@  #include "v3math.h"  #include "v3color.h"  #include "llframetimer.h" +#include "llviewerpartsim.h" +#include "llvertexbuffer.h"  class LLViewerPartGroup;  class LLVOPartGroup : public LLAlphaObject  {  public: + +	//vertex buffer for holding all particles +	static LLPointer<LLVertexBuffer> sVB; +	static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT]; +	static S32* sVBSlotCursor; + +	static void initClass(); +	static void restoreGL(); +	static void destroyGL(); +	static S32 findAvailableVBSlot(); +	static void freeVBSlot(S32 idx); +  	enum  	{ -		VERTEX_DATA_MASK =	(1 << LLVertexBuffer::TYPE_VERTEX) | -							(1 << LLVertexBuffer::TYPE_NORMAL) | -							(1 << LLVertexBuffer::TYPE_TEXCOORD0) | -							(1 << LLVertexBuffer::TYPE_COLOR) +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +							LLVertexBuffer::MAP_NORMAL | +							LLVertexBuffer::MAP_TEXCOORD0 | +							LLVertexBuffer::MAP_COLOR | +							LLVertexBuffer::MAP_TEXTURE_INDEX  	};  	LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index bf6158eeaf..94a3111f4c 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -296,18 +296,20 @@ void LLVOSurfacePatch::updateFaceSize(S32 idx)  	}  	LLFace* facep = mDrawable->getFace(idx); - -	S32 num_vertices = 0; -	S32 num_indices = 0; -	 -	if (mLastStride) +	if (facep)  	{ -		getGeomSizesMain(mLastStride, num_vertices, num_indices); -		getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices); -		getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices); -	} +		S32 num_vertices = 0; +		S32 num_indices = 0; +	 +		if (mLastStride) +		{ +			getGeomSizesMain(mLastStride, num_vertices, num_indices); +			getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices); +			getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices); +		} -	facep->setSize(num_vertices, num_indices);	 +		facep->setSize(num_vertices, num_indices);	 +	}  }  BOOL LLVOSurfacePatch::updateLOD() @@ -322,30 +324,32 @@ void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,  								LLStrider<U16> &indicesp)  {  	LLFace* facep = mDrawable->getFace(0); +	if (facep) +	{ +		U32 index_offset = facep->getGeomIndex(); -	U32 index_offset = facep->getGeomIndex(); - -	updateMainGeometry(facep,  -					verticesp, -					normalsp, -					texCoords0p, -					texCoords1p, -					indicesp, -					index_offset); -	updateNorthGeometry(facep,  -						verticesp, -						normalsp, -						texCoords0p, -						texCoords1p, -						indicesp, -						index_offset); -	updateEastGeometry(facep,  +		updateMainGeometry(facep,   						verticesp,  						normalsp,  						texCoords0p,  						texCoords1p,  						indicesp,  						index_offset); +		updateNorthGeometry(facep,  +							verticesp, +							normalsp, +							texCoords0p, +							texCoords1p, +							indicesp, +							index_offset); +		updateEastGeometry(facep,  +							verticesp, +							normalsp, +							texCoords0p, +							texCoords1p, +							indicesp, +							index_offset); +	}  }  void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -864,7 +868,11 @@ void LLVOSurfacePatch::dirtyGeom()  	if (mDrawable)  	{  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); -		mDrawable->getFace(0)->setVertexBuffer(NULL); +		LLFace* facep = mDrawable->getFace(0); +		if (facep) +		{ +			facep->setVertexBuffer(NULL); +		}  		mDrawable->movePartition();  	}  } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 4564207da4..337ddfb24d 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -374,7 +374,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); @@ -490,11 +490,16 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)  	if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree.  	{  		mReferenceBuffer = NULL ; -		mDrawable->getFace(0)->setVertexBuffer(NULL); +		LLFace * facep = drawable->getFace(0); +		if (facep) +		{ +			facep->setVertexBuffer(NULL); +		}  		return TRUE ;  	} -	if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()) +	if (mDrawable->getFace(0) && +		(mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()))  	{  		const F32 SRR3 = 0.577350269f; // sqrt(1/3)  		const F32 SRR2 = 0.707106781f; // sqrt(1/2) @@ -507,6 +512,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)  		S32 lod;  		LLFace *face = drawable->getFace(0); +		if (!face) return TRUE;  		face->mCenterAgent = getPositionAgent();  		face->mCenterLocal = face->mCenterAgent; @@ -837,10 +843,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 @@ -879,6 +885,7 @@ void LLVOTree::updateMesh()  	calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches);  	LLFace* facep = mDrawable->getFace(0); +	if (!facep) return;  	LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);  	buff->allocateBuffer(vert_count, index_count, TRUE);  	facep->setVertexBuffer(buff); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 080d1f774a..082818b112 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -520,6 +520,7 @@ void LLVOVolume::animateTextures()  		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(); @@ -638,8 +639,8 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  {  	LLViewerObject::idleUpdate(agent, world, time); -	static LLFastTimer::DeclareTimer ftm("Volume"); -	LLFastTimer t(ftm); +	//static LLFastTimer::DeclareTimer ftm("Volume Idle"); +	//LLFastTimer t(ftm);  	if (mDead || mDrawable.isNull())  	{ @@ -682,7 +683,21 @@ void LLVOVolume::updateTextures()  	const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds  	if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)  	{ -		updateTextureVirtualSize();		 +		updateTextureVirtualSize(); + +		if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) +		{ //delete vertex buffer to free up some VRAM +			LLSpatialGroup* group  = mDrawable->getSpatialGroup(); +			if (group) +			{ +				group->destroyGL(true); + +				//flag the group as having changed geometry so it gets a rebuild next time +				//it becomes visible +				group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); +			} +		} +  	}  } @@ -715,7 +730,18 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  	if(!forced)  	{  		if(!isVisible()) -		{ +		{ //don't load textures for non-visible faces +			const S32 num_faces = mDrawable->getNumFaces(); +			for (S32 i = 0; i < num_faces; i++) +			{ +				LLFace* face = mDrawable->getFace(i); +				if (face) +				{ +					face->setPixelArea(0.f);  +					face->setVirtualSize(0.f); +				} +			} +  			return ;  		} @@ -743,6 +769,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  	for (S32 i = 0; i < num_faces; i++)  	{  		LLFace* face = mDrawable->getFace(i); +		if (!face) continue;  		const LLTextureEntry *te = face->getTextureEntry();  		LLViewerTexture *imagep = face->getTexture();  		if (!imagep || !te ||			 @@ -1062,9 +1089,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  			}  		} + +		static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + +		bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && +			(!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); + +		if (cache_in_vram) +		{ //this volume might be used as source data for a transform object, put it in vram +			LLVolume* volume = getVolume(); +			for (S32 i = 0; i < volume->getNumFaces(); ++i) +			{ +				const LLVolumeFace& face = volume->getVolumeFace(i); +				if (face.mVertexBuffer.notNull()) +				{ //already cached +					break; +				} +				volume->genBinormals(i); +				LLFace::cacheFaceInVRAM(face); +			} +		} +		 +  		return TRUE;  	} + +  	return FALSE;  } @@ -1246,7 +1297,8 @@ BOOL LLVOVolume::calcLOD()  									llround(radius, 0.01f)); -	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO)) +	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && +		mDrawable->getFace(0))  	{  		//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); @@ -1325,25 +1377,23 @@ void LLVOVolume::updateFaceFlags()  	for (S32 i = 0; i < getVolume()->getNumFaces(); i++)  	{  		LLFace *face = mDrawable->getFace(i); -		if (!face) +		if (face)  		{ -			return; -		} +			BOOL fullbright = getTE(i)->getFullbright(); +			face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); -		BOOL fullbright = getTE(i)->getFullbright(); -		face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); - -		if (fullbright || (mMaterial == LL_MCODE_LIGHT)) -		{ -			face->setState(LLFace::FULLBRIGHT); -		} -		if (mDrawable->isLight()) -		{ -			face->setState(LLFace::LIGHT); -		} -		if (isHUDAttachment()) -		{ -			face->setState(LLFace::HUD_RENDER); +			if (fullbright || (mMaterial == LL_MCODE_LIGHT)) +			{ +				face->setState(LLFace::FULLBRIGHT); +			} +			if (mDrawable->isLight()) +			{ +				face->setState(LLFace::LIGHT); +			} +			if (isHUDAttachment()) +			{ +				face->setState(LLFace::HUD_RENDER); +			}  		}  	}  } @@ -1380,6 +1430,8 @@ void LLVOVolume::regenFaces()  	for (S32 i = 0; i < mNumFaces; i++)  	{  		LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); +		if (!facep) continue; +  		facep->setTEOffset(i);  		facep->setTexture(getTEImage(i));  		facep->setViewerObject(this); @@ -1416,7 +1468,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); -//	bool rigged = false; +	//	bool rigged = false;  	LLVolume* volume = mRiggedVolume;  	if (!volume)  	{ @@ -1471,11 +1523,11 @@ void LLVOVolume::preRebuild()  	}  } -void LLVOVolume::updateRelativeXform() +void LLVOVolume::updateRelativeXform(bool force_identity)  {  	if (mVolumeImpl)  	{ -		mVolumeImpl->updateRelativeXform(); +		mVolumeImpl->updateRelativeXform(force_identity);  		return;  	} @@ -1495,15 +1547,16 @@ void LLVOVolume::updateRelativeXform()  		mRelativeXform.invert();  		mRelativeXformInvTrans.transpose();  	} -	else if (drawable->isActive()) +	else if (drawable->isActive() || force_identity)  	{				  		// setup relative transforms  		LLQuaternion delta_rot;  		LLVector3 delta_pos, delta_scale;  		//matrix from local space to parent relative/global space -		delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation(); -		delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition(); +		bool use_identity = force_identity || drawable->isSpatialRoot(); +		delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); +		delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();  		delta_scale = mDrawable->getScale();  		// Vertex transform (4x4) @@ -1604,7 +1657,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  		return res;  	} -	dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); +	LLSpatialGroup* group = drawable->getSpatialGroup(); +	if (group) +	{ +		group->dirtyMesh(); +	}  	BOOL compiled = FALSE; @@ -1617,6 +1674,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  	if (mVolumeChanged || mFaceMappingChanged )  	{ +		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); +  		compiled = TRUE;  		if (mVolumeChanged) @@ -1635,6 +1694,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  	}  	else if ((mLODChanged) || (mSculptChanged))  	{ +		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); +  		LLVolume *old_volumep, *new_volumep;  		F32 old_lod, new_lod;  		S32 old_num_faces, new_num_faces ; @@ -1716,16 +1777,19 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  void LLVOVolume::updateFaceSize(S32 idx)  {  	LLFace* facep = mDrawable->getFace(idx); -	if (idx >= getVolume()->getNumVolumeFaces()) +	if (facep)  	{ -		facep->setSize(0,0, true); -	} -	else -	{ -		const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); -		facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,  -						true); // <--- volume faces should be padded for 16-byte alignment +		if (idx >= getVolume()->getNumVolumeFaces()) +		{ +			facep->setSize(0,0, true); +		} +		else +		{ +			const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); +			facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,  +							true); // <--- volume faces should be padded for 16-byte alignment +		}  	}  } @@ -3098,6 +3162,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  	for (S32 i = 0; i < num_faces; ++i)  	{  		const LLFace* face = drawablep->getFace(i); +		if (!face) continue;  		const LLTextureEntry* te = face->getTextureEntry();  		const LLViewerTexture* img = face->getTexture(); @@ -3369,6 +3434,7 @@ F32 LLVOVolume::getBinRadius()  		for (S32 i = 0; i < mDrawable->getNumFaces(); i++)  		{  			LLFace* face = mDrawable->getFace(i); +			if (!face) continue;  			if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&  			    !face->canRenderAsMask())  			{ @@ -3450,9 +3516,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const  {  	LLVector3 ret = pos - getRenderPosition();  	ret = ret * ~getRenderRotation(); -	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); -	LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); -	ret.scaleVec(invObjScale); +	if (!isVolumeGlobal()) +	{ +		LLVector3 objScale = getScale(); +		LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); +		ret.scaleVec(invObjScale); +	}  	return ret;  } @@ -3470,8 +3539,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const  LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const  {  	LLVector3 ret = dir; -	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); -	ret.scaleVec(objScale); +	if (!isVolumeGlobal()) +	{ +		LLVector3 objScale = getScale(); +		ret.scaleVec(objScale); +	} +  	ret = ret * getRenderRotation();  	ret += getRenderPosition(); @@ -3592,7 +3665,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			{  				LLFace* face = mDrawable->getFace(face_hit);				 -				if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) +				if (face && +					(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))  				{  					v_end = p;  					if (face_hitp != NULL) @@ -3902,8 +3976,11 @@ bool can_batch_texture(LLFace* facep)  	return true;  } +static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face"); +  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  { +	LLFastTimer t(FTM_REGISTER_FACE);  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);  	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) @@ -3935,9 +4012,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	const LLMatrix4* model_mat = NULL;  	LLDrawable* drawable = facep->getDrawable(); -	if (drawable->isActive()) +	 +	if (drawable->isState(LLDrawable::ANIMATED_CHILD))  	{ -		model_mat = &(drawable->getRenderMatrix()); +		model_mat = &drawable->getWorldMatrix(); +	} +	else if (drawable->isActive()) +	{ +		model_mat = &drawable->getRenderMatrix();  	}  	else  	{ @@ -3948,6 +4030,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		}  	} +	//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); +  	U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;  	LLViewerTexture* tex = facep->getTexture(); @@ -4041,8 +4125,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)  } -static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); -static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info");  static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)  { @@ -4073,6 +4158,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)  void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  { +	 +  	if (group->changeLOD())  	{  		group->mLastUpdateDistance = group->mDistance; @@ -4084,19 +4171,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	{  		if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)  		{ -			LLFastTimer ftm(FTM_REBUILD_VBO);	 -			LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); -		  			rebuildMesh(group);  		}  		return;  	} -	group->mBuilt = 1.f; -	LLFastTimer ftm(FTM_REBUILD_VBO);	 - -	LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); +	LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); +	group->mBuilt = 1.f; +	  	LLVOAvatar* pAvatarVO = NULL;  	LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); @@ -4145,359 +4228,375 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	bool emissive = false; -	//get all the faces into a list -	for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)  	{ -		LLDrawable* drawablep = *drawable_iter; -		 -		if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) +		LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); + +		//get all the faces into a list +		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ -			continue; -		} +			LLDrawable* drawablep = *drawable_iter; +		 +			if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) +			{ +				continue; +			} -		if (drawablep->isAnimating()) -		{ //fall back to stream draw for animating verts -			useage = GL_STREAM_DRAW_ARB; -		} +			if (drawablep->isAnimating()) +			{ //fall back to stream draw for animating verts +				useage = GL_STREAM_DRAW_ARB; +			} -		LLVOVolume* vobj = drawablep->getVOVolume(); +			LLVOVolume* vobj = drawablep->getVOVolume(); -		if (!vobj) -		{ -			continue; -		} +			if (!vobj) +			{ +				continue; +			} -		if (vobj->isMesh() && -			(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) -		{ -			continue; -		} +			if (vobj->isMesh() && +				(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) +			{ +				continue; +			} -		LLVolume* volume = vobj->getVolume(); -		if (volume) -		{ -			const LLVector3& scale = vobj->getScale(); -			group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); -		} +			LLVolume* volume = vobj->getVolume(); +			if (volume) +			{ +				const LLVector3& scale = vobj->getScale(); +				group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); +			} -		llassert_always(vobj); -		vobj->updateTextureVirtualSize(true); -		vobj->preRebuild(); +			llassert_always(vobj); +			vobj->updateTextureVirtualSize(true); +			vobj->preRebuild(); -		drawablep->clearState(LLDrawable::HAS_ALPHA); +			drawablep->clearState(LLDrawable::HAS_ALPHA); -		bool rigged = vobj->isAttachment() &&  -					vobj->isMesh() &&  -					gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); +			bool rigged = vobj->isAttachment() &&  +						vobj->isMesh() &&  +						gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); -		bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); +			bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); -		bool is_rigged = false; +			bool is_rigged = false; -		//for each face -		for (S32 i = 0; i < drawablep->getNumFaces(); i++) -		{ -			LLFace* facep = drawablep->getFace(i); +			//for each face +			for (S32 i = 0; i < drawablep->getNumFaces(); i++) +			{ +				LLFace* facep = drawablep->getFace(i); +				if (!facep) +				{ +					continue; +				} -			//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render -			// batch, it will recover its vertex buffer reference from the spatial group -			facep->setVertexBuffer(NULL); +				//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render +				// batch, it will recover its vertex buffer reference from the spatial group +				facep->setVertexBuffer(NULL); -			//sum up face verts and indices -			drawablep->updateFaceSize(i); +				//sum up face verts and indices +				drawablep->updateFaceSize(i); -			if (rigged)  -			{ -				if (!facep->isState(LLFace::RIGGED)) -				{ //completely reset vertex buffer -					facep->clearVertexBuffer(); -				} +				if (rigged)  +				{ +					if (!facep->isState(LLFace::RIGGED)) +					{ //completely reset vertex buffer +						facep->clearVertexBuffer(); +					} -				facep->setState(LLFace::RIGGED); -				is_rigged = true; +					facep->setState(LLFace::RIGGED); +					is_rigged = true; -				//get drawpool of avatar with rigged face -				LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); +					//get drawpool of avatar with rigged face +					LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); -				//Determine if we've received skininfo that contains an -				//alternate bind matrix - if it does then apply the translational component -				//to the joints of the avatar. -				bool pelvisGotSet = false; +					//Determine if we've received skininfo that contains an +					//alternate bind matrix - if it does then apply the translational component +					//to the joints of the avatar. +					bool pelvisGotSet = false; -				if ( pAvatarVO ) -				{ -					LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); -					const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); -					 -					if ( pSkinData ) +					if ( pAvatarVO )  					{ -						const int bindCnt = pSkinData->mAlternateBindMatrix.size();								 -						if ( bindCnt > 0 ) -						{					 -							const int jointCnt = pSkinData->mJointNames.size(); -							const F32 pelvisZOffset = pSkinData->mPelvisOffset; -							bool fullRig = (jointCnt>=20) ? true : false; -							if ( fullRig ) -							{ -								for ( int i=0; i<jointCnt; ++i ) +						LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); +						const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); +					 +						if ( pSkinData ) +						{ +							const int bindCnt = pSkinData->mAlternateBindMatrix.size();								 +							if ( bindCnt > 0 ) +							{					 +								const int jointCnt = pSkinData->mJointNames.size(); +								const F32 pelvisZOffset = pSkinData->mPelvisOffset; +								bool fullRig = (jointCnt>=20) ? true : false; +								if ( fullRig )  								{ -									std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); -									//llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl; -									LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint ); -									if ( pJoint && pJoint->getId() != currentId ) -									{   									 -										pJoint->setId( currentId ); -										const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									 -										//Set the joint position -										pJoint->storeCurrentXform( jointPos );																																 -										//If joint is a pelvis then handle old/new pelvis to foot values -										if ( lookingForJoint == "mPelvis" ) -										{	 +									for ( int i=0; i<jointCnt; ++i ) +									{ +										std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); +										//llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl; +										LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint ); +										if ( pJoint && pJoint->getId() != currentId ) +										{   									 +											pJoint->setId( currentId ); +											const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									 +											//Set the joint position  											pJoint->storeCurrentXform( jointPos );																																 -											if ( !pAvatarVO->hasPelvisOffset() ) -											{										 -												pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); -												//Trigger to rebuild viewer AV -												pelvisGotSet = true;											 +											//If joint is a pelvis then handle old/new pelvis to foot values +											if ( lookingForJoint == "mPelvis" ) +											{	 +												pJoint->storeCurrentXform( jointPos );																																 +												if ( !pAvatarVO->hasPelvisOffset() ) +												{										 +													pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); +													//Trigger to rebuild viewer AV +													pelvisGotSet = true;											 +												}										  											}										 -										}										 +										}  									} -								} -							}							 +								}							 +							}  						}  					} -				} -				//If we've set the pelvis to a new position we need to also rebuild some information that the -				//viewer does at launch (e.g. body size etc.) -				if ( pelvisGotSet ) -				{ -					pAvatarVO->postPelvisSetRecalc(); -				} - -				if (pool) -				{ -					const LLTextureEntry* te = facep->getTextureEntry(); - -					//remove face from old pool if it exists -					LLDrawPool* old_pool = facep->getPool(); -					if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) +					//If we've set the pelvis to a new position we need to also rebuild some information that the +					//viewer does at launch (e.g. body size etc.) +					if ( pelvisGotSet )  					{ -						((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); +						pAvatarVO->postPelvisSetRecalc();  					} -					//add face to new pool -					LLViewerTexture* tex = facep->getTexture(); -					U32 type = gPipeline.getPoolTypeFromTE(te, tex); - -					if (type == LLDrawPool::POOL_ALPHA) +					if (pool)  					{ -						if (te->getColor().mV[3] > 0.f) +						const LLTextureEntry* te = facep->getTextureEntry(); + +						//remove face from old pool if it exists +						LLDrawPool* old_pool = facep->getPool(); +						if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) +						{ +							((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); +						} + +						//add face to new pool +						LLViewerTexture* tex = facep->getTexture(); +						U32 type = gPipeline.getPoolTypeFromTE(te, tex); + +						if (type == LLDrawPool::POOL_ALPHA) +						{ +							if (te->getColor().mV[3] > 0.f) +							{ +								if (te->getFullbright()) +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); +								} +								else +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); +								} +							} +						} +						else if (te->getShiny())  						{  							if (te->getFullbright())  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); +								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);  							}  							else  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); +								if (LLPipeline::sRenderDeferred) +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); +								} +								else +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); +								}  							}  						} -					} -					else if (te->getShiny()) -					{ -						if (te->getFullbright()) -						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); -						}  						else  						{ -							if (LLPipeline::sRenderDeferred) +							if (te->getFullbright())  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); +								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);  							}  							else  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); +								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);  							}  						} -					} -					else -					{ -						if (te->getFullbright()) -						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); -						} -						else + +						if (te->getGlow())  						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); +							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);  						} -					} -					if (te->getGlow()) -					{ -						pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); -					} - -					if (LLPipeline::sRenderDeferred) -					{ -						if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) +						if (LLPipeline::sRenderDeferred)  						{ -							if (te->getBumpmap()) +							if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())  							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); -							} -							else -							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); +								if (te->getBumpmap()) +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); +								} +								else +								{ +									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); +								}  							}  						}  					} -				} -				continue; -			} -			else -			{ -				if (facep->isState(LLFace::RIGGED)) -				{ //face is not rigged but used to be, remove from rigged face pool -					LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); -					if (pool) -					{ -						pool->removeRiggedFace(facep); +					continue; +				} +				else +				{ +					if (facep->isState(LLFace::RIGGED)) +					{ //face is not rigged but used to be, remove from rigged face pool +						LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); +						if (pool) +						{ +							pool->removeRiggedFace(facep); +						} +						facep->clearState(LLFace::RIGGED);  					} -					facep->clearState(LLFace::RIGGED);  				} -			} - - -			if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) -			{ -				facep->clearVertexBuffer(); -				continue; -			} - -			cur_total += facep->getGeomCount(); -			if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) -			{ -				const LLTextureEntry* te = facep->getTextureEntry(); -				LLViewerTexture* tex = facep->getTexture(); -				if (te->getGlow() >= 1.f/255.f) +				if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)  				{ -					emissive = true; +					facep->clearVertexBuffer(); +					continue;  				} -				if (facep->isState(LLFace::TEXTURE_ANIM)) -				{ -					if (!vobj->mTexAnimMode) -					{ -						facep->clearState(LLFace::TEXTURE_ANIM); -					} -				} +				cur_total += facep->getGeomCount(); -				BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); -				U32 type = gPipeline.getPoolTypeFromTE(te, tex); -				if (type != LLDrawPool::POOL_ALPHA && force_simple) +				if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)  				{ -					type = LLDrawPool::POOL_SIMPLE; -				} -				facep->setPoolType(type); +					const LLTextureEntry* te = facep->getTextureEntry(); +					LLViewerTexture* tex = facep->getTexture(); -				if (vobj->isHUDAttachment()) -				{ -					facep->setState(LLFace::FULLBRIGHT); -				} +					if (te->getGlow() >= 1.f/255.f) +					{ +						emissive = true; +					} -				if (vobj->mTextureAnimp && vobj->mTexAnimMode) -				{ -					if (vobj->mTextureAnimp->mFace <= -1) +					if (facep->isState(LLFace::TEXTURE_ANIM))  					{ -						S32 face; -						for (face = 0; face < vobj->getNumTEs(); face++) +						if (!vobj->mTexAnimMode)  						{ -							drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM); +							facep->clearState(LLFace::TEXTURE_ANIM);  						}  					} -					else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + +					BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); +					U32 type = gPipeline.getPoolTypeFromTE(te, tex); +					if (type != LLDrawPool::POOL_ALPHA && force_simple)  					{ -						drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM); +						type = LLDrawPool::POOL_SIMPLE;  					} -				} +					facep->setPoolType(type); -				if (type == LLDrawPool::POOL_ALPHA) -				{ -					if (facep->canRenderAsMask()) -					{ //can be treated as alpha mask -						simple_faces.push_back(facep); -					} -					else +					if (vobj->isHUDAttachment())  					{ -						if (te->getColor().mV[3] > 0.f) -						{ //only treat as alpha in the pipeline if < 100% transparent -							drawablep->setState(LLDrawable::HAS_ALPHA); -						} -						alpha_faces.push_back(facep); +						facep->setState(LLFace::FULLBRIGHT);  					} -				} -				else -				{ -					if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + +					if (vobj->mTextureAnimp && vobj->mTexAnimMode)  					{ -						facep->mLastUpdateTime = gFrameTimeSeconds; +						if (vobj->mTextureAnimp->mFace <= -1) +						{ +							S32 face; +							for (face = 0; face < vobj->getNumTEs(); face++) +							{ +								LLFace * facep = drawablep->getFace(face); +								if (facep) +								{ +									facep->setState(LLFace::TEXTURE_ANIM); +								} +							} +						} +						else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) +						{ +							LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); +							if (facep) +							{ +								facep->setState(LLFace::TEXTURE_ANIM); +							} +						}  					} -					if (gPipeline.canUseWindLightShadersOnObjects() -						&& LLPipeline::sRenderBump) +					if (type == LLDrawPool::POOL_ALPHA)  					{ -						if (te->getBumpmap()) -						{ //needs normal + binormal -							bump_faces.push_back(facep); -						} -						else if (te->getShiny() || !te->getFullbright()) -						{ //needs normal +						if (facep->canRenderAsMask()) +						{ //can be treated as alpha mask  							simple_faces.push_back(facep);  						} -						else  -						{ //doesn't need normal -							facep->setState(LLFace::FULLBRIGHT); -							fullbright_faces.push_back(facep); +						else +						{ +							if (te->getColor().mV[3] > 0.f) +							{ //only treat as alpha in the pipeline if < 100% transparent +								drawablep->setState(LLDrawable::HAS_ALPHA); +							} +							alpha_faces.push_back(facep);  						}  					}  					else  					{ -						if (te->getBumpmap() && LLPipeline::sRenderBump) -						{ //needs normal + binormal -							bump_faces.push_back(facep); +						if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) +						{ +							facep->mLastUpdateTime = gFrameTimeSeconds;  						} -						else if ((te->getShiny() && LLPipeline::sRenderBump) || -							!(te->getFullbright() || bake_sunlight)) -						{ //needs normal -							simple_faces.push_back(facep); + +						if (gPipeline.canUseWindLightShadersOnObjects() +							&& LLPipeline::sRenderBump) +						{ +							if (te->getBumpmap()) +							{ //needs normal + binormal +								bump_faces.push_back(facep); +							} +							else if (te->getShiny() || !te->getFullbright()) +							{ //needs normal +								simple_faces.push_back(facep); +							} +							else  +							{ //doesn't need normal +								facep->setState(LLFace::FULLBRIGHT); +								fullbright_faces.push_back(facep); +							}  						} -						else  -						{ //doesn't need normal -							facep->setState(LLFace::FULLBRIGHT); -							fullbright_faces.push_back(facep); +						else +						{ +							if (te->getBumpmap() && LLPipeline::sRenderBump) +							{ //needs normal + binormal +								bump_faces.push_back(facep); +							} +							else if ((te->getShiny() && LLPipeline::sRenderBump) || +								!(te->getFullbright() || bake_sunlight)) +							{ //needs normal +								simple_faces.push_back(facep); +							} +							else  +							{ //doesn't need normal +								facep->setState(LLFace::FULLBRIGHT); +								fullbright_faces.push_back(facep); +							}  						}  					}  				} +				else +				{	//face has no renderable geometry +					facep->clearVertexBuffer(); +				}		  			} -			else -			{	//face has no renderable geometry -				facep->clearVertexBuffer(); -			}		 -		} -		if (is_rigged) -		{ -			drawablep->setState(LLDrawable::RIGGED); -		} -		else -		{ -			drawablep->clearState(LLDrawable::RIGGED); +			if (is_rigged) +			{ +				drawablep->setState(LLDrawable::RIGGED); +			} +			else +			{ +				drawablep->clearState(LLDrawable::RIGGED); +			}  		}  	} @@ -4539,7 +4638,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	if (!LLPipeline::sDelayVBUpdate)  	{  		//drawables have been rebuilt, clear rebuild status -		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) +		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{  			LLDrawable* drawablep = *drawable_iter;  			drawablep->clearState(LLDrawable::REBUILD_ALL); @@ -4564,31 +4663,35 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	}  } -static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); -static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");  void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  {  	llassert(group);  	if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))  	{ -		LLFastTimer tm(FTM_VOLUME_GEOM); +		LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); +		LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers +  		S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;  		group->mBuilt = 1.f;  		std::set<LLVertexBuffer*> mapped_buffers; -		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) +		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ -			LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);  			LLDrawable* drawablep = *drawable_iter; -			if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) +			if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )  			{  				LLVOVolume* vobj = drawablep->getVOVolume();  				vobj->preRebuild(); +				if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) +				{ +					vobj->updateRelativeXform(true); +				} +  				LLVolume* volume = vobj->getVolume();  				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)  				{ @@ -4598,8 +4701,15 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  						LLVertexBuffer* buff = face->getVertexBuffer();  						if (buff)  						{ -							face->getGeometryVolume(*volume, face->getTEOffset(),  -								vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); +							llassert(!face->isState(LLFace::RIGGED)); + +							if (!face->getGeometryVolume(*volume, face->getTEOffset(),  +								vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) +							{ //something's gone wrong with the vertex buffer accounting, rebuild this group  +								group->dirtyGeom(); +								gPipeline.markRebuild(group, TRUE); +							} +  							if (buff->isLocked())  							{ @@ -4608,6 +4718,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  						}  					}  				} + +				if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) +				{ +					vobj->updateRelativeXform(); +				} +  				drawablep->clearState(LLDrawable::REBUILD_ALL);  			} @@ -4630,16 +4746,19 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)   		{  			llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;  -			for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) +			for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  			{  				LLDrawable* drawablep = *drawable_iter;  				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)  				{  					LLFace* face = drawablep->getFace(i); -					LLVertexBuffer* buff = face->getVertexBuffer(); -					if (face && buff && buff->isLocked()) +					if (face)  					{ -						buff->flush(); +						LLVertexBuffer* buff = face->getVertexBuffer(); +						if (buff && buff->isLocked()) +						{ +							buff->flush(); +						}  					}  				}  			}  @@ -4648,7 +4767,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);  	} -	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); +//	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));  }  struct CompareBatchBreakerModified @@ -4674,8 +4793,20 @@ struct CompareBatchBreakerModified  	}  }; +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); + + + + +  void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)  { +	LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); +  	U32 buffer_usage = group->mBufferUsage;  #if LL_DARWIN @@ -4693,15 +4824,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);  	max_vertices = llmin(max_vertices, (U32) 65535); -	if (!distance_sort) -	{ -		//sort faces by things that break batches -		std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); -	} -	else  	{ -		//sort faces by distance -		std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); +		LLFastTimer t(FTM_GEN_DRAW_INFO_SORT); +		if (!distance_sort) +		{ +			//sort faces by things that break batches +			std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); +		} +		else +		{ +			//sort faces by distance +			std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); +		}  	}  	bool hud_group = group->isHUDGroup() ; @@ -4766,57 +4900,86 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		std::vector<LLViewerTexture*> texture_list; -		if (batch_textures)  		{ -			U8 cur_tex = 0; -			facep->setTextureIndex(cur_tex); -			texture_list.push_back(tex); - -			//if (can_batch_texture(facep)) +			LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); +			if (batch_textures)  			{ -				while (i != faces.end()) +				U8 cur_tex = 0; +				facep->setTextureIndex(cur_tex); +				texture_list.push_back(tex); + +				//if (can_batch_texture(facep))  				{ -					facep = *i; -					if (facep->getTexture() != tex) +					while (i != faces.end())  					{ -						if (distance_sort) -						{ //textures might be out of order, see if texture exists in current batch -							bool found = false; -							for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) -							{ -								if (facep->getTexture() == texture_list[tex_idx]) +						facep = *i; +						if (facep->getTexture() != tex) +						{ +							if (distance_sort) +							{ //textures might be out of order, see if texture exists in current batch +								bool found = false; +								for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)  								{ -									cur_tex = tex_idx; -									found = true; -									break; +									if (facep->getTexture() == texture_list[tex_idx]) +									{ +										cur_tex = tex_idx; +										found = true; +										break; +									}  								} -							} -							if (!found) +								if (!found) +								{ +									cur_tex = texture_list.size(); +								} +							} +							else  							{ -								cur_tex = texture_list.size(); +								cur_tex++;  							} -						} -						else -						{ -							cur_tex++; -						} -						if (!can_batch_texture(facep)) -						{ //face is bump mapped or has an animated texture matrix -- can't  -							//batch more than 1 texture at a time -							break; +							if (!can_batch_texture(facep)) +							{ //face is bump mapped or has an animated texture matrix -- can't  +								//batch more than 1 texture at a time +								break; +							} + +							if (cur_tex >= texture_index_channels) +							{ //cut batches when index channels are depleted +								break; +							} + +							tex = facep->getTexture(); + +							texture_list.push_back(tex);  						} -						if (cur_tex >= texture_index_channels) -						{ //cut batches when index channels are depleted +						if (geom_count + facep->getGeomCount() > max_vertices) +						{ //cut batches on geom count too big  							break;  						} -						tex = facep->getTexture(); +						++i; +						index_count += facep->getIndicesCount(); +						geom_count += facep->getGeomCount(); -						texture_list.push_back(tex); +						facep->setTextureIndex(cur_tex);  					} +				} + +				tex = texture_list[0]; +			} +			else +			{ +				while (i != faces.end() &&  +					(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +				{ +					facep = *i; +			 + +					//face has no texture index +					facep->mDrawInfo = NULL; +					facep->setTextureIndex(255);  					if (geom_count + facep->getGeomCount() > max_vertices)  					{ //cut batches on geom count too big @@ -4826,69 +4989,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  					++i;  					index_count += facep->getIndicesCount();  					geom_count += facep->getGeomCount(); - -					facep->setTextureIndex(cur_tex);  				}  			} - -			tex = texture_list[0];  		} -		else -		{ -			while (i != faces.end() &&  -				(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) -			{ -				facep = *i; -			 - -				//face has no texture index -				facep->mDrawInfo = NULL; -				facep->setTextureIndex(255); -				if (geom_count + facep->getGeomCount() > max_vertices) -				{ //cut batches on geom count too big -					break; -				} - -				++i; -				index_count += facep->getIndicesCount(); -				geom_count += facep->getGeomCount(); -			} -		} -	 -		//create/delete/resize vertex buffer if needed +		//create vertex buffer  		LLVertexBuffer* buffer = NULL; -		{ //try to find a buffer to reuse -			LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); -		 -			if (found_iter != group->mBufferMap[mask].end()) -			{ -				if ((U32) buffer_index < found_iter->second.size()) -				{ -					buffer = found_iter->second[buffer_index]; -				} -			} -		} -						 -		if (!buffer || !buffer->isWriteable()) -		{ //create new buffer if needed +		{ +			LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE);  			buffer = createVertexBuffer(mask, buffer_usage);  			buffer->allocateBuffer(geom_count, index_count, TRUE);  		} -		else  -		{ //resize pre-existing buffer -			if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage || -				buffer->getTypeMask() != mask) -			{ -				buffer = createVertexBuffer(mask, buffer_usage); -				buffer->allocateBuffer(geom_count, index_count, TRUE); -			} -			else -			{ -				buffer->resizeBuffer(geom_count, index_count); -			} -		}  		group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); @@ -4922,10 +5034,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  					LLVOVolume* vobj = drawablep->getVOVolume();  					LLVolume* volume = vobj->getVolume(); +					if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) +					{ +						vobj->updateRelativeXform(true); +					} +  					U32 te_idx = facep->getTEOffset(); -					facep->getGeometryVolume(*volume, te_idx,  -						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); +					llassert(!facep->isState(LLFace::RIGGED)); + +					if (!facep->getGeometryVolume(*volume, te_idx,  +						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) +					{ +						llwarns << "Failed to get geometry for face!" << llendl; +					} + +					if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) +					{ +						vobj->updateRelativeXform(false); +					}  				}  			} @@ -5089,7 +5216,8 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  	mFaceList.clear();  	//for each drawable -	for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + +	for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  	{  		LLDrawable* drawablep = *drawable_iter; @@ -5109,17 +5237,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  			//sum up face verts and indices  			drawablep->updateFaceSize(i);  			LLFace* facep = drawablep->getFace(i); -			if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) +			if (facep)  			{ -				vertex_count += facep->getGeomCount(); -				index_count += facep->getIndicesCount(); -				llassert(facep->getIndicesCount() < 65536); -				//remember face (for sorting) -				mFaceList.push_back(facep); -			} -			else -			{ -				facep->clearVertexBuffer(); +				if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA &&  +					facep->getGeomCount() + vertex_count <= 65536) +				{ +					vertex_count += facep->getGeomCount(); +					index_count += facep->getIndicesCount(); +				 +					//remember face (for sorting) +					mFaceList.push_back(facep); +				} +				else +				{ +					facep->clearVertexBuffer(); +				}  			}  		}  	} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 3cf434dc26..5a0960204c 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -68,7 +68,7 @@ class LLVolumeInterface  public:  	virtual ~LLVolumeInterface() { }  	virtual LLVolumeInterfaceType getInterfaceType() const = 0; -	virtual BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0; +	virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;  	virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;  	virtual LLVector3 getPivotPosition() const = 0;  	virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; @@ -79,7 +79,7 @@ public:  	virtual bool isVolumeGlobal() const = 0; // Are we in global space?  	virtual bool isActive() const = 0; // Is this object currently active?  	virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0; -	virtual void updateRelativeXform() = 0; +	virtual void updateRelativeXform(bool force_identity = false) = 0;  	virtual U32 getID() const = 0;  	virtual void preRebuild() = 0;  }; @@ -203,7 +203,7 @@ public:  														  LLAssetType::EType type,  														  void* user_data, S32 status, LLExtStat ext_status); -				void	updateRelativeXform(); +				void	updateRelativeXform(bool force_identity = false);  	/*virtual*/ BOOL	updateGeometry(LLDrawable *drawable);  	/*virtual*/ void	updateFaceSize(S32 idx);  	/*virtual*/ BOOL	updateLOD(); diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index cd78157944..942eff6171 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -146,6 +146,10 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)  		drawable->addFace(poolp, NULL);  	}  	face = drawable->getFace(0); +	if (!face) +	{ +		return TRUE; +	}  //	LLVector2 uvs[4];  //	LLVector3 vtx[4]; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index b061c90d98..78ee3e4fd9 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -657,7 +657,10 @@ void LLWorld::updateRegions(F32 max_update_time)  		if (did_one && max_time <= 0.f)  			break;  		max_time = llmin(max_time, max_update_time*.1f); -		did_one |= regionp->idleUpdate(max_update_time); +		if (regionp->idleUpdate(max_update_time)) +		{ +			did_one = TRUE; +		}  	}  } @@ -837,6 +840,9 @@ void LLWorld::updateWaterObjects()  	}  	mHoleWaterObjects.clear(); +	// Use the water height of the region we're on for areas where there is no region +	F32 water_height = gAgent.getRegion()->getWaterHeight(); +  	// Now, get a list of the holes  	S32 x, y;  	for (x = min_x; x <= max_x; x += rwidth) @@ -845,12 +851,12 @@ void LLWorld::updateWaterObjects()  		{  			U64 region_handle = to_region_handle(x, y);  			if (!getRegionFromHandle(region_handle)) -			{ +			{	// No region at that area, so make water  				LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());  				waterp->setUseTexture(FALSE);  				waterp->setPositionGlobal(LLVector3d(x + rwidth/2,  													 y + rwidth/2, -													 256.f+DEFAULT_WATER_HEIGHT)); +													 256.f + water_height));  				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));  				gPipeline.createObject(waterp);  				mHoleWaterObjects.push_back(waterp); @@ -907,7 +913,7 @@ void LLWorld::updateWaterObjects()  		}  		waterp->setRegion(gAgent.getRegion()); -		LLVector3d water_pos(water_center_x, water_center_y, 256.f+DEFAULT_WATER_HEIGHT) ; +		LLVector3d water_pos(water_center_x, water_center_y, 256.f + water_height) ;  		LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);  		//stretch out to horizon diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ed636a40b2..cfa47b3ba3 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -51,6 +51,10 @@  // newview includes  #include "llagent.h"  #include "llagentcamera.h" +#include "llappviewer.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llimageworker.h"  #include "lldrawable.h"  #include "lldrawpoolalpha.h"  #include "lldrawpoolavatar.h" @@ -113,6 +117,8 @@  //#define DEBUG_INDICES  #endif +bool gShiftFrame = false; +  //cached settings  BOOL LLPipeline::RenderAvatarVP;  BOOL LLPipeline::VertexShaderEnable; @@ -210,7 +216,7 @@ BOOL	gDebugPipeline = FALSE;  LLPipeline gPipeline;  const LLMatrix4* gGLLastMatrix = NULL; -LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry"); +LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Render Geometry");  LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");  LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");  LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion"); @@ -227,8 +233,13 @@ LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");  LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");  LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");  LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update"); +LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create");  LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");  LLFastTimer::DeclareTimer FTM_POOLS("Pools"); +LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)"); +LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)"); +LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)"); +LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)");  LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");  LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");  LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline"); @@ -264,6 +275,7 @@ std::string gPoolNames[] =  void drawBox(const LLVector3& c, const LLVector3& r);  void drawBoxOutline(const LLVector3& pos, const LLVector3& size);  U32 nhpo2(U32 v); +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);  glh::matrix4f glh_copy_matrix(F32* src)  { @@ -403,9 +415,11 @@ LLPipeline::LLPipeline() :  	mInitialized(FALSE),  	mVertexShadersEnabled(FALSE),  	mVertexShadersLoaded(0), +	mTransformFeedbackPrimitives(0),  	mRenderDebugFeatureMask(0),  	mRenderDebugMask(0),  	mOldRenderDebugMask(0), +	mMeshDirtyQueryObject(0),  	mGroupQ1Locked(false),  	mGroupQ2Locked(false),  	mResetVertexBuffers(false), @@ -504,6 +518,11 @@ void LLPipeline::init()  		mSpotLightFade[i] = 1.f;  	} +	if (mCubeVB.isNull()) +	{ +		mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +	} +  	mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);  	mDeferredVB->allocateBuffer(8, 0, true);  	setLightingDetail(-1); @@ -693,6 +712,12 @@ void LLPipeline::destroyGL()  	{  		LLVertexBuffer::sEnableVBOs = FALSE;  	} + +	if (mMeshDirtyQueryObject) +	{ +		glDeleteQueriesARB(1, &mMeshDirtyQueryObject); +		mMeshDirtyQueryObject = 0; +	}  }  static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); @@ -942,6 +967,7 @@ void LLPipeline::refreshCachedSettings()  	LLPipeline::sUseOcclusion =   			(!gUseWireframe +			&& LLGLSLShader::sNoFixedFunction  			&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")   			&& gSavedSettings.getBOOL("UseOcclusion")   			&& gGLManager.mHasOcclusionQuery) ? 2 : 0; @@ -1030,13 +1056,13 @@ void LLPipeline::releaseGLBuffers()  	if (mNoiseMap)  	{ -		LLImageGL::deleteTextures(1, &mNoiseMap); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);  		mNoiseMap = 0;  	}  	if (mTrueNoiseMap)  	{ -		LLImageGL::deleteTextures(1, &mTrueNoiseMap); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);  		mTrueNoiseMap = 0;  	} @@ -1060,7 +1086,7 @@ void LLPipeline::releaseLUTBuffers()  {  	if (mLightFunc)  	{ -		LLImageGL::deleteTextures(1, &mLightFunc); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);  		mLightFunc = 0;  	}  } @@ -1138,7 +1164,7 @@ void LLPipeline::createGLBuffers()  				noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;  			} -			LLImageGL::generateTextures(1, &mNoiseMap); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);  			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); @@ -1154,7 +1180,7 @@ void LLPipeline::createGLBuffers()  				noise[i] = ll_frand()*2.0-1.0;  			} -			LLImageGL::generateTextures(1, &mTrueNoiseMap); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);  			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); @@ -1210,7 +1236,7 @@ void LLPipeline::createLUTBuffers()  				}  			} -			LLImageGL::generateTextures(1, &mLightFunc); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);  			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);  			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); @@ -1349,7 +1375,7 @@ public:  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); -		if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) +		if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())  		{  			for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)  			{ @@ -1658,7 +1684,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)  void LLPipeline::createObjects(F32 max_dtime)  { -	LLFastTimer ftm(FTM_GEO_UPDATE); +	LLFastTimer ftm(FTM_PIPELINE_CREATE);  	LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);  	LLTimer update_timer; @@ -1820,6 +1846,16 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)  		if (done)  		{  			drawablep->clearState(LLDrawable::ON_MOVE_LIST); +			if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) +			{ //will likely not receive any future world matrix updates +				// -- this keeps attachments from getting stuck in space and falling off your avatar +				drawablep->clearState(LLDrawable::ANIMATED_CHILD); +				markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE); +				if (drawablep->getVObj()) +				{ +					drawablep->getVObj()->dirtySpatialGroup(TRUE); +				} +			}  			iter = moved_list.erase(curiter);  		}  	} @@ -1944,7 +1980,7 @@ void LLPipeline::clearReferences()  void check_references(LLSpatialGroup* group, LLDrawable* drawable)  { -	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{  		if (drawable == *i)  		{ @@ -1966,7 +2002,7 @@ void check_references(LLDrawable* drawable, LLFace* face)  void check_references(LLSpatialGroup* group, LLFace* face)  { -	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{  		LLDrawable* drawable = *i;  		check_references(drawable, face); @@ -1978,25 +2014,25 @@ void LLPipeline::checkReferences(LLFace* face)  #if 0  	if (sCull)  	{ -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, face);  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, face);  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, face);  		} -		for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) +		for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)  		{  			LLDrawable* drawable = *iter;  			check_references(drawable, face);	 @@ -2010,25 +2046,25 @@ void LLPipeline::checkReferences(LLDrawable* drawable)  #if 0  	if (sCull)  	{ -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, drawable);  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, drawable);  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, drawable);  		} -		for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) +		for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)  		{  			if (drawable == *iter)  			{ @@ -2061,19 +2097,19 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info)  #if 0  	if (sCull)  	{ -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, draw_info);  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, draw_info);  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			check_references(group, draw_info); @@ -2087,7 +2123,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)  #if 0  	if (sCull)  	{ -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)  		{  			if (group == *iter)  			{ @@ -2095,7 +2131,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)  			}  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)  		{  			if (group == *iter)  			{ @@ -2103,7 +2139,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)  			}  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) +		for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)  		{  			if (group == *iter)  			{ @@ -2214,8 +2250,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	gGLLastMatrix = NULL;  	gGL.loadMatrix(gGLLastModelView); - -	LLVertexBuffer::unbind();  	LLGLDisable blend(GL_BLEND);  	LLGLDisable test(GL_ALPHA_TEST);  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -2259,7 +2293,16 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can  		// (shadow render uses a special shader that clamps to clip planes)  		bound_shader = true; -		gOcclusionProgram.bind(); +		gOcclusionCubeProgram.bind(); +	} + +	if (sUseOcclusion > 1) +	{ +		if (mCubeVB.isNull()) +		{ //cube VB will be used for issuing occlusion queries +			mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +		} +		mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);  	}  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();  @@ -2291,7 +2334,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (bound_shader)  	{ -		gOcclusionProgram.unbind(); +		gOcclusionCubeProgram.unbind();  	}  	camera.disableUserClipPlane(); @@ -2335,7 +2378,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)  { -	if (group->getData().empty()) +	if (group->isEmpty())  	{   		return;  	} @@ -2424,15 +2467,21 @@ void LLPipeline::doOcclusion(LLCamera& camera)  		{  			if (LLPipeline::sShadowRender)  			{ -				gDeferredShadowProgram.bind(); +				gDeferredShadowCubeProgram.bind();  			}  			else  			{ -				gOcclusionProgram.bind(); +				gOcclusionCubeProgram.bind();  			}  		} -		for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) +		if (mCubeVB.isNull()) +		{ //cube VB will be used for issuing occlusion queries +			mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +		} +		mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +		for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter;  			group->doOcclusion(&camera); @@ -2443,11 +2492,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)  		{  			if (LLPipeline::sShadowRender)  			{ -				gDeferredShadowProgram.unbind(); +				gDeferredShadowCubeProgram.unbind();  			}  			else  			{ -				gOcclusionProgram.unbind(); +				gOcclusionCubeProgram.unbind();  			}  		} @@ -2466,22 +2515,36 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)  	return update_complete;  } +static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool"); + +static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL"); +  void LLPipeline::updateGL()  { -	while (!LLGLUpdate::sGLQ.empty())  	{ -		LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); -		glu->updateGL(); -		glu->mInQ = FALSE; -		LLGLUpdate::sGLQ.pop_front(); +		LLFastTimer t(FTM_UPDATE_GL); +		while (!LLGLUpdate::sGLQ.empty()) +		{ +			LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); +			glu->updateGL(); +			glu->mInQ = FALSE; +			LLGLUpdate::sGLQ.pop_front(); +		} +	} + +	{ //seed VBO Pools +		LLFastTimer t(FTM_SEED_VBO_POOLS); +		LLVertexBuffer::seedPools();  	}  } +static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); +  void LLPipeline::rebuildPriorityGroups()  { +	LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS);  	LLTimer update_timer;  	LLMemType mt(LLMemType::MTYPE_PIPELINE); -	  	assertInitialized();  	gMeshRepo.notifyLoadedMeshes(); @@ -2500,7 +2563,9 @@ void LLPipeline::rebuildPriorityGroups()  	mGroupQ1Locked = false;  } -		 + +static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups"); +  void LLPipeline::rebuildGroups()  {  	if (mGroupQ2.empty()) @@ -2508,6 +2573,7 @@ void LLPipeline::rebuildGroups()  		return;  	} +	LLFastTimer t(FTM_REBUILD_GROUPS);  	mGroupQ2Locked = true;  	// Iterate through some drawables on the non-priority build queue  	S32 size = (S32) mGroupQ2.size(); @@ -2749,6 +2815,10 @@ void LLPipeline::markShift(LLDrawable *drawablep)  	}  } +static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable"); +static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree"); +static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD"); +  void LLPipeline::shiftObjects(const LLVector3 &offset)  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS); @@ -2761,35 +2831,46 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)  	LLVector4a offseta;  	offseta.load3(offset.mV); -	for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); -		 iter != mShiftList.end(); iter++)  	{ -		LLDrawable *drawablep = *iter; -		if (drawablep->isDead()) +		LLFastTimer t(FTM_SHIFT_DRAWABLE); + +		for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); +			 iter != mShiftList.end(); iter++)  		{ -			continue; -		}	 -		drawablep->shiftPos(offseta);	 -		drawablep->clearState(LLDrawable::ON_SHIFT_LIST); +			LLDrawable *drawablep = *iter; +			if (drawablep->isDead()) +			{ +				continue; +			}	 +			drawablep->shiftPos(offseta);	 +			drawablep->clearState(LLDrawable::ON_SHIFT_LIST); +		} +		mShiftList.resize(0);  	} -	mShiftList.resize(0); -	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();  -			iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +	  	{ -		LLViewerRegion* region = *iter; -		for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) +		LLFastTimer t(FTM_SHIFT_OCTREE); +		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();  +				iter != LLWorld::getInstance()->getRegionList().end(); ++iter)  		{ -			LLSpatialPartition* part = region->getSpatialPartition(i); -			if (part) +			LLViewerRegion* region = *iter; +			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)  			{ -				part->shift(offseta); +				LLSpatialPartition* part = region->getSpatialPartition(i); +				if (part) +				{ +					part->shift(offseta); +				}  			}  		}  	} -	LLHUDText::shiftAll(offset); -	LLHUDNameTag::shiftAll(offset); +	{ +		LLFastTimer t(FTM_SHIFT_HUD); +		LLHUDText::shiftAll(offset); +		LLHUDNameTag::shiftAll(offset); +	}  	display_update_camera();  } @@ -2822,8 +2903,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable)  	}  } +static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ");  void LLPipeline::processPartitionQ()  { +	LLFastTimer t(FTM_PROCESS_PARTITIONQ);  	for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)  	{  		LLDrawable* drawable = *iter; @@ -2838,6 +2921,11 @@ void LLPipeline::processPartitionQ()  	mPartitionQ.clear();  } +void LLPipeline::markMeshDirty(LLSpatialGroup* group) +{ +	mMeshDirtyGroup.push_back(group); +} +  void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -2934,7 +3022,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  	//LLVertexBuffer::unbind();  	grabReferences(result); -	for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) +	for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)  	{  		LLSpatialGroup* group = *iter;  		group->checkOcclusion(); @@ -2945,7 +3033,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  		else  		{  			group->setVisible(); -			for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +			for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  			{  				markVisible(*i, camera);  			} @@ -2960,9 +3048,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)  	{  		LLSpatialGroup* last_group = NULL; -		for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) +		for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)  		{ -			LLCullResult::bridge_list_t::iterator cur_iter = i; +			LLCullResult::bridge_iterator cur_iter = i;  			LLSpatialBridge* bridge = *cur_iter;  			LLSpatialGroup* group = bridge->getSpatialGroup(); @@ -2992,7 +3080,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  		}  	} -	for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) +	for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)  	{  		LLSpatialGroup* group = *iter;  		group->checkOcclusion(); @@ -3014,7 +3102,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  	{  		LLFastTimer ftm(FTM_STATESORT_DRAWABLE); -		for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); +		for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList();  			 iter != sCull->endVisibleList(); ++iter)  		{  			LLDrawable *drawablep = *iter; @@ -3033,7 +3121,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)  	LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);  	if (group->changeLOD())  	{ -		for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +		for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  		{  			LLDrawable* drawablep = *i;  			stateSort(drawablep, camera); @@ -3150,13 +3238,13 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)  } -void forAllDrawables(LLCullResult::sg_list_t::iterator begin,  -					 LLCullResult::sg_list_t::iterator end, +void forAllDrawables(LLCullResult::sg_iterator begin,  +					 LLCullResult::sg_iterator end,  					 void (*func)(LLDrawable*))  { -	for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i) +	for (LLCullResult::sg_iterator i = begin; i != end; ++i)  	{ -		for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) +		for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)  		{  			func(*j);	  		} @@ -3189,7 +3277,11 @@ void renderScriptedBeacons(LLDrawable* drawablep)  			S32 count = drawablep->getNumFaces();  			for (face_id = 0; face_id < count; face_id++)  			{ -				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); +				LLFace * facep = drawablep->getFace(face_id); +				if (facep)  +				{ +					gPipeline.mHighlightFaces.push_back(facep); +				}  			}  		}  	} @@ -3215,7 +3307,11 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep)  			S32 count = drawablep->getNumFaces();  			for (face_id = 0; face_id < count; face_id++)  			{ -				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); +				LLFace * facep = drawablep->getFace(face_id); +				if (facep) +				{ +					gPipeline.mHighlightFaces.push_back(facep); +				}  			}  		}  	} @@ -3240,7 +3336,11 @@ void renderPhysicalBeacons(LLDrawable* drawablep)  			S32 count = drawablep->getNumFaces();  			for (face_id = 0; face_id < count; face_id++)  			{ -				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); +				LLFace * facep = drawablep->getFace(face_id); +				if (facep) +				{ +					gPipeline.mHighlightFaces.push_back(facep); +				}  			}  		}  	} @@ -3276,7 +3376,11 @@ void renderMOAPBeacons(LLDrawable* drawablep)  			S32 count = drawablep->getNumFaces();  			for (face_id = 0; face_id < count; face_id++)  			{ -				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); +				LLFace * facep = drawablep->getFace(face_id); +				if (facep) +				{ +					gPipeline.mHighlightFaces.push_back(facep); +				}  			}  		}  	} @@ -3301,7 +3405,11 @@ void renderParticleBeacons(LLDrawable* drawablep)  			S32 count = drawablep->getNumFaces();  			for (face_id = 0; face_id < count; face_id++)  			{ -				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); +				LLFace * facep = drawablep->getFace(face_id); +				if (facep) +				{ +					gPipeline.mHighlightFaces.push_back(facep); +				}  			}  		}  	} @@ -3319,7 +3427,11 @@ void renderSoundHighlights(LLDrawable* drawablep)  			S32 count = drawablep->getNumFaces();  			for (face_id = 0; face_id < count; face_id++)  			{ -				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); +				LLFace * facep = drawablep->getFace(face_id); +				if (facep) +				{ +					gPipeline.mHighlightFaces.push_back(facep); +				}  			}  		}  	} @@ -3334,7 +3446,7 @@ void LLPipeline::postSort(LLCamera& camera)  	llpushcallstacks ;  	//rebuild drawable geometry -	for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) +	for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)  	{  		LLSpatialGroup* group = *i;  		if (!sUseOcclusion ||  @@ -3350,23 +3462,9 @@ void LLPipeline::postSort(LLCamera& camera)  	rebuildPriorityGroups();  	llpushcallstacks ; -	const S32 bin_count = 1024*8; -		 -	static LLCullResult::drawinfo_list_t alpha_bins[bin_count]; -	static U32 bin_size[bin_count]; - -	//clear one bin per frame to avoid memory bloat -	static S32 clear_idx = 0; -	clear_idx = (1+clear_idx)%bin_count; -	alpha_bins[clear_idx].clear(); - -	for (U32 j = 0; j < bin_count; j++) -	{ -		bin_size[j] = 0; -	} - +	  	//build render map -	for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) +	for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)  	{  		LLSpatialGroup* group = *i;  		if (sUseOcclusion &&  @@ -3436,11 +3534,43 @@ void LLPipeline::postSort(LLCamera& camera)  			}  		}  	} +	 +	//flush particle VB +	LLVOPartGroup::sVB->flush(); + +	/*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); + +	if (use_transform_feedback) +	{ //place a query around potential transform feedback code for synchronization +		mTransformFeedbackPrimitives = 0; + +		if (!mMeshDirtyQueryObject) +		{ +			glGenQueriesARB(1, &mMeshDirtyQueryObject); +		} + +		glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject); +	}*/ + +	//pack vertex buffers for groups that chose to delay their updates +	for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter) +	{ +		(*iter)->rebuildMesh(); +	} + +	/*if (use_transform_feedback) +	{ +		glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); +	}*/ +	 +	mMeshDirtyGroup.clear(); +  	if (!sShadowRender)  	{  		std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());  	} +  	llpushcallstacks ;  	// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus  	if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) @@ -3514,7 +3644,11 @@ void LLPipeline::postSort(LLCamera& camera)  				{  					if (object->mDrawable)  					{ -						gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te)); +						LLFace * facep = object->mDrawable->getFace(te); +						if (facep) +						{ +							gPipeline.mSelectedFaces.push_back(facep); +						}  					}  					return true;  				} @@ -3523,6 +3657,33 @@ void LLPipeline::postSort(LLCamera& camera)  		}  	} +	/*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence"); +	static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work"); +	if (use_transform_feedback) +	{ //using transform feedback, wait for transform feedback to complete +		LLFastTimer t(FTM_TRANSFORM_WAIT); + +		S32 done = 0; +		//glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count); +		 +		glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); +		 +		while (!done) +		{  +			{ +				LLFastTimer t(FTM_TRANSFORM_DO_WORK); +				F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); +				//do some useful work while we wait +				LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread +				LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread +				LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread +			} +			glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); +		} + +		mTransformFeedbackPrimitives = 0; +	}*/ +						  	//LLSpatialGroup::sNoDelete = FALSE;  	llpushcallstacks ;  } @@ -4005,7 +4166,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  	LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED);  	LLFastTimer t(FTM_RENDER_GEOMETRY); -	LLFastTimer t2(FTM_POOLS); +	LLFastTimer t2(FTM_DEFERRED_POOLS);  	LLGLEnable cull(GL_CULL_FACE); @@ -4047,7 +4208,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  		pool_set_t::iterator iter2 = iter1;  		if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)  		{ -			LLFastTimer t(FTM_POOLRENDER); +			LLFastTimer t(FTM_DEFERRED_POOLRENDER);  			gGLLastMatrix = NULL;  			gGL.loadMatrix(gGLModelView); @@ -4100,7 +4261,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  {  	LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF); -	LLFastTimer t(FTM_POOLS); +	LLFastTimer t(FTM_POST_DEFERRED_POOLS);  	U32 cur_type = 0;  	LLGLEnable cull(GL_CULL_FACE); @@ -4134,7 +4295,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  		pool_set_t::iterator iter2 = iter1;  		if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)  		{ -			LLFastTimer t(FTM_POOLRENDER); +			LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER);  			gGLLastMatrix = NULL;  			gGL.loadMatrix(gGLModelView); @@ -4324,7 +4485,7 @@ void LLPipeline::renderPhysicsDisplay()  		}  	} -	for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) +	for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)  	{  		LLSpatialBridge* bridge = *i;  		if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) @@ -4419,7 +4580,7 @@ void LLPipeline::renderDebug()  		}  	} -	for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) +	for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)  	{  		LLSpatialBridge* bridge = *i;  		if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) @@ -4671,8 +4832,11 @@ void LLPipeline::renderDebug()  	}  } +static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools"); +  void LLPipeline::rebuildPools()  { +	LLFastTimer t(FTM_REBUILD_POOLS);  	LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);  	assertInitialized(); @@ -6219,7 +6383,10 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)  	for (S32 i = 0; i < drawable->getNumFaces(); i++)  	{  		LLFace* facep = drawable->getFace(i); -		facep->clearVertexBuffer(); +		if (facep) +		{ +			facep->clearVertexBuffer(); +		}  	}  } @@ -6228,15 +6395,20 @@ void LLPipeline::resetVertexBuffers()  	mResetVertexBuffers = true;  } +static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB"); +  void LLPipeline::doResetVertexBuffers()  {  	if (!mResetVertexBuffers)  	{  		return;  	} -	 + +	LLFastTimer t(FTM_RESET_VB);  	mResetVertexBuffers = false; +	mCubeVB = NULL; +  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)  	{ @@ -6255,11 +6427,15 @@ void LLPipeline::doResetVertexBuffers()  	gSky.resetVertexBuffers(); +	LLVOPartGroup::destroyGL(); +  	LLVertexBuffer::cleanupClass();  	//delete all name pool caches  	LLGLNamePool::cleanupPools(); +	 +  	if (LLVertexBuffer::sGLCount > 0)  	{  		llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl; @@ -6279,6 +6455,8 @@ void LLPipeline::doResetVertexBuffers()  	LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");  	LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); + +	LLVOPartGroup::restoreGL();  }  void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) @@ -7466,12 +7644,17 @@ void LLPipeline::renderDeferredLighting()  			std::list<LLVector4> light_colors;  			LLVertexBuffer::unbind(); -			LLVector4a* v = (LLVector4a*) vert.get();  			{  				bindDeferredShader(gDeferredLightProgram); -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				 +				if (mCubeVB.isNull()) +				{ +					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +				} +				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				  				LLGLDepthTest depth(GL_TRUE, GL_FALSE);  				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)  				{ @@ -7517,25 +7700,7 @@ void LLPipeline::renderDeferredLighting()  					}  					sVisibleLightCount++; - -					glh::vec3f tc(c); -					mat.mult_matrix_vec(tc); -					 -					//vertex positions are encoded so the 3 bits of their vertex index  -					//correspond to their axis facing, with bit position 3,2,1 matching -					//axis facing x,y,z, bit set meaning positive facing, bit clear  -					//meaning negative facing -					mDeferredVB->getVertexStrider(vert); -					v[0].set(c[0]-s,c[1]-s,c[2]-s);  // 0 - 0000  -					v[1].set(c[0]-s,c[1]-s,c[2]+s);  // 1 - 0001 -					v[2].set(c[0]-s,c[1]+s,c[2]-s);  // 2 - 0010 -					v[3].set(c[0]-s,c[1]+s,c[2]+s);  // 3 - 0011 -																									    -					v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100 -					v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101 -					v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110 -					v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111 - +										  					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||  						camera->getOrigin().mV[0] < c[0] - s - 0.2f ||  						camera->getOrigin().mV[1] > c[1] + s + 0.2f || @@ -7553,16 +7718,13 @@ void LLPipeline::renderDeferredLighting()  							}  							LLFastTimer ftm(FTM_LOCAL_LIGHTS); -							//glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); -							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); +							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);  							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);  							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);  							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); -							//gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);  							gGL.syncMatrices(); -							mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -							glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, -								GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center)); +							 +							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));  							stop_glerror();  						}  					} @@ -7575,6 +7737,9 @@ void LLPipeline::renderDeferredLighting()  							continue;  						} +						glh::vec3f tc(c); +						mat.mult_matrix_vec(tc); +					  						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));  						light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));  					} @@ -7587,7 +7752,7 @@ void LLPipeline::renderDeferredLighting()  				LLGLDepthTest depth(GL_TRUE, GL_FALSE);  				bindDeferredShader(gDeferredSpotLightProgram); -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);  				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -7605,36 +7770,17 @@ void LLPipeline::renderDeferredLighting()  					sVisibleLightCount++; -					glh::vec3f tc(c); -					mat.mult_matrix_vec(tc); -					  					setupSpotLight(gDeferredSpotLightProgram, drawablep);  					LLColor3 col = volume->getLightColor(); -					//vertex positions are encoded so the 3 bits of their vertex index  -					//correspond to their axis facing, with bit position 3,2,1 matching -					//axis facing x,y,z, bit set meaning positive facing, bit clear  -					//meaning negative facing -					mDeferredVB->getVertexStrider(vert); -					v[0].set(c[0]-s,c[1]-s,c[2]-s);  // 0 - 0000  -					v[1].set(c[0]-s,c[1]-s,c[2]+s);  // 1 - 0001 -					v[2].set(c[0]-s,c[1]+s,c[2]-s);  // 2 - 0010 -					v[3].set(c[0]-s,c[1]+s,c[2]+s);  // 3 - 0011 -																									    -					v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100 -					v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101 -					v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110 -					v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111 -					 -					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); +					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);  					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);  					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);  					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);  					gGL.syncMatrices(); -					mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -					glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, -							GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center)); +										 +					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));  				}  				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);  				unbindDeferredShader(gDeferredSpotLightProgram); @@ -7666,8 +7812,6 @@ void LLPipeline::renderDeferredLighting()  				LLVector4 light[max_count];  				LLVector4 col[max_count]; -//				glVertexPointer(2, GL_FLOAT, 0, vert); -  				F32 far_z = 0.f;  				while (!fullscreen_lights.empty()) @@ -8324,7 +8468,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	if (use_shader)  	{ -		gDeferredShadowProgram.bind(); +		gDeferredShadowCubeProgram.bind();  	}  	updateCull(shadow_cam, result); @@ -8341,17 +8485,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	stop_glerror();  	gGLLastMatrix = NULL; -	{ -		//LLGLDepthTest depth(GL_TRUE); -		//glClear(GL_DEPTH_BUFFER_BIT); -	} -  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  	stop_glerror(); -	//glCullFace(GL_FRONT); -  	LLVertexBuffer::unbind();  	{ @@ -8359,6 +8496,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  		{ //occlusion program is general purpose depth-only no-textures  			gOcclusionProgram.bind();  		} +		else +		{ +			gDeferredShadowProgram.bind(); +		}  		gGL.diffuseColor4f(1,1,1,1);  		gGL.setColorMask(false, false); @@ -8408,7 +8549,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	//glCullFace(GL_BACK); -	gDeferredShadowProgram.bind(); +	gDeferredShadowCubeProgram.bind();  	gGLLastMatrix = NULL;  	gGL.loadMatrix(gGLModelView);  	doOcclusion(shadow_cam); @@ -8683,6 +8824,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)  } +static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); +  void LLPipeline::generateSunShadow(LLCamera& camera)  {  	if (!sRenderDeferred || RenderShadowDetail <= 0) @@ -8690,6 +8833,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		return;  	} +	LLFastTimer t(FTM_GEN_SUN_SHADOW); +  	BOOL skip_avatar_update = FALSE;  	if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)  	{ @@ -9439,7 +9584,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)  { -	for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) +	for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)  	{  		LLSpatialGroup* group = *i;  		if (!group->isDead() && @@ -9452,6 +9597,12 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu  	}  } +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize"); +  void LLPipeline::generateImpostor(LLVOAvatar* avatar)  {  	LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR); @@ -9507,101 +9658,114 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	sImpostorRender = TRUE;  	LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); -	markVisible(avatar->mDrawable, *viewer_camera); -	LLVOAvatar::sUseImpostors = FALSE; -	LLVOAvatar::attachment_map_t::iterator iter; -	for (iter = avatar->mAttachmentPoints.begin(); -		iter != avatar->mAttachmentPoints.end(); -		++iter)  	{ -		LLViewerJointAttachment *attachment = iter->second; -		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); -			 attachment_iter != attachment->mAttachedObjects.end(); -			 ++attachment_iter) +		LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE); +		markVisible(avatar->mDrawable, *viewer_camera); +		LLVOAvatar::sUseImpostors = FALSE; + +		LLVOAvatar::attachment_map_t::iterator iter; +		for (iter = avatar->mAttachmentPoints.begin(); +			iter != avatar->mAttachmentPoints.end(); +			++iter)  		{ -			if (LLViewerObject* attached_object = (*attachment_iter)) +			LLViewerJointAttachment *attachment = iter->second; +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +				 attachment_iter != attachment->mAttachedObjects.end(); +				 ++attachment_iter)  			{ -				markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); +				if (LLViewerObject* attached_object = (*attachment_iter)) +				{ +					markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); +				}  			}  		}  	}  	stateSort(*LLViewerCamera::getInstance(), result); -	const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); -	LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); -  	LLCamera camera = *viewer_camera; - -	camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); -	  	LLVector2 tdim; +	U32 resY = 0; +	U32 resX = 0; +	{ +		LLFastTimer t(FTM_IMPOSTOR_SETUP); +		const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); +		LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); -	LLVector4a half_height; -	half_height.setSub(ext[1], ext[0]); -	half_height.mul(0.5f); +		camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); +	 +		LLVector4a half_height; +		half_height.setSub(ext[1], ext[0]); +		half_height.mul(0.5f); -	LLVector4a left; -	left.load3(camera.getLeftAxis().mV); -	left.mul(left); -	left.normalize3fast(); +		LLVector4a left; +		left.load3(camera.getLeftAxis().mV); +		left.mul(left); +		left.normalize3fast(); -	LLVector4a up; -	up.load3(camera.getUpAxis().mV); -	up.mul(up); -	up.normalize3fast(); +		LLVector4a up; +		up.load3(camera.getUpAxis().mV); +		up.mul(up); +		up.normalize3fast(); -	tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); -	tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); +		tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); +		tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.pushMatrix(); +		gGL.matrixMode(LLRender::MM_PROJECTION); +		gGL.pushMatrix(); -	F32 distance = (pos-camera.getOrigin()).length(); -	F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; -	F32 aspect = tdim.mV[0]/tdim.mV[1]; -	glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); -	glh_set_current_projection(persp); -	gGL.loadMatrix(persp.m); +		F32 distance = (pos-camera.getOrigin()).length(); +		F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; +		F32 aspect = tdim.mV[0]/tdim.mV[1]; +		glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); +		glh_set_current_projection(persp); +		gGL.loadMatrix(persp.m); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	glh::matrix4f mat; -	camera.getOpenGLTransform(mat.m); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		gGL.pushMatrix(); +		glh::matrix4f mat; +		camera.getOpenGLTransform(mat.m); -	mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; +		mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; -	gGL.loadMatrix(mat.m); -	glh_set_current_modelview(mat); +		gGL.loadMatrix(mat.m); +		glh_set_current_modelview(mat); -	glClearColor(0.0f,0.0f,0.0f,0.0f); -	gGL.setColorMask(true, true); +		glClearColor(0.0f,0.0f,0.0f,0.0f); +		gGL.setColorMask(true, true); -	// get the number of pixels per angle -	F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); +		// get the number of pixels per angle +		F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); -	//get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) -	U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); -	U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); +		//get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) +		resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); +		resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); -	if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || -		resY != avatar->mImpostor.getHeight()) -	{ -		avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); +		if (!avatar->mImpostor.isComplete()) +		{ +			LLFastTimer t(FTM_IMPOSTOR_ALLOCATE); +			avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + +			if (LLPipeline::sRenderDeferred) +			{ +				addDeferredAttachments(avatar->mImpostor); +			} -		if (LLPipeline::sRenderDeferred) +			gGL.getTexUnit(0)->bind(&avatar->mImpostor); +			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		} +		else if(resX != avatar->mImpostor.getWidth() || +			resY != avatar->mImpostor.getHeight())  		{ -			addDeferredAttachments(avatar->mImpostor); +			LLFastTimer t(FTM_IMPOSTOR_RESIZE); +			avatar->mImpostor.resize(resX,resY,GL_RGBA);  		} -		 -		gGL.getTexUnit(0)->bind(&avatar->mImpostor); -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	} -	avatar->mImpostor.bindTarget(); +		avatar->mImpostor.bindTarget(); +	}  	if (LLPipeline::sRenderDeferred)  	{ @@ -9618,6 +9782,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	}  	{ //create alpha mask based on depth buffer (grey out if muted) +		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);  		if (LLPipeline::sRenderDeferred)  		{  			GLuint buff = GL_COLOR_ATTACHMENT0; @@ -9703,22 +9868,22 @@ BOOL LLPipeline::hasRenderBatches(const U32 type) const  	return sCull->getRenderMapSize(type) > 0;  } -LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type)  {  	return sCull->beginRenderMap(type);  } -LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type)  {  	return sCull->endRenderMap(type);  } -LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups() +LLCullResult::sg_iterator LLPipeline::beginAlphaGroups()  {  	return sCull->beginAlphaGroups();  } -LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() +LLCullResult::sg_iterator LLPipeline::endAlphaGroups()  {  	return sCull->endAlphaGroups();  } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5c623fc9f2..efc94315d7 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -163,6 +163,7 @@ public:  	void		markRebuild(LLSpatialGroup* group, BOOL priority = FALSE);  	void        markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE);  	void		markPartitionMove(LLDrawable* drawablep); +	void		markMeshDirty(LLSpatialGroup* group);  	//get the object between start and end that's closest to start.  	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, @@ -293,10 +294,10 @@ public:  	void setLight(LLDrawable *drawablep, BOOL is_light);  	BOOL hasRenderBatches(const U32 type) const; -	LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type); -	LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type); -	LLCullResult::sg_list_t::iterator beginAlphaGroups(); -	LLCullResult::sg_list_t::iterator endAlphaGroups(); +	LLCullResult::drawinfo_iterator beginRenderMap(U32 type); +	LLCullResult::drawinfo_iterator endRenderMap(U32 type); +	LLCullResult::sg_iterator beginAlphaGroups(); +	LLCullResult::sg_iterator endAlphaGroups();  	void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); @@ -544,6 +545,9 @@ public:  	//utility buffer for rendering post effects, gets abused by renderDeferredLighting  	LLPointer<LLVertexBuffer> mDeferredVB; +	//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1] +	LLPointer<LLVertexBuffer> mCubeVB; +  	//sun shadow map  	LLRenderTarget			mShadow[6];  	std::vector<LLVector3>	mShadowFrustPoints[4]; @@ -595,6 +599,7 @@ public:  	BOOL					mVertexShadersEnabled;  	S32						mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed +	U32						mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback  protected:  	BOOL					mRenderTypeEnabled[NUM_RENDER_TYPES];  	std::stack<std::string> mRenderTypeEnableStack; @@ -652,6 +657,9 @@ protected:  	LLSpatialGroup::sg_vector_t		mGroupQ1; //priority  	LLSpatialGroup::sg_vector_t		mGroupQ2; // non-priority +	LLSpatialGroup::sg_vector_t		mMeshDirtyGroup; //groups that need rebuildMesh called +	U32 mMeshDirtyQueryObject; +  	LLDrawable::drawable_list_t		mPartitionQ; //drawables that need to update their spatial partition radius   	bool mGroupQ2Locked; diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index d011c7295c..c875b8c652 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -21,7 +21,6 @@  			<menu_item_call label="Beschäftigt" name="Set Busy"/>  		</menu>  		<menu_item_call label="L$ kaufen..." name="Buy and Sell L$"/> -		<menu_item_call label="Händler-Outbox..." name="MerchantOutbox"/>  		<menu_item_call label="Kontoübersicht..." name="Manage My Account">  			<menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=de"/>  		</menu_item_call> diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml index 184f296255..ea44fd493e 100644 --- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml @@ -6,7 +6,7 @@   height="570"   help_topic="sidebar_inventory"   min_width="333" - min_height="440" + min_height="560"   name="floater_my_inventory"   save_rect="true"   save_visibility="true" diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index ffb8b842f0..2e29c61cb2 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -134,6 +134,26 @@       top_delta="-25"       name="Pipette"       width="28" /> +   <check_box +     follows="left|bottom" +     height="20" +     initial_value="true" +     label="Live Preview" +     layout="topleft" +     left="4" +     name="apply_immediate_check" +     top="262" +     width="120" /> +   <text +     follows="left|bottom" +     height="20" +     layout="topleft" +     left="8" +     name="preview_disabled" +     top="266" +     value="Preview Disabled" +     visible="false" +     width="120" />      <filter_editor       follows="left|top|right"       height="23" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a26c5bb344..e806a40951 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7197,6 +7197,18 @@ You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME]    <notification     icon="alertmodal.tga" +   name="LivePreviewUnavailable" +   type="alert"> +    +We cannot display a preview of this texture because it is no-copy and/or no-transfer. +  <usetemplate +    ignoretext="Warn me that Live Preview mode is not available for no-copy and/or no-transfer textures" +    name="okignore" +    yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="ConfirmLeaveCall"     type="alert">  Are you sure you want to leave this call? diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 54a312bd59..c5dfb703e5 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -11,6 +11,10 @@  		 name="unknown">          (unknown)  	</panel.string> +    <panel.string +         name="unknown_multiple"> +        (unknown / multiple) +    </panel.string>  	<panel.string  		 name="public">          (public)  | 
