mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1032848 - Part 3: Add tests for HTMLCanvasElement::CaptureStream. r=mt, r=jgilbert, r=jesup
--HG-- extra : transplant_source : %10%FE%B2%29%FD%88%94%3Ax%11%F8%8D%A5%218e%F3%EA%E7%2B
This commit is contained in:
parent
a0fcf04b67
commit
c1f6180c92
174
dom/canvas/test/captureStream_common.js
Normal file
174
dom/canvas/test/captureStream_common.js
Normal file
@ -0,0 +1,174 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* Util base class to help test a captured canvas element. Initializes the
|
||||
* output canvas (used for testing the color of video elements), and optionally
|
||||
* overrides the default element |width| and |height|.
|
||||
*/
|
||||
function CaptureStreamTestHelper(width, height) {
|
||||
this.cout = document.createElement('canvas');
|
||||
if (width) {
|
||||
this.elemWidth = width;
|
||||
}
|
||||
if (height) {
|
||||
this.elemHeight = height;
|
||||
}
|
||||
this.cout.width = this.elemWidth;
|
||||
this.cout.height = this.elemHeight;
|
||||
document.body.appendChild(this.cout);
|
||||
}
|
||||
|
||||
CaptureStreamTestHelper.prototype = {
|
||||
/* Predefined colors for use in the methods below. */
|
||||
black: { data: [0, 0, 0, 255], name: "black" },
|
||||
green: { data: [0, 255, 0, 255], name: "green" },
|
||||
red: { data: [255, 0, 0, 255], name: "red" },
|
||||
|
||||
/* Default element size for createAndAppendElement() */
|
||||
elemWidth: 100,
|
||||
elemHeight: 100,
|
||||
|
||||
/* Request a frame from the stream played by |video|. */
|
||||
requestFrame: function (video) {
|
||||
info("Requesting frame from " + video.id);
|
||||
video.mozSrcObject.requestFrame();
|
||||
},
|
||||
|
||||
/* Tests the top left pixel of |video| against |refData|. Format [R,G,B,A]. */
|
||||
testPixel: function (video, refData, threshold) {
|
||||
var ctxout = this.cout.getContext('2d');
|
||||
ctxout.drawImage(video, 0, 0);
|
||||
var pixel = ctxout.getImageData(0, 0, 1, 1).data;
|
||||
return pixel.every((val, i) => Math.abs(val - refData[i]) <= threshold);
|
||||
},
|
||||
|
||||
/*
|
||||
* Returns a promise that resolves when the pixel matches. Use |threshold|
|
||||
* for fuzzy matching the color on each channel, in the range [0,255].
|
||||
*/
|
||||
waitForPixel: function (video, refColor, threshold, infoString) {
|
||||
return new Promise(resolve => {
|
||||
info("Testing " + video.id + " against [" + refColor.data.join(',') + "]");
|
||||
CaptureStreamTestHelper2D.prototype.clear.call(this, this.cout);
|
||||
video.ontimeupdate = () => {
|
||||
if (this.testPixel(video, refColor.data, threshold)) {
|
||||
ok(true, video.id + " " + infoString);
|
||||
video.ontimeupdate = null;
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
* Returns a promise that resolves after |timeout| ms of playback or when a
|
||||
* pixel of |video| becomes the color |refData|. The test is failed if the
|
||||
* timeout is not reached.
|
||||
*/
|
||||
waitForPixelToTimeout: function (video, refColor, threshold, timeout, infoString) {
|
||||
return new Promise(resolve => {
|
||||
info("Waiting for " + video.id + " to time out after " + timeout +
|
||||
"ms against [" + refColor.data.join(',') + "] - " + refColor.name);
|
||||
CaptureStreamTestHelper2D.prototype.clear.call(this, this.cout);
|
||||
var startTime = video.currentTime;
|
||||
video.ontimeupdate = () => {
|
||||
if (this.testPixel(video, refColor.data, threshold)) {
|
||||
ok(false, video.id + " " + infoString);
|
||||
video.ontimeupdate = null;
|
||||
resolve();
|
||||
} else if (video.currentTime > startTime + (timeout / 1000.0)) {
|
||||
ok(true, video.id + " " + infoString);
|
||||
video.ontimeupdate = null;
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/* Create an element of type |type| with id |id| and append it to the body. */
|
||||
createAndAppendElement: function (type, id) {
|
||||
var e = document.createElement(type);
|
||||
e.id = id;
|
||||
e.width = this.elemWidth;
|
||||
e.height = this.elemHeight;
|
||||
if (type === 'video') {
|
||||
e.autoplay = true;
|
||||
}
|
||||
document.body.appendChild(e);
|
||||
return e;
|
||||
},
|
||||
}
|
||||
|
||||
/* Sub class holding 2D-Canvas specific helpers. */
|
||||
function CaptureStreamTestHelper2D(width, height) {
|
||||
CaptureStreamTestHelper.call(this, width, height);
|
||||
}
|
||||
|
||||
CaptureStreamTestHelper2D.prototype = Object.create(CaptureStreamTestHelper.prototype);
|
||||
CaptureStreamTestHelper2D.prototype.constructor = CaptureStreamTestHelper2D;
|
||||
|
||||
/* Clear all drawn content on |canvas|. */
|
||||
CaptureStreamTestHelper2D.prototype.clear = function(canvas) {
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
};
|
||||
|
||||
/* Draw the color |color| to the source canvas |canvas|. Format [R,G,B,A]. */
|
||||
CaptureStreamTestHelper2D.prototype.drawColor = function(canvas, color) {
|
||||
var ctx = canvas.getContext('2d');
|
||||
var rgba = color.data.slice(); // Copy to not overwrite the original array
|
||||
info("Drawing color " + rgba.join(','));
|
||||
rgba[3] = rgba[3] / 255.0; // Convert opacity to double in range [0,1]
|
||||
ctx.fillStyle = "rgba(" + rgba.join(',') + ")";
|
||||
|
||||
// Only fill top left corner to test that output is not flipped or rotated.
|
||||
ctx.fillRect(0, 0, canvas.width / 2, canvas.height / 2);
|
||||
};
|
||||
|
||||
/* Test that the given 2d canvas is NOT origin-clean. */
|
||||
CaptureStreamTestHelper2D.prototype.testNotClean = function(canvas) {
|
||||
var ctx = canvas.getContext('2d');
|
||||
var error = "OK";
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
} catch(e) {
|
||||
error = e.name;
|
||||
}
|
||||
is(error, "SecurityError",
|
||||
"Canvas '" + canvas.id + "' should not be origin-clean");
|
||||
};
|
||||
|
||||
/* Sub class holding WebGL specific helpers. */
|
||||
function CaptureStreamTestHelperWebGL(width, height) {
|
||||
CaptureStreamTestHelper.call(this, width, height);
|
||||
}
|
||||
|
||||
CaptureStreamTestHelperWebGL.prototype = Object.create(CaptureStreamTestHelper.prototype);
|
||||
CaptureStreamTestHelperWebGL.prototype.constructor = CaptureStreamTestHelperWebGL;
|
||||
|
||||
/* Set the (uniform) color location for future draw calls. */
|
||||
CaptureStreamTestHelperWebGL.prototype.setFragmentColorLocation = function(colorLocation) {
|
||||
this.colorLocation = colorLocation;
|
||||
};
|
||||
|
||||
/* Clear the given WebGL context with |color|. */
|
||||
CaptureStreamTestHelperWebGL.prototype.clearColor = function(canvas, color) {
|
||||
info("WebGL: clearColor(" + color.name + ")");
|
||||
var gl = canvas.getContext('webgl');
|
||||
var conv = color.data.map(i => i / 255.0);
|
||||
gl.clearColor(conv[0], conv[1], conv[2], conv[3]);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
};
|
||||
|
||||
/* Set an already setFragmentColorLocation() to |color| and drawArrays() */
|
||||
CaptureStreamTestHelperWebGL.prototype.drawColor = function(canvas, color) {
|
||||
info("WebGL: drawArrays(" + color.name + ")");
|
||||
var gl = canvas.getContext('webgl');
|
||||
var conv = color.data.map(i => i / 255.0);
|
||||
gl.uniform4f(this.colorLocation, conv[0], conv[1], conv[2], conv[3]);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
};
|
@ -73,6 +73,17 @@ function testImage(url, crossOriginAttribute, expected_error) {
|
||||
"drawImage then get image data on " + url +
|
||||
" with crossOrigin=" + this.crossOrigin);
|
||||
|
||||
try {
|
||||
c.captureStream(0);
|
||||
actual_error = OK;
|
||||
} catch (e) {
|
||||
actual_error = e.name;
|
||||
}
|
||||
|
||||
verifyError(actual_error, expected_error,
|
||||
"drawImage then capture stream on " + url +
|
||||
" with crossOrigin=" + this.crossOrigin);
|
||||
|
||||
// Now test patterns
|
||||
c = document.createElement("canvas");
|
||||
c.width = this.width;
|
||||
@ -91,6 +102,17 @@ function testImage(url, crossOriginAttribute, expected_error) {
|
||||
"createPattern+fill then get image data on " + url +
|
||||
" with crossOrigin=" + this.crossOrigin);
|
||||
|
||||
try {
|
||||
c.captureStream(0);
|
||||
actual_error = OK;
|
||||
} catch (e) {
|
||||
actual_error = e.name;
|
||||
}
|
||||
|
||||
verifyError(actual_error, expected_error,
|
||||
"createPattern+fill then capture stream on " + url +
|
||||
" with crossOrigin=" + this.crossOrigin);
|
||||
|
||||
testDone();
|
||||
};
|
||||
|
||||
@ -130,56 +152,64 @@ const attrValues = [
|
||||
[ "foobar", "anonymous" ]
|
||||
];
|
||||
|
||||
for (var imgIdx = 0; imgIdx < imageFiles.length; ++imgIdx) {
|
||||
for (var hostnameIdx = 0; hostnameIdx < hostnames.length; ++hostnameIdx) {
|
||||
var hostnameData = hostnames[hostnameIdx];
|
||||
var url = "http://" + hostnameData[0] + testPath + imageFiles[imgIdx][0];
|
||||
for (var attrValIdx = 0; attrValIdx < attrValues.length; ++attrValIdx) {
|
||||
var attrValData = attrValues[attrValIdx];
|
||||
// Now compute the expected result
|
||||
var expected_error;
|
||||
if (hostnameData[1] == "same-origin") {
|
||||
// Same-origin; these should all Just Work
|
||||
expected_error = OK;
|
||||
} else {
|
||||
// Cross-origin
|
||||
is(hostnameData[1], "cross-origin",
|
||||
"what sort of host is " + hostnameData[0]);
|
||||
var CORSMode = attrValData[1];
|
||||
if (CORSMode == "none") {
|
||||
// Doesn't matter what headers the server sends; we're not
|
||||
// using CORS on our end.
|
||||
expected_error = "SecurityError";
|
||||
function beginTest() {
|
||||
for (var imgIdx = 0; imgIdx < imageFiles.length; ++imgIdx) {
|
||||
for (var hostnameIdx = 0; hostnameIdx < hostnames.length; ++hostnameIdx) {
|
||||
var hostnameData = hostnames[hostnameIdx];
|
||||
var url = "http://" + hostnameData[0] + testPath + imageFiles[imgIdx][0];
|
||||
for (var attrValIdx = 0; attrValIdx < attrValues.length; ++attrValIdx) {
|
||||
var attrValData = attrValues[attrValIdx];
|
||||
// Now compute the expected result
|
||||
var expected_error;
|
||||
if (hostnameData[1] == "same-origin") {
|
||||
// Same-origin; these should all Just Work
|
||||
expected_error = OK;
|
||||
} else {
|
||||
// Check whether the server will let us talk to them
|
||||
var CORSHeaders = imageFiles[imgIdx][1];
|
||||
// We're going to look for CORS headers from the server
|
||||
if (CORSHeaders == "none") {
|
||||
// No CORS headers from server; load will fail.
|
||||
expected_error = BAD_URI_ERR;
|
||||
} else if (CORSHeaders == "allow-all-anon") {
|
||||
// Server only allows anonymous requests
|
||||
if (CORSMode == "anonymous") {
|
||||
expected_error = OK;
|
||||
} else {
|
||||
is(CORSMode, "use-credentials",
|
||||
"What other CORS modes are there?");
|
||||
// A load with credentials against a server that only
|
||||
// allows anonymous loads will fail.
|
||||
expected_error = BAD_URI_ERR;
|
||||
}
|
||||
// Cross-origin
|
||||
is(hostnameData[1], "cross-origin",
|
||||
"what sort of host is " + hostnameData[0]);
|
||||
var CORSMode = attrValData[1];
|
||||
if (CORSMode == "none") {
|
||||
// Doesn't matter what headers the server sends; we're not
|
||||
// using CORS on our end.
|
||||
expected_error = "SecurityError";
|
||||
} else {
|
||||
is(CORSHeaders, "allow-single-server-creds",
|
||||
"What other CORS headers could there be?");
|
||||
// Our server should allow both anonymous and non-anonymous requests
|
||||
expected_error = OK;
|
||||
// Check whether the server will let us talk to them
|
||||
var CORSHeaders = imageFiles[imgIdx][1];
|
||||
// We're going to look for CORS headers from the server
|
||||
if (CORSHeaders == "none") {
|
||||
// No CORS headers from server; load will fail.
|
||||
expected_error = BAD_URI_ERR;
|
||||
} else if (CORSHeaders == "allow-all-anon") {
|
||||
// Server only allows anonymous requests
|
||||
if (CORSMode == "anonymous") {
|
||||
expected_error = OK;
|
||||
} else {
|
||||
is(CORSMode, "use-credentials",
|
||||
"What other CORS modes are there?");
|
||||
// A load with credentials against a server that only
|
||||
// allows anonymous loads will fail.
|
||||
expected_error = BAD_URI_ERR;
|
||||
}
|
||||
} else {
|
||||
is(CORSHeaders, "allow-single-server-creds",
|
||||
"What other CORS headers could there be?");
|
||||
// Our server should allow both anonymous and non-anonymous requests
|
||||
expected_error = OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
testImage(url, attrValData[0], expected_error);
|
||||
}
|
||||
testImage(url, attrValData[0], expected_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var prefs = [
|
||||
[ "canvas.capturestream.enabled", true ],
|
||||
];
|
||||
SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -28,11 +28,7 @@ function createCanvas(width, height) {
|
||||
return c;
|
||||
}
|
||||
|
||||
function testCanvasDrawImage(v) {
|
||||
var c = createCanvas(v.width, v.height);
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.drawImage(v, 0, 0);
|
||||
|
||||
function checkGetImageData(ctx, v) {
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(true, "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked");
|
||||
@ -42,22 +38,54 @@ function testCanvasDrawImage(v) {
|
||||
}
|
||||
}
|
||||
|
||||
function checkGetImageDataTainted(ctx, v) {
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(false, "changing the CORS mode should not allow reading data from remote videos");
|
||||
} catch (error) {
|
||||
ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed");
|
||||
}
|
||||
}
|
||||
|
||||
function checkCaptureStream(c, v) {
|
||||
try {
|
||||
var stream = c.captureStream(0);
|
||||
ok(true, "drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' worked");
|
||||
} catch(error) {
|
||||
ok(!v.crossOrigin && error.name === "SecurityError", "drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' failed");
|
||||
v.tainted = true;
|
||||
}
|
||||
}
|
||||
|
||||
function checkCaptureStreamTainted(c, v) {
|
||||
try {
|
||||
var stream = c.captureStream(0);
|
||||
ok(false, "changing the CORS mode should not allow capturing a stream from remote videos");
|
||||
} catch (error) {
|
||||
ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' failed");
|
||||
}
|
||||
}
|
||||
|
||||
function testCanvasDrawImage(v) {
|
||||
var c = createCanvas(v.width, v.height);
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.drawImage(v, 0, 0);
|
||||
|
||||
checkGetImageData(ctx, v);
|
||||
checkCaptureStream(c, v);
|
||||
}
|
||||
|
||||
function testCanvasCreatePattern(v) {
|
||||
var c = createCanvas(v.width, v.height);
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.fillStyle = ctx.createPattern(v, "");
|
||||
ctx.fillRect(0, 0, c.width, c.height);
|
||||
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(true, "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked");
|
||||
} catch(error) {
|
||||
ok(!v.crossOrigin && error.name === "SecurityError", "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed");
|
||||
v.tainted = true;
|
||||
}
|
||||
checkGetImageData(ctx, v);
|
||||
checkCaptureStream(c, v);
|
||||
}
|
||||
|
||||
function testWebGL(v) {
|
||||
function testWebGL(gl, v) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
|
||||
@ -75,12 +103,8 @@ function testTaintedCanvas(v) {
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.drawImage(v, 0, 0);
|
||||
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(false, "changing the CORS mode should not allow reading data from remote videos");
|
||||
} catch (error) {
|
||||
ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed");
|
||||
}
|
||||
checkGetImageDataTainted(ctx, v);
|
||||
checkCaptureStreamTainted(c, v);
|
||||
}
|
||||
|
||||
function vidDataSuccess(e) {
|
||||
@ -88,8 +112,8 @@ function vidDataSuccess(e) {
|
||||
|
||||
testCanvasDrawImage(e.target);
|
||||
testCanvasCreatePattern(e.target);
|
||||
if (gl) {
|
||||
testWebGL(e.target);
|
||||
if (document.gl) {
|
||||
testWebGL(document.gl, e.target);
|
||||
}
|
||||
// If we change the CORS mode after loading the file without CORS it should still throw a security error
|
||||
if (e.target.tainted) {
|
||||
@ -121,7 +145,7 @@ function startTest(test, token) {
|
||||
v.crossOrigin = test.cors;
|
||||
}
|
||||
v.token = token;
|
||||
manager.started(token);
|
||||
document.manager.started(token);
|
||||
v.autoplay = true;
|
||||
v.preload = "auto";
|
||||
v.style.display = "none";
|
||||
@ -140,53 +164,59 @@ function startTest(test, token) {
|
||||
function doneTest(e) {
|
||||
var v = e.target;
|
||||
v.parentNode.removeChild(v);
|
||||
manager.finished(v.token);
|
||||
document.manager.finished(v.token);
|
||||
}
|
||||
|
||||
var videoFile = getPlayableVideo(gSmallTests);
|
||||
if (!videoFile) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
videoFile = "?name=tests/dom/media/test/" + videoFile.name + "&type=" + videoFile.type;
|
||||
function beginTest() {
|
||||
var videoFile = getPlayableVideo(gSmallTests);
|
||||
if (!videoFile) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
videoFile = "?name=tests/dom/media/test/" + videoFile.name + "&type=" + videoFile.type;
|
||||
|
||||
var gl;
|
||||
try {
|
||||
gl = createCanvas(16, 16).getContext("experimental-webgl");
|
||||
} catch (ex) {
|
||||
// Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests
|
||||
document.manager = new MediaTestManager;
|
||||
var corsTests = [];
|
||||
|
||||
const host = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs";
|
||||
const serverAttrValues = [
|
||||
[ "&cors=none", "none" ],
|
||||
[ "&cors=anonymous", "anonymous" ],
|
||||
[ "&cors=use-credentials", "use-credentials" ]
|
||||
];
|
||||
const clientAttrValues = [
|
||||
[ "missing-value-default", "none" ],
|
||||
[ "", "anonymous" ],
|
||||
[ "just-crossOrigin-without-value", "anonymous" ],
|
||||
[ "anonymous", "anonymous" ],
|
||||
[ "use-credentials", "use-credentials" ],
|
||||
[ "foobar", "anonymous" ]
|
||||
];
|
||||
|
||||
// Build the video file test array
|
||||
for (var i = 0; i < serverAttrValues.length; i++) {
|
||||
for (var n = 0; n < clientAttrValues.length; n++) {
|
||||
corsTests.push({
|
||||
name: host + videoFile + serverAttrValues[i][0],
|
||||
nameIntent: serverAttrValues[i][1],
|
||||
cors: clientAttrValues[n][0],
|
||||
corsIntent: clientAttrValues[n][1]
|
||||
});
|
||||
}
|
||||
}
|
||||
try {
|
||||
document.gl = createCanvas(16, 16).getContext("experimental-webgl");
|
||||
} catch (ex) {
|
||||
// Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests
|
||||
}
|
||||
document.manager.runTests(corsTests, startTest);
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
var corsTests = [];
|
||||
|
||||
const host = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs";
|
||||
const serverAttrValues = [
|
||||
[ "&cors=none", "none" ],
|
||||
[ "&cors=anonymous", "anonymous" ],
|
||||
[ "&cors=use-credentials", "use-credentials" ]
|
||||
];
|
||||
const clientAttrValues = [
|
||||
[ "missing-value-default", "none" ],
|
||||
[ "", "anonymous" ],
|
||||
[ "just-crossOrigin-without-value", "anonymous" ],
|
||||
[ "anonymous", "anonymous" ],
|
||||
[ "use-credentials", "use-credentials" ],
|
||||
[ "foobar", "anonymous" ]
|
||||
var prefs = [
|
||||
[ "canvas.capturestream.enabled", true ],
|
||||
];
|
||||
|
||||
// Build the video file test array
|
||||
for (var i = 0; i < serverAttrValues.length; i++) {
|
||||
for (var n = 0; n < clientAttrValues.length; n++) {
|
||||
corsTests.push({
|
||||
name: host + videoFile + serverAttrValues[i][0],
|
||||
nameIntent: serverAttrValues[i][1],
|
||||
cors: clientAttrValues[n][0],
|
||||
corsIntent: clientAttrValues[n][1]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
manager.runTests(corsTests, startTest);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
BIN
dom/canvas/test/image_red_crossorigin_credentials.png
Normal file
BIN
dom/canvas/test/image_red_crossorigin_credentials.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 87 B |
@ -0,0 +1,2 @@
|
||||
Access-Control-Allow-Origin: http://mochi.test:8888
|
||||
Access-Control-Allow-Credentials: true
|
@ -14,6 +14,8 @@ support-files =
|
||||
image_green.png
|
||||
image_red-16x16.png
|
||||
image_red.png
|
||||
image_red_crossorigin_credentials.png
|
||||
image_red_crossorigin_credentials.png^headers^
|
||||
image_redtransparent.png
|
||||
image_rgrg-256x256.png
|
||||
image_rrgg-256x256.png
|
||||
@ -224,6 +226,8 @@ skip-if = (toolkit == 'gonk' && !debug) || os == 'win' #specialpowers.wrap
|
||||
[test_hitregion_event.html]
|
||||
skip-if = os == "android" || appname == "b2g"
|
||||
[test_canvas_strokeStyle_getter.html]
|
||||
[test_capture.html]
|
||||
support-files = captureStream_common.js
|
||||
[test_drawImageIncomplete.html]
|
||||
[test_drawImage_document_domain.html]
|
||||
[test_drawImage_edge_cases.html]
|
||||
|
111
dom/canvas/test/test_capture.html
Normal file
111
dom/canvas/test/test_capture.html
Normal file
@ -0,0 +1,111 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Canvas2D test: CaptureStream()</title>
|
||||
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="captureStream_common.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<body>
|
||||
<script>
|
||||
var c; // Canvas element captured by streams.
|
||||
var h; // CaptureStreamTestHelper holding utility test functions.
|
||||
var vauto; // Video element with captureStream stream in automatic mode.
|
||||
var vmanual; // Video element with captureStream stream in manual (fps 0) mode.
|
||||
var vrate; // Video element with captureStream stream with fixed frame rate.
|
||||
|
||||
function checkDrawColorInitialRed() {
|
||||
info("Checking that all video elements become red after first drawColor(red).");
|
||||
|
||||
h.drawColor(c, h.red);
|
||||
|
||||
vauto.mozSrcObject = c.captureStream();
|
||||
vmanual.mozSrcObject = c.captureStream(0);
|
||||
vrate.mozSrcObject = c.captureStream(10);
|
||||
|
||||
ok(h.testPixel(vauto, [0, 0, 0, 0], 0), "vauto hould not be drawn to before stable state");
|
||||
ok(h.testPixel(vrate, [0, 0, 0, 0], 0), "vrate Should not be drawn to before stable state");
|
||||
ok(h.testPixel(vmanual, [0, 0, 0, 0], 0), "vmanual Should not be drawn to before stable state");
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vauto, h.red, 0, "should become red automatically"))
|
||||
.then(() => h.waitForPixel(vrate, h.red, 0, "should become red automatically"))
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should become red when we get" +
|
||||
" to stable state (first frame)"));
|
||||
}
|
||||
|
||||
function checkDrawColorGreen() {
|
||||
info("Checking that drawColor(green) propagates properly to video elements.");
|
||||
h.drawColor(c, h.green);
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vauto, h.green, 0, "should become green automatically"))
|
||||
.then(() => h.waitForPixel(vrate, h.green, 0, "should become green automatically"))
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should still be red"))
|
||||
.then(() => h.requestFrame(vmanual))
|
||||
.then(() => h.waitForPixel(vmanual, h.green, 0, "should become green after requstFrame()"));
|
||||
}
|
||||
|
||||
function checkRequestFrameOrderGuarantee() {
|
||||
info("Checking that requestFrame() immediately before and after drawColor() " +
|
||||
"calls results in the expected frame seen in the stream.");
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vmanual, h.green, 0, "should still be green"))
|
||||
.then(() => h.drawColor(c, h.red)) // 1. Draw canvas red
|
||||
.then(() => h.requestFrame(vmanual)) // 2. Immediately request a frame
|
||||
.then(() => h.drawColor(c, h.green)) // 3. Immediately draw canvas green
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should become red after call order test"))
|
||||
.then(() => h.waitForPixelToTimeout(vmanual, h.green, 0, 500, "should not become green after call order test"));
|
||||
}
|
||||
|
||||
function checkDrawImageNotCleanRed() {
|
||||
info("Checking that drawImage with not origin-clean image renders streams useless.");
|
||||
var ctx = c.getContext('2d');
|
||||
var notCleanRed = new Image();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
notCleanRed.onload = resolve;
|
||||
notCleanRed.onerror = () => reject(new Error("Failed to load tainted image."));
|
||||
notCleanRed.src = "http://example.com/tests/dom/canvas/test/image_red_crossorigin_credentials.png";
|
||||
document.body.appendChild(notCleanRed);
|
||||
})
|
||||
.then(() => ctx.drawImage(notCleanRed, 0, 0, c.width, c.height))
|
||||
.then(() => h.testNotClean(c))
|
||||
.then(() => h.waitForPixelToTimeout(vauto, h.red, 0, 1000, "should not become red"))
|
||||
.then(() => h.waitForPixelToTimeout(vrate, h.red, 0, 0, "should not become red"))
|
||||
.then(() => h.waitForPixel(vmanual, h.green, 0, "should still be green"))
|
||||
.then(() => h.requestFrame(vmanual))
|
||||
.then(() => h.waitForPixelToTimeout(vmanual, h.red, 0, 1000, "should not become red"));
|
||||
}
|
||||
|
||||
function finish() {
|
||||
ok(true, 'Test complete.');
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function beginTest() {
|
||||
h = new CaptureStreamTestHelper2D();
|
||||
|
||||
c = h.createAndAppendElement('canvas', 'c');
|
||||
vauto = h.createAndAppendElement('video', 'vauto');
|
||||
vmanual = h.createAndAppendElement('video', 'vmanual');
|
||||
vrate = h.createAndAppendElement('video', 'vrate');
|
||||
|
||||
Promise.resolve()
|
||||
.then(checkDrawColorInitialRed)
|
||||
.then(checkDrawColorGreen)
|
||||
.then(checkRequestFrameOrderGuarantee)
|
||||
.then(checkDrawColorGreen) // Restore video elements to green.
|
||||
.then(checkDrawImageNotCleanRed)
|
||||
.then(finish);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var prefs = [
|
||||
[ "canvas.capturestream.enabled", true ],
|
||||
];
|
||||
SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest);
|
||||
</script>
|
||||
|
@ -9,6 +9,8 @@ support-files =
|
||||
[webgl-mochitest/test_backbuffer_channels.html]
|
||||
fail-if = (os == 'b2g')
|
||||
[webgl-mochitest/test_depth_readpixels.html]
|
||||
[webgl-mochitest/test_capture.html]
|
||||
support-files = captureStream_common.js
|
||||
[webgl-mochitest/test_draw.html]
|
||||
[webgl-mochitest/test_fb_param.html]
|
||||
[webgl-mochitest/test_fb_param_crash.html]
|
||||
|
200
dom/canvas/test/webgl-mochitest/test_capture.html
Normal file
200
dom/canvas/test/webgl-mochitest/test_capture.html
Normal file
@ -0,0 +1,200 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>WebGL test: CaptureStream()</title>
|
||||
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script src="../captureStream_common.js">
|
||||
<script src="driver-info.js"></script>
|
||||
<script src="webgl-util.js"></script>
|
||||
<script id="vs" type="x-shader/x-vertex">
|
||||
|
||||
attribute vec2 aVertCoord;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = vec4(aVertCoord, 0.0, 1.0);
|
||||
}
|
||||
|
||||
</script>
|
||||
<script id="fs" type="x-shader/x-fragment">
|
||||
|
||||
precision mediump float;
|
||||
uniform vec4 uColor;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = uColor;
|
||||
}
|
||||
|
||||
</script>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
// Globals. Initialized during beginTest().
|
||||
var c; // Canvas element captured by streams.
|
||||
var gl; // WebGLContext of |c|.
|
||||
var h; // CaptureStreamTestHelper holding utility test functions.
|
||||
var vauto; // Video element with captureStream stream in automatic mode.
|
||||
var vmanual; // Video element with captureStream stream in manual (fps 0) mode.
|
||||
var vrate; // Video element with captureStream stream with fixed frame rate.
|
||||
|
||||
/* Fails the test if there was a GL error */
|
||||
function checkGLError(info) {
|
||||
var error = gl.getError();
|
||||
// Comparing strings for sake of log output in hex format.
|
||||
is("0x" + error.toString(16), "0x0", "WebGL error [" + info + "]");
|
||||
}
|
||||
|
||||
function checkClearColorInitialRed() {
|
||||
info("Checking that clearing to red works for first frame.");
|
||||
|
||||
h.clearColor(c, h.red);
|
||||
|
||||
vauto.mozSrcObject = c.captureStream();
|
||||
vmanual.mozSrcObject = c.captureStream(0);
|
||||
vrate.mozSrcObject = c.captureStream(10);
|
||||
|
||||
ok(h.testPixel(vauto, [0, 0, 0, 0], 0), "Should not be drawn to before stable state");
|
||||
ok(h.testPixel(vrate, [0, 0, 0, 0], 0), "Should not be drawn to before stable state");
|
||||
ok(h.testPixel(vmanual, [0, 0, 0, 0], 0), "Should not be drawn to before stable state");
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vauto, h.red, 0, "should become red automatically"))
|
||||
.then(() => h.waitForPixel(vrate, h.red, 0, "should become red automatically"))
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should become red when we get to stable state (first frame)"))
|
||||
}
|
||||
|
||||
function checkDrawColorGreen() {
|
||||
info("Checking that drawColor() results in green frames.");
|
||||
h.drawColor(c, h.green);
|
||||
checkGLError('after DrawColor');
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vauto, h.green, 0, "should become green automatically"))
|
||||
.then(() => h.waitForPixel(vrate, h.green, 0, "should become green automatically"))
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should still be red"))
|
||||
.then(() => h.requestFrame(vmanual))
|
||||
.then(() => h.waitForPixel(vmanual, h.green, 0, "should become green after requstFrame()"))
|
||||
}
|
||||
|
||||
function checkClearColorRed() {
|
||||
info("Checking that clearing to red works.");
|
||||
h.clearColor(c, h.red);
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vauto, h.red, 0, "should become red automatically"))
|
||||
.then(() => h.waitForPixel(vrate, h.red, 0, "should become red automatically"))
|
||||
.then(() => h.waitForPixel(vmanual, h.green, 0, "should still be green"))
|
||||
.then(() => h.requestFrame(vmanual))
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should become red after requestFrame()"))
|
||||
}
|
||||
|
||||
function checkRequestFrameOrderGuarantee() {
|
||||
info("Checking that requestFrame() immediately before and after draw " +
|
||||
"calls results in the expected frame seen in the stream.");
|
||||
return Promise.resolve()
|
||||
.then(() => h.waitForPixel(vmanual, h.red, 0, "should still be red"))
|
||||
.then(() => h.drawColor(c, h.green)) // 1. Draw canvas green
|
||||
.then(() => h.requestFrame(vmanual)) // 2. Immediately request a frame
|
||||
.then(() => h.clearColor(c, h.red)) // 3. Immediately clear to red
|
||||
.then(() => h.waitForPixel(vmanual, h.green, 0, "should become green after call order test"))
|
||||
.then(() => h.waitForPixelToTimeout(vmanual, h.red, 0, 500, "should not become red after call order test"));
|
||||
}
|
||||
|
||||
function checkCapturingForbidden() {
|
||||
info("Checking that capturing a WebGL context with " +
|
||||
"`preservDrawingBuffer: false` is forbidden.");
|
||||
var c2 = h.createAndAppendElement("canvas", "c2");
|
||||
var gl2 = WebGLUtil.getWebGL("c2", false, { preserveDrawingBuffer: false });
|
||||
|
||||
var checkThrows = function(f, expected, fName) {
|
||||
try {
|
||||
f();
|
||||
ok(false, fName + " should throw when not preserving drawing buffer");
|
||||
} catch(e) {
|
||||
is(e.name, expected, fName + " forbidden when not preserving drawing buffer");
|
||||
}
|
||||
};
|
||||
|
||||
checkThrows(() => c2.captureStream(), "NS_ERROR_FAILURE", "captureStream()");
|
||||
checkThrows(() => c2.captureStream(0), "NS_ERROR_FAILURE", "captureStream(0)");
|
||||
checkThrows(() => c2.captureStream(10), "NS_ERROR_FAILURE", "captureStream(10)");
|
||||
}
|
||||
|
||||
function finish() {
|
||||
ok(true, 'Test complete.');
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function beginTest() {
|
||||
h = new CaptureStreamTestHelperWebGL();
|
||||
|
||||
c = h.createAndAppendElement('canvas', 'c');
|
||||
vauto = h.createAndAppendElement('video', 'vauto');
|
||||
vmanual = h.createAndAppendElement('video', 'vmanual');
|
||||
vrate = h.createAndAppendElement('video', 'vrate');
|
||||
|
||||
gl = WebGLUtil.getWebGL('c', false, { preserveDrawingBuffer: true });
|
||||
if (!gl) {
|
||||
todo(false, 'WebGL is unavailable.');
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
function errorFunc(str) {
|
||||
ok(false, 'Error: ' + str);
|
||||
}
|
||||
WebGLUtil.setErrorFunc(errorFunc);
|
||||
WebGLUtil.setWarningFunc(errorFunc);
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
|
||||
prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs');
|
||||
if (!prog) {
|
||||
ok(false, 'Program linking should succeed.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup vertex coordinates for drawing a rectangle across the whole canvas.
|
||||
|
||||
prog.aVertCoord = gl.getAttribLocation(prog, "aVertCoord");
|
||||
ok(prog.aVertCoord >= 0, '`aVertCoord` should be valid.');
|
||||
|
||||
var vertCoordArr = new Float32Array([
|
||||
-1, -1,
|
||||
1, -1,
|
||||
-1, 1,
|
||||
1, 1,
|
||||
]);
|
||||
var vertCoordBuff = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertCoordBuff);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertCoordArr, gl.STATIC_DRAW);
|
||||
|
||||
gl.useProgram(prog);
|
||||
gl.enableVertexAttribArray(prog.aVertCoord);
|
||||
gl.vertexAttribPointer(prog.aVertCoord, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Setup the helper with a pointer to how to change fragment color.
|
||||
|
||||
var uColorLocation = gl.getUniformLocation(prog, "uColor");
|
||||
h.setFragmentColorLocation(uColorLocation);
|
||||
|
||||
checkGLError('after setup');
|
||||
|
||||
// Run tests.
|
||||
|
||||
Promise.resolve()
|
||||
.then(checkClearColorInitialRed)
|
||||
.then(checkDrawColorGreen)
|
||||
.then(checkClearColorRed)
|
||||
.then(checkRequestFrameOrderGuarantee)
|
||||
.then(checkCapturingForbidden)
|
||||
.then(finish);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var prefs = [
|
||||
[ "canvas.capturestream.enabled", true ],
|
||||
];
|
||||
SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest);
|
||||
</script>
|
||||
|
@ -34,19 +34,19 @@ WebGLUtil = (function() {
|
||||
// ---------------------------------------------------------------------------
|
||||
// WebGL helpers
|
||||
|
||||
function getWebGL(canvasId, requireConformant) {
|
||||
function getWebGL(canvasId, requireConformant, attributes) {
|
||||
// `requireConformant` will default to falsey if it is not supplied.
|
||||
|
||||
var canvas = document.getElementById(canvasId);
|
||||
|
||||
var gl = null;
|
||||
try {
|
||||
gl = canvas.getContext('webgl');
|
||||
gl = canvas.getContext('webgl', attributes);
|
||||
} catch(e) {}
|
||||
|
||||
if (!gl && !requireConformant) {
|
||||
try {
|
||||
gl = canvas.getContext('experimental-webgl');
|
||||
gl = canvas.getContext('experimental-webgl', attributes);
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,7 @@ function setupEnvironment() {
|
||||
window.finish = () => SimpleTest.finish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['canvas.capturestream.enabled', true],
|
||||
['dom.messageChannel.enabled', true],
|
||||
['media.peerconnection.enabled', true],
|
||||
['media.peerconnection.identity.enabled', true],
|
||||
|
@ -103,6 +103,10 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g emulator seems to be to
|
||||
skip-if = buildapp == 'b2g' || buildapp == 'mulet' || os == 'android' # bug 1043403 # Bug 1141029 Mulet parity with B2G Desktop for TC
|
||||
[test_peerConnection_capturedVideo.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
[test_peerConnection_captureStream_canvas_2d.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
[test_peerConnection_captureStream_canvas_webgl.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
[test_peerConnection_close.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
[test_peerConnection_errorCallbacks.html]
|
||||
|
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="/tests/dom/canvas/test/captureStream_common.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.8">
|
||||
createHTML({
|
||||
bug: "1032848",
|
||||
title: "Canvas(2D)::CaptureStream as video-only input to peerconnection",
|
||||
visible: true
|
||||
});
|
||||
|
||||
runNetworkTest(() => {
|
||||
var test = new PeerConnectionTest();
|
||||
var vremote;
|
||||
var h = new CaptureStreamTestHelper2D();
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = 'source_canvas';
|
||||
canvas.width = canvas.height = 10;
|
||||
document.getElementById('content').appendChild(canvas);
|
||||
|
||||
test.setMediaConstraints([{video: true}], []);
|
||||
test.chain.replace("PC_LOCAL_GUM", [
|
||||
function DRAW_LOCAL_GREEN(test) {
|
||||
h.drawColor(canvas, h.green);
|
||||
},
|
||||
function PC_LOCAL_CANVAS_CAPTURESTREAM(test) {
|
||||
var stream = canvas.captureStream(10);
|
||||
test.pcLocal.attachMedia(stream, 'video', 'local');
|
||||
}
|
||||
]);
|
||||
test.chain.append([
|
||||
function FIND_REMOTE_VIDEO() {
|
||||
vremote = document.getElementById('pcRemote_remote1_video');
|
||||
ok(!!vremote, "Should have remote video element for pcRemote");
|
||||
},
|
||||
function WAIT_FOR_REMOTE_GREEN() {
|
||||
return h.waitForPixel(vremote, h.green, 128, "pcRemote's remote should become green");
|
||||
},
|
||||
function DRAW_LOCAL_RED() {
|
||||
h.drawColor(canvas, h.red);
|
||||
},
|
||||
function WAIT_FOR_REMOTE_RED() {
|
||||
return h.waitForPixel(vremote, h.red, 128, "pcRemote's remote should become red");
|
||||
}
|
||||
]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,108 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="/tests/dom/canvas/test/captureStream_common.js"></script>
|
||||
<script type="application/javascript" src="/tests/dom/canvas/test/webgl-mochitest/webgl-util.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script id="v-shader" type="x-shader/x-vertex">
|
||||
attribute vec2 aPosition;
|
||||
void main() {
|
||||
gl_Position = vec4(aPosition, 0, 1);
|
||||
}
|
||||
</script>
|
||||
<script id="f-shader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform vec4 uColor;
|
||||
void main() { gl_FragColor = uColor; }
|
||||
</script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
createHTML({
|
||||
bug: "1032848",
|
||||
title: "Canvas(WebGL)::CaptureStream as video-only input to peerconnection"
|
||||
});
|
||||
|
||||
runNetworkTest(() => {
|
||||
var test = new PeerConnectionTest();
|
||||
var vremote;
|
||||
var h = new CaptureStreamTestHelperWebGL();
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = 'source_canvas';
|
||||
canvas.width = canvas.height = 10;
|
||||
document.getElementById('content').appendChild(canvas);
|
||||
|
||||
var gl = WebGLUtil.getWebGL(canvas.id, false, { preserveDrawingBuffer: true });
|
||||
if (!gl) {
|
||||
todo(false, "WebGL unavailable.");
|
||||
networkTestFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
var errorFunc = str => ok(false, 'Error: ' + str);
|
||||
WebGLUtil.setErrorFunc(errorFunc);
|
||||
WebGLUtil.setWarningFunc(errorFunc);
|
||||
|
||||
test.setMediaConstraints([{video: true}], []);
|
||||
test.chain.replace("PC_LOCAL_GUM", [
|
||||
function WEBGL_SETUP(test) {
|
||||
var program = WebGLUtil.createProgramByIds(gl, 'v-shader', 'f-shader');
|
||||
|
||||
if (!program) {
|
||||
ok(false, "Program should link");
|
||||
return Promise.reject();
|
||||
}
|
||||
gl.useProgram(program);
|
||||
|
||||
var uColorLocation = gl.getUniformLocation(program, "uColor");
|
||||
h.setFragmentColorLocation(uColorLocation);
|
||||
|
||||
var squareBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
|
||||
|
||||
var vertices = [ 0, 0,
|
||||
-1, 0,
|
||||
0, 1,
|
||||
-1, 1 ];
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
||||
squareBuffer.itemSize = 2;
|
||||
squareBuffer.numItems = 4;
|
||||
|
||||
program.aPosition = gl.getAttribLocation(program, "aPosition");
|
||||
gl.enableVertexAttribArray(program.aPosition);
|
||||
gl.vertexAttribPointer(program.aPosition, squareBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
},
|
||||
function DRAW_LOCAL_GREEN(test) {
|
||||
h.drawColor(canvas, h.green);
|
||||
},
|
||||
function PC_LOCAL_CANVAS_CAPTURESTREAM(test) {
|
||||
test.pcLocal.canvasStream = canvas.captureStream(0.0);
|
||||
is(test.pcLocal.canvasStream.canvas, canvas, "Canvas attribute is correct");
|
||||
test.pcLocal.attachMedia(test.pcLocal.canvasStream, 'video', 'local');
|
||||
}
|
||||
]);
|
||||
test.chain.append([
|
||||
function FIND_REMOTE_VIDEO() {
|
||||
vremote = document.getElementById('pcRemote_remote1_video');
|
||||
ok(!!vremote, "Should have remote video element for pcRemote");
|
||||
},
|
||||
function WAIT_FOR_REMOTE_GREEN() {
|
||||
return h.waitForPixel(vremote, h.green, 128, "pcRemote's remote should become green");
|
||||
},
|
||||
function DRAW_LOCAL_RED() {
|
||||
h.drawColor(canvas, h.red);
|
||||
},
|
||||
function REQUEST_FRAME(test) {
|
||||
test.pcLocal.canvasStream.requestFrame();
|
||||
},
|
||||
function WAIT_FOR_REMOTE_RED() {
|
||||
return h.waitForPixel(vremote, h.red, 128, "pcRemote's remote should become red");
|
||||
}
|
||||
]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user