1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
// 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.');
|