Skip to content

Commit

Permalink
Fixed ImageBitmap transfer mode.
Browse files Browse the repository at this point in the history
Some gaussian blur fixes.
  • Loading branch information
ILOVEPIE committed Feb 16, 2024
1 parent f9a9af0 commit 0d3bb1c
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 103 deletions.
252 changes: 155 additions & 97 deletions src/renderer-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,24 @@ const renderer_prototype = global.Object.create(Object, {
writable: true
},

_outputCanvasCounter: {
/** @type {number} */
value: global.Number.MIN_SAFE_INTEGER,
writable: true
},

_outputCanvasContexts: {
/** @type {Object<string,CanvasRenderingContext2D|ImageBitmapRenderingContext>} */
value: null,
writable: true
},

_lastImageBitmap: {
/** @type {?ImageBitmap} */
value: null,
writable: true
},

//BEGIN WEBGL VARIABLES

_renderData: {
Expand Down Expand Up @@ -649,7 +667,7 @@ const renderer_prototype = global.Object.create(Object, {
* @return {number} the factor
*/
value: function _calcGaussianBlur (time, style, overrides) {
const blurConstant = 1; //1.17741002251547469;
const blurConstant = 1;//1.17741002251547469;
let transitionOverrides = overrides.getTransitions();
let factor = overrides.getGaussianEdgeBlur() ?? 0;
for (let i = 0; i < transitionOverrides.length; i++)
Expand Down Expand Up @@ -2434,6 +2452,7 @@ const renderer_prototype = global.Object.create(Object, {
);
this._gaussEdgeBlurPass1Shader.addOption("u_texture", 0, "1i");
this._gaussEdgeBlurPass1Shader.addOption("u_sigma", 0, "1f");
this._gaussEdgeBlurPass1Shader.addOption("u_width", 0, "1f");

this._gaussEdgeBlurPass2Shader = new sabre.Shader();
this._gaussEdgeBlurPass2Shader.load(
Expand All @@ -2449,6 +2468,7 @@ const renderer_prototype = global.Object.create(Object, {
);
this._gaussEdgeBlurPass2Shader.addOption("u_texture", 0, "1i");
this._gaussEdgeBlurPass2Shader.addOption("u_sigma", 0, "1f");
this._gaussEdgeBlurPass2Shader.addOption("u_width", 0, "1f");

this._clipShader = new sabre.Shader();
this._clipShader.load(
Expand Down Expand Up @@ -4107,70 +4127,44 @@ const renderer_prototype = global.Object.create(Object, {
let sourceTexture = this._fbTextureA;
let swap;
if (blurInfo !== null) {
if (blurInfo.blur > 0) {
this._convEdgeBlurShader.updateOption(
"u_resolution_x",
this._compositingCanvas.width
if (blurInfo.gaussBlur > 0) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
backFramebuffer
);
this._convEdgeBlurShader.updateOption(
"u_resolution_y",
this._compositingCanvas.height
this._gl.clear(
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
this._convEdgeBlurShader.updateOption("u_texture", 0);
this._convEdgeBlurShader.bindShader(this._gl);
//Draw framebuffer to destination

for (let i = 0; i < blurInfo.blur - 1; i++) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
backFramebuffer
);
this._gl.clear(
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
this._gl.activeTexture(this._gl.TEXTURE0);
this._gl.bindTexture(
this._gl.TEXTURE_2D,
sourceTexture
);
this._gl.bindBuffer(
this._gl.ARRAY_BUFFER,
this._fullscreenPositioningBuffer
);
this._gl.drawArrays(this._gl.TRIANGLES, 0, 6);
swap = backTexture;
backTexture = sourceTexture;
sourceTexture = swap;
swap = backFramebuffer;
backFramebuffer = sourceFramebuffer;
sourceFramebuffer = swap;
}
if (blurInfo.gaussBlur > 0 || clip_coords !== null) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
backFramebuffer
);
this._gl.clear(
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
} else {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
null
);
}

this._gl.activeTexture(this._gl.TEXTURE0);
this._gl.bindTexture(
this._gl.TEXTURE_2D,
sourceTexture
);

let gausswidth = (blurInfo.gaussBlur * 3.0 + 0.5) | 1;
if(gausswidth < 3) gausswidth = 3;
//Apply gaussian filter 1
this._gaussEdgeBlurPass1Shader.updateOption(
"u_resolution_x",
this._compositingCanvas.width
);
this._gaussEdgeBlurPass1Shader.updateOption(
"u_sigma",
blurInfo.gaussBlur
);
this._gaussEdgeBlurPass1Shader.updateOption(
"u_width",
gausswidth
);
this._gaussEdgeBlurPass1Shader.updateOption(
"u_texture",
0
);
this._gaussEdgeBlurPass1Shader.bindShader(this._gl);
//Draw framebuffer X to framebuffer Y
{
let positionAttrib =
this._convEdgeBlurShader.getAttribute(
this._gaussEdgeBlurPass1Shader.getAttribute(
this._gl,
"a_position"
);
Expand All @@ -4196,40 +4190,48 @@ const renderer_prototype = global.Object.create(Object, {
swap = backFramebuffer;
backFramebuffer = sourceFramebuffer;
sourceFramebuffer = swap;
}

if (blurInfo.gaussBlur > 0) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
backFramebuffer
);
this._gl.clear(
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
if (blurInfo.blur > 0 || clip_coords !== null) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
backFramebuffer
);
this._gl.clear(
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
} else
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
null
);
this._gl.activeTexture(this._gl.TEXTURE0);
this._gl.bindTexture(
this._gl.TEXTURE_2D,
sourceTexture
);
//Apply gaussian filter 1
this._gaussEdgeBlurPass1Shader.updateOption(
"u_resolution_x",
this._compositingCanvas.width
//Apply gaussian filter 2
this._gaussEdgeBlurPass2Shader.updateOption(
"u_resolution_y",
this._compositingCanvas.height
);
this._gaussEdgeBlurPass1Shader.updateOption(
this._gaussEdgeBlurPass2Shader.updateOption(
"u_sigma",
blurInfo.gaussBlur
);
this._gaussEdgeBlurPass1Shader.updateOption(
this._gaussEdgeBlurPass2Shader.updateOption(
"u_width",
gausswidth
);
this._gaussEdgeBlurPass2Shader.updateOption(
"u_texture",
0
);
this._gaussEdgeBlurPass1Shader.bindShader(this._gl);
//Draw framebuffer X to framebuffer Y
this._gaussEdgeBlurPass2Shader.bindShader(this._gl);
//Draw framebuffer Y to screen
{
let positionAttrib =
this._gaussEdgeBlurPass1Shader.getAttribute(
this._gaussEdgeBlurPass2Shader.getAttribute(
this._gl,
"a_position"
);
Expand All @@ -4255,7 +4257,47 @@ const renderer_prototype = global.Object.create(Object, {
swap = backFramebuffer;
backFramebuffer = sourceFramebuffer;
sourceFramebuffer = swap;
}

if (blurInfo.blur > 0) {
this._convEdgeBlurShader.updateOption(
"u_resolution_x",
this._compositingCanvas.width
);
this._convEdgeBlurShader.updateOption(
"u_resolution_y",
this._compositingCanvas.height
);
this._convEdgeBlurShader.updateOption("u_texture", 0);
this._convEdgeBlurShader.bindShader(this._gl);
//Draw framebuffer to destination

for (let i = 0; i < blurInfo.blur - 1; i++) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
backFramebuffer
);
this._gl.clear(
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
this._gl.activeTexture(this._gl.TEXTURE0);
this._gl.bindTexture(
this._gl.TEXTURE_2D,
sourceTexture
);
this._gl.bindBuffer(
this._gl.ARRAY_BUFFER,
this._fullscreenPositioningBuffer
);
this._gl.drawArrays(this._gl.TRIANGLES, 0, 6);
swap = backTexture;
backTexture = sourceTexture;
sourceTexture = swap;
swap = backFramebuffer;
backFramebuffer = sourceFramebuffer;
sourceFramebuffer = swap;
}
if (clip_coords !== null) {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
Expand All @@ -4265,34 +4307,22 @@ const renderer_prototype = global.Object.create(Object, {
this._gl.DEPTH_BUFFER_BIT |
this._gl.COLOR_BUFFER_BIT
);
} else
} else {
this._gl.bindFramebuffer(
this._gl.FRAMEBUFFER,
null
);
}

this._gl.activeTexture(this._gl.TEXTURE0);
this._gl.bindTexture(
this._gl.TEXTURE_2D,
sourceTexture
);
//Apply gaussian filter 2
this._gaussEdgeBlurPass2Shader.updateOption(
"u_resolution_y",
this._compositingCanvas.height
);
this._gaussEdgeBlurPass2Shader.updateOption(
"u_sigma",
blurInfo.gaussBlur
);
this._gaussEdgeBlurPass2Shader.updateOption(
"u_texture",
0
);
this._gaussEdgeBlurPass2Shader.bindShader(this._gl);
//Draw framebuffer Y to screen

{
let positionAttrib =
this._gaussEdgeBlurPass1Shader.getAttribute(
this._convEdgeBlurShader.getAttribute(
this._gl,
"a_position"
);
Expand All @@ -4311,7 +4341,7 @@ const renderer_prototype = global.Object.create(Object, {
);
this._gl.drawArrays(this._gl.TRIANGLES, 0, 6);
}

swap = backTexture;
backTexture = sourceTexture;
sourceTexture = swap;
Expand Down Expand Up @@ -4478,6 +4508,7 @@ const renderer_prototype = global.Object.create(Object, {
*/
}
}else{
console.info("Color space support is not available for canvas, falling back to sRGB.");
this._nativeColorSpace = sabre.NativeColorSpaces.RGB;
}

Expand Down Expand Up @@ -4650,6 +4681,11 @@ const renderer_prototype = global.Object.create(Object, {
this._lastAnimating = true;
}

if(this._lastImageBitmap !== null) {
this._lastImageBitmap.close();
this._lastImageBitmap = null;
}

this._gl.clear(
this._gl.DEPTH_BUFFER_BIT | this._gl.COLOR_BUFFER_BIT
);
Expand Down Expand Up @@ -4773,6 +4809,27 @@ const renderer_prototype = global.Object.create(Object, {
writable: false
},



_getOutputCanvasContext: {
/**
* Get a canvas context for the output canvas.
* @param {HTMLCanvasElement|OffscreenCanvas} canvas the canvas to get the context for.
* @param {string} type the type of context to get.
* @return {CanvasRenderingContext2D|ImageBitmapRenderingContext} the context.
*/
value: function _getOutputCanvasContext (canvas, type) {
this._outputCanvasContexts = this._outputCanvasContexts ?? {};
if(typeof(canvas._sabreID) === "undefined"){
canvas._sabreID = (this._outputCanvasCounter++)+"";
return this._outputCanvasContexts[canvas._sabreID] = canvas.getContext(type);
}else{
return this._outputCanvasContexts[canvas._sabreID];
}
},
writable: false
},

"getDisplayBitmap": {
/**
* Get an ImageBitmap containing the frame or null if ImageBitmap is unsupported.
Expand All @@ -4781,7 +4838,7 @@ const renderer_prototype = global.Object.create(Object, {
value: function getDisplayBitmap () {
if (!isImageBitmapSupported) return null;
if (this._compositingCanvas instanceof global.OffscreenCanvas) {
return this._compositingCanvas.transferToImageBitmap();
return /** @type {ImageBitmap} */ (global.structuredClone(this._lastImageBitmap = this._lastImageBitmap ?? this._compositingCanvas.transferToImageBitmap()));
} else return null;
},
writable: false
Expand All @@ -4797,12 +4854,13 @@ const renderer_prototype = global.Object.create(Object, {
value: function copyToCanvas (canvas, bitmap) {
let context;
if (bitmap) {
context = canvas.getContext("bitmaprenderer");
context.transferFromImageBitmap(this["getDisplayBitmap"]());
const bmp = this["getDisplayBitmap"]();
context = this._getOutputCanvasContext(canvas,"bitmaprenderer");
context.transferFromImageBitmap(bmp);
} else {
let width = canvas.width | 0;
let height = canvas.height | 0;
context = canvas.getContext("2d");
context = this._getOutputCanvasContext(canvas,"2d");
context.clearRect(0, 0, width, height);
context.drawImage(this._compositingCanvas, 0, 0, width, height);
}
Expand Down
Loading

0 comments on commit 0d3bb1c

Please sign in to comment.