Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 93 additions & 35 deletions examples/jsm/inspector/Inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Viewer } from './tabs/Viewer.js';
import { Timeline } from './tabs/Timeline.js';
import { setText } from './ui/utils.js';

import { setConsoleFunction, REVISION } from 'three/webgpu';
import { setConsoleFunction, getConsoleFunction, REVISION } from 'three/webgpu';

class Inspector extends RendererInspector {

Expand Down Expand Up @@ -70,6 +70,8 @@ class Inspector extends RendererInspector {
this.settings = settings;
this.once = {};
this.extensionsData = new WeakMap();
this.previousConsoleFunction = null;
this._domObserver = null;

this.displayCycle = {
text: {
Expand Down Expand Up @@ -274,81 +276,129 @@ class Inspector extends RendererInspector {

}

init() {
setRenderer( renderer ) {

const renderer = this.getRenderer();
super.setRenderer( renderer );

let sign = `THREE.WebGPURenderer: ${ REVISION } [ "`;
if ( renderer !== null ) {

if ( renderer.backend.isWebGPUBackend ) {
const previousConsoleFunction = getConsoleFunction();

sign += 'WebGPU';
this.previousConsoleFunction = previousConsoleFunction;

} else if ( renderer.backend.isWebGLBackend ) {
setConsoleFunction( ( type, message, ...params ) => {

sign += 'WebGL2';
if ( previousConsoleFunction ) {

}
previousConsoleFunction( type, message, ...params );

sign += '" ]';
}

this.console.addMessage( 'info', sign );
this.resolveConsole( type, message, ...params );

//
} );

if ( this.isAvailable ) {

const init = async () => {

if ( renderer.hasInitialized() === false ) await renderer.init();

renderer.backend.trackTimestamp = true;

if ( renderer.hasFeature( 'timestamp-query' ) !== true ) {

if ( renderer.inspector.domElement.parentElement === null ) {
this.console.addMessage( 'error', 'THREE.Inspector: GPU Timestamp Queries not available.' );

if ( renderer.domElement.parentElement !== null ) {
}

renderer.domElement.parentElement.appendChild( renderer.inspector.domElement );
let sign = `THREE.WebGPURenderer: ${ REVISION } [ "`;

} else {
if ( renderer.backend.isWebGPUBackend ) {

const observer = new MutationObserver( () => {
sign += 'WebGPU';

if ( renderer.domElement.parentElement !== null ) {
} else if ( renderer.backend.isWebGLBackend ) {

renderer.domElement.parentElement.appendChild( renderer.inspector.domElement );
observer.disconnect();
sign += 'WebGL2';

}

} );
sign += '" ]';

observer.observe( document.body || document.documentElement, { childList: true, subtree: true } );
this.console.addMessage( 'info', sign );

}
//

}
const domElement = this.domElement;

}
if ( domElement.parentElement === null ) {

setRenderer( renderer ) {
if ( renderer.domElement.parentElement !== null ) {

super.setRenderer( renderer );
renderer.domElement.parentElement.appendChild( domElement );

if ( renderer !== null ) {
} else {

setConsoleFunction( this.resolveConsole.bind( this ) );
if ( this._domObserver !== null ) {

if ( this.isAvailable ) {
this._domObserver.disconnect();

renderer.init().then( () => {
}

renderer.backend.trackTimestamp = true;
this._domObserver = new MutationObserver( () => {

if ( renderer.hasFeature( 'timestamp-query' ) !== true ) {
if ( renderer.domElement && renderer.domElement.parentElement !== null ) {

this.console.addMessage( 'error', 'THREE.Inspector: GPU Timestamp Queries not available.' );
renderer.domElement.parentElement.appendChild( domElement );

if ( this._domObserver !== null ) {

this._domObserver.disconnect();
this._domObserver = null;

}

}

} );

this._domObserver.observe( document.body || document.documentElement, { childList: true, subtree: true } );

}

}

} );
};

init();

this.timeline.setRenderer( renderer );

}

} else {

if ( this.previousConsoleFunction ) {

setConsoleFunction( this.previousConsoleFunction );
this.previousConsoleFunction = undefined;

}

if ( this._domObserver !== null ) {

this._domObserver.disconnect();
this._domObserver = null;

}

this.profiler.dispose();

this.statsData.clear();

super.dispose();

}

return this;
Expand Down Expand Up @@ -575,6 +625,14 @@ class Inspector extends RendererInspector {

}

dispose() {

super.dispose();

this.setRenderer( null );

}

}

function getItem( id ) {
Expand Down
43 changes: 42 additions & 1 deletion examples/jsm/inspector/RendererInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class RendererInspector extends InspectorBase {

this._lastFinishTime = 0;
this._resolveTimestampPromise = null;
this._rAFId = null;

this.overdraw = false;
this._overdrawMaterial = null;
Expand Down Expand Up @@ -262,15 +263,33 @@ export class RendererInspector extends InspectorBase {

this._resolveTimestampPromise = new Promise( ( resolve ) => {

requestAnimationFrame( async () => {
this._rAFId = requestAnimationFrame( async () => {

this._rAFId = null;

const renderer = this.getRenderer();

if ( renderer === null ) {

this._resolveTimestampPromise = null;
resolve();
return;

}

if ( renderer.backend.hasTimestamp ) {

await renderer.resolveTimestampsAsync( TimestampQuery.COMPUTE );
await renderer.resolveTimestampsAsync( TimestampQuery.RENDER );

if ( renderer !== this.getRenderer() ) {

this._resolveTimestampPromise = null;
resolve();
return;

}

const computeFrames = renderer.backend.getTimestampFrames( TimestampQuery.COMPUTE );
const renderFrames = renderer.backend.getTimestampFrames( TimestampQuery.RENDER );

Expand Down Expand Up @@ -551,4 +570,26 @@ export class RendererInspector extends InspectorBase {

}

dispose() {

if ( this._rAFId !== null ) {

cancelAnimationFrame( this._rAFId );
this._rAFId = null;

}

this._resolveTimestampPromise = null;

if ( this._overdrawMaterial !== null ) {

this._overdrawMaterial.dispose();
this._overdrawMaterial = null;

}

super.dispose();

}

}
58 changes: 57 additions & 1 deletion examples/jsm/inspector/tabs/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ class Viewer extends Tab {
const onPointerDown = ( e ) => {

isDragging = true;
line.classList.add( 'active' );
e.preventDefault();

};
Expand All @@ -700,6 +701,7 @@ class Viewer extends Tab {
const onPointerUp = () => {

isDragging = false;
line.classList.remove( 'active' );

};

Expand Down Expand Up @@ -946,6 +948,13 @@ class Viewer extends Tab {

const mainCanvas = renderer.domElement;
const rect = mainCanvas.getBoundingClientRect();

if ( rect.width <= 0 || rect.height <= 0 ) {

return;

}

const targetParent = document.fullscreenElement || this.profiler.domElement;
const parentRect = targetParent.getBoundingClientRect();
const localLeft = rect.left - parentRect.left;
Expand Down Expand Up @@ -1019,7 +1028,7 @@ class Viewer extends Tab {

if ( ! renderer.backend.isWebGPUBackend ) {

inspector.resolveConsoleOnce( 'warn', 'Inspector: Viewer is only available with WebGPU.' );
// Viewer is only available with WebGPU.

return;

Expand Down Expand Up @@ -1313,6 +1322,53 @@ class Viewer extends Tab {

}

dispose() {

if ( this.splitActive ) {

this.stopSplitMode();

}

if ( this.splitCanvas ) {

if ( this.splitCanvas.parentElement ) {

this.splitCanvas.parentElement.removeChild( this.splitCanvas );

}

this.splitCanvas = null;

}

if ( this.splitCanvasTarget ) {

this.splitCanvasTarget.dispose();
this.splitCanvasTarget = null;

}

if ( this.splitMaterial ) {

this.splitMaterial.dispose();
this.splitMaterial = null;

}

for ( const canvasData of this.canvasNodes.values() ) {

canvasData.canvasTarget.dispose();
canvasData.material.dispose();

}

this.canvasNodes.clear();

super.dispose();

}

}

export { Viewer };
20 changes: 20 additions & 0 deletions examples/jsm/inspector/ui/Profiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2243,4 +2243,24 @@ export class Profiler extends EventDispatcher {

}

dispose() {

for ( const tab of Object.values( this.tabs ) ) {

tab.dispose();

}

this.domElement.remove();

for ( const detachedWindow of this.detachedWindows ) {

detachedWindow.panel.remove();

}

this.toggleGraph.dispose();

}

}
Loading