Ensure only one update timeout is scheduled at a time and call gl.flush() to encourage eager execution (#156)

This commit is contained in:
Noeri Huisman
2025-09-15 23:46:10 +02:00
committed by GitHub
parent 882def6eb7
commit 3e9ee5f505
+33 -16
View File
@@ -267,10 +267,11 @@ export class SparkRenderer extends THREE.Mesh {
viewpoint: SparkViewpoint; viewpoint: SparkViewpoint;
// Holds data needed to perform a scheduled Gsplat update. // Holds data needed to perform a scheduled Gsplat update.
private pendingUpdate: { private pendingUpdate = {
scene: THREE.Scene; scene: null as THREE.Scene | null,
originToWorld: THREE.Matrix4; originToWorld: new THREE.Matrix4(),
} | null = null; timeoutId: -1,
};
// Internal SparkViewpoint used for environment map rendering. // Internal SparkViewpoint used for environment map rendering.
private envViewpoint: SparkViewpoint | null = null; private envViewpoint: SparkViewpoint | null = null;
@@ -668,23 +669,39 @@ export class SparkRenderer extends THREE.Mesh {
}: { scene: THREE.Scene; viewToWorld?: THREE.Matrix4 }) { }: { scene: THREE.Scene; viewToWorld?: THREE.Matrix4 }) {
// Compute the transform for the SparkRenderer to use as origin // Compute the transform for the SparkRenderer to use as origin
// for Gsplat generation and accumulation. // for Gsplat generation and accumulation.
const originToWorld = this.matrixWorld.clone(); const originToWorld = this.matrixWorld;
// Either do the update now, or in the next "tick" depending on preUpdate // Either do the update now, or in the next "tick" depending on preUpdate
if (this.preUpdate) { if (this.preUpdate) {
this.updateInternal({ scene, originToWorld, viewToWorld }); this.updateInternal({
scene,
originToWorld: originToWorld.clone(),
viewToWorld,
});
} else { } else {
// Pass the update parameters to be performed on the next tick // Pass the update parameters to be performed on the next tick
this.pendingUpdate = { this.pendingUpdate.scene = scene;
scene, this.pendingUpdate.originToWorld.copy(originToWorld);
originToWorld,
}; // Schedule a timeout if there isn't one already
setTimeout(() => { if (this.pendingUpdate.timeoutId === -1) {
if (this.pendingUpdate) { this.pendingUpdate.timeoutId = setTimeout(() => {
const { scene, originToWorld } = this.pendingUpdate; const { scene, originToWorld } = this.pendingUpdate;
this.pendingUpdate = null; this.pendingUpdate.scene = null;
this.updateInternal({ scene, originToWorld, viewToWorld }); this.pendingUpdate.timeoutId = -1;
} const updated = this.updateInternal({
}, 1); scene: scene as THREE.Scene,
originToWorld,
viewToWorld,
});
if (updated) {
// Flush to encourage eager execution
const gl = this.renderer.getContext() as WebGL2RenderingContext;
gl.flush();
}
}, 1);
}
} }
} }