/**
* @namespace gpuUtils
*/
/**
* Class representing device connection and management for WebGPU.
* @member deviceConnect
* @memberof gpuUtils
* @property {GPUAdapter | null} adapter - The GPU adapter object. Set to null if no adapter is connected.
* @property {GPUDevice | null} device - The GPU device object. Set to null if no device is connected.
* @property {EventListener | null} lostListener - The event listener for device loss. Set to null if no listener is attached.
*/
export class deviceConnect {
constructor() {
this.adapter = null;
this.device = null;
this.lostListener = null;
}
/**
* Initializes the device and adds a lost listener to it.
* @returns {Promise<GPUDevice|boolean>} - A promise that resolves to the initialized device, or `false` if initialization fails.
*/
async initialize() {
await this.initDevice();
if (!this.adapter) return false;
while (!this.device) {
this.adapter = null;
await this.initDevice();
if (!this.adapter) return false;
}
this.addLostListener();
return this.device;
}
/**
* Requests the adapter and device for WebGPU.
* @returns {Promise<void>} - A promise that resolves when the adapter and device are requested.
*/
async initDevice() {
if (!this.adapter) {
this.adapter = await navigator.gpu.requestAdapter();
if (!this.adapter) {
console.error(
'WebGPU is not available in your browser. Return to other engines, if possible.'
);
return;
}
}
this.device = await this.adapter.requestDevice();
}
/**
* Adds a lost listener to the device.
* @returns {void}
*/
addLostListener() {
if (this.lostListener) return;
this.lostListener = this.device.lost.then(async (info) => {
console.error('Device was lost. Reconnecting... Info: ', info);
try {
await this.recoverDevice();
} catch (error) {
console.error('Device could not be recovered', error);
}
});
}
/**
* Removes the lost listener from the device.
* @returns {void}
*/
removeLostListener() {
if (this.lostListener) {
this.lostListener = null;
}
}
/**
* Recovers the device after it has been lost.
* @returns {Promise<void>} - A promise that resolves when the device is recovered.
*/
async recoverDevice() {
this.removeLostListener();
await this.initDevice();
this.addLostListener();
}
}