Bug 1918529 - fix some subpixel misalignment issues with gfx.webrender.svg-filter...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance / textures / misc / texture-srgb-upload.html
blob6f66bfdde65b73e5213b2a373d578734d9e45a54
1 <!--
2 Copyright (c) 2022 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 <title>Upload texture from video into srgb internalformats</title>
11 <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
12 <script src="../../../js/js-test-pre.js"></script>
13 <script src="../../../js/webgl-test-utils.js"></script>
14 </head>
15 <body>
16 <div id="description"></div>
17 <div id="console"></div>
18 <div>
19 Video:
20 <canvas id="e_rgba" width="300" height="200"></canvas>
21 0x7f: <canvas id="e_rgba_color" width="30" height="200"></canvas>
22 <div>GL.RGBA</div>
23 </div>
24 <hr>
25 <div>
26 Video:
27 <canvas id="e_srgb8" width="300" height="200"></canvas>
28 0x7f: <canvas id="e_srgb8_color" width="30" height="200"></canvas>
29 <div>GL.SRGB8</div>
30 </div>
31 <hr>
32 <div>
33 Video:
34 <canvas id="e_srgb8_alpha8" width="300" height="200"></canvas>
35 0x7f: <canvas id="e_srgb8_alpha8_color" width="30" height="200"></canvas>
36 <div>GL.SRGB8_ALPHA8</div>
37 </div>
38 <script>
39 "use strict";
40 const wtu = WebGLTestUtils;
41 description();
43 const DATA_URL_FOR_720p_png_bt709_bt709_tv_yuv420p_vp9_webm = '\
44 data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEA\
45 AAAAAAMBEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHGTbuMU6uEElTDZ1OsggElTbuMU6u\
46 EHFO7a1OsggLr7AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
47 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmoCrXsYMPQ\
48 kBNgIRMYXZmV0GETGF2ZkSJiEBEAAAAAAAAFlSua9quAQAAAAAAAFHXgQFzxYgAAAAAAAAAAZyBACK1\
49 nIN1bmSGhVZfVlA5g4EBI+ODhAJiWgDgAQAAAAAAAB6wggUAuoIC0JqBAlWwkFW6gQFVsYEBVbuBAVW\
50 5gQESVMNn43NzAQAAAAAAAFljwItjxYgAAAAAAAAAAWfIAQAAAAAAABxFo4dFTkNPREVSRIePTGF2Yy\
51 BsaWJ2cHgtdnA5Z8iiRaOIRFVSQVRJT05Eh5QwMDowMDowMC4wNDAwMDAwMDAAAB9DtnVBWOeBAKNBU\
52 oEAAICCSYNCQE/wLPYAOCQcGAAYAFB/N9H/HZUjnnscu9GvIJt3936AAAAAACh4E4g/fJ8GmILlgmQ6\
53 iUMwWlrCvdZpJAjY24ONeWCZEIrug5k4YTeAAAAAaXgTiD98nwaYguWCZDq6Zy9PLtRqFgTRRWpDzEC\
54 RrKr8wtgzCibnQJwWtOOaHH9ZRjl4+aOQHHoHk/YUdplRSYiwuJO6LIyUXumq92uzm/wLAqBN0N9kRR\
55 evcxyTv6VcsFqLJ5W5INE4AAAAAGN4E3vgaWsaGceNeWlTmlA/W7BnrSNUEx9X/o/hlK8PPDCgN5Kpw\
56 0gRJkKtiMQMtYO7DQAUWLnf3+GjIUUj4hiAGdY+FNLJIdswhZLCeSDQfqV1btKL/ns57OfXQc0R3HFz\
57 YyB4E3vgaWsaGceNeWjppQzBaWtIcWVNbYO5ARh7kHkq6WBosnlbkfoAHFO7a5G7j7OBALeK94EB8YI\
58 BjfCBAw==';
60 function invoke(fn) { return fn(); }
62 invoke(async () => {
63 const video = document.createElement("video");
64 video.src = DATA_URL_FOR_720p_png_bt709_bt709_tv_yuv420p_vp9_webm;
65 if (!video.canPlayType('video/webm')) {
66 debug('Browser can not play webm videos. Skipping test.');
67 finishTest();
68 return;
71 video.muted = true;
72 video.loop = true;
73 video.crossOrigin = "anonymous";
74 try {
75 await video.play();
76 } catch (e) {
77 debug('Browser could not play this specific video. Skipping test.');
78 finishTest();
79 return;
82 function renderTex(canvas, fn_tex_image) {
83 const gl = canvas.gl = wtu.create3DContext(canvas);
85 const vs = `
86 attribute float a_VertexID;
87 varying vec2 v_uv;
88 void main() {
89 float id = a_VertexID;
90 v_uv.x = mod(id, 2.0);
91 id -= v_uv.x;
92 id /= 2.0;
93 v_uv.y = mod(id, 2.0);
94 gl_Position = vec4(2.0 * v_uv - 1.0, 0, 1);
95 }`;
97 const fs = `
98 precision mediump float;
99 uniform sampler2D tex;
100 varying vec2 v_uv;
101 void main() {
102 gl_FragColor = texture2D(tex, v_uv);
105 const program = gl.createProgram();
106 let shader = gl.createShader(gl.VERTEX_SHADER);
107 gl.shaderSource(shader, vs);
108 gl.compileShader(shader);
109 gl.attachShader(program, shader);
110 shader = gl.createShader(gl.FRAGMENT_SHADER);
111 gl.shaderSource(shader, fs);
112 gl.compileShader(shader);
113 gl.attachShader(program, shader);
114 gl.bindAttribLocation(program, 0, 'a_VertexID');
115 gl.linkProgram(program);
116 gl.useProgram(program);
117 if (gl.getError()) throw 'Error during linking';
119 const vbuf = gl.createBuffer();
120 gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
121 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,1,2,3]), gl.STATIC_DRAW);
122 gl.enableVertexAttribArray(0);
123 gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
125 const texture = gl.createTexture();
126 gl.bindTexture(gl.TEXTURE_2D, texture);
127 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
128 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
129 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
131 const draw = function() {
132 //requestAnimationFrame(draw);
133 fn_tex_image(gl);
134 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
136 draw();
138 if (gl.getError()) throw 'Error during drawing';
141 const GL = WebGL2RenderingContext;
142 const COLOR_DATA = new Uint8Array([127, 127, 127, 255]);
144 function internalformat_webgl1or2(gl, internalformat_name) {
145 let internalformat = gl[internalformat_name];
146 if (!internalformat) {
147 const ext = gl.getExtension('EXT_srgb');
148 if (!ext) {
149 testPassed('EXT_srgb not supported. (ok!)');
150 return;
152 switch (internalformat_name) {
153 case 'SRGB8':
154 internalformat = ext.SRGB_EXT;
155 break;
156 case 'SRGB8_ALPHA8':
157 internalformat = ext.SRGB_ALPHA_EXT;
158 break;
159 default:
160 throw internalformat_name;
163 return internalformat;
166 function begin(e_video, e_color, internalformat_name, unpackformat) {
167 renderTex(e_video, gl => {
168 const internalformat = internalformat_webgl1or2(gl, internalformat_name);
169 if (!gl.SRGB8) {
170 unpackformat = internalformat; // Must match in webgl1.
172 gl.texImage2D(GL.TEXTURE_2D, 0, internalformat,
173 unpackformat, GL.UNSIGNED_BYTE, video);
175 renderTex(e_color, gl => {
176 const internalformat = internalformat_webgl1or2(gl, internalformat_name);
177 if (!gl.SRGB8) {
178 unpackformat = internalformat; // Must match in webgl1.
180 gl.texImage2D(GL.TEXTURE_2D, 0, internalformat, 1, 1, 0,
181 unpackformat, GL.UNSIGNED_BYTE, COLOR_DATA);
185 begin(e_rgba, e_rgba_color, 'RGBA', GL.RGBA);
186 begin(e_srgb8, e_srgb8_color, 'SRGB8', GL.RGB);
187 begin(e_srgb8_alpha8, e_srgb8_alpha8_color, 'SRGB8_ALPHA8', GL.RGBA);
189 // -
191 const GREY50_COLOR_COORD = {
192 x: 0,
193 y: 0,
195 const GREY50_TEX_COORD = {
196 x: e_rgba.width/2 + 1,
197 y: e_rgba.height/2 + 1,
199 const fn_test = (canvas, coord, data) => {
200 wtu.checkCanvasRect(canvas.gl, coord.x, coord.y, 1, 1, data,
201 `${canvas.id} @${JSON.stringify(coord)}`);
204 debug('');
205 debug('e_rgba');
206 fn_test(e_rgba_color, GREY50_COLOR_COORD, [0x7f, 0x7f, 0x7f, 0xff]);
207 fn_test(e_rgba, GREY50_TEX_COORD, [0x7f, 0x7f, 0x7f, 0xff]);
209 debug('');
210 debug('e_srgb8');
211 fn_test(e_srgb8_color, GREY50_COLOR_COORD, [0x36, 0x36, 0x36, 0xff]);
212 fn_test(e_srgb8, GREY50_TEX_COORD, [0x36, 0x36, 0x36, 0xff]);
214 debug('');
215 debug('e_srgb8_alpha8');
216 fn_test(e_srgb8_alpha8_color, GREY50_COLOR_COORD, [0x36, 0x36, 0x36, 0xff]);
217 fn_test(e_srgb8_alpha8, GREY50_TEX_COORD, [0x36, 0x36, 0x36, 0xff]);
219 finishTest();
223 async function blobToDataURL(blob) {
224 const fr = new FileReader();
225 return await new Promise((yes, no) => {
226 fr.addEventListener('loadend', ev => {
227 if (fr.result) {
228 return yes(fr.result);
230 return no(fr.error);
232 fr.readAsDataURL(blob);
236 async function fetchDataUrl(url, wrapAt) {
237 const r = await fetch(url);
238 const b = await r.blob();
239 const durl = await blobToDataURL(b);
240 return durl;
243 function wrapLines(str, wrapAt) {
244 const lines = [];
245 let remaining = str;
246 while (remaining) {
247 lines.push(remaining.slice(0, wrapAt));
248 remaining = remaining.slice(wrapAt);
250 return lines;
253 (async () => {
254 const url = '720p.png.bt709.bt709.tv.yuv420p.vp9.webm';
255 const ident = 'DATA_URL_FOR_' + url.replaceAll('.', '_');
256 const durl = await fetchDataUrl(url);
257 const lines = wrapLines(durl, 79);
258 console.log(ident, '= \'\\\n' + lines.join('\\\n') + '\';');
259 })();
261 </script>
262 </body>
263 </html>