|
1 <!-- |
|
2 Copyright (c) 2011 The Chromium Authors. |
|
3 Copyright (c) 2011 Mozilla Foundation. |
|
4 |
|
5 All rights reserved. |
|
6 Use of this source code is governed by a BSD-style license that can be |
|
7 found in the LICENSE file. |
|
8 --> |
|
9 <!DOCTYPE html> |
|
10 <html> |
|
11 <head> |
|
12 <meta charset="utf-8"> |
|
13 <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
|
14 <script src="../../resources/js-test-pre.js"></script> |
|
15 <script src="../resources/webgl-test.js"></script> |
|
16 <script src="../resources/webgl-test-utils.js"></script> |
|
17 </head> |
|
18 <body> |
|
19 <div id="description"></div> |
|
20 <div id="console"></div> |
|
21 |
|
22 <script> |
|
23 description("Tests deletion behavior for texture, renderbuffer, shader, and program"); |
|
24 |
|
25 var wtu = WebGLTestUtils; |
|
26 var gl = wtu.create3DContext(); |
|
27 var shouldGenerateGLError = wtu.shouldGenerateGLError; |
|
28 |
|
29 debug(""); |
|
30 debug("shader and program deletion"); |
|
31 |
|
32 var vertexShader = wtu.loadStandardVertexShader(gl); |
|
33 assertMsg(vertexShader, "vertex shader loaded"); |
|
34 var fragmentShader = wtu.loadStandardFragmentShader(gl); |
|
35 assertMsg(fragmentShader, "fragment shader loaded"); |
|
36 |
|
37 var program = gl.createProgram(); |
|
38 shouldBeNonNull("program"); |
|
39 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, vertexShader)"); |
|
40 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, fragmentShader)"); |
|
41 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.linkProgram(program)"); |
|
42 shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)"); |
|
43 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(program)"); |
|
44 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(vertexShader)"); |
|
45 shouldBeTrue("gl.isShader(vertexShader)"); |
|
46 shouldBeTrue("gl.getShaderParameter(vertexShader, gl.DELETE_STATUS)"); |
|
47 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.detachShader(program, vertexShader)"); |
|
48 shouldBeFalse("gl.isShader(vertexShader)"); |
|
49 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(fragmentShader)"); |
|
50 shouldBeTrue("gl.isShader(fragmentShader)"); |
|
51 shouldBeTrue("gl.getShaderParameter(fragmentShader, gl.DELETE_STATUS)"); |
|
52 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteProgram(program)"); |
|
53 shouldBeTrue("gl.isProgram(program)"); |
|
54 shouldBeTrue("gl.getProgramParameter(program, gl.DELETE_STATUS)"); |
|
55 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(null)"); |
|
56 shouldBeFalse("gl.isProgram(program)"); |
|
57 shouldBeFalse("gl.isShader(fragmentShader)"); |
|
58 |
|
59 debug(""); |
|
60 debug("texture deletion"); |
|
61 |
|
62 var fbo = gl.createFramebuffer(), fbo2 = gl.createFramebuffer(), fbo3 = gl.createFramebuffer(); |
|
63 shouldBeNonNull("fbo"); |
|
64 shouldBeNonNull("fbo2"); |
|
65 shouldBeNonNull("fbo3"); |
|
66 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
67 |
|
68 var tex = gl.createTexture(); |
|
69 shouldBeNonNull("tex"); |
|
70 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)"); |
|
71 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex"); |
|
72 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)"); |
|
73 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex"); |
|
74 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.TEXTURE"); |
|
75 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)"); |
|
76 // Deleting a texture bound to the currently-bound fbo is the same as |
|
77 // detaching the textue from fbo first, then delete the texture. |
|
78 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE"); |
|
79 shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)"); |
|
80 shouldBeFalse("gl.isTexture(tex)"); |
|
81 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)"); |
|
82 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)"); |
|
83 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)"); |
|
84 |
|
85 var texCubeMap = gl.createTexture(); |
|
86 shouldBeNonNull("texCubeMap"); |
|
87 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)"); |
|
88 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)", "texCubeMap"); |
|
89 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(texCubeMap)"); |
|
90 shouldBeFalse("gl.isTexture(texCubeMap)"); |
|
91 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)"); |
|
92 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)"); |
|
93 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)"); |
|
94 |
|
95 var t = gl.createTexture(); |
|
96 shouldBeNonNull("t"); |
|
97 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)"); |
|
98 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)"); |
|
99 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t)"); |
|
100 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)"); |
|
101 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)"); |
|
102 |
|
103 var t2 = gl.createTexture(); |
|
104 shouldBeNonNull("t2"); |
|
105 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)"); |
|
106 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)"); |
|
107 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2"); |
|
108 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE1)"); |
|
109 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)"); |
|
110 shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2"); |
|
111 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t2)"); |
|
112 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)"); |
|
113 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)"); |
|
114 shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)"); |
|
115 |
|
116 debug(""); |
|
117 debug("renderbuffer deletion"); |
|
118 |
|
119 var rbo = gl.createRenderbuffer(), rbo2 = gl.createRenderbuffer(), rbo3 = gl.createRenderbuffer(); |
|
120 shouldBeNonNull("rbo"); |
|
121 shouldBeNonNull("rbo2"); |
|
122 shouldBeNonNull("rbo3"); |
|
123 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)"); |
|
124 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo"); |
|
125 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)"); |
|
126 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo"); |
|
127 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)"); |
|
128 // Deleting a renderbuffer bound to the currently-bound fbo is the same as |
|
129 // detaching the renderbuffer from fbo first, then delete the renderbuffer. |
|
130 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE"); |
|
131 shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)"); |
|
132 shouldBeFalse("gl.isRenderbuffer(rbo)"); |
|
133 shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)"); |
|
134 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)"); |
|
135 shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)"); |
|
136 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)"); |
|
137 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2"); |
|
138 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo3)"); |
|
139 shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2"); |
|
140 |
|
141 debug(""); |
|
142 debug("using deleted renderbuffer"); |
|
143 rbo = gl.createRenderbuffer(); |
|
144 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)"); |
|
145 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)"); |
|
146 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
147 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)"); |
|
148 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { |
|
149 // make backbuffer red |
|
150 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
151 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)"); |
|
152 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
153 // make fbo green |
|
154 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
155 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)"); |
|
156 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
157 // Bind backbuffer. |
|
158 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
159 // delete renderbuffer. It should still be attached to fbo though. |
|
160 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)"); |
|
161 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")'); |
|
162 // Use fbo that has deleted rbo. |
|
163 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
164 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")'); |
|
165 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)"); |
|
166 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
167 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")'); |
|
168 // Bind backbuffer. |
|
169 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
170 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")'); |
|
171 } |
|
172 |
|
173 debug(""); |
|
174 debug("renderbuffer attached twice to same framebuffer"); |
|
175 rbo = gl.createRenderbuffer(); |
|
176 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)"); |
|
177 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)"); |
|
178 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
179 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)"); |
|
180 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { |
|
181 rbo2 = gl.createRenderbuffer(); |
|
182 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)"); |
|
183 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)"); |
|
184 // attach rbo2 at two attachment points incompatible with it |
|
185 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo2)"); |
|
186 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo2)"); |
|
187 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2"); |
|
188 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2"); |
|
189 // fbo can't be complete as rbo2 is attached at incompatible attachment points |
|
190 shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
191 // now we delete rbo2, which detaches it from the two attachment points where it currently is attached |
|
192 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo2)"); |
|
193 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE"); |
|
194 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE"); |
|
195 // we should now be in the same state as before with only rbo attached, so fbo should be complete again |
|
196 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
197 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo"); |
|
198 } |
|
199 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)"); |
|
200 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
201 |
|
202 |
|
203 |
|
204 debug(""); |
|
205 debug("using deleted texture"); |
|
206 tex = gl.createTexture(); |
|
207 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)"); |
|
208 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
209 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)"); |
|
210 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)"); |
|
211 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { |
|
212 // make fbo green |
|
213 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
214 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)"); |
|
215 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
216 // Bind backbuffer. |
|
217 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
218 // delete texture. It should still be attached to fbo though. |
|
219 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)"); |
|
220 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255,0,0,255], "backbuffer should be red")'); |
|
221 // Use fbo that has deleted texture. |
|
222 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
223 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")'); |
|
224 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)"); |
|
225 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
226 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")'); |
|
227 // Bind backbuffer. |
|
228 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
229 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")'); |
|
230 } |
|
231 |
|
232 debug(""); |
|
233 debug("using deleted renderbuffer"); |
|
234 rbo = gl.createRenderbuffer(); |
|
235 shouldBeNonNull("rbo"); |
|
236 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)"); |
|
237 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)"); |
|
238 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
239 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)"); |
|
240 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { |
|
241 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)"); |
|
242 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)"); |
|
243 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
244 // make backbuffer red |
|
245 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
246 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)"); |
|
247 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
248 // make fbo green |
|
249 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
250 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)"); |
|
251 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
252 // delete renderbuffer. It should still be attached to fbo2 though. |
|
253 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)"); |
|
254 // fbo has no attachments |
|
255 shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
256 // Use fbo2 that has deleted rbo. |
|
257 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)"); |
|
258 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")'); |
|
259 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)"); |
|
260 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
261 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")'); |
|
262 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo"); |
|
263 |
|
264 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
265 shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)"); |
|
266 shouldGenerateGLError(gl, gl.NONE, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)"); |
|
267 shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
268 // Bind backbuffer. |
|
269 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
270 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")'); |
|
271 } |
|
272 |
|
273 debug(""); |
|
274 debug("using deleted texture"); |
|
275 tex = gl.createTexture(); |
|
276 shouldBeNonNull("tex"); |
|
277 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)"); |
|
278 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
279 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)"); |
|
280 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)"); |
|
281 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { |
|
282 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)"); |
|
283 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)"); |
|
284 // make fbo green |
|
285 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
286 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)"); |
|
287 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
288 // delete texture. It should still be attached to fbo2 though. |
|
289 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)"); |
|
290 // fbo has no attachments |
|
291 shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
292 // Use fbo that has deleted texture. |
|
293 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)"); |
|
294 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
295 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")'); |
|
296 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)"); |
|
297 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
298 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")'); |
|
299 shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex"); |
|
300 |
|
301 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
302 shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)"); |
|
303 shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
|
304 // Bind backbuffer. |
|
305 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
306 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")'); |
|
307 } |
|
308 |
|
309 debug(""); |
|
310 debug("buffer deletion"); |
|
311 |
|
312 var buffer = gl.createBuffer(); |
|
313 shouldBeNonNull("buffer"); |
|
314 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)"); |
|
315 shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer"); |
|
316 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer)"); |
|
317 shouldBeFalse("gl.isBuffer(buffer)"); |
|
318 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)"); |
|
319 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)"); |
|
320 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)"); |
|
321 |
|
322 var buffer2 = gl.createBuffer(); |
|
323 shouldBeNonNull("buffer2"); |
|
324 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)"); |
|
325 shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer2"); |
|
326 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, null)"); |
|
327 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)"); |
|
328 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer2)"); |
|
329 shouldBeFalse("gl.isBuffer(buffer2)"); |
|
330 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)"); |
|
331 shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)"); |
|
332 |
|
333 var bufferElement = gl.createBuffer(); |
|
334 shouldBeNonNull("bufferElement"); |
|
335 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)"); |
|
336 shouldBe("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)", "bufferElement"); |
|
337 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferElement)"); |
|
338 shouldBeFalse("gl.isBuffer(bufferElement)"); |
|
339 shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)"); |
|
340 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)"); |
|
341 shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)"); |
|
342 |
|
343 var b = gl.createBuffer(); |
|
344 shouldBeNonNull("b"); |
|
345 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)"); |
|
346 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)"); |
|
347 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b)"); |
|
348 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)"); |
|
349 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)"); |
|
350 |
|
351 var b1 = gl.createBuffer(); |
|
352 shouldBeNonNull("b1"); |
|
353 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b1);"); |
|
354 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(1);"); |
|
355 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);"); |
|
356 var b2 = gl.createBuffer(); |
|
357 shouldBeNonNull("b2"); |
|
358 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b2);"); |
|
359 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(2);"); |
|
360 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);"); |
|
361 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(3);"); |
|
362 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0);"); |
|
363 shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1"); |
|
364 shouldBe("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2"); |
|
365 shouldBe("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2"); |
|
366 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b2);"); |
|
367 shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1"); |
|
368 shouldBeNull("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)"); |
|
369 shouldBeNull("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)"); |
|
370 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b1);"); |
|
371 shouldBeNull("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)"); |
|
372 |
|
373 debug(""); |
|
374 debug("framebuffer deletion"); |
|
375 |
|
376 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
377 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo"); |
|
378 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo)"); |
|
379 shouldBeFalse("gl.isFramebuffer(fbo)"); |
|
380 shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)"); |
|
381 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
382 shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)"); |
|
383 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)"); |
|
384 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2"); |
|
385 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo3)"); |
|
386 shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2"); |
|
387 |
|
388 fbo = gl.createFramebuffer(); |
|
389 rbo = gl.createRenderbuffer(); |
|
390 shouldBeNonNull("fbo"); |
|
391 shouldBeNonNull("rbo"); |
|
392 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
393 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)"); |
|
394 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)"); |
|
395 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)"); |
|
396 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { |
|
397 // set backbuffer to red |
|
398 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
399 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)"); |
|
400 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
401 // set framebuffer to green |
|
402 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)"); |
|
403 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)"); |
|
404 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
405 // check framebuffer |
|
406 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")'); |
|
407 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 16, 16, 1, 1, [0,0,0,0], "outside fbo should be black")'); |
|
408 // delete framebuffer. because this was the bound fbo the backbuffer should be active now |
|
409 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo)"); |
|
410 // check backbuffer |
|
411 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [255,0,0,255], "backbuffer should be red")'); |
|
412 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 300, 0, 300, 300, [0,0,0,0], "outside backbuffer should be black")'); |
|
413 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 150, 300, 300, [0,0,0,0], "outside backbuffer should be black")'); |
|
414 // check drawing to backbuffer |
|
415 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)"); |
|
416 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
|
417 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")'); |
|
418 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)"); |
|
419 // check again because many buggy implementations will have bound to the true backbuffer on deleteFramebuffer. |
|
420 shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")'); |
|
421 } |
|
422 |
|
423 successfullyParsed = true; |
|
424 </script> |
|
425 |
|
426 <script>finishTest();</script> |
|
427 </body> |
|
428 </html> |