@gnsx/three 0.184.18 → 0.184.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.cjs +88 -1
- package/build/three.core.js +88 -1
- package/build/three.core.min.js +1 -1
- package/package.json +2 -2
- package/src/profiler/ProfilerService.js +88 -1
package/build/three.cjs
CHANGED
|
@@ -59733,7 +59733,7 @@ class ProfilerServiceClass {
|
|
|
59733
59733
|
this._profile = 'full';
|
|
59734
59734
|
this._enabled = false;
|
|
59735
59735
|
|
|
59736
|
-
/** @type {Map<string, Float64Array>} */
|
|
59736
|
+
/** @type {Map<string, Float64Array>} Inclusive time ring buffers (one per label). */
|
|
59737
59737
|
this.buffers = new Map();
|
|
59738
59738
|
/** @type {Map<string, number>} */
|
|
59739
59739
|
this.cursors = new Map();
|
|
@@ -59746,6 +59746,20 @@ class ProfilerServiceClass {
|
|
|
59746
59746
|
this.traceStartTime = 0;
|
|
59747
59747
|
this._markId = 0;
|
|
59748
59748
|
|
|
59749
|
+
/** @type {Map<string, Float64Array>} Exclusive (self) time ring buffers (one per label). */
|
|
59750
|
+
this.selfBuffers = new Map();
|
|
59751
|
+
/** @type {Map<string, number>} */
|
|
59752
|
+
this.selfCursors = new Map();
|
|
59753
|
+
/** @type {Map<string, number>} */
|
|
59754
|
+
this.selfCounts = new Map();
|
|
59755
|
+
/**
|
|
59756
|
+
* Global call stack tracking nesting across all labels for exclusive-time computation.
|
|
59757
|
+
* @type {Array<{ label: string, childTime: number }>}
|
|
59758
|
+
*/
|
|
59759
|
+
this.callStack = [];
|
|
59760
|
+
/** @type {Map<string, number>} Total (uncapped) invocation count since last reset, for calls-per-frame. */
|
|
59761
|
+
this.invocations = new Map();
|
|
59762
|
+
|
|
59749
59763
|
if ( this._enabled ) {
|
|
59750
59764
|
|
|
59751
59765
|
this.traceStartTime = performance.now();
|
|
@@ -59852,6 +59866,9 @@ class ProfilerServiceClass {
|
|
|
59852
59866
|
performance.mark( startMark );
|
|
59853
59867
|
stack.push( { startTime, startMark, traced } );
|
|
59854
59868
|
|
|
59869
|
+
// Push onto the global call stack for exclusive-time tracking.
|
|
59870
|
+
this.callStack.push( { label, childTime: 0 } );
|
|
59871
|
+
|
|
59855
59872
|
}
|
|
59856
59873
|
|
|
59857
59874
|
/**
|
|
@@ -59887,6 +59904,42 @@ class ProfilerServiceClass {
|
|
|
59887
59904
|
this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
|
|
59888
59905
|
this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
|
|
59889
59906
|
|
|
59907
|
+
// Track total invocations (uncapped) for calls-per-frame computation.
|
|
59908
|
+
this.invocations.set( label, ( this.invocations.get( label ) ?? 0 ) + 1 );
|
|
59909
|
+
|
|
59910
|
+
// Exclusive (self) time via the global call stack.
|
|
59911
|
+
const top = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
|
|
59912
|
+
if ( top !== undefined && top.label === label ) {
|
|
59913
|
+
|
|
59914
|
+
this.callStack.pop();
|
|
59915
|
+
const selfTime = Math.max( 0, duration - top.childTime );
|
|
59916
|
+
|
|
59917
|
+
let selfBuffer = this.selfBuffers.get( label );
|
|
59918
|
+
if ( ! selfBuffer ) {
|
|
59919
|
+
|
|
59920
|
+
selfBuffer = new Float64Array( RING_SIZE );
|
|
59921
|
+
this.selfBuffers.set( label, selfBuffer );
|
|
59922
|
+
this.selfCursors.set( label, 0 );
|
|
59923
|
+
this.selfCounts.set( label, 0 );
|
|
59924
|
+
|
|
59925
|
+
}
|
|
59926
|
+
|
|
59927
|
+
const selfCursor = this.selfCursors.get( label );
|
|
59928
|
+
selfBuffer[ selfCursor ] = selfTime;
|
|
59929
|
+
this.selfCursors.set( label, ( selfCursor + 1 ) % RING_SIZE );
|
|
59930
|
+
this.selfCounts.set( label, Math.min( ( this.selfCounts.get( label ) + 1 ), RING_SIZE ) );
|
|
59931
|
+
|
|
59932
|
+
// Propagate inclusive duration to the parent scope's child accumulator.
|
|
59933
|
+
const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
|
|
59934
|
+
if ( parent !== undefined ) parent.childTime += duration;
|
|
59935
|
+
|
|
59936
|
+
} else {
|
|
59937
|
+
|
|
59938
|
+
// Label mismatch — likely async interleaving. Reset to avoid corruption.
|
|
59939
|
+
this.callStack.length = 0;
|
|
59940
|
+
|
|
59941
|
+
}
|
|
59942
|
+
|
|
59890
59943
|
if ( traced ) {
|
|
59891
59944
|
|
|
59892
59945
|
this.traceEvents.push( {
|
|
@@ -59929,6 +59982,23 @@ class ProfilerServiceClass {
|
|
|
59929
59982
|
const sorted = [ ...samples ].sort( ( a, b ) => a - b );
|
|
59930
59983
|
const avg = sorted.reduce( ( a, b ) => a + b, 0 ) / sorted.length;
|
|
59931
59984
|
|
|
59985
|
+
// Exclusive (self) time stats.
|
|
59986
|
+
const selfCount = this.selfCounts.get( label ) ?? 0;
|
|
59987
|
+
let selfAvg, selfMin, selfMax, selfP95, selfFrameBudget;
|
|
59988
|
+
if ( selfCount > 0 ) {
|
|
59989
|
+
|
|
59990
|
+
const selfBuffer = this.selfBuffers.get( label );
|
|
59991
|
+
const selfSamples = [ ...( selfCount < RING_SIZE
|
|
59992
|
+
? selfBuffer.subarray( 0, selfCount )
|
|
59993
|
+
: selfBuffer ) ].sort( ( a, b ) => a - b );
|
|
59994
|
+
selfAvg = selfSamples.reduce( ( a, b ) => a + b, 0 ) / selfSamples.length;
|
|
59995
|
+
selfMin = selfSamples[ 0 ];
|
|
59996
|
+
selfMax = selfSamples[ selfSamples.length - 1 ];
|
|
59997
|
+
selfP95 = selfSamples[ Math.floor( selfSamples.length * 0.95 ) ];
|
|
59998
|
+
selfFrameBudget = ( selfAvg / FRAME_BUDGET_MS ) * 100;
|
|
59999
|
+
|
|
60000
|
+
}
|
|
60001
|
+
|
|
59932
60002
|
return {
|
|
59933
60003
|
label,
|
|
59934
60004
|
samples: samples.length,
|
|
@@ -59937,6 +60007,12 @@ class ProfilerServiceClass {
|
|
|
59937
60007
|
max: sorted[ sorted.length - 1 ],
|
|
59938
60008
|
p95: sorted[ Math.floor( sorted.length * 0.95 ) ],
|
|
59939
60009
|
frameBudget: ( avg / FRAME_BUDGET_MS ) * 100,
|
|
60010
|
+
totalInvocations: this.invocations.get( label ) ?? 0,
|
|
60011
|
+
selfAvg,
|
|
60012
|
+
selfMin,
|
|
60013
|
+
selfMax,
|
|
60014
|
+
selfP95,
|
|
60015
|
+
selfFrameBudget,
|
|
59940
60016
|
};
|
|
59941
60017
|
|
|
59942
60018
|
}
|
|
@@ -60059,6 +60135,11 @@ class ProfilerServiceClass {
|
|
|
60059
60135
|
this.traceEvents = [];
|
|
60060
60136
|
this.traceStartTime = performance.now();
|
|
60061
60137
|
this._markId = 0;
|
|
60138
|
+
this.selfBuffers.clear();
|
|
60139
|
+
this.selfCursors.clear();
|
|
60140
|
+
this.selfCounts.clear();
|
|
60141
|
+
this.callStack.length = 0;
|
|
60142
|
+
this.invocations.clear();
|
|
60062
60143
|
|
|
60063
60144
|
}
|
|
60064
60145
|
|
|
@@ -60080,6 +60161,12 @@ class ProfilerServiceClass {
|
|
|
60080
60161
|
* @property {number} max
|
|
60081
60162
|
* @property {number} p95
|
|
60082
60163
|
* @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
|
|
60164
|
+
* @property {number} totalInvocations Total (uncapped) call count since last reset, for calls-per-frame computation.
|
|
60165
|
+
* @property {number|undefined} selfAvg Exclusive (self) avg ms — inclusive time minus child scope time.
|
|
60166
|
+
* @property {number|undefined} selfMin
|
|
60167
|
+
* @property {number|undefined} selfMax
|
|
60168
|
+
* @property {number|undefined} selfP95
|
|
60169
|
+
* @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
|
|
60083
60170
|
*/
|
|
60084
60171
|
|
|
60085
60172
|
/**
|
package/build/three.core.js
CHANGED
|
@@ -59753,7 +59753,7 @@ class ProfilerServiceClass {
|
|
|
59753
59753
|
this._profile = 'full';
|
|
59754
59754
|
this._enabled = false;
|
|
59755
59755
|
|
|
59756
|
-
/** @type {Map<string, Float64Array>} */
|
|
59756
|
+
/** @type {Map<string, Float64Array>} Inclusive time ring buffers (one per label). */
|
|
59757
59757
|
this.buffers = new Map();
|
|
59758
59758
|
/** @type {Map<string, number>} */
|
|
59759
59759
|
this.cursors = new Map();
|
|
@@ -59766,6 +59766,20 @@ class ProfilerServiceClass {
|
|
|
59766
59766
|
this.traceStartTime = 0;
|
|
59767
59767
|
this._markId = 0;
|
|
59768
59768
|
|
|
59769
|
+
/** @type {Map<string, Float64Array>} Exclusive (self) time ring buffers (one per label). */
|
|
59770
|
+
this.selfBuffers = new Map();
|
|
59771
|
+
/** @type {Map<string, number>} */
|
|
59772
|
+
this.selfCursors = new Map();
|
|
59773
|
+
/** @type {Map<string, number>} */
|
|
59774
|
+
this.selfCounts = new Map();
|
|
59775
|
+
/**
|
|
59776
|
+
* Global call stack tracking nesting across all labels for exclusive-time computation.
|
|
59777
|
+
* @type {Array<{ label: string, childTime: number }>}
|
|
59778
|
+
*/
|
|
59779
|
+
this.callStack = [];
|
|
59780
|
+
/** @type {Map<string, number>} Total (uncapped) invocation count since last reset, for calls-per-frame. */
|
|
59781
|
+
this.invocations = new Map();
|
|
59782
|
+
|
|
59769
59783
|
if ( this._enabled ) {
|
|
59770
59784
|
|
|
59771
59785
|
this.traceStartTime = performance.now();
|
|
@@ -59872,6 +59886,9 @@ class ProfilerServiceClass {
|
|
|
59872
59886
|
performance.mark( startMark );
|
|
59873
59887
|
stack.push( { startTime, startMark, traced } );
|
|
59874
59888
|
|
|
59889
|
+
// Push onto the global call stack for exclusive-time tracking.
|
|
59890
|
+
this.callStack.push( { label, childTime: 0 } );
|
|
59891
|
+
|
|
59875
59892
|
}
|
|
59876
59893
|
|
|
59877
59894
|
/**
|
|
@@ -59907,6 +59924,42 @@ class ProfilerServiceClass {
|
|
|
59907
59924
|
this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
|
|
59908
59925
|
this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
|
|
59909
59926
|
|
|
59927
|
+
// Track total invocations (uncapped) for calls-per-frame computation.
|
|
59928
|
+
this.invocations.set( label, ( this.invocations.get( label ) ?? 0 ) + 1 );
|
|
59929
|
+
|
|
59930
|
+
// Exclusive (self) time via the global call stack.
|
|
59931
|
+
const top = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
|
|
59932
|
+
if ( top !== undefined && top.label === label ) {
|
|
59933
|
+
|
|
59934
|
+
this.callStack.pop();
|
|
59935
|
+
const selfTime = Math.max( 0, duration - top.childTime );
|
|
59936
|
+
|
|
59937
|
+
let selfBuffer = this.selfBuffers.get( label );
|
|
59938
|
+
if ( ! selfBuffer ) {
|
|
59939
|
+
|
|
59940
|
+
selfBuffer = new Float64Array( RING_SIZE );
|
|
59941
|
+
this.selfBuffers.set( label, selfBuffer );
|
|
59942
|
+
this.selfCursors.set( label, 0 );
|
|
59943
|
+
this.selfCounts.set( label, 0 );
|
|
59944
|
+
|
|
59945
|
+
}
|
|
59946
|
+
|
|
59947
|
+
const selfCursor = this.selfCursors.get( label );
|
|
59948
|
+
selfBuffer[ selfCursor ] = selfTime;
|
|
59949
|
+
this.selfCursors.set( label, ( selfCursor + 1 ) % RING_SIZE );
|
|
59950
|
+
this.selfCounts.set( label, Math.min( ( this.selfCounts.get( label ) + 1 ), RING_SIZE ) );
|
|
59951
|
+
|
|
59952
|
+
// Propagate inclusive duration to the parent scope's child accumulator.
|
|
59953
|
+
const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
|
|
59954
|
+
if ( parent !== undefined ) parent.childTime += duration;
|
|
59955
|
+
|
|
59956
|
+
} else {
|
|
59957
|
+
|
|
59958
|
+
// Label mismatch — likely async interleaving. Reset to avoid corruption.
|
|
59959
|
+
this.callStack.length = 0;
|
|
59960
|
+
|
|
59961
|
+
}
|
|
59962
|
+
|
|
59910
59963
|
if ( traced ) {
|
|
59911
59964
|
|
|
59912
59965
|
this.traceEvents.push( {
|
|
@@ -59949,6 +60002,23 @@ class ProfilerServiceClass {
|
|
|
59949
60002
|
const sorted = [ ...samples ].sort( ( a, b ) => a - b );
|
|
59950
60003
|
const avg = sorted.reduce( ( a, b ) => a + b, 0 ) / sorted.length;
|
|
59951
60004
|
|
|
60005
|
+
// Exclusive (self) time stats.
|
|
60006
|
+
const selfCount = this.selfCounts.get( label ) ?? 0;
|
|
60007
|
+
let selfAvg, selfMin, selfMax, selfP95, selfFrameBudget;
|
|
60008
|
+
if ( selfCount > 0 ) {
|
|
60009
|
+
|
|
60010
|
+
const selfBuffer = this.selfBuffers.get( label );
|
|
60011
|
+
const selfSamples = [ ...( selfCount < RING_SIZE
|
|
60012
|
+
? selfBuffer.subarray( 0, selfCount )
|
|
60013
|
+
: selfBuffer ) ].sort( ( a, b ) => a - b );
|
|
60014
|
+
selfAvg = selfSamples.reduce( ( a, b ) => a + b, 0 ) / selfSamples.length;
|
|
60015
|
+
selfMin = selfSamples[ 0 ];
|
|
60016
|
+
selfMax = selfSamples[ selfSamples.length - 1 ];
|
|
60017
|
+
selfP95 = selfSamples[ Math.floor( selfSamples.length * 0.95 ) ];
|
|
60018
|
+
selfFrameBudget = ( selfAvg / FRAME_BUDGET_MS ) * 100;
|
|
60019
|
+
|
|
60020
|
+
}
|
|
60021
|
+
|
|
59952
60022
|
return {
|
|
59953
60023
|
label,
|
|
59954
60024
|
samples: samples.length,
|
|
@@ -59957,6 +60027,12 @@ class ProfilerServiceClass {
|
|
|
59957
60027
|
max: sorted[ sorted.length - 1 ],
|
|
59958
60028
|
p95: sorted[ Math.floor( sorted.length * 0.95 ) ],
|
|
59959
60029
|
frameBudget: ( avg / FRAME_BUDGET_MS ) * 100,
|
|
60030
|
+
totalInvocations: this.invocations.get( label ) ?? 0,
|
|
60031
|
+
selfAvg,
|
|
60032
|
+
selfMin,
|
|
60033
|
+
selfMax,
|
|
60034
|
+
selfP95,
|
|
60035
|
+
selfFrameBudget,
|
|
59960
60036
|
};
|
|
59961
60037
|
|
|
59962
60038
|
}
|
|
@@ -60079,6 +60155,11 @@ class ProfilerServiceClass {
|
|
|
60079
60155
|
this.traceEvents = [];
|
|
60080
60156
|
this.traceStartTime = performance.now();
|
|
60081
60157
|
this._markId = 0;
|
|
60158
|
+
this.selfBuffers.clear();
|
|
60159
|
+
this.selfCursors.clear();
|
|
60160
|
+
this.selfCounts.clear();
|
|
60161
|
+
this.callStack.length = 0;
|
|
60162
|
+
this.invocations.clear();
|
|
60082
60163
|
|
|
60083
60164
|
}
|
|
60084
60165
|
|
|
@@ -60100,6 +60181,12 @@ class ProfilerServiceClass {
|
|
|
60100
60181
|
* @property {number} max
|
|
60101
60182
|
* @property {number} p95
|
|
60102
60183
|
* @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
|
|
60184
|
+
* @property {number} totalInvocations Total (uncapped) call count since last reset, for calls-per-frame computation.
|
|
60185
|
+
* @property {number|undefined} selfAvg Exclusive (self) avg ms — inclusive time minus child scope time.
|
|
60186
|
+
* @property {number|undefined} selfMin
|
|
60187
|
+
* @property {number|undefined} selfMax
|
|
60188
|
+
* @property {number|undefined} selfP95
|
|
60189
|
+
* @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
|
|
60103
60190
|
*/
|
|
60104
60191
|
|
|
60105
60192
|
/**
|