| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import Check from "../Core/Check.js";
- import destroyObject from "../Core/destroyObject.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import Frozen from "../Core/Frozen.js";
- import RuntimeError from "../Core/RuntimeError.js";
- import WebGLConstants from "../Core/WebGLConstants.js";
-
- /**
- * The WebGLSync interface is part of the WebGL 2 API and is used to synchronize activities between the GPU and the application.
- *
- * @param {object} options Object with the following properties:
- * @param {Context} context
- *
- * @exception {DeveloperError} A WebGL 2 context is required to use Sync operations.
- *
- * @private
- * @constructor
- */
- function Sync(options) {
- options = options ?? Frozen.EMPTY_OBJECT;
- const context = options.context;
-
- //>>includeStart('debug', pragmas.debug);
- Check.defined("options.context", context);
- //>>includeEnd('debug');
-
- if (!context._webgl2) {
- throw new DeveloperError(
- "A WebGL 2 context is required to use Sync operations.",
- );
- }
-
- const gl = context._gl;
- const sync = gl.fenceSync(WebGLConstants.SYNC_GPU_COMMANDS_COMPLETE, 0);
-
- this._gl = gl;
- this._sync = sync;
- }
- Sync.create = function (options) {
- return new Sync(options);
- };
- /**
- * Query the sync status of this Sync object.
- *
- * @returns {number} Returns a WebGLConstants indicating the status of the sync object (WebGLConstants.SIGNALED or WebGLConstants.UNSIGNALED).
- *
- * @private
- */
- Sync.prototype.getStatus = function () {
- const status = this._gl.getSyncParameter(
- this._sync,
- WebGLConstants.SYNC_STATUS,
- );
- return status;
- };
- Sync.prototype.isDestroyed = function () {
- return false;
- };
- Sync.prototype.destroy = function () {
- this._gl.deleteSync(this._sync);
- return destroyObject(this);
- };
-
- /**
- * Incremantally polls the status of the Sync object until signaled then resolves.
- * Usually polling should be done once per frame.
- *
- * @example
- * try {
- * await sync.waitForSignal(function (next) {
- * setTimeout(next, 100);
- * });
- *} catch (e) {
- * throw "Signal timeout";
- *} finally {
- * sync.destroy();
- *}
- *
- * @param {function} scheduleFunction Function for scheduling the next poll. Receives a callback as its only parameter.
- * @param {number} [ttl=10] Max number of iterations to poll until timeout.
- *
- * @exception {RuntimeError} Wait for signal timeout.
- */
- Sync.prototype.waitForSignal = async function (scheduleFunction, ttl) {
- const self = this;
- ttl = ttl ?? 10;
- function waitForSignal0(resolve, reject, ttl) {
- return () => {
- const syncStatus = self.getStatus();
- const signaled = syncStatus === WebGLConstants.SIGNALED;
- if (signaled) {
- resolve();
- } else if (ttl <= 0) {
- reject(new RuntimeError("Wait for signal timeout"));
- } else {
- scheduleFunction(waitForSignal0(resolve, reject, ttl - 1));
- }
- };
- }
- return new Promise((resolve, reject) => {
- scheduleFunction(waitForSignal0(resolve, reject, ttl));
- });
- };
- export default Sync;
|