npot-video-sizing.html (5864B)
1 <!-- 2 Copyright (c) 2019 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 <!DOCTYPE html> 7 <html> 8 <head> 9 <meta charset="utf-8"> 10 <link rel="stylesheet" href="../../../resources/js-test-style.css"/> 11 <script src="../../../js/js-test-pre.js"></script> 12 <script src="../../../js/webgl-test-utils.js"></script> 13 <script> 14 "use strict"; 15 var wtu = WebGLTestUtils; 16 var gl = null; 17 var textureLoc = null; 18 var expectedVideoHeightLoc = null; 19 var successfullyParsed = false; 20 var resourcePath = "../../../resources/"; 21 // Test each format separately because many browsers implement each 22 // differently. Some might be GPU accelerated, some might not. Etc... 23 var videos = [ 24 { src: resourcePath + "npot-video-1920x1080.mp4" , 25 type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', 26 // It was found that Firefox's videoHeight doesn't report the 27 // correct answer for this video resource, though the uploaded 28 // video texture is the correct size. 29 expectedHeight: 1080, 30 }, 31 // Should port this to other formats. See tex-image-and-sub-image-2d-with-video.js. 32 ]; 33 var videoNdx = 0; 34 var videoInfo; 35 var video; 36 37 initTestingHarness(); 38 39 var vertexShader = [ 40 '#version 300 es', 41 'in vec4 vPosition;', 42 'in vec2 texCoord0;', 43 'out vec2 texCoord;', 44 'void main() {', 45 ' gl_Position = vPosition;', 46 ' texCoord = texCoord0;', 47 '}'].join('\n'); 48 49 // ESSL 3.00 and WebGL 2.0 are used in order to gain access to the 50 // "textureSize" built-in function. This was the most reliable way to 51 // verify the behavior of video-to-texture uploads. 52 53 var fragmentShader = [ 54 '#version 300 es', 55 'precision mediump float;', 56 'uniform mediump sampler2D tex;', 57 'uniform int expectedVideoHeight;', 58 'in vec2 texCoord;', 59 'out vec4 fragData;', 60 'void main() {', 61 ' if (textureSize(tex, 0).y == expectedVideoHeight) {', 62 ' fragData = vec4(0.0, 1.0, 0.0, 1.0);', 63 ' } else {', 64 ' fragData = vec4(1.0, 0.0, 0.0, 1.0);', 65 ' }', 66 '}'].join('\n'); 67 68 function init() 69 { 70 description('Verify sizing of npot videos uploaded to textures'); 71 72 debug('Verifies that the size of a texture, uploaded from a video, is exactly the expected size of the video.'); 73 debug('Regression test for <a href="http://crbug.com/672895">http://crbug.com/672895</a>'); 74 75 var canvas = document.getElementById("example"); 76 gl = wtu.create3DContext(canvas, { preserveDrawingBuffer: true }, 2); 77 wtu.setupUnitQuad(gl); 78 var program = wtu.setupProgram( 79 gl, 80 [vertexShader, fragmentShader], 81 ['vPosition', 'texCoord0'], 82 [0, 1]); 83 84 if (!program) { 85 testFailed("Error creating program"); 86 return; 87 } 88 89 gl.clearColor(0,0,0,1); 90 gl.clearDepth(1); 91 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 92 // Disable any writes to the alpha channel 93 gl.colorMask(1, 1, 1, 0); 94 95 textureLoc = gl.getUniformLocation(program, "tex"); 96 expectedVideoHeightLoc = gl.getUniformLocation( 97 program, "expectedVideoHeight"); 98 99 requestAnimationFrame(runNextVideo); 100 } 101 102 function runNextVideo() { 103 if (video) { 104 video.pause(); 105 } 106 107 if (videoNdx == videos.length) { 108 finishTest(); 109 return; 110 } 111 112 videoInfo = videos[videoNdx++]; 113 debug(""); 114 debug("testing: " + videoInfo.type); 115 video = document.createElement("video"); 116 video.muted = true; 117 var canPlay = true; 118 if (!video.canPlayType) { 119 testFailed("video.canPlayType required method missing"); 120 requestAnimationFrame(runNextVideo); 121 return; 122 } 123 124 if (!video.canPlayType(videoInfo.type).replace(/no/, '')) { 125 debug(videoInfo.type + " unsupported"); 126 requestAnimationFrame(runNextVideo); 127 return; 128 }; 129 130 document.body.appendChild(video); 131 video.style = "display:none;"; 132 video.type = videoInfo.type; 133 video.src = videoInfo.src; 134 wtu.startPlayingAndWaitForVideo(video, runTest); 135 } 136 137 function runTest() 138 { 139 var texture = gl.createTexture(); 140 // Bind the texture to texture unit 0 141 gl.bindTexture(gl.TEXTURE_2D, texture); 142 // Set up texture parameters 143 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 144 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 145 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 146 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 147 // Set up pixel store parameters 148 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 149 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); 150 // Upload the video element into the texture 151 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, video); 152 // Point the uniform sampler to texture unit 0 153 gl.uniform1i(textureLoc, 0); 154 // Set up the expected video size 155 debug('video\'s expected height: ' + videoInfo.expectedHeight); 156 debug('video\'s reported width and height: ' + video.videoWidth + ' x ' + video.videoHeight); 157 // We only verify the height. Chrome was generating the wrong 158 // height for some video resources. As it stands, not all browsers 159 // match the video's width exactly. 160 gl.uniform1i(expectedVideoHeightLoc, videoInfo.expectedHeight); 161 162 // Draw the triangles 163 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 164 165 // Verify that the video texture's size was as expected 166 wtu.checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, 167 [0, 255, 0, 255], 168 "Should be green -- that indicates the video texture's height was correct", 169 1); 170 171 requestAnimationFrame(runNextVideo); 172 } 173 174 </script> 175 </head> 176 <body onload="init()"> 177 <canvas id="example" width="32" height="32"></canvas> 178 <div id="description"></div> 179 <div id="console"></div> 180 </body> 181 </html>