Skip to content

Commit

Permalink
fix: compatibility with chrome 51 (#454)
Browse files Browse the repository at this point in the history
- added alternative to roundRect it not supported
- added fallback if createImageBitmap(image, options) signature is not
supported
- added WebGlContext error message
  • Loading branch information
wouterlucas authored Nov 28, 2024
2 parents 857c8e9 + ce7e730 commit 18de7ad
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 19 deletions.
14 changes: 7 additions & 7 deletions BROWSERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ Add the following to your \`vite.config.js\`:
import legacy from '@vitejs/plugin-legacy';

export default {
plugins: [
legacy({
targets: ['chrome>=38'],
modernPolyfills: true,
additionalLegacyPolyfills: ['whatwg-fetch'],
}),
],
plugins: [
legacy({
targets: ['chrome>=38'],
modernPolyfills: true,
additionalLegacyPolyfills: ['whatwg-fetch'],
}),
],
};
```

Expand Down
16 changes: 16 additions & 0 deletions src/core/lib/WebGlContextWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export class WebGlContextWrapper {
public readonly LINK_STATUS;
public readonly DYNAMIC_DRAW;
public readonly COLOR_ATTACHMENT0;
public readonly INVALID_ENUM: number;
public readonly INVALID_OPERATION: number;
//#endregion WebGL Enums

constructor(private gl: WebGLRenderingContext | WebGL2RenderingContext) {
Expand Down Expand Up @@ -175,6 +177,8 @@ export class WebGlContextWrapper {
this.LINK_STATUS = gl.LINK_STATUS;
this.DYNAMIC_DRAW = gl.DYNAMIC_DRAW;
this.COLOR_ATTACHMENT0 = gl.COLOR_ATTACHMENT0;
this.INVALID_ENUM = gl.INVALID_ENUM;
this.INVALID_OPERATION = gl.INVALID_OPERATION;
}
/**
* Returns true if the WebGL context is WebGL2
Expand Down Expand Up @@ -1020,6 +1024,18 @@ export class WebGlContextWrapper {
return gl.getExtension(name);
}

/**
* ```
* gl.getError(type);
* ```
*
* @returns
*/
getError() {
const { gl } = this;
return gl.getError();
}

/**
* ```
* gl.createVertexArray();
Expand Down
12 changes: 9 additions & 3 deletions src/core/renderers/canvas/CanvasCoreRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ import {
type QuadOptions,
} from '../CoreRenderer.js';
import { CanvasCoreTexture } from './CanvasCoreTexture.js';
import { getBorder, getRadius, strokeLine } from './internal/C2DShaderUtils.js';
import {
getBorder,
getRadius,
roundRect,
strokeLine,
} from './internal/C2DShaderUtils.js';
import {
formatRgba,
parseColorRgba,
Expand Down Expand Up @@ -166,7 +171,7 @@ export class CanvasCoreRenderer extends CoreRenderer {

if (radius) {
const path = new Path2D();
path.roundRect(tx, ty, width, height, radius);
roundRect.call(path, tx, ty, width, height, radius);
ctx.clip(path);
}

Expand Down Expand Up @@ -224,7 +229,8 @@ export class CanvasCoreRenderer extends CoreRenderer {
ctx.strokeStyle = borderColor;
ctx.globalAlpha = alpha;
if (radius) {
ctx.roundRect(
roundRect.call(
ctx,
tx + borderInnerWidth,
ty + borderInnerWidth,
width - borderWidth,
Expand Down
93 changes: 93 additions & 0 deletions src/core/renderers/canvas/internal/C2DShaderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,99 @@ export function getBorder(
return undefined;
}

export function roundRect(
this: CanvasRenderingContext2D | Path2D,
x: number,
y: number,
width: number,
height: number,
radius: number | DOMPointInit | (number | DOMPointInit)[],
) {
const context = Object.getPrototypeOf(this) as Path2D;
if (!context.roundRect) {
const fixOverlappingCorners = (radii: {
topLeft: number;
topRight: number;
bottomRight: number;
bottomLeft: number;
}) => {
const maxRadius = Math.min(width / 2, height / 2);
const totalHorizontal =
radii.topLeft + radii.topRight + radii.bottomRight + radii.bottomLeft;

if (totalHorizontal > width || totalHorizontal > height) {
const scale =
maxRadius /
Math.max(
radii.topLeft,
radii.topRight,
radii.bottomRight,
radii.bottomLeft,
);
radii.topLeft *= scale;
radii.topRight *= scale;
radii.bottomRight *= scale;
radii.bottomLeft *= scale;
}
};
const radii =
typeof radius === 'number'
? {
topLeft: radius,
topRight: radius,
bottomRight: radius,
bottomLeft: radius,
}
: { topLeft: 0, topRight: 0, bottomRight: 0, bottomLeft: 0, ...radius };

fixOverlappingCorners(radii);

this.moveTo(x + radii.topLeft, y);
this.lineTo(x + width - radii.topRight, y);
this.ellipse(
x + width - radii.topRight,
y + radii.topRight,
radii.topRight,
radii.topRight,
0,
1.5 * Math.PI,
2 * Math.PI,
);
this.lineTo(x + width, y + height - radii.bottomRight);
this.ellipse(
x + width - radii.bottomRight,
y + height - radii.bottomRight,
radii.bottomRight,
radii.bottomRight,
0,
0,
0.5 * Math.PI,
);
this.lineTo(x + radii.bottomLeft, y + height);
this.ellipse(
x + radii.bottomLeft,
y + height - radii.bottomLeft,
radii.bottomLeft,
radii.bottomLeft,
0,
0.5 * Math.PI,
Math.PI,
);
this.lineTo(x, y + radii.topLeft);
this.ellipse(
x + radii.topLeft,
y + radii.topLeft,
radii.topLeft,
radii.topLeft,
0,
Math.PI,
1.5 * Math.PI,
);
} else {
this.roundRect(x, y, width, height, radius);
}
}

export function strokeLine(
ctx: CanvasRenderingContext2D,
x: number,
Expand Down
8 changes: 7 additions & 1 deletion src/core/renderers/webgl/WebGlCoreShader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,15 @@ export abstract class WebGlCoreShader extends CoreShader {
glw.FRAGMENT_SHADER,
fragmentSource,
);

if (!vertexShader || !fragmentShader) {
throw new Error(
`Unable to create shader type: ${glw.FRAGMENT_SHADER}. Source: ${fragmentSource}`,
`Unable to create the following shader(s): ${[
!vertexShader && 'VERTEX_SHADER',
!fragmentShader && 'FRAGMENT_SHADER',
]
.filter(Boolean)
.join(' and ')}`,
);
}

Expand Down
12 changes: 9 additions & 3 deletions src/core/renderers/webgl/internal/ShaderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,22 @@ export function createShader(
) {
const shader = glw.createShader(type);
if (!shader) {
throw new Error(`Unable to create shader type: ${type}. Source: ${source}`);
const glError = glw.getError();
throw new Error(
`Unable to create the shader: ${
type === glw.VERTEX_SHADER ? 'VERTEX_SHADER' : 'FRAGMENT_SHADER'
}.${glError ? ` WebGlContext Error: ${glError}` : ''}`,
);
}

glw.shaderSource(shader, source);
glw.compileShader(shader);
const success = !!glw.getShaderParameter(shader, glw.COMPILE_STATUS);
if (success) {
return shader;
}

console.log(glw.getShaderInfoLog(shader));
console.error(glw.getShaderInfoLog(shader));
glw.deleteShader(shader);
}

Expand All @@ -131,7 +137,7 @@ export function createProgram(
return program;
}

console.log(glw.getProgramInfoLog(program));
console.warn(glw.getProgramInfoLog(program));
glw.deleteProgram(program);
return undefined;
}
8 changes: 3 additions & 5 deletions visual-regression/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export async function saveFailedSnapshot(
writeTasks.push(
fs.promises.writeFile(
path.join(failedResultsDir, `${subtestName}-${snapshotIndex}-diff.png`),

PNG.sync.write(diffPng),
),
);
Expand All @@ -171,7 +171,6 @@ export function compareBuffers(
width: number,
height: number,
): CompareResult {

const diff = new PNG({ width: width as number, height: height as number });
const actualImage = PNG.sync.read(actualImageBuffer);
const expectedImage = PNG.sync.read(expectedImageBuffer);
Expand All @@ -187,11 +186,10 @@ export function compareBuffers(
};
}


const count = pixelmatch(
actualImage.data,
expectedImage.data,

diff.data,
width,
height,
Expand All @@ -202,7 +200,7 @@ export function compareBuffers(

return {
doesMatch,

diffImageBuffer: doesMatch ? undefined : diff,
reason: doesMatch ? undefined : `${count} pixels differ`,
};
Expand Down

0 comments on commit 18de7ad

Please sign in to comment.