From 5653914d190de252e42bdbd0ad34232f91cbe63d Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:53:03 +0700 Subject: [PATCH] Move WebGL2's drawFrame() function to animate() function --- dist/better-xcloud.lite.user.js | 36 +++++++++------- dist/better-xcloud.user.js | 38 +++++++++-------- src/modules/player/webgl2-player.ts | 66 ++++++++++++++--------------- src/utils/screenshot-manager.ts | 2 +- 4 files changed, 75 insertions(+), 67 deletions(-) diff --git a/dist/better-xcloud.lite.user.js b/dist/better-xcloud.lite.user.js index b2586f9..0043ce6 100644 --- a/dist/better-xcloud.lite.user.js +++ b/dist/better-xcloud.lite.user.js @@ -5427,28 +5427,32 @@ class WebGL2Player { let gl = this.gl, program = this.program; gl.uniform2f(gl.getUniformLocation(program, "iResolution"), this.$canvas.width, this.$canvas.height), gl.uniform1i(gl.getUniformLocation(program, "filterId"), this.options.filterId), gl.uniform1f(gl.getUniformLocation(program, "sharpenFactor"), this.options.sharpenFactor), gl.uniform1f(gl.getUniformLocation(program, "brightness"), this.options.brightness), gl.uniform1f(gl.getUniformLocation(program, "contrast"), this.options.contrast), gl.uniform1f(gl.getUniformLocation(program, "saturation"), this.options.saturation); } - drawFrame(force = !1) { - if (!force) { - if (this.targetFps === 0) return; - if (this.targetFps < 60) { - let currentTime = performance.now(); - if (currentTime - this.lastFrameTime < this.frameInterval) return; - this.lastFrameTime = currentTime; - } - } + forceDrawFrame() { let gl = this.gl; gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.$video), gl.drawArrays(gl.TRIANGLES, 0, 6); } setupRendering() { - let animate; + let frameCallback; if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) { let $video = this.$video; - animate = () => { - if (!this.stopped) this.drawFrame(), this.animFrameId = $video.requestVideoFrameCallback(animate); - }, this.animFrameId = $video.requestVideoFrameCallback(animate); - } else animate = () => { - if (!this.stopped) this.drawFrame(), this.animFrameId = requestAnimationFrame(animate); - }, this.animFrameId = requestAnimationFrame(animate); + frameCallback = $video.requestVideoFrameCallback.bind($video); + } else frameCallback = requestAnimationFrame; + let animate = () => { + if (this.stopped) return; + let draw = !0; + if (this.targetFps === 0) draw = !1; + else if (this.targetFps < 60) { + let currentTime = performance.now(); + if (currentTime - this.lastFrameTime < this.frameInterval) draw = !1; + else this.lastFrameTime = currentTime; + } + if (draw) { + let gl = this.gl; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.$video), gl.drawArrays(gl.TRIANGLES, 0, 6); + } + this.animFrameId = frameCallback(animate); + }; + this.animFrameId = frameCallback(animate); } setupShaders() { BxLogger.info(this.LOG_TAG, "Setting up", getPref("video_power_preference")); diff --git a/dist/better-xcloud.user.js b/dist/better-xcloud.user.js index 0321854..b51fb21 100644 --- a/dist/better-xcloud.user.js +++ b/dist/better-xcloud.user.js @@ -1842,7 +1842,7 @@ class ScreenshotManager { if (!$player || !$player.isConnected) return; $player.parentElement.addEventListener("animationend", this.onAnimationEnd, { once: !0 }), $player.parentElement.classList.add("bx-taking-screenshot"); let canvasContext = this.canvasContext; - if ($player instanceof HTMLCanvasElement) streamPlayer.getWebGL2Player().drawFrame(!0); + if ($player instanceof HTMLCanvasElement) streamPlayer.getWebGL2Player().forceDrawFrame(); if (canvasContext.drawImage($player, 0, 0, $canvas.width, $canvas.height), AppInterface) { let data = $canvas.toDataURL("image/png").split(";base64,")[1]; AppInterface.saveScreenshot(currentStream.titleSlug, data), canvasContext.clearRect(0, 0, $canvas.width, $canvas.height), callback && callback(); @@ -7043,28 +7043,32 @@ class WebGL2Player { let gl = this.gl, program = this.program; gl.uniform2f(gl.getUniformLocation(program, "iResolution"), this.$canvas.width, this.$canvas.height), gl.uniform1i(gl.getUniformLocation(program, "filterId"), this.options.filterId), gl.uniform1f(gl.getUniformLocation(program, "sharpenFactor"), this.options.sharpenFactor), gl.uniform1f(gl.getUniformLocation(program, "brightness"), this.options.brightness), gl.uniform1f(gl.getUniformLocation(program, "contrast"), this.options.contrast), gl.uniform1f(gl.getUniformLocation(program, "saturation"), this.options.saturation); } - drawFrame(force = !1) { - if (!force) { - if (this.targetFps === 0) return; - if (this.targetFps < 60) { - let currentTime = performance.now(); - if (currentTime - this.lastFrameTime < this.frameInterval) return; - this.lastFrameTime = currentTime; - } - } + forceDrawFrame() { let gl = this.gl; gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.$video), gl.drawArrays(gl.TRIANGLES, 0, 6); } setupRendering() { - let animate; + let frameCallback; if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) { let $video = this.$video; - animate = () => { - if (!this.stopped) this.drawFrame(), this.animFrameId = $video.requestVideoFrameCallback(animate); - }, this.animFrameId = $video.requestVideoFrameCallback(animate); - } else animate = () => { - if (!this.stopped) this.drawFrame(), this.animFrameId = requestAnimationFrame(animate); - }, this.animFrameId = requestAnimationFrame(animate); + frameCallback = $video.requestVideoFrameCallback.bind($video); + } else frameCallback = requestAnimationFrame; + let animate = () => { + if (this.stopped) return; + let draw = !0; + if (this.targetFps === 0) draw = !1; + else if (this.targetFps < 60) { + let currentTime = performance.now(); + if (currentTime - this.lastFrameTime < this.frameInterval) draw = !1; + else this.lastFrameTime = currentTime; + } + if (draw) { + let gl = this.gl; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.$video), gl.drawArrays(gl.TRIANGLES, 0, 6); + } + this.animFrameId = frameCallback(animate); + }; + this.animFrameId = frameCallback(animate); } setupShaders() { BxLogger.info(this.LOG_TAG, "Setting up", getPref("video_power_preference")); diff --git a/src/modules/player/webgl2-player.ts b/src/modules/player/webgl2-player.ts index ffd80ad..1d6ff09 100644 --- a/src/modules/player/webgl2-player.ts +++ b/src/modules/player/webgl2-player.ts @@ -94,52 +94,52 @@ export class WebGL2Player { gl.uniform1f(gl.getUniformLocation(program, 'saturation'), this.options.saturation); } - drawFrame(force=false) { - if (!force) { - // Don't draw when FPS is 0 - if (this.targetFps === 0) { - return; - } - - // Limit FPS - if (this.targetFps < 60) { - const currentTime = performance.now(); - const timeSinceLastFrame = currentTime - this.lastFrameTime; - if (timeSinceLastFrame < this.frameInterval) { - return; - } - this.lastFrameTime = currentTime; - } - } - + forceDrawFrame() { const gl = this.gl!; gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.$video); gl.drawArrays(gl.TRIANGLES, 0, 6); } private setupRendering() { - let animate: any; - + let frameCallback: any; if ('requestVideoFrameCallback' in HTMLVideoElement.prototype) { const $video = this.$video; - animate = () => { - if (!this.stopped) { - this.drawFrame(); - this.animFrameId = $video.requestVideoFrameCallback(animate); - } - } - - this.animFrameId = $video.requestVideoFrameCallback(animate); + frameCallback = $video.requestVideoFrameCallback.bind($video); } else { - animate = () => { - if (!this.stopped) { - this.drawFrame(); - this.animFrameId = requestAnimationFrame(animate); + frameCallback = requestAnimationFrame; + } + + let animate = () => { + if (this.stopped) { + return; + } + + let draw = true; + + // Don't draw when FPS is 0 + if (this.targetFps === 0) { + draw = false; + } else if (this.targetFps < 60) { + // Limit FPS + const currentTime = performance.now(); + const timeSinceLastFrame = currentTime - this.lastFrameTime; + if (timeSinceLastFrame < this.frameInterval) { + draw = false; + } else { + this.lastFrameTime = currentTime; } } - this.animFrameId = requestAnimationFrame(animate); + if (draw) { + const gl = this.gl!; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.$video); + gl.drawArrays(gl.TRIANGLES, 0, 6); + } + + this.animFrameId = frameCallback(animate); } + + this.animFrameId = frameCallback(animate); } private setupShaders() { diff --git a/src/utils/screenshot-manager.ts b/src/utils/screenshot-manager.ts index 699112e..7f54fcd 100644 --- a/src/utils/screenshot-manager.ts +++ b/src/utils/screenshot-manager.ts @@ -65,7 +65,7 @@ export class ScreenshotManager { const canvasContext = this.canvasContext; if ($player instanceof HTMLCanvasElement) { - streamPlayer.getWebGL2Player().drawFrame(true); + streamPlayer.getWebGL2Player().forceDrawFrame(); } canvasContext.drawImage($player, 0, 0, $canvas.width, $canvas.height);