mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
141 lines
4.6 KiB
JavaScript
141 lines
4.6 KiB
JavaScript
// META: global=window,dedicatedworker
|
|
// META: script=/webcodecs/utils.js
|
|
// META: script=/webcodecs/webgl-test-utils.js
|
|
|
|
function testGLCanvas(gl, width, height, expectedPixel, assertCompares) {
|
|
var colorData =
|
|
new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
|
|
gl.readPixels(
|
|
0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA,
|
|
gl.UNSIGNED_BYTE, colorData);
|
|
assertCompares(gl.getError(), gl.NO_ERROR);
|
|
|
|
const kMaxPixelToCheck = 128 * 96;
|
|
let step = width * height / kMaxPixelToCheck;
|
|
step = Math.round(step);
|
|
step = (step < 1) ? 1 : step;
|
|
for (let i = 0; i < 4 * width * height; i += (4 * step)) {
|
|
assertCompares(colorData[i], expectedPixel[0]);
|
|
assertCompares(colorData[i + 1], expectedPixel[1]);
|
|
assertCompares(colorData[i + 2], expectedPixel[2]);
|
|
assertCompares(colorData[i + 3], expectedPixel[3]);
|
|
}
|
|
}
|
|
|
|
function testTexImage2DFromVideoFrame(
|
|
width, height, useTexSubImage2D, expectedPixel) {
|
|
let vfInit =
|
|
{format: 'RGBA', timestamp: 0, codedWidth: width, codedHeight: height};
|
|
let argbData = new Uint32Array(vfInit.codedWidth * vfInit.codedHeight);
|
|
argbData.fill(0xFF966432); // 'rgb(50, 100, 150)';
|
|
let frame = new VideoFrame(argbData, vfInit);
|
|
|
|
let canvas;
|
|
if (self.HTMLCanvasElement) {
|
|
canvas = document.createElement("canvas");
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
} else
|
|
canvas = new OffscreenCanvas(width, height);
|
|
let gl = canvas.getContext('webgl');
|
|
|
|
let program = WebGLTestUtils.setupTexturedQuad(gl);
|
|
gl.clearColor(0, 0, 0, 1);
|
|
gl.clearDepth(1);
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
gl.colorMask(1, 1, 1, 0); // Disable any writes to the alpha channel.
|
|
let textureLoc = gl.getUniformLocation(program, 'tex');
|
|
|
|
let texture = gl.createTexture();
|
|
|
|
// Bind the texture to texture unit 0.
|
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
|
|
// Set up texture parameters.
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
|
|
// Set up pixel store parameters.
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
|
|
// Upload the videoElement into the texture
|
|
if (useTexSubImage2D) {
|
|
// Initialize the texture to black first
|
|
gl.texImage2D(
|
|
gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
|
|
null);
|
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, frame);
|
|
} else {
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, frame);
|
|
}
|
|
|
|
frame.close();
|
|
|
|
assert_equals(gl.getError(), gl.NO_ERROR);
|
|
|
|
// Point the uniform sampler to texture unit 0
|
|
gl.uniform1i(textureLoc, 0);
|
|
|
|
// Draw the triangles
|
|
WebGLTestUtils.drawQuad(gl, [0, 0, 0, 255]);
|
|
|
|
// Wait for drawing to complete.
|
|
gl.finish();
|
|
|
|
testGLCanvas(gl, width, height, expectedPixel, assert_equals);
|
|
}
|
|
|
|
function testTexImageWithClosedVideoFrame(useTexSubImage2D) {
|
|
let width = 128;
|
|
let height = 128;
|
|
let vfInit =
|
|
{format: 'RGBA', timestamp: 0, codedWidth: width, codedHeight: height};
|
|
let argbData = new Uint32Array(vfInit.codedWidth * vfInit.codedHeight);
|
|
argbData.fill(0xFF966432); // 'rgb(50, 100, 150)';
|
|
let frame = new VideoFrame(argbData, vfInit);
|
|
|
|
let canvas;
|
|
if (self.HTMLCanvasElement) {
|
|
canvas = document.createElement("canvas");
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
} else
|
|
canvas = new OffscreenCanvas(width, height);
|
|
let gl = canvas.getContext('webgl');
|
|
|
|
frame.close();
|
|
if (useTexSubImage2D) {
|
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, frame);
|
|
} else {
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, frame);
|
|
}
|
|
|
|
assert_equals(gl.getError(), gl.INVALID_OPERATION);
|
|
}
|
|
|
|
test(_ => {
|
|
testTexImage2DFromVideoFrame(48, 36, false, kSRGBPixel);
|
|
}, 'texImage2D with 48x36 srgb VideoFrame.');
|
|
|
|
test(_ => {
|
|
testTexImage2DFromVideoFrame(48, 36, true, kSRGBPixel);
|
|
}, 'texSubImage2D with 48x36 srgb VideoFrame.');
|
|
|
|
test(_ => {
|
|
testTexImage2DFromVideoFrame(480, 360, false, kSRGBPixel);
|
|
}, 'texImage2D with 480x360 srgb VideoFrame.');
|
|
|
|
test(_ => {
|
|
testTexImage2DFromVideoFrame(480, 360, true, kSRGBPixel);
|
|
}, 'texSubImage2D with 480x360 srgb VideoFrame.');
|
|
|
|
test(_ => {
|
|
testTexImageWithClosedVideoFrame(false);
|
|
}, 'texImage2D with a closed VideoFrame.');
|
|
|
|
test(_ => {
|
|
testTexImageWithClosedVideoFrame(true);
|
|
}, 'texSubImage2D with a closed VideoFrame.');
|