tests: Vendor blink perf tests (#38654)

Vendors the [blink perf
tests](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/perf_tests/).
These perf tests are useful to evaluate the performance of servo. 
The license that governs the perf tests is included in the folder. 
Running benchmark cases automatically is left to future work.

The update.py script is taken from mozjs and slightly adapted, so we can
easily filter
(and patch if this should be necessary in the future.

Testing: This PR just adds the perf_tests, but does not use or modify
them in any way.

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
Jonathan Schwender 2025-08-17 11:54:04 +02:00 committed by GitHub
parent 7621332824
commit ee781b71b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
648 changed files with 359694 additions and 0 deletions

View file

@ -0,0 +1 @@
mixins: "//third_party/blink/renderer/modules/webgl/COMMON_METADATA"

View file

@ -0,0 +1 @@
file://third_party/blink/renderer/modules/webgl/OWNERS

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test CPU performance of the WebGLRenderingContext.bindBuffer binding
</title>
<script src="../resources/runner.js"></script>
</head>
<body>
<canvas id="canvas" width=400 height=400></canvas>
<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
const vertexBuffer1 = gl.createBuffer();
const vertexBuffer2 = gl.createBuffer();
const iterations = 100000;
PerfTestRunner.measureInnerRAFTime({
description: `CPU time for ${iterations*3} calls to WebGLRenderingContext.bindBuffer`,
warmUpCount: 10,
run() {
for (let i = 0; i < iterations; ++i) {
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer2);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
});
</script>
</body>
</html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test CPU performance of the WebGLRenderingContext.bufferSubData binding
</title>
<script src="../resources/runner.js"></script>
</head>
<body>
<canvas id="canvas" width=400 height=400></canvas>
<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
const vertexBuffer = gl.createBuffer();
const data = new Float32Array([
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
]);
const dataCopy = new Float32Array([
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
]);
const sizeInBytes = data.length * data.BYTES_PER_ELEMENT;
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// Ensure twice the size of `data`.
gl.bufferData(gl.ARRAY_BUFFER, sizeInBytes * 2, gl.STATIC_DRAW);
const iterations = 10000;
PerfTestRunner.measureInnerRAFTime({
description: `CPU time for ${iterations * 2} calls to WebGLRenderingContext.bufferSubData`,
warmUpCount: 10,
run() {
for (let i = 0; i < iterations; ++i) {
gl.bufferSubData(gl.ARRAY_BUFFER, 0, data);
gl.bufferSubData(gl.ARRAY_BUFFER, sizeInBytes, dataCopy);
}
}
});
</script>
</body>
</html>

View file

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test CPU performance of the WebGLRenderingContext.drawArrays binding
</title>
<script src="../resources/runner.js"></script>
</head>
<body>
<canvas id="canvas" width=400 height=400></canvas>
<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
]), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
const vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, `
attribute vec3 a_coord;
void main() {
gl_Position = vec4(a_coord, 1.0);
}`);
gl.compileShader(vertShader);
const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, `
precision mediump float;
uniform vec3 u_color;
void main() {
gl_FragColor = vec4(u_color, 1.0);
}`);
gl.compileShader(fragShader);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
const aCoord = gl.getAttribLocation(shaderProgram, 'a_coord');
const uColor = gl.getUniformLocation(shaderProgram, 'u_color');
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(aCoord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aCoord);
gl.clearColor(0, 0, 0, 1);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.uniform3fv(uColor, [0, 1, 0]);
const iterations = 10000;
PerfTestRunner.measureInnerRAFTime({
description: `CPU time for ${iterations} calls to WebGLRenderingContext.drawArrays`,
warmUpCount: 10,
run() {
gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < iterations; ++i) {
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
}
});
</script>
</body>
</html>

View file

@ -0,0 +1,114 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test CPU performance of the WebGL typed array uniform uploads binding
</title>
<script src="../resources/runner.js"></script>
</head>
<body>
<canvas id="canvas" width=400 height=400></canvas>
<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
function compileOrReportError(shader) {
gl.compileShader(shader);
const message = gl.getShaderInfoLog(shader);
if (message.length > 0) {
throw new Error(message);
}
}
const vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, `
uniform mat4 transform_matrix;
uniform vec3 position_offset;
attribute vec2 a_coord;
void main() {
gl_Position = transform_matrix * vec4(a_coord, 0.0, 1.0) + vec4(position_offset, 0.0);
}`);
compileOrReportError(vertShader);
const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, `
precision mediump float;
uniform vec3 u_color;
void main() {
gl_FragColor = vec4(u_color, 1.0);
}`);
compileOrReportError(fragShader);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
const info = gl.getProgramInfoLog(shaderProgram);
throw new Error('Could not compile WebGL program. \n\n' + info);
}
gl.useProgram(shaderProgram);
// Initialize uniforms
const aCoord = gl.getAttribLocation(shaderProgram, 'a_coord');
const uColor = gl.getUniformLocation(shaderProgram, 'u_color');
const transformLoc = gl.getUniformLocation(shaderProgram, 'transform_matrix');
const offsetLoc = gl.getUniformLocation(shaderProgram, 'position_offset');
// Initialize vertices
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.enableVertexAttribArray(aCoord);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0,
-1.0, 1.0,
-1.0, -1.0,
1.0, -1.0]), gl.STATIC_DRAW);
gl.vertexAttribPointer(aCoord, 2, gl.FLOAT, false, 0, 0);
gl.clearColor(0, 0, 0, 1);
gl.viewport(0, 0, canvas.width, canvas.height);
const tilesPerSide = 50;
const iterations = tilesPerSide;
let transformMatrix = new Float32Array(16);
let offset = new Float32Array(3);
let ripeness = 0;
{
transformMatrix[15] = 1.0;
const scaleFactor = 1.0 / tilesPerSide;
transformMatrix[0] = scaleFactor;
transformMatrix[5] = scaleFactor;
transformMatrix[10] = scaleFactor;
}
PerfTestRunner.measureInnerRAFTime({
description: `CPU time for ${iterations} calls to WebGLRenderingContext.uniformMatrix4fv`,
warmUpCount: 10,
iterationCount: iterations,
run() {
gl.clear(gl.COLOR_BUFFER_BIT);
for (var yy = 0; yy < tilesPerSide; ++yy) {
for (var xx = 0; xx < tilesPerSide; ++xx) {
gl.uniform3fv(uColor, [ripeness, 1 - ripeness, 0]);
gl.uniformMatrix4fv(transformLoc, false, transformMatrix);
offset[0] = 2.0 * ((0.5 + xx) / tilesPerSide) - 1.0;
offset[1] = 2.0 * ((0.5 + yy) / tilesPerSide) - 1.0;
gl.uniform3fv(offsetLoc, offset);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
}
ripeness = ripeness < 1 ? ripeness += 0.02 : 0;
}
});
</script>
</body>
</html>