blob: 098af74136932b95af4b61b8caa2ecaed683d3fb [file] [log] [blame]
/*
* Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
* for details. All rights reserved. Use of this source code is governed by a
* BSD-style license that can be found in the LICENSE file.
*/
/**
* @description This test ensures WebGL implementations interact correctly with
* the canvas tag.
*/
import "dart:html";
import "dart:web_gl" as wgl;
import 'dart:typed_data';
import "../../../testcommon.dart";
import "resources/webgl-test.dart";
import "resources/webgl-test-utils.dart" as wtu;
import "../../../../Utils/async_utils.dart";
runAfterDisplay(callback) {
window.requestAnimationFrame((_) {
// At this point, only the animate has happened, but no compositing
// or layout. Use a timeout for the callback so that notifyDone
// can be called inside of it.
setTimeout(callback, 0);
});
}
main() {
document.body.setInnerHtml('''
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<canvas id="canvas2d" width="40" height="40"> </canvas>
''', treeSanitizer: new NullTreeSanitizer());
debug("Canvas.getContext");
var canvas = document.getElementById("canvas");
var canvas2d = document.getElementById("canvas2d");
var ctx2d = canvas2d.getContext("2d");
var gl = create3DContext(canvas);
if (gl == null) {
testFailed("context does not exist");
} else {
testPassed("context exists");
debug("Checking canvas and WebGL interaction");
// Check that a canvas with no width or height is 300x150 pixels
shouldBe(canvas.width, 300);
shouldBe(canvas.height, 150);
// Check get a 4 value gl parameter as a csv string.
getValue4v(name) {
var v = gl.getParameter(name);
return v.join(',');
}
getViewport() {
return getValue4v(wgl.VIEWPORT);
}
getClearColor() {
return getValue4v(wgl.COLOR_CLEAR_VALUE);
}
isAboutEqual(a, b) {
return (a - b).abs() < 0.01;
}
isAboutEqualInt(a, b) {
return (a - b).abs() < 3;
}
checkCanvasContentIs(r3d,g3d,b3d,a3d) {
var r2d;
var g2d;
var b2d;
var a2d;
var imgData;
checkPixel(x, y, r3d,g3d,b3d,a3d) {
var offset = (y * 40 + x) * 4;
r2d = imgData.data[offset];
g2d = imgData.data[offset + 1];
b2d = imgData.data[offset + 2];
a2d = imgData.data[offset + 3];
//debug('$x,$y($offset) = $r2d,$g2d,$b2d,$a2d');
return isAboutEqualInt(r2d, r3d) &&
isAboutEqualInt(g2d, g3d) &&
isAboutEqualInt(b2d, b3d) &&
isAboutEqualInt(a2d, a3d);
}
checkPixels(r3d,g3d,b3d,a3d) {
return checkPixel(0, 0, r3d, g3d, b3d, a3d) &&
checkPixel(0, 39, r3d, g3d, b3d, a3d) &&
checkPixel(39, 0, r3d, g3d, b3d, a3d) &&
checkPixel(39, 39, r3d, g3d, b3d, a3d) &&
checkPixel(0, 0, r3d, g3d, b3d, a3d);
};
// Set to just take the color from the 3d canvas
ctx2d.globalCompositeOperation = 'copy';
// fill 2d canvas with orange
ctx2d.fillStyle = "rgb(255,192,128)";
ctx2d.fillRect (0, 0, 40, 40);
// get the image data
imgData = ctx2d.getImageData(0, 0, 40, 40);
// check it got cleared.
if (!checkPixels(255, 192, 128, 255)) {
testFailed("unable to fill 2d context.");
return;
}
// draw 3d canvas on top.
ctx2d.drawImageScaled(canvas, 0,0, 40, 40);
// get the image data
imgData = ctx2d.getImageData(0, 0, 40, 40);
// Check it's the expected color.
if (!checkPixels(r3d, g3d, b3d, a3d)) {
testFailed("pixels are $r2d,$g2d,$b2d,$a2d expected $r3d,$g3d,$b3d,$a3d");
} else {
testPassed("pixels are $r3d,$g3d,$b3d,$a3d");
}
}
checkCanvasContentIs(0, 0, 0, 0);
shouldBe(getViewport(), "0,0,300,150");
// Change the display size of the canvas and check
// the viewport size does not change.
debug("change display size of canvas and see that viewport does not change");
canvas.style.width = "100px";
canvas.style.height = "25px";
asyncStart();
runAfterDisplay(() {
if (canvas.clientWidth == 100 &&
canvas.clientHeight == 25) {
shouldBe(getViewport(), "0,0,300,150");
shouldBe(canvas.width, 300);
shouldBe(canvas.height, 150);
// Change the actual size of the canvas
// Check that the viewport does not change.
// Check that the clear color does not change.
// Check that the color mask does not change.
debug("change the actual size of the canvas and see that the viewport does not change");
gl.clearColor(0.25, 0.5, 0.75, 1);
gl.clear(wgl.COLOR_BUFFER_BIT | wgl.DEPTH_BUFFER_BIT);
checkCanvasContentIs(64, 128, 192, 255);
gl.colorMask(false, false, false, false);
canvas.width = 400;
canvas.height = 10;
var v = gl.getParameter(wgl.COLOR_CLEAR_VALUE);
assertMsg(isAboutEqual(v[0], 0.25) &&
isAboutEqual(v[1], 0.5) &&
isAboutEqual(v[2], 0.75) &&
isAboutEqual(v[3], 1),
"gl.clearColor should not change after canvas resize");
v = gl.getParameter(wgl.COLOR_WRITEMASK);
assertMsg(v[0] == false &&
v[1] == false &&
v[2] == false &&
v[3] == false,
"gl.colorMask should not change after canvas resize");
shouldBe(getViewport(), "0,0,300,150");
checkCanvasContentIs(0, 0, 0, 0);
asyncEnd();
}
});
}
}