74 lines
2 KiB
TypeScript
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;
|
|
}
|
|
}
|