|
@@ -9898,7 +9898,6 @@ class BufferAttribute {
|
|
|
this.normalized = normalized;
|
|
this.normalized = normalized;
|
|
|
|
|
|
|
|
this.usage = StaticDrawUsage;
|
|
this.usage = StaticDrawUsage;
|
|
|
- this._updateRange = { offset: 0, count: - 1 };
|
|
|
|
|
this.updateRanges = [];
|
|
this.updateRanges = [];
|
|
|
this.gpuType = FloatType;
|
|
this.gpuType = FloatType;
|
|
|
|
|
|
|
@@ -9914,13 +9913,6 @@ class BufferAttribute {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- get updateRange() {
|
|
|
|
|
-
|
|
|
|
|
- warnOnce( 'THREE.BufferAttribute: updateRange() is deprecated and will be removed in r169. Use addUpdateRange() instead.' ); // @deprecated, r159
|
|
|
|
|
- return this._updateRange;
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
setUsage( value ) {
|
|
setUsage( value ) {
|
|
|
|
|
|
|
|
this.usage = value;
|
|
this.usage = value;
|
|
@@ -13605,40 +13597,71 @@ function WebGLAttributes( gl ) {
|
|
|
function updateBuffer( buffer, attribute, bufferType ) {
|
|
function updateBuffer( buffer, attribute, bufferType ) {
|
|
|
|
|
|
|
|
const array = attribute.array;
|
|
const array = attribute.array;
|
|
|
- const updateRange = attribute._updateRange; // @deprecated, r159
|
|
|
|
|
const updateRanges = attribute.updateRanges;
|
|
const updateRanges = attribute.updateRanges;
|
|
|
|
|
|
|
|
gl.bindBuffer( bufferType, buffer );
|
|
gl.bindBuffer( bufferType, buffer );
|
|
|
|
|
|
|
|
- if ( updateRange.count === - 1 && updateRanges.length === 0 ) {
|
|
|
|
|
|
|
+ if ( updateRanges.length === 0 ) {
|
|
|
|
|
|
|
|
// Not using update ranges
|
|
// Not using update ranges
|
|
|
gl.bufferSubData( bufferType, 0, array );
|
|
gl.bufferSubData( bufferType, 0, array );
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+
|
|
|
|
|
+ // Before applying update ranges, we merge any adjacent / overlapping
|
|
|
|
|
+ // ranges to reduce load on `gl.bufferSubData`. Empirically, this has led
|
|
|
|
|
+ // to performance improvements for applications which make heavy use of
|
|
|
|
|
+ // update ranges. Likely due to GPU command overhead.
|
|
|
|
|
+ //
|
|
|
|
|
+ // Note that to reduce garbage collection between frames, we merge the
|
|
|
|
|
+ // update ranges in-place. This is safe because this method will clear the
|
|
|
|
|
+ // update ranges once updated.
|
|
|
|
|
|
|
|
- if ( updateRanges.length !== 0 ) {
|
|
|
|
|
|
|
+ updateRanges.sort( ( a, b ) => a.start - b.start );
|
|
|
|
|
|
|
|
- for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
|
|
|
|
|
|
|
+ // To merge the update ranges in-place, we work from left to right in the
|
|
|
|
|
+ // existing updateRanges array, merging ranges. This may result in a final
|
|
|
|
|
+ // array which is smaller than the original. This index tracks the last
|
|
|
|
|
+ // index representing a merged range, any data after this index can be
|
|
|
|
|
+ // trimmed once the merge algorithm is completed.
|
|
|
|
|
+ let mergeIndex = 0;
|
|
|
|
|
|
|
|
|
|
+ for ( let i = 1; i < updateRanges.length; i ++ ) {
|
|
|
|
|
+
|
|
|
|
|
+ const previousRange = updateRanges[ mergeIndex ];
|
|
|
const range = updateRanges[ i ];
|
|
const range = updateRanges[ i ];
|
|
|
|
|
|
|
|
- gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
|
|
|
|
|
- array, range.start, range.count );
|
|
|
|
|
|
|
+ // We add one here to merge adjacent ranges. This is safe because ranges
|
|
|
|
|
+ // operate over positive integers.
|
|
|
|
|
+ if ( range.start <= previousRange.start + previousRange.count + 1 ) {
|
|
|
|
|
+
|
|
|
|
|
+ previousRange.count = Math.max(
|
|
|
|
|
+ previousRange.count,
|
|
|
|
|
+ range.start + range.count - previousRange.start
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+
|
|
|
|
|
+ ++ mergeIndex;
|
|
|
|
|
+ updateRanges[ mergeIndex ] = range;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- attribute.clearUpdateRanges();
|
|
|
|
|
|
|
+ // Trim the array to only contain the merged ranges.
|
|
|
|
|
+ updateRanges.length = mergeIndex + 1;
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
|
|
|
|
|
|
|
|
- // @deprecated, r159
|
|
|
|
|
- if ( updateRange.count !== - 1 ) {
|
|
|
|
|
|
|
+ const range = updateRanges[ i ];
|
|
|
|
|
|
|
|
- gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
|
|
|
|
|
- array, updateRange.offset, updateRange.count );
|
|
|
|
|
|
|
+ gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
|
|
|
|
|
+ array, range.start, range.count );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- updateRange.count = - 1; // reset range
|
|
|
|
|
|
|
+ attribute.clearUpdateRanges();
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -31587,7 +31610,6 @@ class InterleavedBuffer {
|
|
|
this.count = array !== undefined ? array.length / stride : 0;
|
|
this.count = array !== undefined ? array.length / stride : 0;
|
|
|
|
|
|
|
|
this.usage = StaticDrawUsage;
|
|
this.usage = StaticDrawUsage;
|
|
|
- this._updateRange = { offset: 0, count: - 1 };
|
|
|
|
|
this.updateRanges = [];
|
|
this.updateRanges = [];
|
|
|
|
|
|
|
|
this.version = 0;
|
|
this.version = 0;
|
|
@@ -31604,13 +31626,6 @@ class InterleavedBuffer {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- get updateRange() {
|
|
|
|
|
-
|
|
|
|
|
- warnOnce( 'THREE.InterleavedBuffer: updateRange() is deprecated and will be removed in r169. Use addUpdateRange() instead.' ); // @deprecated, r159
|
|
|
|
|
- return this._updateRange;
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
setUsage( value ) {
|
|
setUsage( value ) {
|
|
|
|
|
|
|
|
this.usage = value;
|
|
this.usage = value;
|
|
@@ -45814,7 +45829,7 @@ class MaterialLoader extends Loader {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const material = MaterialLoader.createMaterialFromType( json.type );
|
|
|
|
|
|
|
+ const material = this.createMaterialFromType( json.type );
|
|
|
|
|
|
|
|
if ( json.uuid !== undefined ) material.uuid = json.uuid;
|
|
if ( json.uuid !== undefined ) material.uuid = json.uuid;
|
|
|
if ( json.name !== undefined ) material.name = json.name;
|
|
if ( json.name !== undefined ) material.name = json.name;
|
|
@@ -46070,6 +46085,12 @@ class MaterialLoader extends Loader {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ createMaterialFromType( type ) {
|
|
|
|
|
+
|
|
|
|
|
+ return MaterialLoader.createMaterialFromType( type );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
static createMaterialFromType( type ) {
|
|
static createMaterialFromType( type ) {
|
|
|
|
|
|
|
|
const materialLib = {
|
|
const materialLib = {
|