Initial project import
This commit is contained in:
425
node_modules/three/examples/jsm/inspector/RendererInspector.js
generated
vendored
Normal file
425
node_modules/three/examples/jsm/inspector/RendererInspector.js
generated
vendored
Normal file
@@ -0,0 +1,425 @@
|
||||
|
||||
import { InspectorBase, TimestampQuery, warnOnce } from 'three/webgpu';
|
||||
|
||||
class ObjectStats {
|
||||
|
||||
constructor( uid, name ) {
|
||||
|
||||
this.uid = uid;
|
||||
this.cid = uid.match( /^(.*):f(\d+)$/ )[ 1 ]; // call id
|
||||
this.name = name;
|
||||
this.timestamp = 0;
|
||||
this.cpu = 0;
|
||||
this.gpu = 0;
|
||||
this.fps = 0;
|
||||
|
||||
this.children = [];
|
||||
this.parent = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RenderStats extends ObjectStats {
|
||||
|
||||
constructor( uid, scene, camera, renderTarget ) {
|
||||
|
||||
let name = scene.name;
|
||||
|
||||
if ( name === '' ) {
|
||||
|
||||
if ( scene.isScene ) {
|
||||
|
||||
name = 'Scene';
|
||||
|
||||
} else if ( scene.isQuadMesh ) {
|
||||
|
||||
name = 'QuadMesh';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
super( uid, name );
|
||||
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.renderTarget = renderTarget;
|
||||
|
||||
this.isRenderStats = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ComputeStats extends ObjectStats {
|
||||
|
||||
constructor( uid, computeNode ) {
|
||||
|
||||
super( uid, computeNode.name );
|
||||
|
||||
this.computeNode = computeNode;
|
||||
|
||||
this.isComputeStats = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class RendererInspector extends InspectorBase {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.currentFrame = null;
|
||||
this.currentRender = null;
|
||||
this.currentNodes = null;
|
||||
this.lastFrame = null;
|
||||
|
||||
this.frames = [];
|
||||
this.framesLib = {};
|
||||
this.maxFrames = 512;
|
||||
|
||||
this._lastFinishTime = 0;
|
||||
this._resolveTimestampPromise = null;
|
||||
|
||||
this.isRendererInspector = true;
|
||||
|
||||
}
|
||||
|
||||
getParent() {
|
||||
|
||||
return this.currentRender || this.getFrame();
|
||||
|
||||
}
|
||||
|
||||
begin() {
|
||||
|
||||
this.currentFrame = this._createFrame();
|
||||
this.currentRender = this.currentFrame;
|
||||
this.currentNodes = [];
|
||||
|
||||
}
|
||||
|
||||
finish() {
|
||||
|
||||
const now = performance.now();
|
||||
|
||||
const frame = this.currentFrame;
|
||||
frame.finishTime = now;
|
||||
frame.deltaTime = now - ( this._lastFinishTime > 0 ? this._lastFinishTime : now );
|
||||
|
||||
this.addFrame( frame );
|
||||
|
||||
this.fps = this._getFPS();
|
||||
|
||||
this.lastFrame = frame;
|
||||
|
||||
this.currentFrame = null;
|
||||
this.currentRender = null;
|
||||
this.currentNodes = null;
|
||||
|
||||
this._lastFinishTime = now;
|
||||
|
||||
}
|
||||
|
||||
_getFPS() {
|
||||
|
||||
let frameSum = 0;
|
||||
let timeSum = 0;
|
||||
|
||||
for ( let i = this.frames.length - 1; i >= 0; i -- ) {
|
||||
|
||||
const frame = this.frames[ i ];
|
||||
|
||||
frameSum ++;
|
||||
timeSum += frame.deltaTime;
|
||||
|
||||
if ( timeSum >= 1000 ) break;
|
||||
|
||||
}
|
||||
|
||||
return ( frameSum * 1000 ) / timeSum;
|
||||
|
||||
}
|
||||
|
||||
_createFrame() {
|
||||
|
||||
return {
|
||||
frameId: this.nodeFrame.frameId,
|
||||
resolvedCompute: false,
|
||||
resolvedRender: false,
|
||||
deltaTime: 0,
|
||||
startTime: performance.now(),
|
||||
finishTime: 0,
|
||||
miscellaneous: 0,
|
||||
children: [],
|
||||
renders: [],
|
||||
computes: []
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
getFrame() {
|
||||
|
||||
return this.currentFrame || this.lastFrame;
|
||||
|
||||
}
|
||||
|
||||
getFrameById( frameId ) {
|
||||
|
||||
return this.framesLib[ frameId ] || null;
|
||||
|
||||
}
|
||||
|
||||
updateTabs() { }
|
||||
|
||||
resolveFrame( /*frame*/ ) { }
|
||||
|
||||
async resolveTimestamp() {
|
||||
|
||||
if ( this._resolveTimestampPromise !== null ) {
|
||||
|
||||
return this._resolveTimestampPromise;
|
||||
|
||||
}
|
||||
|
||||
this._resolveTimestampPromise = new Promise( ( resolve ) => {
|
||||
|
||||
requestAnimationFrame( async () => {
|
||||
|
||||
const renderer = this.getRenderer();
|
||||
|
||||
await renderer.resolveTimestampsAsync( TimestampQuery.COMPUTE );
|
||||
await renderer.resolveTimestampsAsync( TimestampQuery.RENDER );
|
||||
|
||||
const computeFrames = renderer.backend.getTimestampFrames( TimestampQuery.COMPUTE );
|
||||
const renderFrames = renderer.backend.getTimestampFrames( TimestampQuery.RENDER );
|
||||
|
||||
const frameIds = [ ...new Set( [ ...computeFrames, ...renderFrames ] ) ];
|
||||
|
||||
for ( const frameId of frameIds ) {
|
||||
|
||||
const frame = this.getFrameById( frameId );
|
||||
|
||||
if ( frame !== null ) {
|
||||
|
||||
// resolve compute timestamps
|
||||
|
||||
if ( frame.resolvedCompute === false ) {
|
||||
|
||||
if ( frame.computes.length > 0 ) {
|
||||
|
||||
if ( computeFrames.includes( frameId ) ) {
|
||||
|
||||
for ( const stats of frame.computes ) {
|
||||
|
||||
if ( renderer.backend.hasTimestamp( stats.uid ) ) {
|
||||
|
||||
stats.gpu = renderer.backend.getTimestamp( stats.uid );
|
||||
|
||||
} else {
|
||||
|
||||
stats.gpu = 0;
|
||||
stats.gpuNotAvailable = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
frame.resolvedCompute = true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
frame.resolvedCompute = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// resolve render timestamps
|
||||
|
||||
if ( frame.resolvedRender === false ) {
|
||||
|
||||
if ( frame.renders.length > 0 ) {
|
||||
|
||||
if ( renderFrames.includes( frameId ) ) {
|
||||
|
||||
for ( const stats of frame.renders ) {
|
||||
|
||||
if ( renderer.backend.hasTimestamp( stats.uid ) ) {
|
||||
|
||||
stats.gpu = renderer.backend.getTimestamp( stats.uid );
|
||||
|
||||
} else {
|
||||
|
||||
stats.gpu = 0;
|
||||
stats.gpuNotAvailable = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
frame.resolvedRender = true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
frame.resolvedRender = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( frame.resolvedCompute === true && frame.resolvedRender === true ) {
|
||||
|
||||
this.resolveFrame( frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._resolveTimestampPromise = null;
|
||||
|
||||
resolve();
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
return this._resolveTimestampPromise;
|
||||
|
||||
}
|
||||
|
||||
get isAvailable() {
|
||||
|
||||
const renderer = this.getRenderer();
|
||||
|
||||
return renderer !== null;
|
||||
|
||||
}
|
||||
|
||||
addFrame( frame ) {
|
||||
|
||||
// Limit to max frames.
|
||||
|
||||
if ( this.frames.length >= this.maxFrames ) {
|
||||
|
||||
const removedFrame = this.frames.shift();
|
||||
delete this.framesLib[ removedFrame.frameId ];
|
||||
|
||||
}
|
||||
|
||||
this.frames.push( frame );
|
||||
this.framesLib[ frame.frameId ] = frame;
|
||||
|
||||
if ( this.isAvailable ) {
|
||||
|
||||
this.updateTabs();
|
||||
this.resolveTimestamp();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inspect( node ) {
|
||||
|
||||
const currentNodes = this.currentNodes;
|
||||
|
||||
if ( currentNodes !== null ) {
|
||||
|
||||
currentNodes.push( node );
|
||||
|
||||
} else {
|
||||
|
||||
warnOnce( 'RendererInspector: Unable to inspect node outside of frame scope. Use "renderer.setAnimationLoop()".' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
beginCompute( uid, computeNode ) {
|
||||
|
||||
const frame = this.getFrame();
|
||||
|
||||
if ( ! frame ) return;
|
||||
|
||||
const currentCompute = new ComputeStats( uid, computeNode );
|
||||
currentCompute.timestamp = performance.now();
|
||||
currentCompute.parent = this.currentCompute || this.getParent();
|
||||
|
||||
frame.computes.push( currentCompute );
|
||||
|
||||
if ( this.currentRender !== null ) {
|
||||
|
||||
this.currentRender.children.push( currentCompute );
|
||||
|
||||
} else {
|
||||
|
||||
frame.children.push( currentCompute );
|
||||
|
||||
}
|
||||
|
||||
this.currentCompute = currentCompute;
|
||||
|
||||
}
|
||||
|
||||
finishCompute() {
|
||||
|
||||
const frame = this.getFrame();
|
||||
|
||||
if ( ! frame ) return;
|
||||
|
||||
const currentCompute = this.currentCompute;
|
||||
currentCompute.cpu = performance.now() - currentCompute.timestamp;
|
||||
|
||||
this.currentCompute = currentCompute.parent.isComputeStats ? currentCompute.parent : null;
|
||||
|
||||
}
|
||||
|
||||
beginRender( uid, scene, camera, renderTarget ) {
|
||||
|
||||
const frame = this.getFrame();
|
||||
|
||||
if ( ! frame ) return;
|
||||
|
||||
const currentRender = new RenderStats( uid, scene, camera, renderTarget );
|
||||
currentRender.timestamp = performance.now();
|
||||
currentRender.parent = this.getParent();
|
||||
|
||||
frame.renders.push( currentRender );
|
||||
|
||||
if ( this.currentRender !== null ) {
|
||||
|
||||
this.currentRender.children.push( currentRender );
|
||||
|
||||
} else {
|
||||
|
||||
frame.children.push( currentRender );
|
||||
|
||||
}
|
||||
|
||||
this.currentRender = currentRender;
|
||||
|
||||
}
|
||||
|
||||
finishRender() {
|
||||
|
||||
const frame = this.getFrame();
|
||||
|
||||
if ( ! frame ) return;
|
||||
|
||||
const currentRender = this.currentRender;
|
||||
currentRender.cpu = performance.now() - currentRender.timestamp;
|
||||
|
||||
this.currentRender = currentRender.parent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user