import { Observable } from "babylonjs/Misc/observable" ; import { Scene } from "babylonjs/scene" ; import * as React from "react" ; import { useEffect , useState } from "react" ; import { ButtonLineComponent } from "../../../../sharedUiComponents/lines/buttonLineComponent" ; import { FileButtonLineComponent } from "../../../../sharedUiComponents/lines/fileButtonLineComponent" ; import { LineContainerComponent } from "../../../../sharedUiComponents/lines/lineContainerComponent" ; import { IPerfLayoutSize } from "../../../graph/graphSupportingTypes" ; import { PerformanceViewerCollector } from "babylonjs/Misc/PerformanceViewer/performanceViewerCollector" ; import { PerfCollectionStrategy } from "babylonjs/Misc/PerformanceViewer/performanceViewerCollectionStrategies" ; import { Tools } from "babylonjs/Misc/tools" ; import "babylonjs/Misc/PerformanceViewer/performanceViewerSceneExtension" ; import { Inspector } from "../../../../inspector" ; import { PerformanceViewerPopupComponent } from "./performanceViewerPopupComponent" ; import { ComputePressureObserverWrapper } from "babylonjs/Misc/computePressure" ; require ( "./scss/performanceViewer.scss" ) ; interface IPerformanceViewerComponentProps { scene : Scene ; } const initialWindowSize = { width : 1024 , height : 512 } ; export enum IPerfMetadataCategory { Count = "Count" , FrameSteps = "Frame Steps Duration" } const defaultStrategiesList = [ { strategyCallback : PerfCollectionStrategy . FpsStrategy ( ) } , { strategyCallback : PerfCollectionStrategy . TotalMeshesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . ActiveMeshesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . ActiveIndicesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . ActiveBonesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . ActiveParticlesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . DrawCallsStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . TotalLightsStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . TotalVerticesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . TotalMaterialsStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . TotalTexturesStrategy ( ) , category : IPerfMetadataCategory . Count , hidden : true } , { strategyCallback : PerfCollectionStrategy . AbsoluteFpsStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . MeshesSelectionStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . RenderTargetsStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . ParticlesStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . SpritesStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . AnimationsStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . PhysicsStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . RenderStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . FrameTotalStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . InterFrameStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , { strategyCallback : PerfCollectionStrategy . GpuFrameTimeStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } , ] ; export const PerformanceViewerComponent = ( props ) => { const { scene } = props ; const [ isOpen , setIsOpen ] = useState ( false ) ; const [ isLoadedFromCsv , setIsLoadedFromCsv ] = useState ( false ) ; const [ performanceCollector , setPerformanceCollector ] = useState < PerformanceViewerCollector | undefined > ( ) ; const [ layoutObservable ] = useState ( new Observable < IPerfLayoutSize > ( ) ) ; const [ returnToLiveObservable ] = useState ( new Observable < void > ( ) ) ; const onClosePerformanceViewer = ( window ) => { if ( window ) { window . close ( ) ; } setIsLoadedFromCsv ( false ) ; setIsOpen ( false ) ; } ; useEffect ( ( ) => { if ( ! isLoadedFromCsv ) { if ( performanceCollector ) { performanceCollector . stop ( ) ; performanceCollector . clear ( false ) ; addStrategies ( performanceCollector ) ; } } } , [ isLoadedFromCsv ] ) ; const startPerformanceViewerPopup = ( ) => { if ( performanceCollector ) { Inspector . _CreatePersistentPopup ( { props : { id : "performance-viewer" , title : "Realtime Performance Viewer" , onClose : onClosePerformanceViewer , onResize : onResize , size : initialWindowSize , } , children : ( < PerformanceViewerPopupComponent scene = { scene } layoutObservable = { layoutObservable } returnToLiveObservable = { returnToLiveObservable } performanceCollector = { performanceCollector } / > ) , } , document . body ) ; } } ; const onPerformanceButtonClick = ( ) => { setIsOpen ( true ) ; performanceCollector ?. start ( true ) ; startPerformanceViewerPopup ( ) ; } ; const onLoadClick = ( file ) => { Tools . ReadFile ( file , ( data ) => { setIsOpen ( false ) ; setIsLoadedFromCsv ( true ) ; performanceCollector ?. stop ( ) ; const isValid = performanceCollector ?. loadFromFileData ( data ) ; if ( ! isValid ) { setIsOpen ( false ) ; performanceCollector ?. start ( true ) ; } else { startPerformanceViewerPopup ( ) ; } } ) ; } ; const onExportClick = ( ) => { performanceCollector ?. exportDataToCsv ( ) ; } ; const onResize = ( window ) => { const width = window ?. innerWidth ?? 0 ; const height = window ?. innerHeight ?? 0 ; layoutObservable . notifyObservers ( { width , height } ) ; } ; const onToggleRecording = ( ) => { if ( ! performanceCollector ?. isStarted ) { performanceCollector ?. start ( true ) ; } else { performanceCollector ?. stop ( ) ; } } ; const addStrategies = ( perfCollector ) => { perfCollector . addCollectionStrategies ( ... defaultStrategiesList ) ; if ( ComputePressureObserverWrapper . IsAvailable ) { perfCollector . addCollectionStrategies ( { strategyCallback : PerfCollectionStrategy . CpuStrategy ( ) , category : IPerfMetadataCategory . FrameSteps , hidden : true } ) ; } } ; useEffect ( ( ) => { const perfCollector = scene . getPerfCollector ( ) ; addStrategies ( perfCollector ) ; setPerformanceCollector ( perfCollector ) ; } , [ ] ) ; return ( < LineContainerComponent title = "Performance Viewer" > { ! isOpen && < ButtonLineComponent label = "Open Realtime Perf Viewer" onClick = { onPerformanceButtonClick } / > } { ! isOpen && < FileButtonLineComponent accept = "csv" label = "Load Perf Viewer using CSV" onClick = { onLoadClick } / > } < ButtonLineComponent label = "Export Perf to CSV" onClick = { onExportClick } / > { ! isOpen && < ButtonLineComponent label = { performanceCollector ?. isStarted ? "Stop Recording" : "Begin Recording" } onClick = { onToggleRecording } / > } < /LineContainerComponent>); } ;