sdf-2d/src/graphics/graphics-library/helper/stopwatch.ts
2020-09-23 16:27:02 +02:00

74 lines
2 KiB
TypeScript

import { UniversalRenderingContext } from '../universal-rendering-context';
import { enableExtension } from './enable-extension';
enum StopwatchState {
ready = 'ready',
running = 'running',
waitingForResults = 'waitingForResults',
}
export class WebGlStopwatch {
private state = StopwatchState.ready;
private resultsInNanoSeconds = 0;
private timerExtension: any;
private timerQuery?: WebGLQuery;
constructor(private readonly gl: UniversalRenderingContext) {
this.timerExtension = enableExtension(gl, 'EXT_disjoint_timer_query_webgl2');
}
public start() {
if (this.state != StopwatchState.ready) {
throw new Error(`Could not start stopwatch in state ${this.state}`);
}
this.timerQuery = this.gl.createQuery()!;
this.gl.beginQuery(this.timerExtension.TIME_ELAPSED_EXT, this.timerQuery);
this.state = StopwatchState.running;
}
public stop() {
if (this.state != StopwatchState.running) {
throw new Error(`Could not stop stopwatch in state ${this.state}`);
}
this.gl.endQuery(this.timerExtension.TIME_ELAPSED_EXT);
this.state = StopwatchState.waitingForResults;
}
public tryGetResults(): boolean {
if (this.state != StopwatchState.waitingForResults) {
throw new Error(`Could not check for results in state ${this.state}`);
}
const available = this.gl.getQueryParameter(
this.timerQuery!,
this.gl.QUERY_RESULT_AVAILABLE
);
const disjoint = this.gl.getParameter(this.timerExtension.GPU_DISJOINT_EXT);
if (available && !disjoint) {
this.resultsInNanoSeconds = this.gl.getQueryParameter(
this.timerQuery!,
this.gl.QUERY_RESULT
);
this.state = StopwatchState.ready;
return true;
}
return false;
}
public get isReady(): boolean {
return this.state == StopwatchState.ready;
}
public get isRunning(): boolean {
return this.state == StopwatchState.running;
}
public get resultsInMilliSeconds(): number {
return this.resultsInNanoSeconds! / 1000 / 1000;
}
}