Browse Source

extract mesh/line/pointCloud rendering from renderBufferDirect.

At the moment, renderBufferDirect is a large method body with a common
and 3 separate codes for each object type.
This patch extracts each code into its own method, this helps the
JavaScript JIT compiler inlining, but most importantly it allows easier
method level profiling. Right now a lot of profiles just show
`renderBufferDirect`.
Fabian Lange 10 years ago
parent
commit
f2a191b4a7
1 changed files with 211 additions and 198 deletions
  1. 211 198
      src/renderers/WebGLRenderer.js

+ 211 - 198
src/renderers/WebGLRenderer.js

@@ -1010,380 +1010,393 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		// render mesh
-
 		if ( object instanceof THREE.Mesh ) {
 
-			var mode = material.wireframe === true ? _gl.LINES : _gl.TRIANGLES;
+			renderMesh( material, geometry, object, program, updateBuffers );
 
-			var index = geometry.attributes.index;
+		} else if ( object instanceof THREE.PointCloud ) {
 
-			if ( index ) {
+			renderPointCloud( material, geometry, object, program, updateBuffers );
 
-				// indexed triangles
+		} else if ( object instanceof THREE.Line ) {
 
-				var type, size;
+			renderLine( material, geometry, object, program, updateBuffers );
 
-				if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
+		}
 
-					type = _gl.UNSIGNED_INT;
-					size = 4;
+	};
 
-				} else {
+	function renderMesh ( material, geometry, object, program, updateBuffers ) {
 
-					type = _gl.UNSIGNED_SHORT;
-					size = 2;
+		var mode = material.wireframe === true ? _gl.LINES : _gl.TRIANGLES;
 
-				}
+		var index = geometry.attributes.index;
 
-				var offsets = geometry.offsets;
+		if ( index ) {
 
-				if ( offsets.length === 0 ) {
+			// indexed triangles
 
-					if ( updateBuffers ) {
+			var type, size;
 
-						setupVertexAttributes( material, program, geometry, 0 );
-						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
+			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
 
-					}
+				type = _gl.UNSIGNED_INT;
+				size = 4;
 
-					if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
+			} else {
 
-						var extension = extensions.get( 'ANGLE_instanced_arrays' );
+				type = _gl.UNSIGNED_SHORT;
+				size = 2;
 
-						if ( extension === null ) {
+			}
 
-							THREE.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
-							return;
+			var offsets = geometry.offsets;
 
-						}
+			if ( offsets.length === 0 ) {
 
-						extension.drawElementsInstancedANGLE( mode, index.array.length, type, 0, geometry.maxInstancedCount ); // Draw the instanced meshes
+				if ( updateBuffers ) {
 
-					} else {
+					setupVertexAttributes( material, program, geometry, 0 );
+					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
 
-						_gl.drawElements( mode, index.array.length, type, 0 );
+				}
+
+				if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
+
+					var extension = extensions.get( 'ANGLE_instanced_arrays' );
+
+					if ( extension === null ) {
+
+						THREE.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
+						return;
 
 					}
-					_this.info.render.calls ++;
-					_this.info.render.vertices += index.array.length; // not really true, here vertices can be shared
-					_this.info.render.faces += index.array.length / 3;
 
-				} else {
+					extension.drawElementsInstancedANGLE( mode, index.array.length, type, 0, geometry.maxInstancedCount ); // Draw the instanced meshes
 
-					// if there is more than 1 chunk
-					// must set attribute pointers to use new offsets for each chunk
-					// even if geometry and materials didn't change
+				} else {
 
-					updateBuffers = true;
+					_gl.drawElements( mode, index.array.length, type, 0 );
 
-					for ( var i = 0, il = offsets.length; i < il; i ++ ) {
+				}
+				_this.info.render.calls ++;
+				_this.info.render.vertices += index.array.length; // not really true, here vertices can be shared
+				_this.info.render.faces += index.array.length / 3;
 
-						var startIndex = offsets[ i ].index;
+			} else {
 
-						if ( updateBuffers ) {
+				// if there is more than 1 chunk
+				// must set attribute pointers to use new offsets for each chunk
+				// even if geometry and materials didn't change
 
-							setupVertexAttributes( material, program, geometry, startIndex );
-							_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
+				updateBuffers = true;
 
-						}
+				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
 
-						// render indexed triangles
+					var startIndex = offsets[ i ].index;
 
-						if ( geometry instanceof THREE.InstancedBufferGeometry && offsets[i].instances > 0 ) {
+					if ( updateBuffers ) {
 
-							var extension = extensions.get( 'ANGLE_instanced_arrays' );
+						setupVertexAttributes( material, program, geometry, startIndex );
+						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
 
-							if ( extension === null ) {
+					}
 
-								THREE.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
-								return;
+					// render indexed triangles
 
-							}
+					if ( geometry instanceof THREE.InstancedBufferGeometry && offsets[i].instances > 0 ) {
 
-							extension.drawElementsInstancedANGLE( mode, offsets[i].count, type, offsets[i].start * size, offsets[i].count, type, offsets[i].instances ); // Draw the instanced meshes
+						var extension = extensions.get( 'ANGLE_instanced_arrays' );
 
-						} else {
+						if ( extension === null ) {
 
-							_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size );
+							THREE.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
+							return;
 
 						}
 
-						_this.info.render.calls ++;
-						_this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
-						_this.info.render.faces += offsets[ i ].count / 3;
+						extension.drawElementsInstancedANGLE( mode, offsets[i].count, type, offsets[i].start * size, offsets[i].count, type, offsets[i].instances ); // Draw the instanced meshes
+
+					} else {
+
+						_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size );
 
 					}
 
+					_this.info.render.calls ++;
+					_this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
+					_this.info.render.faces += offsets[ i ].count / 3;
+
 				}
 
-			} else {
+			}
 
-				// non-indexed triangles
+		} else {
 
-				if ( updateBuffers ) {
+			// non-indexed triangles
 
-					setupVertexAttributes( material, program, geometry, 0 );
+			if ( updateBuffers ) {
 
-				}
+				setupVertexAttributes( material, program, geometry, 0 );
 
-				var position = geometry.attributes[ 'position' ];
+			}
 
-				// render non-indexed triangles
+			var position = geometry.attributes[ 'position' ];
 
-				if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
+			// render non-indexed triangles
 
-					var extension = extensions.get( 'ANGLE_instanced_arrays' );
+			if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
 
-					if ( extension === null ) {
+				var extension = extensions.get( 'ANGLE_instanced_arrays' );
 
-						THREE.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
-						return;
+				if ( extension === null ) {
 
-					}
+					THREE.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
+					return;
 
-					if ( position instanceof THREE.InterleavedBufferAttribute ) {
+				}
 
-						extension.drawArraysInstancedANGLE( mode, 0, position.data.array.length / position.data.stride, geometry.maxInstancedCount ); // Draw the instanced meshes
+				if ( position instanceof THREE.InterleavedBufferAttribute ) {
 
-					} else {
+					extension.drawArraysInstancedANGLE( mode, 0, position.data.array.length / position.data.stride, geometry.maxInstancedCount ); // Draw the instanced meshes
 
-						extension.drawArraysInstancedANGLE( mode, 0, position.array.length / position.itemSize, geometry.maxInstancedCount ); // Draw the instanced meshes
+				} else {
 
-					}
+					extension.drawArraysInstancedANGLE( mode, 0, position.array.length / position.itemSize, geometry.maxInstancedCount ); // Draw the instanced meshes
 
-				} else {
+				}
 
-					if ( position instanceof THREE.InterleavedBufferAttribute ) {
+			} else {
 
-						_gl.drawArrays( mode, 0, position.data.array.length / position.data.stride );
+				if ( position instanceof THREE.InterleavedBufferAttribute ) {
 
-					} else {
+					_gl.drawArrays( mode, 0, position.data.array.length / position.data.stride );
 
-						_gl.drawArrays( mode, 0, position.array.length / position.itemSize );
+				} else {
 
-					}
+					_gl.drawArrays( mode, 0, position.array.length / position.itemSize );
 
 				}
 
-				_this.info.render.calls ++;
-				_this.info.render.vertices += position.array.length / position.itemSize;
-				_this.info.render.faces += position.array.length / ( 3 * position.itemSize );
-
 			}
 
-		} else if ( object instanceof THREE.PointCloud ) {
+			_this.info.render.calls ++;
+			_this.info.render.vertices += position.array.length / position.itemSize;
+			_this.info.render.faces += position.array.length / ( 3 * position.itemSize );
 
-			// render particles
+		}
 
-			var mode = _gl.POINTS;
+	};
 
-			var index = geometry.attributes.index;
+	function renderPointCloud ( material, geometry, object, program, updateBuffers ) {
 
-			if ( index ) {
+		var mode = _gl.POINTS;
 
-				// indexed points
+		var index = geometry.attributes.index;
 
-				var type, size;
+		if ( index ) {
 
-				if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
+			// indexed points
 
-					type = _gl.UNSIGNED_INT;
-					size = 4;
+			var type, size;
 
-				} else {
+			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
 
-					type = _gl.UNSIGNED_SHORT;
-					size = 2;
+				type = _gl.UNSIGNED_INT;
+				size = 4;
 
-				}
+			} else {
 
-				var offsets = geometry.offsets;
+				type = _gl.UNSIGNED_SHORT;
+				size = 2;
 
-				if ( offsets.length === 0 ) {
+			}
 
-					if ( updateBuffers ) {
+			var offsets = geometry.offsets;
 
-						setupVertexAttributes( material, program, geometry, 0 );
-						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
+			if ( offsets.length === 0 ) {
 
-					}
+				if ( updateBuffers ) {
 
-					_gl.drawElements( mode, index.array.length, type, 0);
+					setupVertexAttributes( material, program, geometry, 0 );
+					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
 
-					_this.info.render.calls ++;
-					_this.info.render.points += index.array.length;
+				}
 
-				} else {
+				_gl.drawElements( mode, index.array.length, type, 0);
+
+				_this.info.render.calls ++;
+				_this.info.render.points += index.array.length;
 
-					// if there is more than 1 chunk
-					// must set attribute pointers to use new offsets for each chunk
-					// even if geometry and materials didn't change
+			} else {
 
-					if ( offsets.length > 1 ) updateBuffers = true;
+				// if there is more than 1 chunk
+				// must set attribute pointers to use new offsets for each chunk
+				// even if geometry and materials didn't change
 
-					for ( var i = 0, il = offsets.length; i < il; i ++ ) {
+				if ( offsets.length > 1 ) updateBuffers = true;
 
-						var startIndex = offsets[ i ].index;
+				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
 
-						if ( updateBuffers ) {
+					var startIndex = offsets[ i ].index;
 
-							setupVertexAttributes( material, program, geometry, startIndex );
-							_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
+					if ( updateBuffers ) {
 
-						}
+						setupVertexAttributes( material, program, geometry, startIndex );
+						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
 
-						// render indexed points
+					}
 
-						_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size );
+					// render indexed points
 
-						_this.info.render.calls ++;
-						_this.info.render.points += offsets[ i ].count;
+					_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size );
 
-					}
+					_this.info.render.calls ++;
+					_this.info.render.points += offsets[ i ].count;
 
 				}
 
-			} else {
+			}
 
-				// non-indexed points
+		} else {
 
-				if ( updateBuffers ) {
+			// non-indexed points
 
-					setupVertexAttributes( material, program, geometry, 0 );
+			if ( updateBuffers ) {
 
-				}
+				setupVertexAttributes( material, program, geometry, 0 );
 
-				var position = geometry.attributes.position;
-				var offsets = geometry.offsets;
+			}
 
-				if ( offsets.length === 0 ) {
+			var position = geometry.attributes.position;
+			var offsets = geometry.offsets;
 
-					_gl.drawArrays( mode, 0, position.array.length / 3 );
+			if ( offsets.length === 0 ) {
 
-					_this.info.render.calls ++;
-					_this.info.render.points += position.array.length / 3;
+				_gl.drawArrays( mode, 0, position.array.length / 3 );
 
-				} else {
+				_this.info.render.calls ++;
+				_this.info.render.points += position.array.length / 3;
 
-					for ( var i = 0, il = offsets.length; i < il; i ++ ) {
+			} else {
 
-						_gl.drawArrays( mode, offsets[ i ].index, offsets[ i ].count );
+				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
 
-						_this.info.render.calls ++;
-						_this.info.render.points += offsets[ i ].count;
+					_gl.drawArrays( mode, offsets[ i ].index, offsets[ i ].count );
 
-					}
+					_this.info.render.calls ++;
+					_this.info.render.points += offsets[ i ].count;
 
 				}
 
 			}
 
-		} else if ( object instanceof THREE.Line ) {
+		}
 
-			var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
+	};
 
-			// In case user is not using Line*Material by mistake
-			var lineWidth = material.linewidth !== undefined ? material.linewidth : 1;
+	function renderLine ( material, geometry, object, program, updateBuffers ) {
+		var mode = ( object.mode === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
 
-			state.setLineWidth( lineWidth * pixelRatio );
+		// In case user is not using Line*Material by mistake
+		var lineWidth = material.linewidth !== undefined ? material.linewidth : 1;
 
-			var index = geometry.attributes.index;
+		state.setLineWidth( lineWidth * pixelRatio );
 
-			if ( index ) {
+		var index = geometry.attributes.index;
 
-				// indexed lines
+		if ( index ) {
 
-				var type, size;
+			// indexed lines
 
-				if ( index.array instanceof Uint32Array ) {
+			var type, size;
 
-					type = _gl.UNSIGNED_INT;
-					size = 4;
+			if ( index.array instanceof Uint32Array ) {
 
-				} else {
+				type = _gl.UNSIGNED_INT;
+				size = 4;
 
-					type = _gl.UNSIGNED_SHORT;
-					size = 2;
+			} else {
 
-				}
+				type = _gl.UNSIGNED_SHORT;
+				size = 2;
 
-				var offsets = geometry.offsets;
+			}
 
-				if ( offsets.length === 0 ) {
+			var offsets = geometry.offsets;
 
-					if ( updateBuffers ) {
+			if ( offsets.length === 0 ) {
 
-						setupVertexAttributes( material, program, geometry, 0 );
-						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
+				if ( updateBuffers ) {
 
-					}
+					setupVertexAttributes( material, program, geometry, 0 );
+					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
 
-					_gl.drawElements( mode, index.array.length, type, 0 ); // 2 bytes per Uint16Array
+				}
 
-					_this.info.render.calls ++;
-					_this.info.render.vertices += index.array.length; // not really true, here vertices can be shared
+				_gl.drawElements( mode, index.array.length, type, 0 ); // 2 bytes per Uint16Array
 
-				} else {
+				_this.info.render.calls ++;
+				_this.info.render.vertices += index.array.length; // not really true, here vertices can be shared
 
-					// if there is more than 1 chunk
-					// must set attribute pointers to use new offsets for each chunk
-					// even if geometry and materials didn't change
+			} else {
 
-					if ( offsets.length > 1 ) updateBuffers = true;
+				// if there is more than 1 chunk
+				// must set attribute pointers to use new offsets for each chunk
+				// even if geometry and materials didn't change
 
-					for ( var i = 0, il = offsets.length; i < il; i ++ ) {
+				if ( offsets.length > 1 ) updateBuffers = true;
 
-						var startIndex = offsets[ i ].index;
+				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
 
-						if ( updateBuffers ) {
+					var startIndex = offsets[ i ].index;
 
-							setupVertexAttributes( material, program, geometry, startIndex );
-							_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
+					if ( updateBuffers ) {
 
-						}
+						setupVertexAttributes( material, program, geometry, startIndex );
+						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
 
-						// render indexed lines
+					}
 
-						_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size ); // 2 bytes per Uint16Array
+					// render indexed lines
 
-						_this.info.render.calls ++;
-						_this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
+					_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size ); // 2 bytes per Uint16Array
 
-					}
+					_this.info.render.calls ++;
+					_this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
 
 				}
 
-			} else {
+			}
 
-				// non-indexed lines
+		} else {
 
-				if ( updateBuffers ) {
+			// non-indexed lines
 
-					setupVertexAttributes( material, program, geometry, 0 );
+			if ( updateBuffers ) {
 
-				}
+				setupVertexAttributes( material, program, geometry, 0 );
 
-				var position = geometry.attributes.position;
-				var offsets = geometry.offsets;
+			}
 
-				if ( offsets.length === 0 ) {
+			var position = geometry.attributes.position;
+			var offsets = geometry.offsets;
 
-					_gl.drawArrays( mode, 0, position.array.length / 3 );
+			if ( offsets.length === 0 ) {
 
-					_this.info.render.calls ++;
-					_this.info.render.vertices += position.array.length / 3;
+				_gl.drawArrays( mode, 0, position.array.length / 3 );
 
-				} else {
+				_this.info.render.calls ++;
+				_this.info.render.vertices += position.array.length / 3;
 
-					for ( var i = 0, il = offsets.length; i < il; i ++ ) {
+			} else {
 
-						_gl.drawArrays( mode, offsets[ i ].index, offsets[ i ].count );
+				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
 
-						_this.info.render.calls ++;
-						_this.info.render.vertices += offsets[ i ].count;
+					_gl.drawArrays( mode, offsets[ i ].index, offsets[ i ].count );
 
-					}
+					_this.info.render.calls ++;
+					_this.info.render.vertices += offsets[ i ].count;
 
 				}