4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=utf-8">
5 <title>WebGL Uninitialized GL Resources Tests
</title>
6 <script src=
"../../../resources/js-test.js"></script>
7 <script src=
"resources/webgl-test.js"></script>
10 <div id=
"description"></div>
11 <div id=
"console"></div>
12 <canvas id=
"canvas" width=
"2" height=
"2"> </canvas>
14 description("Tests to check user code cannot access uninitialized data from GL resources.");
16 var canvas
= document
.getElementById("canvas");
17 var gl
= create3DContext(canvas
);
19 testFailed("Context created.");
21 testPassed("Context created.");
23 function setupTexture(texWidth
, texHeight
) {
24 var texture
= gl
.createTexture();
25 gl
.bindTexture(gl
.TEXTURE_2D
, texture
);
26 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, texWidth
, texHeight
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
28 // this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
29 // into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
30 // with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
32 var badData
= new Uint8Array(texWidth
* texHeight
* 4);
33 for (var i
= 0; i
< badData
.length
; ++i
)
36 gl
.texSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, texWidth
, texHeight
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, badData
);
37 gl
.finish(); // make sure it has been uploaded
39 gl
.deleteTexture(texture
);
40 gl
.finish(); // make sure it has been deleted
42 var texture
= gl
.createTexture();
43 gl
.bindTexture(gl
.TEXTURE_2D
, texture
);
47 function checkNonZeroPixels(texture
, texWidth
, texHeight
, skipX
, skipY
, skipWidth
, skipHeight
, skipR
, skipG
, skipB
, skipA
) {
48 gl
.bindTexture(gl
.TEXTURE_2D
, null);
49 var fb
= gl
.createFramebuffer();
50 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fb
);
51 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, texture
, 0);
52 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
54 var data
= new Uint8Array(texWidth
* texHeight
* 4);
55 gl
.readPixels(0, 0, texWidth
, texHeight
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, data
);
58 for (var y
= 0; y
< texHeight
; ++y
) {
59 for (var x
= 0; x
< texWidth
; ++x
) {
60 var index
= (y
* texWidth
+ x
) * 4;
61 if (x
>= skipX
&& x
< skipX
+ skipWidth
&& y
>= skipY
&& y
< skipY
+ skipHeight
) {
62 if (data
[index
] != skipR
|| data
[index
+ 1] != skipG
|| data
[index
+ 2] != skipB
|| data
[index
+ 3] != skipA
) {
63 testFailed("non-zero pixel values are wrong");
67 for (var i
= 0; i
< 4; ++i
) {
68 if (data
[index
+ i
] != 0)
75 testFailed("Found " + k
+ " non-zero bytes");
77 testPassed("All data initialized");
85 debug("Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0.");
87 var tex
= setupTexture(width
, height
);
88 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, width
, height
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
89 checkNonZeroPixels(tex
, width
, height
, 0, 0, 0, 0, 0, 0, 0, 0);
90 gl
.deleteTexture(tex
);
92 glErrorShouldBe(gl
, gl
.NO_ERROR
);
95 debug("Reading an uninitialized portion of a texture (copyTexImage2D) should succeed with all bytes set to 0.");
97 var tex
= setupTexture(width
, height
);
98 var fbo
= gl
.createFramebuffer();
99 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
100 var rbo
= gl
.createRenderbuffer();
101 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
104 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.RGBA4
, fboWidth
, fboHeight
);
105 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rbo
);
106 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
107 gl
.clearColor(1.0, 0.0, 0.0, 1.0);
108 gl
.clear(gl
.COLOR_BUFFER_BIT
);
109 glErrorShouldBe(gl
, gl
.NO_ERROR
);
110 gl
.copyTexImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, 0, 0, width
, height
, 0);
111 checkNonZeroPixels(tex
, width
, height
, 0, 0, fboWidth
, fboHeight
, 255, 0, 0, 255);
112 gl
.deleteTexture(tex
);
114 glErrorShouldBe(gl
, gl
.NO_ERROR
);
117 debug("Reading an uninitialized portion of a texture (copyTexImage2D with negative x and y) should succeed with all bytes set to 0.");
119 var tex
= setupTexture(width
, height
);
120 var fbo
= gl
.createFramebuffer();
121 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
122 var rbo
= gl
.createRenderbuffer();
123 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
126 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.RGBA4
, fboWidth
, fboHeight
);
127 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rbo
);
128 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
129 gl
.clearColor(1.0, 0.0, 0.0, 1.0);
130 gl
.clear(gl
.COLOR_BUFFER_BIT
);
131 glErrorShouldBe(gl
, gl
.NO_ERROR
);
134 gl
.copyTexImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, x
, y
, width
, height
, 0);
135 checkNonZeroPixels(tex
, width
, height
, -x
, -y
, fboWidth
, fboHeight
, 255, 0, 0, 255);
136 gl
.deleteTexture(tex
);
138 glErrorShouldBe(gl
, gl
.NO_ERROR
);
141 debug("Reading an uninitialized portion of a texture (copyTexImage2D from WebGL internal fbo) should succeed with all bytes set to 0.");
143 var tex
= setupTexture(width
, height
);
144 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
145 gl
.clearColor(0.0, 1.0, 0.0, 0.0);
146 gl
.clear(gl
.COLOR_BUFFER_BIT
);
147 glErrorShouldBe(gl
, gl
.NO_ERROR
);
148 gl
.copyTexImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, 0, 0, width
, height
, 0);
149 checkNonZeroPixels(tex
, width
, height
, 0, 0, canvas
.width
, canvas
.height
, 0, 255, 0, 0);
150 gl
.deleteTexture(tex
);
152 glErrorShouldBe(gl
, gl
.NO_ERROR
);
155 debug("Reading an uninitialized portion of a texture (copyTexSubImage2D) should succeed with all bytes set to 0.");
157 var tex
= gl
.createTexture();
158 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
159 var data
= new Uint8Array(width
* height
* 4);
160 for (var i
= 0; i
< width
* height
* 4; ++i
)
162 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, width
, height
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, data
);
163 glErrorShouldBe(gl
, gl
.NO_ERROR
);
164 var fbo
= gl
.createFramebuffer();
165 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
166 var rbo
= gl
.createRenderbuffer();
167 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
170 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.RGBA4
, fboWidth
, fboHeight
);
171 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rbo
);
172 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
173 gl
.clearColor(1.0, 0.0, 0.0, 1.0);
174 gl
.clear(gl
.COLOR_BUFFER_BIT
);
175 glErrorShouldBe(gl
, gl
.NO_ERROR
);
176 gl
.copyTexSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, 0, 0, width
, height
);
177 checkNonZeroPixels(tex
, width
, height
, 0, 0, fboWidth
, fboHeight
, 255, 0, 0, 255);
178 gl
.deleteTexture(tex
);
180 glErrorShouldBe(gl
, gl
.NO_ERROR
);
183 debug("Reading an uninitialized portion of a texture (copyTexSubImage2D with negative x and y) should succeed with all bytes set to 0.");
185 var tex
= gl
.createTexture();
186 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
187 var data
= new Uint8Array(width
* height
* 4);
188 for (var i
= 0; i
< width
* height
* 4; ++i
)
190 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, width
, height
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, data
);
191 glErrorShouldBe(gl
, gl
.NO_ERROR
);
192 var fbo
= gl
.createFramebuffer();
193 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
194 var rbo
= gl
.createRenderbuffer();
195 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
198 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.RGBA4
, fboWidth
, fboHeight
);
199 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rbo
);
200 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
201 gl
.clearColor(1.0, 0.0, 0.0, 1.0);
202 gl
.clear(gl
.COLOR_BUFFER_BIT
);
203 glErrorShouldBe(gl
, gl
.NO_ERROR
);
206 gl
.copyTexSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, x
, y
, width
, height
);
207 checkNonZeroPixels(tex
, width
, height
, -x
, -y
, fboWidth
, fboHeight
, 255, 0, 0, 255);
208 gl
.deleteTexture(tex
);
210 glErrorShouldBe(gl
, gl
.NO_ERROR
);
213 debug("Reading an uninitialized portion of a texture (copyTexSubImage2D from WebGL internal fbo) should succeed with all bytes set to 0.");
215 var tex
= gl
.createTexture();
216 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
217 var data
= new Uint8Array(width
* height
* 4);
218 for (var i
= 0; i
< width
* height
* 4; ++i
)
220 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, width
, height
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, data
);
221 glErrorShouldBe(gl
, gl
.NO_ERROR
);
222 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
223 gl
.clearColor(0.0, 1.0, 0.0, 0.0);
224 gl
.clear(gl
.COLOR_BUFFER_BIT
);
225 glErrorShouldBe(gl
, gl
.NO_ERROR
);
226 gl
.copyTexSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, 0, 0, width
, height
);
227 checkNonZeroPixels(tex
, width
, height
, 0, 0, canvas
.width
, canvas
.height
, 0, 255, 0, 0);
228 gl
.deleteTexture(tex
);
230 glErrorShouldBe(gl
, gl
.NO_ERROR
);
232 //TODO: uninitialized vertex array buffer
233 //TODO: uninitialized vertex elements buffer
234 //TODO: uninitialized framebuffer? (implementations would need to do a GL clear at first binding?)
235 //TODO: uninitialized renderbuffer? (implementations would need to do a GL clear at first binding?)
236 //TODO: uninitialized uniform arrays?