blob: dbe19a7598e8fd6c6d873a99b4f639b056186296 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src ="routines.js"></script>
<style type="text/css">
video { width: 40px; }
canvas { width: 40px; }
</style>
</head>
<body>
<div id="debuge"></div>
<script>
"use strict";
function with2DContext(subcase, canvas, patternNumber)
{
drawCanvasTestPattern2D(canvas, patternNumber);
}
function withWebGL(subcase, canvas, patternNumber)
{
drawCanvasTestPatternWebGL(canvas, patternNumber);
}
async function createLocalPeerConnectionStream(stream)
{
return new Promise((resolve, reject) => {
createConnections((firstConnection) => {
firstConnection.addTrack(stream.getVideoTracks()[0], stream);
}, (secondConnection) => {
secondConnection.ontrack = (trackEvent) => {
resolve(trackEvent.streams[0]);
};
});
});
}
function waitForVideoFrame(video)
{
return new Promise((resolve) => {
video.requestVideoFrameCallback((now, metadata) => {
resolve(now, metadata);
});
});
}
const width = 500;
const height = 500;
async function waitForVideoFrameSize(video, width, height, counter)
{
if (!counter)
counter = 0;
else if (counter > 100)
return Promise.reject("waitForVideoFrameSize timed out");
const result = await new Promise((resolve, reject) => {
video.requestVideoFrameCallback((now, metadata) => {
resolve(metadata.width === width && metadata.height === height);
});
setTimeout(() => reject("video.requestVideoFrameCallback timed out"), 5000);
});
if (result)
return;
return waitForVideoFrameSize(video, width, height, ++counter);
}
async function drawAndValidate(subcase, canvas, video, counter, stepName)
{
// First change canvas width and wait for width change to clear previous frames.
canvas.width = canvas.width + 500;
canvas.height = canvas.height + 500;
let counter1 = counter;
let id = setInterval(() => { subcase.draw(subcase, canvas, counter1++)}, 100);
await waitForVideoFrameSize(video, canvas.width, canvas.height);
clearInterval(id);
// Get back canvas size to normal and wait for width change to get test frames.
canvas.width = canvas.width - 500;
canvas.height = canvas.height - 500;
id = setInterval(() => { subcase.draw(subcase, canvas, counter)}, 100);
subcase.draw(subcase, canvas, counter);
await waitForVideoFrameSize(video, canvas.width, canvas.height);
clearInterval(id);
assertImageSourceContainsCanvasTestPattern(video, counter, stepName);
}
async function testCanvasToPeerConnection(t, subcase)
{
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
debuge.appendChild(canvas);
t.add_cleanup(async () => debuge.removeChild(canvas));
const localStream = canvas.captureStream();
const remoteStream = await createLocalPeerConnectionStream(localStream);
t.add_cleanup(async () => closeConnections());
const video = document.createElement("video");
video.autoplay = true;
video.controls = false;
debuge.appendChild(video);
t.add_cleanup(async () => debuge.removeChild(video));
video.srcObject = remoteStream;
for (let i = 0; i < 5; ++i)
await drawAndValidate(subcase, canvas, video, 1, `base case: ${i}`);
for (let i = 0; i < 5; ++i)
await drawAndValidate(subcase, canvas, video, i, `iteration: ${i}`);
}
const subcases = [];
// FIXME: This should be filled when 2D context supports HTMLCanvasElement.captureStream().
// subcases.push({draw: with2DContext});
subcases.push({draw: withWebGL});
function testDescription(subcase) {
return Object.keys(subcase).map((k) => `${k}: ${typeof subcase[k] === "function" ? subcase[k].name : subcase[k]}`).join(",");
}
function createCanvasToPeerConnectionTests(slice, slices) {
const sliceSize = Math.floor(subcases.length / slices);
const first = sliceSize * slice;
for (const subcase of subcases.slice(first, first + sliceSize))
promise_test(async t => { await testCanvasToPeerConnection(t, subcase); }, testDescription(subcase));
}
createCanvasToPeerConnectionTests(0, 1);
</script>
</body>
</html>