From 241c7eec0cd379b8a33e82e65b5abbe418daf01a Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Thu, 12 Dec 2024 15:50:51 -0800 Subject: [PATCH] Try async readPixels from MDN. --- src/lib/workers/pow.ts | 82 +++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/src/lib/workers/pow.ts b/src/lib/workers/pow.ts index b71370e..6425937 100644 --- a/src/lib/workers/pow.ts +++ b/src/lib/workers/pow.ts @@ -43,6 +43,47 @@ export class Pow { return out } + static clientWaitAsync (gl: any, sync: any, flags: any, interval_ms: any): Promise { + return new Promise((resolve, reject) => { + function test () { + const res = gl.clientWaitSync(sync, flags, 0) + if (res === gl.WAIT_FAILED) { + reject() + return + } + if (res === gl.TIMEOUT_EXPIRED) { + setTimeout(test, interval_ms) + return + } + resolve() + } + test() + }) + } + + static async readPixelsAsync (x: any, y: any, w: any, h: any, format: any, type: any, dest: any) { + if (this.gl == null) throw new Error('webgl2_required') + const buf = this.gl.createBuffer() + this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, buf) + this.gl.bufferData(this.gl.PIXEL_PACK_BUFFER, dest.byteLength, this.gl.STREAM_READ) + this.gl.readPixels(x, y, w, h, format, type, 0) + this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, null) + + const sync = this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE, 0) + this.gl.flush() + + await this.clientWaitAsync(this.gl, sync, 0, 1) + this.gl.deleteSync(sync) + + this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, buf) + this.gl.getBufferSubData(this.gl.PIXEL_PACK_BUFFER, 0, dest) + this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, null) + + this.gl.deleteBuffer(buf) + return dest + } + + static calculate (hashHex: string, threshold: number | string = '0xFFFFFFF8', callback: (nonce: string | PromiseLike) => any): void { console.log(`start calculate: ${performance.now()}`) if (typeof threshold === 'number') threshold = '0x' + threshold.toString(16) @@ -300,27 +341,28 @@ export class Pow { this.gl.clear(this.gl.COLOR_BUFFER_BIT) this.gl.drawArrays(this.gl.TRIANGLES, 0, 6) const pixels = new Uint8Array(this.gl.drawingBufferWidth * this.gl.drawingBufferHeight * 4) - - this.gl.readPixels(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels) - - // Check the pixels for any success - for (let i = pixels.length - 4; i >= 0; i -= 4) { - if (pixels[i] !== 0) { + // this.gl.readPixels(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels) + this.readPixelsAsync(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels) + .then(pixels => { + // Check the pixels for any success + for (let i = pixels.length - 4; i >= 0; i -= 4) { + if (pixels[i] !== 0) { + console.log(`frame time: ${performance.now() - start}`) + const hex = this.hexify(this.work1) + this.hexify([ + pixels[i + 2], + pixels[i + 3], + this.work0[2] ^ (pixels[i] - 1), + this.work0[3] ^ (pixels[i + 1] - 1) + ]) + // Return the work value with the custom bits + typeof callback === 'function' && callback(hex) + return + } + } console.log(`frame time: ${performance.now() - start}`) - const hex = this.hexify(this.work1) + this.hexify([ - pixels[i + 2], - pixels[i + 3], - this.work0[2] ^ (pixels[i] - 1), - this.work0[3] ^ (pixels[i + 1] - 1) - ]) - // Return the work value with the custom bits - typeof callback === 'function' && callback(hex) - return - } - } - console.log(`frame time: ${performance.now() - start}`) - // Nothing found yet, try again - self.requestAnimationFrame(draw) + // Nothing found yet, try again + self.requestAnimationFrame(draw) + }) } // Begin generation -- 2.34.1