| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
| <title>WebGL Canvas Conformance Tests</title> |
| <script src="resources/desktop-gl-constants.js" type="text/javascript"></script> |
| <script src="../../../resources/js-test.js"></script> |
| <script src="resources/webgl-test.js"></script> |
| </head> |
| <body> |
| <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> |
| <script> |
| if (window.initNonKhronosFramework) { |
| window.initNonKhronosFramework(true); |
| } |
| |
| description("This test ensures WebGL implementations interact correctly with the canvas tag."); |
| |
| debug(""); |
| debug("Canvas.getContext"); |
| |
| var canvas = document.getElementById("canvas"); |
| var canvas2d = document.getElementById("canvas2d"); |
| var ctx2d = canvas2d.getContext("2d"); |
| var gl = create3DContext(canvas); |
| if (!gl) { |
| testFailed("context does not exist"); |
| } else { |
| testPassed("context exists"); |
| |
| debug(""); |
| 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. |
| function getValue4v(name) { |
| var v = gl.getParameter(name); |
| var result = '' + |
| v[0] + ',' + |
| v[1] + ',' + |
| v[2] + ',' + |
| v[3]; |
| return result; |
| } |
| |
| function getViewport() { |
| return getValue4v(gl.VIEWPORT); |
| } |
| |
| function getClearColor() { |
| return getValue4v(gl.COLOR_CLEAR_VALUE); |
| } |
| |
| function isAboutEqual(a, b) { |
| return Math.abs(a - b) < 0.01; |
| } |
| |
| function isAboutEqualInt(a, b) { |
| return Math.abs(a - b) < 3; |
| } |
| |
| function checkCanvasContentIs(r3d,g3d,b3d,a3d) { |
| var r2d; |
| var g2d; |
| var b2d; |
| var a2d; |
| |
| function 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); |
| } |
| |
| function 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 |
| var 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.drawImage(canvas, 0,0, 40, 40); |
| |
| // get the image data |
| var 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(""); |
| debug("change display size of canvas and see that viewport does not change"); |
| canvas.style.width = "100px"; |
| canvas.style.height = "25px"; |
| var intervalId; |
| intervalId = window.setInterval(function() { |
| if (window.testRunner) |
| testRunner.displayAndTrackRepaints(); |
| if (canvas.clientWidth == 100 && |
| canvas.clientHeight == 25) { |
| window.clearInterval(intervalId); |
| 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(""); |
| 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(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| checkCanvasContentIs(64, 128, 192, 255); |
| gl.colorMask(0,0,0,0); |
| canvas.width = 400; |
| canvas.height = 10; |
| |
| var v = gl.getParameter(gl.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(gl.COLOR_WRITEMASK); |
| assertMsg(isAboutEqual(v[0], 0) && |
| isAboutEqual(v[1], 0) && |
| isAboutEqual(v[2], 0) && |
| isAboutEqual(v[3], 0), |
| "gl.colorMask should not change after canvas resize"); |
| shouldBe('getViewport()', '"0,0,300,150"'); |
| checkCanvasContentIs(0, 0, 0, 0); |
| |
| debug(""); |
| var epilogue = document.createElement("script"); |
| epilogue.onload = finish; |
| epilogue.src = "../../../resources/js-test-post.js"; |
| document.body.appendChild(epilogue); |
| } |
| }, 1000/30); |
| } |
| |
| function finish() { |
| if (window.nonKhronosFrameworkNotifyDone) { |
| window.nonKhronosFrameworkNotifyDone(); |
| } |
| } |
| |
| </script> |
| </body> |
| </html> |