5 <title>WebGL in OffscreenCanvas
</title>
6 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
7 <link rel=
"stylesheet" href=
"/tests/SimpleTest/test.css">
10 <canvas id=
"c1" width=
"64" height=
"64"></canvas>
11 <canvas id=
"c2" width=
"64" height=
"64"></canvas>
12 <canvas id=
"c_ref" width=
"64" height=
"64"></canvas>
15 function testWorker(onFinished
) {
16 var worker
= new Worker("offscreencanvas.js");
18 ok(worker
, "Web worker successfully created");
20 worker
.onmessage = function(evt
) {
21 var msg
= evt
.data
|| {};
22 //console.log('onmessage', {evt}, msg.type, msg.result, msg.name);
23 if (msg
.type
== "test") {
24 ok(msg
.result
, msg
.name
);
26 if (msg
.type
== "imagebitmap") {
28 // Fill c_ref with green color.
29 var ctx
= c_ref
.getContext("2d");
30 ctx
.rect(0, 0, 64, 64);
31 ctx
.fillStyle
= "#00FF00";
34 var bitmapRenderer
= c1
.getContext("bitmaprenderer");
35 bitmapRenderer
.transferFromImageBitmap(msg
.bitmap
);
37 ok(c1
.toDataURL() == c_ref
.toDataURL(),
38 "c1.toDataURL MUST return a 64x64 green square");
40 // The ownership of msg.bitmap should be transferred to canvas c1 when
41 // we called transferFromImageBitmap, marking msg.bitmap as "detached".
42 // Ensure that transferFromImageBitmap again should throw.
43 var bitmapRenderer
= c2
.getContext("bitmaprenderer");
47 bitmapRenderer
.transferFromImageBitmap(msg
.bitmap
)
51 ok(didThrow
, 'transferFromImageBitmap(detached) must throw');
52 ok(c1
.toDataURL() == c_ref
.toDataURL(),
53 "c2.toDataURL MUST NOT return a 64x64 green square");
60 worker
.postMessage({test
: 'webgl_imagebitmap'});
63 function expectEq(name
, expected
, was
, when
) {
64 let msg
= `${name} was ${was}`;
66 msg
= `[${when}] ` + msg
;
68 let eq
= (was
== expected
);
70 if (typeof(expected
) == 'number') {
71 eq
= (Math
.abs(was
- expected
) < 0.000001);
75 msg
= msg
+ `, expected ${expected}`;
79 function expectMemberEq(obj
, key
, expected
, when
) {
81 expectEq(`${obj}.${key}`, expected
, was
, when
);
83 function expectEachMemberEq(obj
, expectedByKeyMap
, when
) {
84 for (const [key
,expected
] of Object
.entries(expectedByKeyMap
)) {
85 expectMemberEq(obj
, key
, expected
, when
);
94 function invoke(fn
) { return fn(); }
97 SimpleTest
.waitForExplicitFinish();
99 await
new Promise(go
=>
100 SpecialPowers
.pushPrefEnv({'set': [
101 ['webgl.force-enabled', true],
104 console
.log('await testWorker...');
105 await
new Promise(go
=> testWorker(go
));
109 const [W
, H
] = [5, 7];
111 note('Begin canvas2d transferToImageBitmap tests...');
113 const oc
= new OffscreenCanvas(W
, H
);
114 const c2d
= oc
.getContext('2d');
116 c2d
.fillStyle
= '#00ff00';
117 c2d
.fillRect(0, 0, W
, H
);
119 const idata
= c2d
.getImageData(0, 0, W
, H
);
120 expectEq('getImageData.data.slice(0, 4)', '[0,255,0,255]',
121 `[${idata.data.slice(0,4).join(',')}]`, 'after fillRect');
126 const NON_DEFAULT_STATE_2D
= {
128 fillStyle
: '#aaaaaa',
132 globalCompositeOperation
: 'xor',
133 imageSmoothingEnabled
: false,
134 imageSmoothingQuality
: 'high',
141 shadowColor
: '#bbbbbb',
144 strokeStyle
: '#cccccc',
146 textBaseline
: 'middle',
148 Object
.assign(c2d
, NON_DEFAULT_STATE_2D
);
149 expectEachMemberEq(c2d
, NON_DEFAULT_STATE_2D
, 'before transferToImageBitmap');
151 const beforeTtibData
= c2d
.getImageData(0, 0, W
, H
);
152 const ib
= oc
.transferToImageBitmap();
153 const afterTtibData
= c2d
.getImageData(0, 0, W
, H
);
155 // Same state afterwards
156 expectEachMemberEq(oc
, {width
: W
, height
: H
}, 'after transferToImageBitmap');
157 expectEachMemberEq(c2d
, NON_DEFAULT_STATE_2D
, 'after transferToImageBitmap');
158 // But bitmap cleared afterwards
159 let was
= `[${afterTtibData.data.slice(0, 4).join(',')}]`;
160 expectEq('getImageData.data.slice(0, 4)', '[0,0,0,0]', was
, 'after transferToImageBitmap');
163 note('Begin webgl transferToImageBitmap tests...');
165 const oc
= new OffscreenCanvas(W
, H
);
166 const gl
= oc
.getContext('webgl', {preserveDrawingBuffer
:true});
168 gl
.clearColor(0, 1, 0, 1);
169 gl
.clear(gl
.COLOR_BUFFER_BIT
);
170 const p
= new Uint8Array(4);
171 gl
.readPixels(0,0,1,1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, p
);
172 expectEq('gl.readPixels(0,0,1,1)', '[0,255,0,255]',
173 `[${p.slice(0,4).join(',')}]`, 'after gl.clear');
177 const buf
= gl
.createBuffer();
178 gl
.bindBuffer(gl
.ARRAY_BUFFER
, buf
);
179 expectEq(`ARRAY_BUFFER_BINDING`, buf
,
180 gl
.getParameter(gl
.ARRAY_BUFFER_BINDING
), 'before transferToImageBitmap');
182 const ib
= oc
.transferToImageBitmap();
184 // Same state afterwards
185 expectEachMemberEq(oc
, {width
: W
, height
: H
}, 'after transferToImageBitmap');
186 expectEq(`ARRAY_BUFFER_BINDING`, buf
,
187 gl
.getParameter(gl
.ARRAY_BUFFER_BINDING
), 'after transferToImageBitmap');
188 // But bitmap cleared afterwards
189 gl
.readPixels(0,0,1,1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, p
);
190 expectEq('gl.readPixels(0,0,1,1)', '[0,0,0,0]',
191 `[${p.slice(0,4).join(',')}]`, 'after transferToImageBitmap');
194 note('Tests complete.');