|
1 /* |
|
2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
|
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
|
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #include "config.h" |
|
27 |
|
28 #if ENABLE(3D_CANVAS) |
|
29 |
|
30 #include "WebGLRenderingContext.h" |
|
31 |
|
32 #include "CheckedInt.h" |
|
33 #include "CanvasPixelArray.h" |
|
34 #include "Console.h" |
|
35 #include "DOMWindow.h" |
|
36 #include "FrameView.h" |
|
37 #include "HTMLCanvasElement.h" |
|
38 #include "HTMLImageElement.h" |
|
39 #include "ImageBuffer.h" |
|
40 #include "ImageData.h" |
|
41 #include "NotImplemented.h" |
|
42 #include "RenderBox.h" |
|
43 #include "RenderLayer.h" |
|
44 #include "WebGLActiveInfo.h" |
|
45 #include "Uint16Array.h" |
|
46 #include "WebGLBuffer.h" |
|
47 #include "WebGLContextAttributes.h" |
|
48 #include "WebGLFramebuffer.h" |
|
49 #include "WebGLProgram.h" |
|
50 #include "WebGLRenderbuffer.h" |
|
51 #include "WebGLTexture.h" |
|
52 #include "WebGLShader.h" |
|
53 #include "WebGLUniformLocation.h" |
|
54 |
|
55 #include <wtf/ByteArray.h> |
|
56 #include <wtf/OwnArrayPtr.h> |
|
57 |
|
58 namespace WebCore { |
|
59 |
|
60 class WebGLStateRestorer { |
|
61 public: |
|
62 WebGLStateRestorer(WebGLRenderingContext* context, |
|
63 bool changed) |
|
64 : m_context(context) |
|
65 , m_changed(changed) |
|
66 { |
|
67 } |
|
68 |
|
69 ~WebGLStateRestorer() |
|
70 { |
|
71 m_context->cleanupAfterGraphicsCall(m_changed); |
|
72 } |
|
73 |
|
74 private: |
|
75 WebGLRenderingContext* m_context; |
|
76 bool m_changed; |
|
77 }; |
|
78 |
|
79 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs) |
|
80 { |
|
81 HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow(); |
|
82 OwnPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs->attributes(), hostWindow)); |
|
83 |
|
84 if (!context) |
|
85 return 0; |
|
86 |
|
87 return new WebGLRenderingContext(canvas, context.release()); |
|
88 } |
|
89 |
|
90 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<GraphicsContext3D> context) |
|
91 : CanvasRenderingContext(passedCanvas) |
|
92 , m_context(context) |
|
93 , m_needsUpdate(true) |
|
94 , m_markedCanvasDirty(false) |
|
95 , m_activeTextureUnit(0) |
|
96 , m_packAlignment(4) |
|
97 , m_unpackAlignment(4) |
|
98 , m_unpackFlipY(false) |
|
99 , m_unpackPremultiplyAlpha(false) |
|
100 { |
|
101 ASSERT(m_context); |
|
102 |
|
103 int numCombinedTextureImageUnits = 0; |
|
104 m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits); |
|
105 m_textureUnits.resize(numCombinedTextureImageUnits); |
|
106 |
|
107 int numVertexAttribs = 0; |
|
108 m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs); |
|
109 m_maxVertexAttribs = numVertexAttribs; |
|
110 |
|
111 int implementationColorReadFormat = GraphicsContext3D::RGBA; |
|
112 m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT, &implementationColorReadFormat); |
|
113 m_implementationColorReadFormat = implementationColorReadFormat; |
|
114 int implementationColorReadType = GraphicsContext3D::UNSIGNED_BYTE; |
|
115 m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType); |
|
116 m_implementationColorReadType = implementationColorReadType; |
|
117 |
|
118 m_maxTextureSize = 0; |
|
119 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize); |
|
120 m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize); |
|
121 m_maxCubeMapTextureSize = 0; |
|
122 m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize); |
|
123 m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize); |
|
124 |
|
125 if (!isGLES2Compliant()) { |
|
126 createFallbackBlackTextures1x1(); |
|
127 initVertexAttrib0(); |
|
128 } |
|
129 m_context->reshape(canvas()->width(), canvas()->height()); |
|
130 m_context->viewport(0, 0, canvas()->width(), canvas()->height()); |
|
131 } |
|
132 |
|
133 WebGLRenderingContext::~WebGLRenderingContext() |
|
134 { |
|
135 detachAndRemoveAllObjects(); |
|
136 } |
|
137 |
|
138 void WebGLRenderingContext::markContextChanged() |
|
139 { |
|
140 #if USE(ACCELERATED_COMPOSITING) |
|
141 RenderBox* renderBox = canvas()->renderBox(); |
|
142 if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing()) |
|
143 renderBox->layer()->rendererContentChanged(); |
|
144 #endif |
|
145 if (!m_markedCanvasDirty) { |
|
146 // Make sure the canvas's image buffer is allocated. |
|
147 canvas()->buffer(); |
|
148 canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height())); |
|
149 m_markedCanvasDirty = true; |
|
150 } |
|
151 } |
|
152 |
|
153 bool WebGLRenderingContext::paintRenderingResultsToCanvas() |
|
154 { |
|
155 if (m_markedCanvasDirty) { |
|
156 m_markedCanvasDirty = false; |
|
157 m_context->paintRenderingResultsToCanvas(this); |
|
158 return true; |
|
159 } |
|
160 return false; |
|
161 } |
|
162 |
|
163 void WebGLRenderingContext::beginPaint() |
|
164 { |
|
165 if (m_markedCanvasDirty) { |
|
166 m_context->beginPaint(this); |
|
167 } |
|
168 } |
|
169 |
|
170 void WebGLRenderingContext::endPaint() |
|
171 { |
|
172 if (m_markedCanvasDirty) { |
|
173 m_markedCanvasDirty = false; |
|
174 m_context->endPaint(); |
|
175 } |
|
176 } |
|
177 |
|
178 void WebGLRenderingContext::reshape(int width, int height) |
|
179 { |
|
180 if (m_needsUpdate) { |
|
181 #if USE(ACCELERATED_COMPOSITING) |
|
182 RenderBox* renderBox = canvas()->renderBox(); |
|
183 if (renderBox && renderBox->hasLayer()) |
|
184 renderBox->layer()->rendererContentChanged(); |
|
185 #endif |
|
186 m_needsUpdate = false; |
|
187 } |
|
188 |
|
189 m_context->reshape(width, height); |
|
190 } |
|
191 |
|
192 int WebGLRenderingContext::sizeInBytes(int type, ExceptionCode& ec) |
|
193 { |
|
194 UNUSED_PARAM(ec); |
|
195 int result = m_context->sizeInBytes(type); |
|
196 if (result <= 0) |
|
197 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
198 |
|
199 return result; |
|
200 } |
|
201 |
|
202 void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec) |
|
203 { |
|
204 UNUSED_PARAM(ec); |
|
205 if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) { |
|
206 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
207 return; |
|
208 } |
|
209 m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0; |
|
210 m_context->activeTexture(texture); |
|
211 cleanupAfterGraphicsCall(false); |
|
212 } |
|
213 |
|
214 void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) |
|
215 { |
|
216 UNUSED_PARAM(ec); |
|
217 if (!validateWebGLObject(program) || !validateWebGLObject(shader)) |
|
218 return; |
|
219 m_context->attachShader(program, shader); |
|
220 cleanupAfterGraphicsCall(false); |
|
221 } |
|
222 |
|
223 void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec) |
|
224 { |
|
225 UNUSED_PARAM(ec); |
|
226 if (!validateWebGLObject(program)) |
|
227 return; |
|
228 m_context->bindAttribLocation(program, index, name); |
|
229 cleanupAfterGraphicsCall(false); |
|
230 } |
|
231 |
|
232 void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec) |
|
233 { |
|
234 UNUSED_PARAM(ec); |
|
235 if (buffer && buffer->context() != this) { |
|
236 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
237 return; |
|
238 } |
|
239 if (buffer && buffer->getTarget() && buffer->getTarget() != target) { |
|
240 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
241 return; |
|
242 } |
|
243 |
|
244 if (target == GraphicsContext3D::ARRAY_BUFFER) |
|
245 m_boundArrayBuffer = buffer; |
|
246 else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) |
|
247 m_boundElementArrayBuffer = buffer; |
|
248 else { |
|
249 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
250 return; |
|
251 } |
|
252 |
|
253 m_context->bindBuffer(target, buffer); |
|
254 if (buffer) |
|
255 buffer->setTarget(target); |
|
256 cleanupAfterGraphicsCall(false); |
|
257 } |
|
258 |
|
259 |
|
260 void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec) |
|
261 { |
|
262 UNUSED_PARAM(ec); |
|
263 if (buffer && buffer->context() != this) { |
|
264 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
265 return; |
|
266 } |
|
267 if (target != GraphicsContext3D::FRAMEBUFFER) { |
|
268 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
269 return; |
|
270 } |
|
271 m_framebufferBinding = buffer; |
|
272 m_context->bindFramebuffer(target, buffer); |
|
273 if (m_framebufferBinding) |
|
274 m_framebufferBinding->onBind(); |
|
275 cleanupAfterGraphicsCall(false); |
|
276 } |
|
277 |
|
278 void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec) |
|
279 { |
|
280 UNUSED_PARAM(ec); |
|
281 if (renderBuffer && renderBuffer->context() != this) { |
|
282 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
283 return; |
|
284 } |
|
285 if (target != GraphicsContext3D::RENDERBUFFER) { |
|
286 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
287 return; |
|
288 } |
|
289 m_renderbufferBinding = renderBuffer; |
|
290 m_context->bindRenderbuffer(target, renderBuffer); |
|
291 cleanupAfterGraphicsCall(false); |
|
292 } |
|
293 |
|
294 |
|
295 void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec) |
|
296 { |
|
297 UNUSED_PARAM(ec); |
|
298 if (texture && texture->context() != this) { |
|
299 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
300 return; |
|
301 } |
|
302 int maxLevel = 0; |
|
303 if (target == GraphicsContext3D::TEXTURE_2D) { |
|
304 m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture; |
|
305 maxLevel = m_maxTextureLevel; |
|
306 } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) { |
|
307 m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture; |
|
308 maxLevel = m_maxCubeMapTextureLevel; |
|
309 } else { |
|
310 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
311 return; |
|
312 } |
|
313 m_context->bindTexture(target, texture); |
|
314 if (!isGLES2Compliant() && texture) |
|
315 texture->setTarget(target, maxLevel); |
|
316 cleanupAfterGraphicsCall(false); |
|
317 } |
|
318 |
|
319 void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha) |
|
320 { |
|
321 m_context->blendColor(red, green, blue, alpha); |
|
322 cleanupAfterGraphicsCall(false); |
|
323 } |
|
324 |
|
325 void WebGLRenderingContext::blendEquation( unsigned long mode ) |
|
326 { |
|
327 if (!isGLES2Compliant()) { |
|
328 if (!validateBlendEquation(mode)) |
|
329 return; |
|
330 } |
|
331 m_context->blendEquation(mode); |
|
332 cleanupAfterGraphicsCall(false); |
|
333 } |
|
334 |
|
335 void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha) |
|
336 { |
|
337 if (!isGLES2Compliant()) { |
|
338 if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha)) |
|
339 return; |
|
340 } |
|
341 m_context->blendEquationSeparate(modeRGB, modeAlpha); |
|
342 cleanupAfterGraphicsCall(false); |
|
343 } |
|
344 |
|
345 |
|
346 void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor) |
|
347 { |
|
348 m_context->blendFunc(sfactor, dfactor); |
|
349 cleanupAfterGraphicsCall(false); |
|
350 } |
|
351 |
|
352 void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha) |
|
353 { |
|
354 m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); |
|
355 cleanupAfterGraphicsCall(false); |
|
356 } |
|
357 |
|
358 void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec) |
|
359 { |
|
360 UNUSED_PARAM(ec); |
|
361 WebGLBuffer* buffer = validateBufferDataParameters(target, usage); |
|
362 if (!buffer) |
|
363 return; |
|
364 if (!buffer->associateBufferData(size)) { |
|
365 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
366 return; |
|
367 } |
|
368 |
|
369 m_context->bufferData(target, size, usage); |
|
370 cleanupAfterGraphicsCall(false); |
|
371 } |
|
372 |
|
373 void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode& ec) |
|
374 { |
|
375 UNUSED_PARAM(ec); |
|
376 WebGLBuffer* buffer = validateBufferDataParameters(target, usage); |
|
377 if (!buffer) |
|
378 return; |
|
379 if (!buffer->associateBufferData(data)) { |
|
380 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
381 return; |
|
382 } |
|
383 |
|
384 m_context->bufferData(target, data, usage); |
|
385 cleanupAfterGraphicsCall(false); |
|
386 } |
|
387 |
|
388 void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec) |
|
389 { |
|
390 UNUSED_PARAM(ec); |
|
391 WebGLBuffer* buffer = validateBufferDataParameters(target, usage); |
|
392 if (!buffer) |
|
393 return; |
|
394 if (!buffer->associateBufferData(data)) { |
|
395 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
396 return; |
|
397 } |
|
398 |
|
399 m_context->bufferData(target, data, usage); |
|
400 cleanupAfterGraphicsCall(false); |
|
401 } |
|
402 |
|
403 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode& ec) |
|
404 { |
|
405 UNUSED_PARAM(ec); |
|
406 WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); |
|
407 if (!buffer) |
|
408 return; |
|
409 if (!buffer->associateBufferSubData(offset, data)) { |
|
410 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
411 return; |
|
412 } |
|
413 |
|
414 m_context->bufferSubData(target, offset, data); |
|
415 cleanupAfterGraphicsCall(false); |
|
416 } |
|
417 |
|
418 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec) |
|
419 { |
|
420 UNUSED_PARAM(ec); |
|
421 WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); |
|
422 if (!buffer) |
|
423 return; |
|
424 if (!buffer->associateBufferSubData(offset, data)) { |
|
425 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
426 return; |
|
427 } |
|
428 |
|
429 m_context->bufferSubData(target, offset, data); |
|
430 cleanupAfterGraphicsCall(false); |
|
431 } |
|
432 |
|
433 unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target) |
|
434 { |
|
435 if (!isGLES2Compliant()) { |
|
436 if (target != GraphicsContext3D::FRAMEBUFFER) { |
|
437 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
438 return 0; |
|
439 } |
|
440 } |
|
441 if (!m_framebufferBinding || !m_framebufferBinding->object()) |
|
442 return GraphicsContext3D::FRAMEBUFFER_COMPLETE; |
|
443 return m_context->checkFramebufferStatus(target); |
|
444 cleanupAfterGraphicsCall(false); |
|
445 } |
|
446 |
|
447 void WebGLRenderingContext::clear(unsigned long mask) |
|
448 { |
|
449 if (!isGLES2Compliant()) { |
|
450 if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) { |
|
451 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
452 return; |
|
453 } |
|
454 } |
|
455 m_context->clear(mask); |
|
456 cleanupAfterGraphicsCall(true); |
|
457 } |
|
458 |
|
459 void WebGLRenderingContext::clearColor(double r, double g, double b, double a) |
|
460 { |
|
461 if (isnan(r)) |
|
462 r = 0; |
|
463 if (isnan(g)) |
|
464 g = 0; |
|
465 if (isnan(b)) |
|
466 b = 0; |
|
467 if (isnan(a)) |
|
468 a = 1; |
|
469 m_context->clearColor(r, g, b, a); |
|
470 cleanupAfterGraphicsCall(false); |
|
471 } |
|
472 |
|
473 void WebGLRenderingContext::clearDepth(double depth) |
|
474 { |
|
475 m_context->clearDepth(depth); |
|
476 cleanupAfterGraphicsCall(false); |
|
477 } |
|
478 |
|
479 void WebGLRenderingContext::clearStencil(long s) |
|
480 { |
|
481 m_context->clearStencil(s); |
|
482 cleanupAfterGraphicsCall(false); |
|
483 } |
|
484 |
|
485 void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha) |
|
486 { |
|
487 m_context->colorMask(red, green, blue, alpha); |
|
488 cleanupAfterGraphicsCall(false); |
|
489 } |
|
490 |
|
491 void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec) |
|
492 { |
|
493 UNUSED_PARAM(ec); |
|
494 if (!validateWebGLObject(shader)) |
|
495 return; |
|
496 m_context->compileShader(shader); |
|
497 cleanupAfterGraphicsCall(false); |
|
498 } |
|
499 |
|
500 void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) |
|
501 { |
|
502 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE)) |
|
503 return; |
|
504 if (!isGLES2Compliant()) { |
|
505 if (m_framebufferBinding && m_framebufferBinding->object() |
|
506 && !isTexInternalFormatColorBufferCombinationValid(internalformat, |
|
507 m_framebufferBinding->getColorBufferFormat())) { |
|
508 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
509 return; |
|
510 } |
|
511 if (level && WebGLTexture::isNPOT(width, height)) { |
|
512 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
513 return; |
|
514 } |
|
515 } |
|
516 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); |
|
517 // FIXME: if the framebuffer is not complete, none of the below should be executed. |
|
518 WebGLTexture* tex = getTextureBinding(target); |
|
519 if (!isGLES2Compliant()) { |
|
520 if (tex) |
|
521 tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
|
522 } |
|
523 if (m_framebufferBinding && tex) |
|
524 m_framebufferBinding->onAttachedObjectChange(tex); |
|
525 cleanupAfterGraphicsCall(false); |
|
526 } |
|
527 |
|
528 void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) |
|
529 { |
|
530 if (!isGLES2Compliant()) { |
|
531 WebGLTexture* tex = getTextureBinding(target); |
|
532 if (m_framebufferBinding && m_framebufferBinding->object() && tex |
|
533 && !isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(), |
|
534 m_framebufferBinding->getColorBufferFormat())) { |
|
535 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
536 return; |
|
537 } |
|
538 } |
|
539 m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); |
|
540 cleanupAfterGraphicsCall(false); |
|
541 } |
|
542 |
|
543 PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer() |
|
544 { |
|
545 RefPtr<WebGLBuffer> o = WebGLBuffer::create(this); |
|
546 addObject(o.get()); |
|
547 return o; |
|
548 } |
|
549 |
|
550 PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer() |
|
551 { |
|
552 RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this); |
|
553 addObject(o.get()); |
|
554 return o; |
|
555 } |
|
556 |
|
557 PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture() |
|
558 { |
|
559 RefPtr<WebGLTexture> o = WebGLTexture::create(this); |
|
560 addObject(o.get()); |
|
561 return o; |
|
562 } |
|
563 |
|
564 PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram() |
|
565 { |
|
566 RefPtr<WebGLProgram> o = WebGLProgram::create(this); |
|
567 addObject(o.get()); |
|
568 return o; |
|
569 } |
|
570 |
|
571 PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer() |
|
572 { |
|
573 RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this); |
|
574 addObject(o.get()); |
|
575 return o; |
|
576 } |
|
577 |
|
578 PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec) |
|
579 { |
|
580 UNUSED_PARAM(ec); |
|
581 if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) { |
|
582 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
583 return 0; |
|
584 } |
|
585 |
|
586 RefPtr<WebGLShader> o = WebGLShader::create(this, static_cast<GraphicsContext3D::WebGLEnumType>(type)); |
|
587 addObject(o.get()); |
|
588 return o; |
|
589 } |
|
590 |
|
591 void WebGLRenderingContext::cullFace(unsigned long mode) |
|
592 { |
|
593 m_context->cullFace(mode); |
|
594 cleanupAfterGraphicsCall(false); |
|
595 } |
|
596 |
|
597 void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) |
|
598 { |
|
599 if (!buffer) |
|
600 return; |
|
601 |
|
602 buffer->deleteObject(); |
|
603 |
|
604 if (!isGLES2Compliant()) { |
|
605 VertexAttribState& state = m_vertexAttribState[0]; |
|
606 if (buffer == state.bufferBinding) { |
|
607 state.bufferBinding = m_vertexAttrib0Buffer; |
|
608 state.bytesPerElement = 0; |
|
609 state.size = 4; |
|
610 state.type = GraphicsContext3D::FLOAT; |
|
611 state.normalized = false; |
|
612 state.stride = 16; |
|
613 state.originalStride = 0; |
|
614 state.offset = 0; |
|
615 } |
|
616 } |
|
617 } |
|
618 |
|
619 void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer) |
|
620 { |
|
621 if (!framebuffer) |
|
622 return; |
|
623 |
|
624 framebuffer->deleteObject(); |
|
625 } |
|
626 |
|
627 void WebGLRenderingContext::deleteProgram(WebGLProgram* program) |
|
628 { |
|
629 if (!program) |
|
630 return; |
|
631 |
|
632 program->deleteObject(); |
|
633 } |
|
634 |
|
635 void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer) |
|
636 { |
|
637 if (!renderbuffer) |
|
638 return; |
|
639 |
|
640 renderbuffer->deleteObject(); |
|
641 if (m_framebufferBinding) |
|
642 m_framebufferBinding->onAttachedObjectChange(renderbuffer); |
|
643 } |
|
644 |
|
645 void WebGLRenderingContext::deleteShader(WebGLShader* shader) |
|
646 { |
|
647 if (!shader) |
|
648 return; |
|
649 |
|
650 shader->deleteObject(); |
|
651 } |
|
652 |
|
653 void WebGLRenderingContext::deleteTexture(WebGLTexture* texture) |
|
654 { |
|
655 if (!texture) |
|
656 return; |
|
657 |
|
658 texture->deleteObject(); |
|
659 if (m_framebufferBinding) |
|
660 m_framebufferBinding->onAttachedObjectChange(texture); |
|
661 } |
|
662 |
|
663 void WebGLRenderingContext::depthFunc(unsigned long func) |
|
664 { |
|
665 m_context->depthFunc(func); |
|
666 cleanupAfterGraphicsCall(false); |
|
667 } |
|
668 |
|
669 void WebGLRenderingContext::depthMask(bool flag) |
|
670 { |
|
671 m_context->depthMask(flag); |
|
672 cleanupAfterGraphicsCall(false); |
|
673 } |
|
674 |
|
675 void WebGLRenderingContext::depthRange(double zNear, double zFar) |
|
676 { |
|
677 m_context->depthRange(zNear, zFar); |
|
678 cleanupAfterGraphicsCall(false); |
|
679 } |
|
680 |
|
681 void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) |
|
682 { |
|
683 UNUSED_PARAM(ec); |
|
684 if (!validateWebGLObject(program) || !validateWebGLObject(shader)) |
|
685 return; |
|
686 m_context->detachShader(program, shader); |
|
687 cleanupAfterGraphicsCall(false); |
|
688 } |
|
689 |
|
690 |
|
691 void WebGLRenderingContext::disable(unsigned long cap) |
|
692 { |
|
693 if (!isGLES2Compliant()) { |
|
694 if (!validateCapability(cap)) |
|
695 return; |
|
696 } |
|
697 m_context->disable(cap); |
|
698 cleanupAfterGraphicsCall(false); |
|
699 } |
|
700 |
|
701 void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec) |
|
702 { |
|
703 UNUSED_PARAM(ec); |
|
704 if (index >= m_maxVertexAttribs) { |
|
705 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
706 return; |
|
707 } |
|
708 |
|
709 if (index < m_vertexAttribState.size()) |
|
710 m_vertexAttribState[index].enabled = false; |
|
711 |
|
712 if (index > 0 || isGLES2Compliant()) { |
|
713 m_context->disableVertexAttribArray(index); |
|
714 cleanupAfterGraphicsCall(false); |
|
715 } |
|
716 } |
|
717 |
|
718 bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset) |
|
719 { |
|
720 if (!m_boundElementArrayBuffer) |
|
721 return false; |
|
722 |
|
723 if (offset < 0) |
|
724 return false; |
|
725 |
|
726 unsigned long uoffset = static_cast<unsigned long>(offset); |
|
727 |
|
728 if (type == GraphicsContext3D::UNSIGNED_SHORT) { |
|
729 // For an unsigned short array, offset must be divisible by 2 for alignment reasons. |
|
730 if (uoffset & 1) |
|
731 return false; |
|
732 |
|
733 // Make uoffset an element offset. |
|
734 uoffset /= 2; |
|
735 |
|
736 unsigned long n = m_boundElementArrayBuffer->byteLength() / 2; |
|
737 if (uoffset > n || count > n - uoffset) |
|
738 return false; |
|
739 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { |
|
740 unsigned long n = m_boundElementArrayBuffer->byteLength(); |
|
741 if (uoffset > n || count > n - uoffset) |
|
742 return false; |
|
743 } |
|
744 return true; |
|
745 } |
|
746 |
|
747 bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& numElementsRequired) |
|
748 { |
|
749 // Performs conservative validation by caching a maximum index of |
|
750 // the given type per element array buffer. If all of the bound |
|
751 // array buffers have enough elements to satisfy that maximum |
|
752 // index, skips the expensive per-draw-call iteration in |
|
753 // validateIndexArrayPrecise. |
|
754 |
|
755 long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type); |
|
756 if (maxIndex < 0) { |
|
757 // Compute the maximum index in the entire buffer for the given type of index. |
|
758 switch (type) { |
|
759 case GraphicsContext3D::UNSIGNED_BYTE: { |
|
760 unsigned numElements = m_boundElementArrayBuffer->byteLength(); |
|
761 if (!numElements) |
|
762 maxIndex = 0; |
|
763 else { |
|
764 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); |
|
765 for (unsigned i = 0; i < numElements; i++) |
|
766 maxIndex = max(maxIndex, static_cast<long>(p[i])); |
|
767 } |
|
768 break; |
|
769 } |
|
770 case GraphicsContext3D::UNSIGNED_SHORT: { |
|
771 unsigned numElements = m_boundElementArrayBuffer->byteLength() / sizeof(unsigned short); |
|
772 if (!numElements) |
|
773 maxIndex = 0; |
|
774 else { |
|
775 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); |
|
776 for (unsigned i = 0; i < numElements; i++) |
|
777 maxIndex = max(maxIndex, static_cast<long>(p[i])); |
|
778 } |
|
779 break; |
|
780 } |
|
781 default: |
|
782 return false; |
|
783 } |
|
784 m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex); |
|
785 } |
|
786 |
|
787 if (maxIndex >= 0) { |
|
788 // The number of required elements is one more than the maximum |
|
789 // index that will be accessed. |
|
790 numElementsRequired = maxIndex + 1; |
|
791 return true; |
|
792 } |
|
793 |
|
794 return false; |
|
795 } |
|
796 |
|
797 bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired) |
|
798 { |
|
799 long lastIndex = -1; |
|
800 |
|
801 if (!m_boundElementArrayBuffer) |
|
802 return false; |
|
803 |
|
804 unsigned long uoffset = static_cast<unsigned long>(offset); |
|
805 unsigned long n = count; |
|
806 |
|
807 if (type == GraphicsContext3D::UNSIGNED_SHORT) { |
|
808 // Make uoffset an element offset. |
|
809 uoffset /= 2; |
|
810 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; |
|
811 while (n-- > 0) { |
|
812 if (*p > lastIndex) |
|
813 lastIndex = *p; |
|
814 ++p; |
|
815 } |
|
816 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { |
|
817 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; |
|
818 while (n-- > 0) { |
|
819 if (*p > lastIndex) |
|
820 lastIndex = *p; |
|
821 ++p; |
|
822 } |
|
823 } |
|
824 |
|
825 // Then set the last index in the index array and make sure it is valid. |
|
826 numElementsRequired = lastIndex + 1; |
|
827 return numElementsRequired > 0; |
|
828 } |
|
829 |
|
830 bool WebGLRenderingContext::validateRenderingState(long numElementsRequired) |
|
831 { |
|
832 if (!m_currentProgram) |
|
833 return false; |
|
834 |
|
835 int numAttribStates = static_cast<int>(m_vertexAttribState.size()); |
|
836 |
|
837 // Look in each enabled vertex attrib and check if they've been bound to a buffer. |
|
838 for (int i = 0; i < numAttribStates; ++i) { |
|
839 if (m_vertexAttribState[i].enabled |
|
840 && (!m_vertexAttribState[i].bufferBinding || !m_vertexAttribState[i].bufferBinding->object())) |
|
841 return false; |
|
842 } |
|
843 |
|
844 // Look in each consumed vertex attrib (by the current program) and find the smallest buffer size |
|
845 long smallestNumElements = LONG_MAX; |
|
846 int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations(); |
|
847 for (int i = 0; i < numActiveAttribLocations; ++i) { |
|
848 int loc = m_currentProgram->getActiveAttribLocation(i); |
|
849 if (loc >=0 && loc < numAttribStates) { |
|
850 const VertexAttribState& state = m_vertexAttribState[loc]; |
|
851 if (state.enabled) { |
|
852 // Avoid off-by-one errors in numElements computation. |
|
853 // For the last element, we will only touch the data for the |
|
854 // element and nothing beyond it. |
|
855 long bytesRemaining = state.bufferBinding->byteLength() - state.offset; |
|
856 long numElements = 0; |
|
857 if (bytesRemaining >= state.bytesPerElement) |
|
858 numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride; |
|
859 if (numElements < smallestNumElements) |
|
860 smallestNumElements = numElements; |
|
861 } |
|
862 } |
|
863 } |
|
864 |
|
865 if (smallestNumElements == LONG_MAX) |
|
866 smallestNumElements = 0; |
|
867 |
|
868 return numElementsRequired <= smallestNumElements; |
|
869 } |
|
870 |
|
871 bool WebGLRenderingContext::validateWebGLObject(CanvasObject* object) |
|
872 { |
|
873 if (!object) { |
|
874 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
875 return false; |
|
876 } |
|
877 if (object->context() != this) { |
|
878 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
879 return false; |
|
880 } |
|
881 return true; |
|
882 } |
|
883 |
|
884 void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec) |
|
885 { |
|
886 UNUSED_PARAM(ec); |
|
887 |
|
888 if (!validateDrawMode(mode)) |
|
889 return; |
|
890 |
|
891 if (first < 0 || count < 0) { |
|
892 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
893 return; |
|
894 } |
|
895 |
|
896 // Ensure we have a valid rendering state |
|
897 CheckedInt<int32_t> checkedFirst(first); |
|
898 CheckedInt<int32_t> checkedCount(count); |
|
899 CheckedInt<int32_t> checkedSum = checkedFirst + checkedCount; |
|
900 if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) { |
|
901 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
902 return; |
|
903 } |
|
904 |
|
905 bool vertexAttrib0Simulated = false; |
|
906 if (!isGLES2Compliant()) { |
|
907 vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1); |
|
908 handleNPOTTextures(true); |
|
909 } |
|
910 m_context->drawArrays(mode, first, count); |
|
911 if (!isGLES2Compliant()) { |
|
912 handleNPOTTextures(false); |
|
913 if (vertexAttrib0Simulated) |
|
914 restoreStatesAfterVertexAttrib0Simulation(); |
|
915 } |
|
916 cleanupAfterGraphicsCall(true); |
|
917 } |
|
918 |
|
919 void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigned long type, long offset, ExceptionCode& ec) |
|
920 { |
|
921 UNUSED_PARAM(ec); |
|
922 |
|
923 if (!validateDrawMode(mode)) |
|
924 return; |
|
925 |
|
926 switch (type) { |
|
927 case GraphicsContext3D::UNSIGNED_BYTE: |
|
928 case GraphicsContext3D::UNSIGNED_SHORT: |
|
929 break; |
|
930 default: |
|
931 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
932 return; |
|
933 } |
|
934 |
|
935 if (count < 0 || offset < 0) { |
|
936 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
937 return; |
|
938 } |
|
939 |
|
940 // Ensure we have a valid rendering state |
|
941 long numElements; |
|
942 |
|
943 if (!validateElementArraySize(count, type, offset)) { |
|
944 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
945 return; |
|
946 } |
|
947 |
|
948 if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) |
|
949 if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) { |
|
950 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
951 return; |
|
952 } |
|
953 |
|
954 bool vertexAttrib0Simulated = false; |
|
955 if (!isGLES2Compliant()) { |
|
956 vertexAttrib0Simulated = simulateVertexAttrib0(numElements); |
|
957 handleNPOTTextures(true); |
|
958 } |
|
959 m_context->drawElements(mode, count, type, offset); |
|
960 if (!isGLES2Compliant()) { |
|
961 handleNPOTTextures(false); |
|
962 if (vertexAttrib0Simulated) |
|
963 restoreStatesAfterVertexAttrib0Simulation(); |
|
964 } |
|
965 cleanupAfterGraphicsCall(true); |
|
966 } |
|
967 |
|
968 void WebGLRenderingContext::enable(unsigned long cap) |
|
969 { |
|
970 if (!isGLES2Compliant()) { |
|
971 if (!validateCapability(cap)) |
|
972 return; |
|
973 } |
|
974 m_context->enable(cap); |
|
975 cleanupAfterGraphicsCall(false); |
|
976 } |
|
977 |
|
978 void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec) |
|
979 { |
|
980 UNUSED_PARAM(ec); |
|
981 if (index >= m_maxVertexAttribs) { |
|
982 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
983 return; |
|
984 } |
|
985 |
|
986 if (index >= m_vertexAttribState.size()) |
|
987 m_vertexAttribState.resize(index + 1); |
|
988 |
|
989 m_vertexAttribState[index].enabled = true; |
|
990 |
|
991 m_context->enableVertexAttribArray(index); |
|
992 cleanupAfterGraphicsCall(false); |
|
993 } |
|
994 |
|
995 void WebGLRenderingContext::finish() |
|
996 { |
|
997 m_context->finish(); |
|
998 cleanupAfterGraphicsCall(true); |
|
999 } |
|
1000 |
|
1001 |
|
1002 void WebGLRenderingContext::flush() |
|
1003 { |
|
1004 m_context->flush(); |
|
1005 cleanupAfterGraphicsCall(true); |
|
1006 } |
|
1007 |
|
1008 void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec) |
|
1009 { |
|
1010 UNUSED_PARAM(ec); |
|
1011 if (!validateFramebufferFuncParameters(target, attachment)) |
|
1012 return; |
|
1013 if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) { |
|
1014 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1015 return; |
|
1016 } |
|
1017 if (buffer && buffer->context() != this) { |
|
1018 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1019 return; |
|
1020 } |
|
1021 // Don't allow the default framebuffer to be mutated; all current |
|
1022 // implementations use an FBO internally in place of the default |
|
1023 // FBO. |
|
1024 if (!m_framebufferBinding || !m_framebufferBinding->object()) { |
|
1025 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1026 return; |
|
1027 } |
|
1028 if (buffer && buffer->object()) { |
|
1029 bool isConflicted = false; |
|
1030 switch (attachment) { |
|
1031 case GraphicsContext3D::DEPTH_ATTACHMENT: |
|
1032 if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached()) |
|
1033 isConflicted = true; |
|
1034 if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16) |
|
1035 isConflicted = true; |
|
1036 break; |
|
1037 case GraphicsContext3D::STENCIL_ATTACHMENT: |
|
1038 if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached()) |
|
1039 isConflicted = true; |
|
1040 if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8) |
|
1041 isConflicted = true; |
|
1042 break; |
|
1043 case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: |
|
1044 if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached()) |
|
1045 isConflicted = true; |
|
1046 if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL) |
|
1047 isConflicted = true; |
|
1048 break; |
|
1049 } |
|
1050 if (isConflicted) { |
|
1051 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1052 return; |
|
1053 } |
|
1054 } |
|
1055 m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer); |
|
1056 m_framebufferBinding->setAttachment(attachment, buffer); |
|
1057 cleanupAfterGraphicsCall(false); |
|
1058 } |
|
1059 |
|
1060 void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec) |
|
1061 { |
|
1062 UNUSED_PARAM(ec); |
|
1063 if (!validateFramebufferFuncParameters(target, attachment)) |
|
1064 return; |
|
1065 if (level) { |
|
1066 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1067 return; |
|
1068 } |
|
1069 if (texture && texture->context() != this) { |
|
1070 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1071 return; |
|
1072 } |
|
1073 // Don't allow the default framebuffer to be mutated; all current |
|
1074 // implementations use an FBO internally in place of the default |
|
1075 // FBO. |
|
1076 if (!m_framebufferBinding || !m_framebufferBinding->object()) { |
|
1077 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1078 return; |
|
1079 } |
|
1080 m_context->framebufferTexture2D(target, attachment, textarget, texture, level); |
|
1081 m_framebufferBinding->setAttachment(attachment, texture); |
|
1082 cleanupAfterGraphicsCall(false); |
|
1083 } |
|
1084 |
|
1085 void WebGLRenderingContext::frontFace(unsigned long mode) |
|
1086 { |
|
1087 m_context->frontFace(mode); |
|
1088 cleanupAfterGraphicsCall(false); |
|
1089 } |
|
1090 |
|
1091 void WebGLRenderingContext::generateMipmap(unsigned long target) |
|
1092 { |
|
1093 RefPtr<WebGLTexture> tex; |
|
1094 if (!isGLES2Compliant()) { |
|
1095 if (target == GraphicsContext3D::TEXTURE_2D) |
|
1096 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding; |
|
1097 else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) |
|
1098 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding; |
|
1099 if (tex && !tex->canGenerateMipmaps()) { |
|
1100 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1101 return; |
|
1102 } |
|
1103 } |
|
1104 m_context->generateMipmap(target); |
|
1105 if (!isGLES2Compliant()) { |
|
1106 if (tex) |
|
1107 tex->generateMipmapLevelInfo(); |
|
1108 } |
|
1109 cleanupAfterGraphicsCall(false); |
|
1110 } |
|
1111 |
|
1112 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec) |
|
1113 { |
|
1114 UNUSED_PARAM(ec); |
|
1115 ActiveInfo info; |
|
1116 if (!validateWebGLObject(program)) |
|
1117 return 0; |
|
1118 if (!m_context->getActiveAttrib(program, index, info)) { |
|
1119 return 0; |
|
1120 } |
|
1121 return WebGLActiveInfo::create(info.name, info.type, info.size); |
|
1122 } |
|
1123 |
|
1124 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec) |
|
1125 { |
|
1126 UNUSED_PARAM(ec); |
|
1127 ActiveInfo info; |
|
1128 if (!validateWebGLObject(program)) |
|
1129 return 0; |
|
1130 if (!m_context->getActiveUniform(program, index, info)) { |
|
1131 return 0; |
|
1132 } |
|
1133 if (!isGLES2Compliant()) { |
|
1134 if (info.size > 1 && !info.name.endsWith("[0]")) |
|
1135 info.name.append("[0]"); |
|
1136 } |
|
1137 return WebGLActiveInfo::create(info.name, info.type, info.size); |
|
1138 } |
|
1139 |
|
1140 bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<WebGLShader*>& shaderObjects, ExceptionCode& ec) |
|
1141 { |
|
1142 UNUSED_PARAM(ec); |
|
1143 shaderObjects.clear(); |
|
1144 if (!validateWebGLObject(program)) |
|
1145 return false; |
|
1146 int numShaders = 0; |
|
1147 m_context->getProgramiv(program, GraphicsContext3D::ATTACHED_SHADERS, &numShaders); |
|
1148 if (numShaders) { |
|
1149 OwnArrayPtr<unsigned int> shaders(new unsigned int[numShaders]); |
|
1150 int count; |
|
1151 m_context->getAttachedShaders(program, numShaders, &count, shaders.get()); |
|
1152 if (count != numShaders) |
|
1153 return false; |
|
1154 shaderObjects.resize(numShaders); |
|
1155 for (int ii = 0; ii < numShaders; ++ii) { |
|
1156 WebGLShader* shader = findShader(shaders[ii]); |
|
1157 if (!shader) { |
|
1158 shaderObjects.clear(); |
|
1159 return false; |
|
1160 } |
|
1161 shaderObjects[ii] = shader; |
|
1162 } |
|
1163 } |
|
1164 return true; |
|
1165 } |
|
1166 |
|
1167 int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name) |
|
1168 { |
|
1169 return m_context->getAttribLocation(program, name); |
|
1170 } |
|
1171 |
|
1172 WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) |
|
1173 { |
|
1174 UNUSED_PARAM(ec); |
|
1175 if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) { |
|
1176 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1177 return WebGLGetInfo(); |
|
1178 } |
|
1179 |
|
1180 if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) { |
|
1181 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1182 return WebGLGetInfo(); |
|
1183 } |
|
1184 |
|
1185 WebGLStateRestorer(this, false); |
|
1186 int value; |
|
1187 m_context->getBufferParameteriv(target, pname, &value); |
|
1188 if (pname == GraphicsContext3D::BUFFER_SIZE) |
|
1189 return WebGLGetInfo(static_cast<long>(value)); |
|
1190 else |
|
1191 return WebGLGetInfo(static_cast<unsigned long>(value)); |
|
1192 } |
|
1193 |
|
1194 PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes() |
|
1195 { |
|
1196 // We always need to return a new WebGLContextAttributes object to |
|
1197 // prevent the user from mutating any cached version. |
|
1198 return WebGLContextAttributes::create(m_context->getContextAttributes()); |
|
1199 } |
|
1200 |
|
1201 unsigned long WebGLRenderingContext::getError() |
|
1202 { |
|
1203 return m_context->getError(); |
|
1204 } |
|
1205 |
|
1206 WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec) |
|
1207 { |
|
1208 UNUSED_PARAM(ec); |
|
1209 if (!validateFramebufferFuncParameters(target, attachment)) |
|
1210 return WebGLGetInfo(); |
|
1211 switch (pname) { |
|
1212 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: |
|
1213 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: |
|
1214 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: |
|
1215 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: |
|
1216 break; |
|
1217 default: |
|
1218 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1219 return WebGLGetInfo(); |
|
1220 } |
|
1221 |
|
1222 if (!m_framebufferBinding || !m_framebufferBinding->object()) { |
|
1223 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1224 return WebGLGetInfo(); |
|
1225 } |
|
1226 |
|
1227 if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { |
|
1228 WebGLStateRestorer(this, false); |
|
1229 int value; |
|
1230 m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value); |
|
1231 if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) |
|
1232 return WebGLGetInfo(static_cast<unsigned long>(value)); |
|
1233 else |
|
1234 return WebGLGetInfo(static_cast<long>(value)); |
|
1235 } else { |
|
1236 WebGLStateRestorer(this, false); |
|
1237 int type = 0; |
|
1238 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); |
|
1239 int value = 0; |
|
1240 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value); |
|
1241 switch (type) { |
|
1242 case GraphicsContext3D::RENDERBUFFER: |
|
1243 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(findRenderbuffer(static_cast<Platform3DObject>(value)))); |
|
1244 case GraphicsContext3D::TEXTURE: |
|
1245 return WebGLGetInfo(PassRefPtr<WebGLTexture>(findTexture(static_cast<Platform3DObject>(value)))); |
|
1246 default: |
|
1247 // FIXME: raise exception? |
|
1248 return WebGLGetInfo(); |
|
1249 } |
|
1250 } |
|
1251 } |
|
1252 |
|
1253 WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec) |
|
1254 { |
|
1255 UNUSED_PARAM(ec); |
|
1256 WebGLStateRestorer(this, false); |
|
1257 switch (pname) { |
|
1258 case GraphicsContext3D::ACTIVE_TEXTURE: |
|
1259 return getUnsignedLongParameter(pname); |
|
1260 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE: |
|
1261 return getWebGLFloatArrayParameter(pname); |
|
1262 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE: |
|
1263 return getWebGLFloatArrayParameter(pname); |
|
1264 case GraphicsContext3D::ALPHA_BITS: |
|
1265 return getLongParameter(pname); |
|
1266 case GraphicsContext3D::ARRAY_BUFFER_BINDING: |
|
1267 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer)); |
|
1268 case GraphicsContext3D::BLEND: |
|
1269 return getBooleanParameter(pname); |
|
1270 case GraphicsContext3D::BLEND_COLOR: |
|
1271 return getWebGLFloatArrayParameter(pname); |
|
1272 case GraphicsContext3D::BLEND_DST_ALPHA: |
|
1273 return getUnsignedLongParameter(pname); |
|
1274 case GraphicsContext3D::BLEND_DST_RGB: |
|
1275 return getUnsignedLongParameter(pname); |
|
1276 case GraphicsContext3D::BLEND_EQUATION_ALPHA: |
|
1277 return getUnsignedLongParameter(pname); |
|
1278 case GraphicsContext3D::BLEND_EQUATION_RGB: |
|
1279 return getUnsignedLongParameter(pname); |
|
1280 case GraphicsContext3D::BLEND_SRC_ALPHA: |
|
1281 return getUnsignedLongParameter(pname); |
|
1282 case GraphicsContext3D::BLEND_SRC_RGB: |
|
1283 return getUnsignedLongParameter(pname); |
|
1284 case GraphicsContext3D::BLUE_BITS: |
|
1285 return getLongParameter(pname); |
|
1286 case GraphicsContext3D::COLOR_CLEAR_VALUE: |
|
1287 return getWebGLFloatArrayParameter(pname); |
|
1288 case GraphicsContext3D::COLOR_WRITEMASK: |
|
1289 return getBooleanArrayParameter(pname); |
|
1290 case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS: |
|
1291 // Defined as null in the spec |
|
1292 return WebGLGetInfo(); |
|
1293 case GraphicsContext3D::CULL_FACE: |
|
1294 return getBooleanParameter(pname); |
|
1295 case GraphicsContext3D::CULL_FACE_MODE: |
|
1296 return getUnsignedLongParameter(pname); |
|
1297 case GraphicsContext3D::CURRENT_PROGRAM: |
|
1298 return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram)); |
|
1299 case GraphicsContext3D::DEPTH_BITS: |
|
1300 return getLongParameter(pname); |
|
1301 case GraphicsContext3D::DEPTH_CLEAR_VALUE: |
|
1302 return getFloatParameter(pname); |
|
1303 case GraphicsContext3D::DEPTH_FUNC: |
|
1304 return getUnsignedLongParameter(pname); |
|
1305 case GraphicsContext3D::DEPTH_RANGE: |
|
1306 return getWebGLFloatArrayParameter(pname); |
|
1307 case GraphicsContext3D::DEPTH_TEST: |
|
1308 return getBooleanParameter(pname); |
|
1309 case GraphicsContext3D::DEPTH_WRITEMASK: |
|
1310 return getBooleanParameter(pname); |
|
1311 case GraphicsContext3D::DITHER: |
|
1312 return getBooleanParameter(pname); |
|
1313 case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING: |
|
1314 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundElementArrayBuffer)); |
|
1315 case GraphicsContext3D::FRAMEBUFFER_BINDING: |
|
1316 return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding)); |
|
1317 case GraphicsContext3D::FRONT_FACE: |
|
1318 return getUnsignedLongParameter(pname); |
|
1319 case GraphicsContext3D::GENERATE_MIPMAP_HINT: |
|
1320 return getUnsignedLongParameter(pname); |
|
1321 case GraphicsContext3D::GREEN_BITS: |
|
1322 return getLongParameter(pname); |
|
1323 case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT: |
|
1324 return getLongParameter(pname); |
|
1325 case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE: |
|
1326 return getLongParameter(pname); |
|
1327 case GraphicsContext3D::LINE_WIDTH: |
|
1328 return getFloatParameter(pname); |
|
1329 case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS: |
|
1330 return getLongParameter(pname); |
|
1331 case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE: |
|
1332 return getLongParameter(pname); |
|
1333 case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS: |
|
1334 return getLongParameter(pname); |
|
1335 case GraphicsContext3D::MAX_RENDERBUFFER_SIZE: |
|
1336 return getLongParameter(pname); |
|
1337 case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS: |
|
1338 return getLongParameter(pname); |
|
1339 case GraphicsContext3D::MAX_TEXTURE_SIZE: |
|
1340 return getLongParameter(pname); |
|
1341 case GraphicsContext3D::MAX_VARYING_VECTORS: |
|
1342 return getLongParameter(pname); |
|
1343 case GraphicsContext3D::MAX_VERTEX_ATTRIBS: |
|
1344 return getLongParameter(pname); |
|
1345 case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS: |
|
1346 return getLongParameter(pname); |
|
1347 case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS: |
|
1348 return getLongParameter(pname); |
|
1349 case GraphicsContext3D::MAX_VIEWPORT_DIMS: |
|
1350 return getWebGLIntArrayParameter(pname); |
|
1351 case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS: |
|
1352 // WebGL 1.0 specifies that there are no compressed texture formats. |
|
1353 return WebGLGetInfo(static_cast<long>(0)); |
|
1354 case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS: |
|
1355 // FIXME: should we always return 0 for this? |
|
1356 return getLongParameter(pname); |
|
1357 case GraphicsContext3D::PACK_ALIGNMENT: |
|
1358 return getLongParameter(pname); |
|
1359 case GraphicsContext3D::POLYGON_OFFSET_FACTOR: |
|
1360 return getFloatParameter(pname); |
|
1361 case GraphicsContext3D::POLYGON_OFFSET_FILL: |
|
1362 return getBooleanParameter(pname); |
|
1363 case GraphicsContext3D::POLYGON_OFFSET_UNITS: |
|
1364 return getFloatParameter(pname); |
|
1365 case GraphicsContext3D::RED_BITS: |
|
1366 return getLongParameter(pname); |
|
1367 case GraphicsContext3D::RENDERBUFFER_BINDING: |
|
1368 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding)); |
|
1369 case GraphicsContext3D::SAMPLE_BUFFERS: |
|
1370 return getLongParameter(pname); |
|
1371 case GraphicsContext3D::SAMPLE_COVERAGE_INVERT: |
|
1372 return getBooleanParameter(pname); |
|
1373 case GraphicsContext3D::SAMPLE_COVERAGE_VALUE: |
|
1374 return getFloatParameter(pname); |
|
1375 case GraphicsContext3D::SAMPLES: |
|
1376 return getLongParameter(pname); |
|
1377 case GraphicsContext3D::SCISSOR_BOX: |
|
1378 return getWebGLIntArrayParameter(pname); |
|
1379 case GraphicsContext3D::SCISSOR_TEST: |
|
1380 return getBooleanParameter(pname); |
|
1381 case GraphicsContext3D::STENCIL_BACK_FAIL: |
|
1382 return getUnsignedLongParameter(pname); |
|
1383 case GraphicsContext3D::STENCIL_BACK_FUNC: |
|
1384 return getUnsignedLongParameter(pname); |
|
1385 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL: |
|
1386 return getUnsignedLongParameter(pname); |
|
1387 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS: |
|
1388 return getUnsignedLongParameter(pname); |
|
1389 case GraphicsContext3D::STENCIL_BACK_REF: |
|
1390 return getLongParameter(pname); |
|
1391 case GraphicsContext3D::STENCIL_BACK_VALUE_MASK: |
|
1392 return getUnsignedLongParameter(pname); |
|
1393 case GraphicsContext3D::STENCIL_BACK_WRITEMASK: |
|
1394 return getUnsignedLongParameter(pname); |
|
1395 case GraphicsContext3D::STENCIL_BITS: |
|
1396 return getLongParameter(pname); |
|
1397 case GraphicsContext3D::STENCIL_CLEAR_VALUE: |
|
1398 return getLongParameter(pname); |
|
1399 case GraphicsContext3D::STENCIL_FAIL: |
|
1400 return getUnsignedLongParameter(pname); |
|
1401 case GraphicsContext3D::STENCIL_FUNC: |
|
1402 return getUnsignedLongParameter(pname); |
|
1403 case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL: |
|
1404 return getUnsignedLongParameter(pname); |
|
1405 case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS: |
|
1406 return getUnsignedLongParameter(pname); |
|
1407 case GraphicsContext3D::STENCIL_REF: |
|
1408 return getLongParameter(pname); |
|
1409 case GraphicsContext3D::STENCIL_TEST: |
|
1410 return getBooleanParameter(pname); |
|
1411 case GraphicsContext3D::STENCIL_VALUE_MASK: |
|
1412 return getUnsignedLongParameter(pname); |
|
1413 case GraphicsContext3D::STENCIL_WRITEMASK: |
|
1414 return getUnsignedLongParameter(pname); |
|
1415 case GraphicsContext3D::SUBPIXEL_BITS: |
|
1416 return getLongParameter(pname); |
|
1417 case GraphicsContext3D::TEXTURE_BINDING_2D: |
|
1418 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding)); |
|
1419 case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP: |
|
1420 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding)); |
|
1421 case GraphicsContext3D::UNPACK_ALIGNMENT: |
|
1422 // FIXME: should this be "long" in the spec? |
|
1423 return getIntParameter(pname); |
|
1424 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL: |
|
1425 return WebGLGetInfo(m_unpackFlipY); |
|
1426 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL: |
|
1427 return WebGLGetInfo(m_unpackPremultiplyAlpha); |
|
1428 case GraphicsContext3D::VIEWPORT: |
|
1429 return getWebGLIntArrayParameter(pname); |
|
1430 default: |
|
1431 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1432 return WebGLGetInfo(); |
|
1433 } |
|
1434 } |
|
1435 |
|
1436 WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec) |
|
1437 { |
|
1438 UNUSED_PARAM(ec); |
|
1439 if (!validateWebGLObject(program)) |
|
1440 return WebGLGetInfo(); |
|
1441 |
|
1442 WebGLStateRestorer(this, false); |
|
1443 int value = 0; |
|
1444 switch (pname) { |
|
1445 case GraphicsContext3D::DELETE_STATUS: |
|
1446 case GraphicsContext3D::VALIDATE_STATUS: |
|
1447 m_context->getProgramiv(program, pname, &value); |
|
1448 return WebGLGetInfo(static_cast<bool>(value)); |
|
1449 case GraphicsContext3D::LINK_STATUS: |
|
1450 if (program->isLinkFailureFlagSet()) |
|
1451 return WebGLGetInfo(false); |
|
1452 m_context->getProgramiv(program, pname, &value); |
|
1453 return WebGLGetInfo(static_cast<bool>(value)); |
|
1454 case GraphicsContext3D::INFO_LOG_LENGTH: |
|
1455 case GraphicsContext3D::ATTACHED_SHADERS: |
|
1456 case GraphicsContext3D::ACTIVE_ATTRIBUTES: |
|
1457 case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH: |
|
1458 case GraphicsContext3D::ACTIVE_UNIFORMS: |
|
1459 case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH: |
|
1460 m_context->getProgramiv(program, pname, &value); |
|
1461 return WebGLGetInfo(static_cast<long>(value)); |
|
1462 default: |
|
1463 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1464 return WebGLGetInfo(); |
|
1465 } |
|
1466 } |
|
1467 |
|
1468 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec) |
|
1469 { |
|
1470 UNUSED_PARAM(ec); |
|
1471 if (!validateWebGLObject(program)) |
|
1472 return ""; |
|
1473 WebGLStateRestorer(this, false); |
|
1474 return m_context->getProgramInfoLog(program); |
|
1475 } |
|
1476 |
|
1477 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) |
|
1478 { |
|
1479 UNUSED_PARAM(ec); |
|
1480 if (target != GraphicsContext3D::RENDERBUFFER) { |
|
1481 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1482 return WebGLGetInfo(); |
|
1483 } |
|
1484 |
|
1485 WebGLStateRestorer(this, false); |
|
1486 int value = 0; |
|
1487 switch (pname) { |
|
1488 case GraphicsContext3D::RENDERBUFFER_WIDTH: |
|
1489 case GraphicsContext3D::RENDERBUFFER_HEIGHT: |
|
1490 case GraphicsContext3D::RENDERBUFFER_RED_SIZE: |
|
1491 case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE: |
|
1492 case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE: |
|
1493 case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE: |
|
1494 case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE: |
|
1495 case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE: |
|
1496 m_context->getRenderbufferParameteriv(target, pname, &value); |
|
1497 return WebGLGetInfo(static_cast<long>(value)); |
|
1498 case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: |
|
1499 if (!m_renderbufferBinding) { |
|
1500 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1501 return WebGLGetInfo(); |
|
1502 } |
|
1503 return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); |
|
1504 default: |
|
1505 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1506 return WebGLGetInfo(); |
|
1507 } |
|
1508 } |
|
1509 |
|
1510 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec) |
|
1511 { |
|
1512 UNUSED_PARAM(ec); |
|
1513 if (!validateWebGLObject(shader)) |
|
1514 return WebGLGetInfo(); |
|
1515 WebGLStateRestorer(this, false); |
|
1516 int value = 0; |
|
1517 switch (pname) { |
|
1518 case GraphicsContext3D::DELETE_STATUS: |
|
1519 case GraphicsContext3D::COMPILE_STATUS: |
|
1520 m_context->getShaderiv(shader, pname, &value); |
|
1521 return WebGLGetInfo(static_cast<bool>(value)); |
|
1522 case GraphicsContext3D::SHADER_TYPE: |
|
1523 m_context->getShaderiv(shader, pname, &value); |
|
1524 return WebGLGetInfo(static_cast<unsigned long>(value)); |
|
1525 case GraphicsContext3D::INFO_LOG_LENGTH: |
|
1526 case GraphicsContext3D::SHADER_SOURCE_LENGTH: |
|
1527 m_context->getShaderiv(shader, pname, &value); |
|
1528 return WebGLGetInfo(static_cast<long>(value)); |
|
1529 default: |
|
1530 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1531 return WebGLGetInfo(); |
|
1532 } |
|
1533 } |
|
1534 |
|
1535 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec) |
|
1536 { |
|
1537 UNUSED_PARAM(ec); |
|
1538 if (!validateWebGLObject(shader)) |
|
1539 return ""; |
|
1540 WebGLStateRestorer(this, false); |
|
1541 return m_context->getShaderInfoLog(shader); |
|
1542 } |
|
1543 |
|
1544 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec) |
|
1545 { |
|
1546 UNUSED_PARAM(ec); |
|
1547 if (!validateWebGLObject(shader)) |
|
1548 return ""; |
|
1549 WebGLStateRestorer(this, false); |
|
1550 return m_context->getShaderSource(shader); |
|
1551 } |
|
1552 |
|
1553 String WebGLRenderingContext::getString(unsigned long name) |
|
1554 { |
|
1555 WebGLStateRestorer(this, false); |
|
1556 return m_context->getString(name); |
|
1557 } |
|
1558 |
|
1559 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) |
|
1560 { |
|
1561 UNUSED_PARAM(ec); |
|
1562 if (target != GraphicsContext3D::TEXTURE_2D |
|
1563 && target != GraphicsContext3D::TEXTURE_CUBE_MAP) { |
|
1564 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1565 return WebGLGetInfo(); |
|
1566 } |
|
1567 WebGLStateRestorer(this, false); |
|
1568 int value = 0; |
|
1569 switch (pname) { |
|
1570 case GraphicsContext3D::TEXTURE_MAG_FILTER: |
|
1571 case GraphicsContext3D::TEXTURE_MIN_FILTER: |
|
1572 case GraphicsContext3D::TEXTURE_WRAP_S: |
|
1573 case GraphicsContext3D::TEXTURE_WRAP_T: |
|
1574 m_context->getTexParameteriv(target, pname, &value); |
|
1575 return WebGLGetInfo(static_cast<unsigned long>(value)); |
|
1576 default: |
|
1577 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1578 return WebGLGetInfo(); |
|
1579 } |
|
1580 } |
|
1581 |
|
1582 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec) |
|
1583 { |
|
1584 UNUSED_PARAM(ec); |
|
1585 if (!validateWebGLObject(program)) |
|
1586 return WebGLGetInfo(); |
|
1587 if (!uniformLocation) { |
|
1588 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1589 return WebGLGetInfo(); |
|
1590 } |
|
1591 if (uniformLocation->program() != program) { |
|
1592 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1593 return WebGLGetInfo(); |
|
1594 } |
|
1595 long location = uniformLocation->location(); |
|
1596 |
|
1597 WebGLStateRestorer(this, false); |
|
1598 // FIXME: make this more efficient using WebGLUniformLocation and caching types in it |
|
1599 int activeUniforms = 0; |
|
1600 m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms); |
|
1601 for (int i = 0; i < activeUniforms; i++) { |
|
1602 ActiveInfo info; |
|
1603 if (!m_context->getActiveUniform(program, i, info)) |
|
1604 return WebGLGetInfo(); |
|
1605 // Strip "[0]" from the name if it's an array. |
|
1606 if (info.size > 1) |
|
1607 info.name = info.name.left(info.name.length() - 3); |
|
1608 // If it's an array, we need to iterate through each element, appending "[index]" to the name. |
|
1609 for (int index = 0; index < info.size; ++index) { |
|
1610 String name = info.name; |
|
1611 if (info.size > 1 && index >= 1) { |
|
1612 name.append('['); |
|
1613 name.append(String::number(index)); |
|
1614 name.append(']'); |
|
1615 } |
|
1616 // Now need to look this up by name again to find its location |
|
1617 long loc = m_context->getUniformLocation(program, name); |
|
1618 if (loc == location) { |
|
1619 // Found it. Use the type in the ActiveInfo to determine the return type. |
|
1620 GraphicsContext3D::WebGLEnumType baseType; |
|
1621 unsigned length; |
|
1622 switch (info.type) { |
|
1623 case GraphicsContext3D::BOOL: |
|
1624 baseType = GraphicsContext3D::BOOL; |
|
1625 length = 1; |
|
1626 break; |
|
1627 case GraphicsContext3D::BOOL_VEC2: |
|
1628 baseType = GraphicsContext3D::BOOL; |
|
1629 length = 2; |
|
1630 break; |
|
1631 case GraphicsContext3D::BOOL_VEC3: |
|
1632 baseType = GraphicsContext3D::BOOL; |
|
1633 length = 3; |
|
1634 break; |
|
1635 case GraphicsContext3D::BOOL_VEC4: |
|
1636 baseType = GraphicsContext3D::BOOL; |
|
1637 length = 4; |
|
1638 break; |
|
1639 case GraphicsContext3D::INT: |
|
1640 baseType = GraphicsContext3D::INT; |
|
1641 length = 1; |
|
1642 break; |
|
1643 case GraphicsContext3D::INT_VEC2: |
|
1644 baseType = GraphicsContext3D::INT; |
|
1645 length = 2; |
|
1646 break; |
|
1647 case GraphicsContext3D::INT_VEC3: |
|
1648 baseType = GraphicsContext3D::INT; |
|
1649 length = 3; |
|
1650 break; |
|
1651 case GraphicsContext3D::INT_VEC4: |
|
1652 baseType = GraphicsContext3D::INT; |
|
1653 length = 4; |
|
1654 break; |
|
1655 case GraphicsContext3D::FLOAT: |
|
1656 baseType = GraphicsContext3D::FLOAT; |
|
1657 length = 1; |
|
1658 break; |
|
1659 case GraphicsContext3D::FLOAT_VEC2: |
|
1660 baseType = GraphicsContext3D::FLOAT; |
|
1661 length = 2; |
|
1662 break; |
|
1663 case GraphicsContext3D::FLOAT_VEC3: |
|
1664 baseType = GraphicsContext3D::FLOAT; |
|
1665 length = 3; |
|
1666 break; |
|
1667 case GraphicsContext3D::FLOAT_VEC4: |
|
1668 baseType = GraphicsContext3D::FLOAT; |
|
1669 length = 4; |
|
1670 break; |
|
1671 case GraphicsContext3D::FLOAT_MAT2: |
|
1672 baseType = GraphicsContext3D::FLOAT; |
|
1673 length = 4; |
|
1674 break; |
|
1675 case GraphicsContext3D::FLOAT_MAT3: |
|
1676 baseType = GraphicsContext3D::FLOAT; |
|
1677 length = 9; |
|
1678 break; |
|
1679 case GraphicsContext3D::FLOAT_MAT4: |
|
1680 baseType = GraphicsContext3D::FLOAT; |
|
1681 length = 16; |
|
1682 break; |
|
1683 default: |
|
1684 // Can't handle this type |
|
1685 // FIXME: what to do about samplers? |
|
1686 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1687 return WebGLGetInfo(); |
|
1688 } |
|
1689 switch (baseType) { |
|
1690 case GraphicsContext3D::FLOAT: { |
|
1691 float value[16] = {0}; |
|
1692 m_context->getUniformfv(program, location, value); |
|
1693 if (length == 1) |
|
1694 return WebGLGetInfo(value[0]); |
|
1695 return WebGLGetInfo(Float32Array::create(value, length)); |
|
1696 } |
|
1697 case GraphicsContext3D::INT: { |
|
1698 int value[16] = {0}; |
|
1699 m_context->getUniformiv(program, location, value); |
|
1700 if (length == 1) |
|
1701 return WebGLGetInfo(static_cast<long>(value[0])); |
|
1702 return WebGLGetInfo(Int32Array::create(value, length)); |
|
1703 } |
|
1704 case GraphicsContext3D::BOOL: { |
|
1705 int value[16] = {0}; |
|
1706 m_context->getUniformiv(program, location, value); |
|
1707 if (length > 1) { |
|
1708 unsigned char boolValue[16] = {0}; |
|
1709 for (unsigned j = 0; j < length; j++) |
|
1710 boolValue[j] = static_cast<bool>(value[j]); |
|
1711 return WebGLGetInfo(Uint8Array::create(boolValue, length)); |
|
1712 } |
|
1713 return WebGLGetInfo(static_cast<bool>(value[0])); |
|
1714 } |
|
1715 default: |
|
1716 notImplemented(); |
|
1717 } |
|
1718 } |
|
1719 } |
|
1720 } |
|
1721 // If we get here, something went wrong in our unfortunately complex logic above |
|
1722 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1723 return WebGLGetInfo(); |
|
1724 } |
|
1725 |
|
1726 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec) |
|
1727 { |
|
1728 UNUSED_PARAM(ec); |
|
1729 if (!validateWebGLObject(program)) |
|
1730 return 0; |
|
1731 WebGLStateRestorer(this, false); |
|
1732 long uniformLocation = m_context->getUniformLocation(program, name); |
|
1733 if (uniformLocation == -1) |
|
1734 return 0; |
|
1735 return WebGLUniformLocation::create(program, uniformLocation); |
|
1736 } |
|
1737 |
|
1738 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec) |
|
1739 { |
|
1740 UNUSED_PARAM(ec); |
|
1741 WebGLStateRestorer(this, false); |
|
1742 if (index >= m_maxVertexAttribs) { |
|
1743 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1744 return WebGLGetInfo(); |
|
1745 } |
|
1746 switch (pname) { |
|
1747 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: |
|
1748 if (!isGLES2Compliant() && !index && m_vertexAttribState[0].bufferBinding == m_vertexAttrib0Buffer |
|
1749 || index >= m_vertexAttribState.size() |
|
1750 || !m_vertexAttribState[index].bufferBinding |
|
1751 || !m_vertexAttribState[index].bufferBinding->object()) |
|
1752 return WebGLGetInfo(); |
|
1753 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_vertexAttribState[index].bufferBinding)); |
|
1754 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED: |
|
1755 if (index >= m_vertexAttribState.size()) |
|
1756 return WebGLGetInfo(false); |
|
1757 return WebGLGetInfo(m_vertexAttribState[index].enabled); |
|
1758 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED: |
|
1759 if (index >= m_vertexAttribState.size()) |
|
1760 return WebGLGetInfo(false); |
|
1761 return WebGLGetInfo(m_vertexAttribState[index].normalized); |
|
1762 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE: |
|
1763 if (index >= m_vertexAttribState.size()) |
|
1764 return WebGLGetInfo(static_cast<long>(4)); |
|
1765 return WebGLGetInfo(m_vertexAttribState[index].size); |
|
1766 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE: |
|
1767 if (index >= m_vertexAttribState.size()) |
|
1768 return WebGLGetInfo(static_cast<long>(0)); |
|
1769 return WebGLGetInfo(m_vertexAttribState[index].originalStride); |
|
1770 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE: |
|
1771 if (index >= m_vertexAttribState.size()) |
|
1772 return WebGLGetInfo(static_cast<unsigned long>(GraphicsContext3D::FLOAT)); |
|
1773 return WebGLGetInfo(m_vertexAttribState[index].type); |
|
1774 case GraphicsContext3D::CURRENT_VERTEX_ATTRIB: |
|
1775 if (index >= m_vertexAttribState.size()) { |
|
1776 float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; |
|
1777 return WebGLGetInfo(Float32Array::create(value, 4)); |
|
1778 } |
|
1779 return WebGLGetInfo(Float32Array::create(m_vertexAttribState[index].value, 4)); |
|
1780 default: |
|
1781 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1782 return WebGLGetInfo(); |
|
1783 } |
|
1784 } |
|
1785 |
|
1786 long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname) |
|
1787 { |
|
1788 long result = m_context->getVertexAttribOffset(index, pname); |
|
1789 cleanupAfterGraphicsCall(false); |
|
1790 return result; |
|
1791 } |
|
1792 |
|
1793 void WebGLRenderingContext::hint(unsigned long target, unsigned long mode) |
|
1794 { |
|
1795 if (!isGLES2Compliant()) { |
|
1796 if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) { |
|
1797 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1798 return; |
|
1799 } |
|
1800 } |
|
1801 m_context->hint(target, mode); |
|
1802 cleanupAfterGraphicsCall(false); |
|
1803 } |
|
1804 |
|
1805 bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer) |
|
1806 { |
|
1807 if (!buffer) |
|
1808 return false; |
|
1809 |
|
1810 return m_context->isBuffer(buffer); |
|
1811 } |
|
1812 |
|
1813 bool WebGLRenderingContext::isEnabled(unsigned long cap) |
|
1814 { |
|
1815 if (!isGLES2Compliant()) { |
|
1816 if (!validateCapability(cap)) |
|
1817 return false; |
|
1818 } |
|
1819 return m_context->isEnabled(cap); |
|
1820 } |
|
1821 |
|
1822 bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer) |
|
1823 { |
|
1824 if (!framebuffer) |
|
1825 return false; |
|
1826 |
|
1827 return m_context->isFramebuffer(framebuffer); |
|
1828 } |
|
1829 |
|
1830 bool WebGLRenderingContext::isProgram(WebGLProgram* program) |
|
1831 { |
|
1832 if (!program) |
|
1833 return false; |
|
1834 |
|
1835 return m_context->isProgram(program); |
|
1836 } |
|
1837 |
|
1838 bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer) |
|
1839 { |
|
1840 if (!renderbuffer) |
|
1841 return false; |
|
1842 |
|
1843 return m_context->isRenderbuffer(renderbuffer); |
|
1844 } |
|
1845 |
|
1846 bool WebGLRenderingContext::isShader(WebGLShader* shader) |
|
1847 { |
|
1848 if (!shader) |
|
1849 return false; |
|
1850 |
|
1851 return m_context->isShader(shader); |
|
1852 } |
|
1853 |
|
1854 bool WebGLRenderingContext::isTexture(WebGLTexture* texture) |
|
1855 { |
|
1856 if (!texture) |
|
1857 return false; |
|
1858 |
|
1859 return m_context->isTexture(texture); |
|
1860 } |
|
1861 |
|
1862 void WebGLRenderingContext::lineWidth(double width) |
|
1863 { |
|
1864 m_context->lineWidth((float) width); |
|
1865 cleanupAfterGraphicsCall(false); |
|
1866 } |
|
1867 |
|
1868 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec) |
|
1869 { |
|
1870 UNUSED_PARAM(ec); |
|
1871 if (!validateWebGLObject(program)) |
|
1872 return; |
|
1873 if (!isGLES2Compliant()) { |
|
1874 Vector<WebGLShader*> shaders; |
|
1875 bool succeed = getAttachedShaders(program, shaders, ec); |
|
1876 if (succeed) { |
|
1877 bool vShader = false; |
|
1878 bool fShader = false; |
|
1879 for (size_t ii = 0; ii < shaders.size() && (!vShader || !fShader); ++ii) { |
|
1880 if (shaders[ii]->getType() == GraphicsContext3D::VERTEX_SHADER) |
|
1881 vShader = true; |
|
1882 else if (shaders[ii]->getType() == GraphicsContext3D::FRAGMENT_SHADER) |
|
1883 fShader = true; |
|
1884 } |
|
1885 if (!vShader || !fShader) |
|
1886 succeed = false; |
|
1887 } |
|
1888 if (!succeed) { |
|
1889 program->setLinkFailureFlag(true); |
|
1890 return; |
|
1891 } |
|
1892 program->setLinkFailureFlag(false); |
|
1893 } |
|
1894 |
|
1895 m_context->linkProgram(program); |
|
1896 program->cacheActiveAttribLocations(); |
|
1897 cleanupAfterGraphicsCall(false); |
|
1898 } |
|
1899 |
|
1900 void WebGLRenderingContext::pixelStorei(unsigned long pname, long param) |
|
1901 { |
|
1902 switch (pname) { |
|
1903 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL: |
|
1904 m_unpackFlipY = param; |
|
1905 break; |
|
1906 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL: |
|
1907 m_unpackPremultiplyAlpha = param; |
|
1908 break; |
|
1909 case GraphicsContext3D::PACK_ALIGNMENT: |
|
1910 case GraphicsContext3D::UNPACK_ALIGNMENT: |
|
1911 m_context->pixelStorei(pname, param); |
|
1912 if (param == 1 || param == 2 || param == 4 || param == 8) { |
|
1913 if (pname == GraphicsContext3D::PACK_ALIGNMENT) |
|
1914 m_packAlignment = static_cast<int>(param); |
|
1915 else // GraphicsContext3D::UNPACK_ALIGNMENT: |
|
1916 m_unpackAlignment = static_cast<int>(param); |
|
1917 } |
|
1918 break; |
|
1919 default: |
|
1920 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1921 return; |
|
1922 } |
|
1923 cleanupAfterGraphicsCall(false); |
|
1924 } |
|
1925 |
|
1926 void WebGLRenderingContext::polygonOffset(double factor, double units) |
|
1927 { |
|
1928 m_context->polygonOffset((float) factor, (float) units); |
|
1929 cleanupAfterGraphicsCall(false); |
|
1930 } |
|
1931 |
|
1932 void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels) |
|
1933 { |
|
1934 // Validate input parameters. |
|
1935 unsigned long componentsPerPixel, bytesPerComponent; |
|
1936 if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) { |
|
1937 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
1938 return; |
|
1939 } |
|
1940 if (!pixels) { |
|
1941 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1942 return; |
|
1943 } |
|
1944 if (width < 0 || height < 0) { |
|
1945 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
1946 return; |
|
1947 } |
|
1948 if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) { |
|
1949 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1950 return; |
|
1951 } |
|
1952 // Validate array type against pixel type. |
|
1953 if (type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray() |
|
1954 || type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray()) { |
|
1955 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1956 return; |
|
1957 } |
|
1958 // Calculate array size, taking into consideration of PACK_ALIGNMENT. |
|
1959 unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width; |
|
1960 unsigned long padding = 0; |
|
1961 unsigned long residualBytes = bytesPerRow % m_packAlignment; |
|
1962 if (residualBytes) { |
|
1963 padding = m_packAlignment - residualBytes; |
|
1964 bytesPerRow += padding; |
|
1965 } |
|
1966 // The last row needs no padding. |
|
1967 unsigned long totalBytes = bytesPerRow * height - padding; |
|
1968 unsigned long num = totalBytes / bytesPerComponent; |
|
1969 if (pixels->length() < num) { |
|
1970 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
1971 return; |
|
1972 } |
|
1973 void* data = pixels->baseAddress(); |
|
1974 m_context->readPixels(x, y, width, height, format, type, data); |
|
1975 #if PLATFORM(CG) |
|
1976 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e., |
|
1977 // when alpha is off, readPixels should set alpha to 255 instead of 0. |
|
1978 if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) { |
|
1979 if (type == GraphicsContext3D::UNSIGNED_BYTE) { |
|
1980 unsigned char* pixels = reinterpret_cast<unsigned char*>(data); |
|
1981 for (long iy = 0; iy < height; ++iy) { |
|
1982 for (long ix = 0; ix < width; ++ix) { |
|
1983 pixels[componentsPerPixel - 1] = 255; |
|
1984 pixels += componentsPerPixel; |
|
1985 } |
|
1986 pixels += padding; |
|
1987 } |
|
1988 } |
|
1989 // FIXME: check whether we need to do the same with UNSIGNED_SHORT. |
|
1990 } |
|
1991 #endif |
|
1992 cleanupAfterGraphicsCall(false); |
|
1993 } |
|
1994 |
|
1995 void WebGLRenderingContext::releaseShaderCompiler() |
|
1996 { |
|
1997 m_context->releaseShaderCompiler(); |
|
1998 cleanupAfterGraphicsCall(false); |
|
1999 } |
|
2000 |
|
2001 void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) |
|
2002 { |
|
2003 switch (internalformat) { |
|
2004 case GraphicsContext3D::DEPTH_COMPONENT16: |
|
2005 case GraphicsContext3D::RGBA4: |
|
2006 case GraphicsContext3D::RGB5_A1: |
|
2007 case GraphicsContext3D::RGB565: |
|
2008 case GraphicsContext3D::STENCIL_INDEX8: |
|
2009 case GraphicsContext3D::DEPTH_STENCIL: |
|
2010 m_context->renderbufferStorage(target, internalformat, width, height); |
|
2011 if (m_renderbufferBinding) { |
|
2012 m_renderbufferBinding->setInternalFormat(internalformat); |
|
2013 if (m_framebufferBinding) |
|
2014 m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get()); |
|
2015 } |
|
2016 cleanupAfterGraphicsCall(false); |
|
2017 break; |
|
2018 default: |
|
2019 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
2020 } |
|
2021 } |
|
2022 |
|
2023 void WebGLRenderingContext::sampleCoverage(double value, bool invert) |
|
2024 { |
|
2025 m_context->sampleCoverage((float) value, invert); |
|
2026 cleanupAfterGraphicsCall(false); |
|
2027 } |
|
2028 |
|
2029 void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height) |
|
2030 { |
|
2031 m_context->scissor(x, y, width, height); |
|
2032 cleanupAfterGraphicsCall(false); |
|
2033 } |
|
2034 |
|
2035 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec) |
|
2036 { |
|
2037 UNUSED_PARAM(ec); |
|
2038 if (!validateWebGLObject(shader)) |
|
2039 return; |
|
2040 m_context->shaderSource(shader, string); |
|
2041 cleanupAfterGraphicsCall(false); |
|
2042 } |
|
2043 |
|
2044 void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask) |
|
2045 { |
|
2046 m_context->stencilFunc(func, ref, mask); |
|
2047 cleanupAfterGraphicsCall(false); |
|
2048 } |
|
2049 |
|
2050 void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask) |
|
2051 { |
|
2052 m_context->stencilFuncSeparate(face, func, ref, mask); |
|
2053 cleanupAfterGraphicsCall(false); |
|
2054 } |
|
2055 |
|
2056 void WebGLRenderingContext::stencilMask(unsigned long mask) |
|
2057 { |
|
2058 m_context->stencilMask(mask); |
|
2059 cleanupAfterGraphicsCall(false); |
|
2060 } |
|
2061 |
|
2062 void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask) |
|
2063 { |
|
2064 m_context->stencilMaskSeparate(face, mask); |
|
2065 cleanupAfterGraphicsCall(false); |
|
2066 } |
|
2067 |
|
2068 void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass) |
|
2069 { |
|
2070 m_context->stencilOp(fail, zfail, zpass); |
|
2071 cleanupAfterGraphicsCall(false); |
|
2072 } |
|
2073 |
|
2074 void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass) |
|
2075 { |
|
2076 m_context->stencilOpSeparate(face, fail, zfail, zpass); |
|
2077 cleanupAfterGraphicsCall(false); |
|
2078 } |
|
2079 |
|
2080 void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsigned internalformat, |
|
2081 unsigned width, unsigned height, unsigned border, |
|
2082 unsigned format, unsigned type, void* pixels, ExceptionCode& ec) |
|
2083 { |
|
2084 // FIXME: For now we ignore any errors returned |
|
2085 ec = 0; |
|
2086 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type)) |
|
2087 return; |
|
2088 if (!isGLES2Compliant()) { |
|
2089 if (level && WebGLTexture::isNPOT(width, height)) { |
|
2090 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2091 return; |
|
2092 } |
|
2093 } |
|
2094 m_context->texImage2D(target, level, internalformat, width, height, |
|
2095 border, format, type, pixels); |
|
2096 WebGLTexture* tex = getTextureBinding(target); |
|
2097 if (!isGLES2Compliant()) { |
|
2098 if (tex) |
|
2099 tex->setLevelInfo(target, level, internalformat, width, height, type); |
|
2100 } |
|
2101 if (m_framebufferBinding && tex) |
|
2102 m_framebufferBinding->onAttachedObjectChange(tex); |
|
2103 cleanupAfterGraphicsCall(false); |
|
2104 } |
|
2105 |
|
2106 void WebGLRenderingContext::texImage2DImpl(unsigned target, unsigned level, unsigned internalformat, |
|
2107 unsigned format, unsigned type, Image* image, |
|
2108 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2109 { |
|
2110 ec = 0; |
|
2111 Vector<uint8_t> data; |
|
2112 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) { |
|
2113 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2114 return; |
|
2115 } |
|
2116 if (m_unpackAlignment != 1) |
|
2117 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); |
|
2118 texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, |
|
2119 format, type, data.data(), ec); |
|
2120 if (m_unpackAlignment != 1) |
|
2121 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); |
|
2122 } |
|
2123 |
|
2124 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, |
|
2125 unsigned width, unsigned height, unsigned border, |
|
2126 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec) |
|
2127 { |
|
2128 if (!validateTexFuncData(width, height, format, type, pixels)) |
|
2129 return; |
|
2130 void* data = pixels ? pixels->baseAddress() : 0; |
|
2131 Vector<uint8_t> tempData; |
|
2132 bool changeUnpackAlignment = false; |
|
2133 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { |
|
2134 if (!m_context->extractTextureData(width, height, format, type, |
|
2135 m_unpackAlignment, |
|
2136 m_unpackFlipY, m_unpackPremultiplyAlpha, |
|
2137 pixels, |
|
2138 tempData)) |
|
2139 return; |
|
2140 data = tempData.data(); |
|
2141 changeUnpackAlignment = true; |
|
2142 } |
|
2143 if (changeUnpackAlignment) |
|
2144 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); |
|
2145 texImage2DBase(target, level, internalformat, width, height, border, |
|
2146 format, type, data, ec); |
|
2147 if (changeUnpackAlignment) |
|
2148 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); |
|
2149 } |
|
2150 |
|
2151 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, |
|
2152 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec) |
|
2153 { |
|
2154 ec = 0; |
|
2155 Vector<uint8_t> data; |
|
2156 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { |
|
2157 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2158 return; |
|
2159 } |
|
2160 if (m_unpackAlignment != 1) |
|
2161 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); |
|
2162 texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, |
|
2163 format, type, data.data(), ec); |
|
2164 if (m_unpackAlignment != 1) |
|
2165 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); |
|
2166 } |
|
2167 |
|
2168 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, |
|
2169 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec) |
|
2170 { |
|
2171 ec = 0; |
|
2172 if (!image || !image->cachedImage()) { |
|
2173 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2174 return; |
|
2175 } |
|
2176 texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(), |
|
2177 m_unpackFlipY, m_unpackPremultiplyAlpha, ec); |
|
2178 } |
|
2179 |
|
2180 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, |
|
2181 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec) |
|
2182 { |
|
2183 ec = 0; |
|
2184 if (!canvas || !canvas->buffer()) { |
|
2185 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2186 return; |
|
2187 } |
|
2188 texImage2DImpl(target, level, internalformat, format, type, canvas->buffer()->image(), |
|
2189 m_unpackFlipY, m_unpackPremultiplyAlpha, ec); |
|
2190 } |
|
2191 |
|
2192 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, |
|
2193 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec) |
|
2194 { |
|
2195 // FIXME: Need to implement this call |
|
2196 UNUSED_PARAM(target); |
|
2197 UNUSED_PARAM(level); |
|
2198 UNUSED_PARAM(internalformat); |
|
2199 UNUSED_PARAM(format); |
|
2200 UNUSED_PARAM(type); |
|
2201 UNUSED_PARAM(video); |
|
2202 |
|
2203 ec = 0; |
|
2204 cleanupAfterGraphicsCall(false); |
|
2205 } |
|
2206 |
|
2207 // Obsolete texImage2D entry points -- to be removed shortly. (FIXME) |
|
2208 |
|
2209 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels, |
|
2210 ExceptionCode& ec) |
|
2211 { |
|
2212 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels)"); |
|
2213 texImage2D(target, level, pixels, 0, 0, ec); |
|
2214 } |
|
2215 |
|
2216 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels, |
|
2217 bool flipY, ExceptionCode& ec) |
|
2218 { |
|
2219 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY)"); |
|
2220 texImage2D(target, level, pixels, flipY, 0, ec); |
|
2221 } |
|
2222 |
|
2223 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels, |
|
2224 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2225 { |
|
2226 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)"); |
|
2227 ec = 0; |
|
2228 Vector<uint8_t> data; |
|
2229 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) { |
|
2230 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2231 return; |
|
2232 } |
|
2233 texImage2DBase(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0, |
|
2234 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec); |
|
2235 } |
|
2236 |
|
2237 |
|
2238 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image, |
|
2239 ExceptionCode& ec) |
|
2240 { |
|
2241 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image)"); |
|
2242 texImage2D(target, level, image, 0, 0, ec); |
|
2243 } |
|
2244 |
|
2245 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image, |
|
2246 bool flipY, ExceptionCode& ec) |
|
2247 { |
|
2248 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY)"); |
|
2249 texImage2D(target, level, image, flipY, 0, ec); |
|
2250 } |
|
2251 |
|
2252 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image, |
|
2253 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2254 { |
|
2255 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)"); |
|
2256 ec = 0; |
|
2257 if (!image || !image->cachedImage()) { |
|
2258 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2259 return; |
|
2260 } |
|
2261 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(), flipY, premultiplyAlpha, ec); |
|
2262 } |
|
2263 |
|
2264 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas, |
|
2265 ExceptionCode& ec) |
|
2266 { |
|
2267 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas)"); |
|
2268 texImage2D(target, level, canvas, 0, 0, ec); |
|
2269 } |
|
2270 |
|
2271 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas, |
|
2272 bool flipY, ExceptionCode& ec) |
|
2273 { |
|
2274 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY)"); |
|
2275 texImage2D(target, level, canvas, flipY, 0, ec); |
|
2276 } |
|
2277 |
|
2278 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas, |
|
2279 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2280 { |
|
2281 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)"); |
|
2282 ec = 0; |
|
2283 if (!canvas || !canvas->buffer()) { |
|
2284 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2285 return; |
|
2286 } |
|
2287 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(), flipY, premultiplyAlpha, ec); |
|
2288 } |
|
2289 |
|
2290 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video, |
|
2291 ExceptionCode& ec) |
|
2292 { |
|
2293 texImage2D(target, level, video, 0, 0, ec); |
|
2294 } |
|
2295 |
|
2296 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video, |
|
2297 bool flipY, ExceptionCode& ec) |
|
2298 { |
|
2299 texImage2D(target, level, video, flipY, 0, ec); |
|
2300 } |
|
2301 |
|
2302 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video, |
|
2303 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2304 { |
|
2305 // FIXME: Need implement this call |
|
2306 UNUSED_PARAM(target); |
|
2307 UNUSED_PARAM(level); |
|
2308 UNUSED_PARAM(video); |
|
2309 UNUSED_PARAM(flipY); |
|
2310 UNUSED_PARAM(premultiplyAlpha); |
|
2311 |
|
2312 ec = 0; |
|
2313 cleanupAfterGraphicsCall(false); |
|
2314 } |
|
2315 |
|
2316 void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat) |
|
2317 { |
|
2318 if (!isGLES2Compliant()) { |
|
2319 RefPtr<WebGLTexture> tex = 0; |
|
2320 switch (target) { |
|
2321 case GraphicsContext3D::TEXTURE_2D: |
|
2322 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding; |
|
2323 break; |
|
2324 case GraphicsContext3D::TEXTURE_CUBE_MAP: |
|
2325 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding; |
|
2326 break; |
|
2327 default: |
|
2328 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
2329 return; |
|
2330 } |
|
2331 switch (pname) { |
|
2332 case GraphicsContext3D::TEXTURE_MIN_FILTER: |
|
2333 case GraphicsContext3D::TEXTURE_MAG_FILTER: |
|
2334 break; |
|
2335 case GraphicsContext3D::TEXTURE_WRAP_S: |
|
2336 case GraphicsContext3D::TEXTURE_WRAP_T: |
|
2337 if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT |
|
2338 || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) { |
|
2339 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
2340 return; |
|
2341 } |
|
2342 break; |
|
2343 default: |
|
2344 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
2345 return; |
|
2346 } |
|
2347 if (tex) { |
|
2348 if (isFloat) |
|
2349 tex->setParameterf(pname, paramf); |
|
2350 else |
|
2351 tex->setParameteri(pname, parami); |
|
2352 } |
|
2353 } |
|
2354 if (isFloat) |
|
2355 m_context->texParameterf(target, pname, paramf); |
|
2356 else |
|
2357 m_context->texParameteri(target, pname, parami); |
|
2358 cleanupAfterGraphicsCall(false); |
|
2359 } |
|
2360 |
|
2361 void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param) |
|
2362 { |
|
2363 texParameter(target, pname, param, 0, true); |
|
2364 } |
|
2365 |
|
2366 void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param) |
|
2367 { |
|
2368 texParameter(target, pname, 0, param, false); |
|
2369 } |
|
2370 |
|
2371 void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2372 unsigned width, unsigned height, |
|
2373 unsigned format, unsigned type, void* pixels, ExceptionCode& ec) |
|
2374 { |
|
2375 // FIXME: For now we ignore any errors returned |
|
2376 ec = 0; |
|
2377 if (!validateTexFuncFormatAndType(format, type)) |
|
2378 return; |
|
2379 |
|
2380 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); |
|
2381 cleanupAfterGraphicsCall(false); |
|
2382 } |
|
2383 |
|
2384 void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2385 unsigned format, unsigned type, |
|
2386 Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2387 { |
|
2388 ec = 0; |
|
2389 Vector<uint8_t> data; |
|
2390 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) { |
|
2391 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2392 return; |
|
2393 } |
|
2394 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), |
|
2395 format, type, data.data(), ec); |
|
2396 } |
|
2397 |
|
2398 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2399 unsigned width, unsigned height, |
|
2400 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec) |
|
2401 { |
|
2402 if (!validateTexFuncData(width, height, format, type, pixels)) |
|
2403 return; |
|
2404 void* data = pixels ? pixels->baseAddress() : 0; |
|
2405 Vector<uint8_t> tempData; |
|
2406 bool changeUnpackAlignment = false; |
|
2407 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { |
|
2408 if (!m_context->extractTextureData(width, height, format, type, |
|
2409 m_unpackAlignment, |
|
2410 m_unpackFlipY, m_unpackPremultiplyAlpha, |
|
2411 pixels, |
|
2412 tempData)) |
|
2413 return; |
|
2414 data = tempData.data(); |
|
2415 changeUnpackAlignment = true; |
|
2416 } |
|
2417 if (changeUnpackAlignment) |
|
2418 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); |
|
2419 texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec); |
|
2420 if (changeUnpackAlignment) |
|
2421 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); |
|
2422 } |
|
2423 |
|
2424 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2425 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec) |
|
2426 { |
|
2427 ec = 0; |
|
2428 Vector<uint8_t> data; |
|
2429 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { |
|
2430 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2431 return; |
|
2432 } |
|
2433 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), |
|
2434 format, type, data.data(), ec); |
|
2435 } |
|
2436 |
|
2437 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2438 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec) |
|
2439 { |
|
2440 ec = 0; |
|
2441 if (!image || !image->cachedImage()) { |
|
2442 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2443 return; |
|
2444 } |
|
2445 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(), |
|
2446 m_unpackFlipY, m_unpackPremultiplyAlpha, ec); |
|
2447 } |
|
2448 |
|
2449 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2450 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec) |
|
2451 { |
|
2452 ec = 0; |
|
2453 if (!canvas || !canvas->buffer()) { |
|
2454 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2455 return; |
|
2456 } |
|
2457 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->buffer()->image(), |
|
2458 m_unpackFlipY, m_unpackPremultiplyAlpha, ec); |
|
2459 } |
|
2460 |
|
2461 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2462 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec) |
|
2463 { |
|
2464 // FIXME: Need to implement this call |
|
2465 UNUSED_PARAM(target); |
|
2466 UNUSED_PARAM(level); |
|
2467 UNUSED_PARAM(xoffset); |
|
2468 UNUSED_PARAM(yoffset); |
|
2469 UNUSED_PARAM(format); |
|
2470 UNUSED_PARAM(type); |
|
2471 UNUSED_PARAM(video); |
|
2472 ec = 0; |
|
2473 cleanupAfterGraphicsCall(false); |
|
2474 } |
|
2475 |
|
2476 // Obsolete texSubImage2D entry points -- to be removed shortly. (FIXME) |
|
2477 |
|
2478 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2479 ImageData* pixels, ExceptionCode& ec) |
|
2480 { |
|
2481 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels)"); |
|
2482 texSubImage2D(target, level, xoffset, yoffset, pixels, 0, 0, ec); |
|
2483 } |
|
2484 |
|
2485 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2486 ImageData* pixels, bool flipY, ExceptionCode& ec) |
|
2487 { |
|
2488 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY)"); |
|
2489 texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, 0, ec); |
|
2490 } |
|
2491 |
|
2492 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2493 ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2494 { |
|
2495 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)"); |
|
2496 ec = 0; |
|
2497 Vector<uint8_t> data; |
|
2498 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) { |
|
2499 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2500 return; |
|
2501 } |
|
2502 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), |
|
2503 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec); |
|
2504 } |
|
2505 |
|
2506 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2507 HTMLImageElement* image, ExceptionCode& ec) |
|
2508 { |
|
2509 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image)"); |
|
2510 texSubImage2D(target, level, xoffset, yoffset, image, 0, 0, ec); |
|
2511 } |
|
2512 |
|
2513 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2514 HTMLImageElement* image, bool flipY, ExceptionCode& ec) |
|
2515 { |
|
2516 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY)"); |
|
2517 texSubImage2D(target, level, xoffset, yoffset, image, flipY, 0, ec); |
|
2518 } |
|
2519 |
|
2520 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2521 HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2522 { |
|
2523 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)"); |
|
2524 ec = 0; |
|
2525 if (!image || !image->cachedImage()) { |
|
2526 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2527 return; |
|
2528 } |
|
2529 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(), |
|
2530 flipY, premultiplyAlpha, ec); |
|
2531 } |
|
2532 |
|
2533 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2534 HTMLCanvasElement* canvas, ExceptionCode& ec) |
|
2535 { |
|
2536 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas)"); |
|
2537 texSubImage2D(target, level, xoffset, yoffset, canvas, 0, 0, ec); |
|
2538 } |
|
2539 |
|
2540 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2541 HTMLCanvasElement* canvas, bool flipY, ExceptionCode& ec) |
|
2542 { |
|
2543 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY)"); |
|
2544 texSubImage2D(target, level, xoffset, yoffset, canvas, flipY, 0, ec); |
|
2545 } |
|
2546 |
|
2547 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2548 HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2549 { |
|
2550 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)"); |
|
2551 ec = 0; |
|
2552 if (!canvas || !canvas->buffer()) { |
|
2553 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
2554 return; |
|
2555 } |
|
2556 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(), |
|
2557 flipY, premultiplyAlpha, ec); |
|
2558 } |
|
2559 |
|
2560 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2561 HTMLVideoElement* video, ExceptionCode& ec) |
|
2562 { |
|
2563 texSubImage2D(target, level, xoffset, yoffset, video, 0, 0, ec); |
|
2564 } |
|
2565 |
|
2566 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2567 HTMLVideoElement* video, bool flipY, ExceptionCode& ec) |
|
2568 { |
|
2569 texSubImage2D(target, level, xoffset, yoffset, video, flipY, 0, ec); |
|
2570 } |
|
2571 |
|
2572 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, |
|
2573 HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) |
|
2574 { |
|
2575 // FIXME: Need to implement this call |
|
2576 UNUSED_PARAM(target); |
|
2577 UNUSED_PARAM(level); |
|
2578 UNUSED_PARAM(xoffset); |
|
2579 UNUSED_PARAM(yoffset); |
|
2580 UNUSED_PARAM(video); |
|
2581 UNUSED_PARAM(flipY); |
|
2582 UNUSED_PARAM(premultiplyAlpha); |
|
2583 ec = 0; |
|
2584 cleanupAfterGraphicsCall(false); |
|
2585 } |
|
2586 |
|
2587 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec) |
|
2588 { |
|
2589 UNUSED_PARAM(ec); |
|
2590 if (!location) |
|
2591 return; |
|
2592 |
|
2593 if (location->program() != m_currentProgram) { |
|
2594 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2595 return; |
|
2596 } |
|
2597 |
|
2598 m_context->uniform1f(location->location(), x); |
|
2599 cleanupAfterGraphicsCall(false); |
|
2600 } |
|
2601 |
|
2602 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) |
|
2603 { |
|
2604 UNUSED_PARAM(ec); |
|
2605 if (!validateUniformParameters(location, v, 1)) |
|
2606 return; |
|
2607 |
|
2608 m_context->uniform1fv(location->location(), v->data(), v->length()); |
|
2609 cleanupAfterGraphicsCall(false); |
|
2610 } |
|
2611 |
|
2612 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) |
|
2613 { |
|
2614 UNUSED_PARAM(ec); |
|
2615 if (!validateUniformParameters(location, v, size, 1)) |
|
2616 return; |
|
2617 |
|
2618 m_context->uniform1fv(location->location(), v, size); |
|
2619 cleanupAfterGraphicsCall(false); |
|
2620 } |
|
2621 |
|
2622 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec) |
|
2623 { |
|
2624 UNUSED_PARAM(ec); |
|
2625 if (!location) |
|
2626 return; |
|
2627 |
|
2628 if (location->program() != m_currentProgram) { |
|
2629 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2630 return; |
|
2631 } |
|
2632 |
|
2633 m_context->uniform1i(location->location(), x); |
|
2634 cleanupAfterGraphicsCall(false); |
|
2635 } |
|
2636 |
|
2637 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) |
|
2638 { |
|
2639 UNUSED_PARAM(ec); |
|
2640 if (!validateUniformParameters(location, v, 1)) |
|
2641 return; |
|
2642 |
|
2643 m_context->uniform1iv(location->location(), v->data(), v->length()); |
|
2644 cleanupAfterGraphicsCall(false); |
|
2645 } |
|
2646 |
|
2647 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) |
|
2648 { |
|
2649 UNUSED_PARAM(ec); |
|
2650 if (!validateUniformParameters(location, v, size, 1)) |
|
2651 return; |
|
2652 |
|
2653 m_context->uniform1iv(location->location(), v, size); |
|
2654 cleanupAfterGraphicsCall(false); |
|
2655 } |
|
2656 |
|
2657 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec) |
|
2658 { |
|
2659 UNUSED_PARAM(ec); |
|
2660 if (!location) |
|
2661 return; |
|
2662 |
|
2663 if (location->program() != m_currentProgram) { |
|
2664 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2665 return; |
|
2666 } |
|
2667 |
|
2668 m_context->uniform2f(location->location(), x, y); |
|
2669 cleanupAfterGraphicsCall(false); |
|
2670 } |
|
2671 |
|
2672 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) |
|
2673 { |
|
2674 UNUSED_PARAM(ec); |
|
2675 if (!validateUniformParameters(location, v, 2)) |
|
2676 return; |
|
2677 |
|
2678 m_context->uniform2fv(location->location(), v->data(), v->length() / 2); |
|
2679 cleanupAfterGraphicsCall(false); |
|
2680 } |
|
2681 |
|
2682 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) |
|
2683 { |
|
2684 UNUSED_PARAM(ec); |
|
2685 if (!validateUniformParameters(location, v, size, 2)) |
|
2686 return; |
|
2687 |
|
2688 m_context->uniform2fv(location->location(), v, size / 2); |
|
2689 cleanupAfterGraphicsCall(false); |
|
2690 } |
|
2691 |
|
2692 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec) |
|
2693 { |
|
2694 UNUSED_PARAM(ec); |
|
2695 if (!location) |
|
2696 return; |
|
2697 |
|
2698 if (location->program() != m_currentProgram) { |
|
2699 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2700 return; |
|
2701 } |
|
2702 |
|
2703 m_context->uniform2i(location->location(), x, y); |
|
2704 cleanupAfterGraphicsCall(false); |
|
2705 } |
|
2706 |
|
2707 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) |
|
2708 { |
|
2709 UNUSED_PARAM(ec); |
|
2710 if (!validateUniformParameters(location, v, 2)) |
|
2711 return; |
|
2712 |
|
2713 m_context->uniform2iv(location->location(), v->data(), v->length() / 2); |
|
2714 cleanupAfterGraphicsCall(false); |
|
2715 } |
|
2716 |
|
2717 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) |
|
2718 { |
|
2719 UNUSED_PARAM(ec); |
|
2720 if (!validateUniformParameters(location, v, size, 2)) |
|
2721 return; |
|
2722 |
|
2723 m_context->uniform2iv(location->location(), v, size / 2); |
|
2724 cleanupAfterGraphicsCall(false); |
|
2725 } |
|
2726 |
|
2727 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec) |
|
2728 { |
|
2729 UNUSED_PARAM(ec); |
|
2730 if (!location) |
|
2731 return; |
|
2732 |
|
2733 if (location->program() != m_currentProgram) { |
|
2734 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2735 return; |
|
2736 } |
|
2737 |
|
2738 m_context->uniform3f(location->location(), x, y, z); |
|
2739 cleanupAfterGraphicsCall(false); |
|
2740 } |
|
2741 |
|
2742 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) |
|
2743 { |
|
2744 UNUSED_PARAM(ec); |
|
2745 if (!validateUniformParameters(location, v, 3)) |
|
2746 return; |
|
2747 |
|
2748 m_context->uniform3fv(location->location(), v->data(), v->length() / 3); |
|
2749 cleanupAfterGraphicsCall(false); |
|
2750 } |
|
2751 |
|
2752 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) |
|
2753 { |
|
2754 UNUSED_PARAM(ec); |
|
2755 if (!validateUniformParameters(location, v, size, 3)) |
|
2756 return; |
|
2757 |
|
2758 m_context->uniform3fv(location->location(), v, size / 3); |
|
2759 cleanupAfterGraphicsCall(false); |
|
2760 } |
|
2761 |
|
2762 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec) |
|
2763 { |
|
2764 UNUSED_PARAM(ec); |
|
2765 if (!location) |
|
2766 return; |
|
2767 |
|
2768 if (location->program() != m_currentProgram) { |
|
2769 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2770 return; |
|
2771 } |
|
2772 |
|
2773 m_context->uniform3i(location->location(), x, y, z); |
|
2774 cleanupAfterGraphicsCall(false); |
|
2775 } |
|
2776 |
|
2777 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) |
|
2778 { |
|
2779 UNUSED_PARAM(ec); |
|
2780 if (!validateUniformParameters(location, v, 3)) |
|
2781 return; |
|
2782 |
|
2783 m_context->uniform3iv(location->location(), v->data(), v->length() / 3); |
|
2784 cleanupAfterGraphicsCall(false); |
|
2785 } |
|
2786 |
|
2787 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) |
|
2788 { |
|
2789 UNUSED_PARAM(ec); |
|
2790 if (!validateUniformParameters(location, v, size, 3)) |
|
2791 return; |
|
2792 |
|
2793 m_context->uniform3iv(location->location(), v, size / 3); |
|
2794 cleanupAfterGraphicsCall(false); |
|
2795 } |
|
2796 |
|
2797 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec) |
|
2798 { |
|
2799 UNUSED_PARAM(ec); |
|
2800 if (!location) |
|
2801 return; |
|
2802 |
|
2803 if (location->program() != m_currentProgram) { |
|
2804 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2805 return; |
|
2806 } |
|
2807 |
|
2808 m_context->uniform4f(location->location(), x, y, z, w); |
|
2809 cleanupAfterGraphicsCall(false); |
|
2810 } |
|
2811 |
|
2812 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) |
|
2813 { |
|
2814 UNUSED_PARAM(ec); |
|
2815 if (!validateUniformParameters(location, v, 4)) |
|
2816 return; |
|
2817 |
|
2818 m_context->uniform4fv(location->location(), v->data(), v->length() / 4); |
|
2819 cleanupAfterGraphicsCall(false); |
|
2820 } |
|
2821 |
|
2822 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) |
|
2823 { |
|
2824 UNUSED_PARAM(ec); |
|
2825 if (!validateUniformParameters(location, v, size, 4)) |
|
2826 return; |
|
2827 |
|
2828 m_context->uniform4fv(location->location(), v, size / 4); |
|
2829 cleanupAfterGraphicsCall(false); |
|
2830 } |
|
2831 |
|
2832 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec) |
|
2833 { |
|
2834 UNUSED_PARAM(ec); |
|
2835 if (!location) |
|
2836 return; |
|
2837 |
|
2838 if (location->program() != m_currentProgram) { |
|
2839 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2840 return; |
|
2841 } |
|
2842 |
|
2843 m_context->uniform4i(location->location(), x, y, z, w); |
|
2844 cleanupAfterGraphicsCall(false); |
|
2845 } |
|
2846 |
|
2847 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) |
|
2848 { |
|
2849 UNUSED_PARAM(ec); |
|
2850 if (!validateUniformParameters(location, v, 4)) |
|
2851 return; |
|
2852 |
|
2853 m_context->uniform4iv(location->location(), v->data(), v->length() / 4); |
|
2854 cleanupAfterGraphicsCall(false); |
|
2855 } |
|
2856 |
|
2857 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) |
|
2858 { |
|
2859 UNUSED_PARAM(ec); |
|
2860 if (!validateUniformParameters(location, v, size, 4)) |
|
2861 return; |
|
2862 |
|
2863 m_context->uniform4iv(location->location(), v, size / 4); |
|
2864 cleanupAfterGraphicsCall(false); |
|
2865 } |
|
2866 |
|
2867 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec) |
|
2868 { |
|
2869 UNUSED_PARAM(ec); |
|
2870 if (!validateUniformMatrixParameters(location, transpose, v, 4)) |
|
2871 return; |
|
2872 m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4); |
|
2873 cleanupAfterGraphicsCall(false); |
|
2874 } |
|
2875 |
|
2876 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) |
|
2877 { |
|
2878 UNUSED_PARAM(ec); |
|
2879 if (!validateUniformMatrixParameters(location, transpose, v, size, 4)) |
|
2880 return; |
|
2881 m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4); |
|
2882 cleanupAfterGraphicsCall(false); |
|
2883 } |
|
2884 |
|
2885 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec) |
|
2886 { |
|
2887 UNUSED_PARAM(ec); |
|
2888 if (!validateUniformMatrixParameters(location, transpose, v, 9)) |
|
2889 return; |
|
2890 m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9); |
|
2891 cleanupAfterGraphicsCall(false); |
|
2892 } |
|
2893 |
|
2894 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) |
|
2895 { |
|
2896 UNUSED_PARAM(ec); |
|
2897 if (!validateUniformMatrixParameters(location, transpose, v, size, 9)) |
|
2898 return; |
|
2899 m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9); |
|
2900 cleanupAfterGraphicsCall(false); |
|
2901 } |
|
2902 |
|
2903 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec) |
|
2904 { |
|
2905 UNUSED_PARAM(ec); |
|
2906 if (!validateUniformMatrixParameters(location, transpose, v, 16)) |
|
2907 return; |
|
2908 m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16); |
|
2909 cleanupAfterGraphicsCall(false); |
|
2910 } |
|
2911 |
|
2912 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) |
|
2913 { |
|
2914 UNUSED_PARAM(ec); |
|
2915 if (!validateUniformMatrixParameters(location, transpose, v, size, 16)) |
|
2916 return; |
|
2917 m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16); |
|
2918 cleanupAfterGraphicsCall(false); |
|
2919 } |
|
2920 |
|
2921 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) |
|
2922 { |
|
2923 UNUSED_PARAM(ec); |
|
2924 if (program && program->context() != this) { |
|
2925 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
2926 return; |
|
2927 } |
|
2928 m_currentProgram = program; |
|
2929 m_context->useProgram(program); |
|
2930 cleanupAfterGraphicsCall(false); |
|
2931 } |
|
2932 |
|
2933 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec) |
|
2934 { |
|
2935 UNUSED_PARAM(ec); |
|
2936 if (!validateWebGLObject(program)) |
|
2937 return; |
|
2938 m_context->validateProgram(program); |
|
2939 cleanupAfterGraphicsCall(false); |
|
2940 } |
|
2941 |
|
2942 void WebGLRenderingContext::vertexAttrib1f(unsigned long index, float v0) |
|
2943 { |
|
2944 vertexAttribfImpl(index, 1, v0, 0.0f, 0.0f, 1.0f); |
|
2945 } |
|
2946 |
|
2947 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, Float32Array* v) |
|
2948 { |
|
2949 vertexAttribfvImpl(index, v, 1); |
|
2950 } |
|
2951 |
|
2952 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, float* v, int size) |
|
2953 { |
|
2954 vertexAttribfvImpl(index, v, size, 1); |
|
2955 } |
|
2956 |
|
2957 void WebGLRenderingContext::vertexAttrib2f(unsigned long index, float v0, float v1) |
|
2958 { |
|
2959 vertexAttribfImpl(index, 2, v0, v1, 0.0f, 1.0f); |
|
2960 } |
|
2961 |
|
2962 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, Float32Array* v) |
|
2963 { |
|
2964 vertexAttribfvImpl(index, v, 2); |
|
2965 } |
|
2966 |
|
2967 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, float* v, int size) |
|
2968 { |
|
2969 vertexAttribfvImpl(index, v, size, 2); |
|
2970 } |
|
2971 |
|
2972 void WebGLRenderingContext::vertexAttrib3f(unsigned long index, float v0, float v1, float v2) |
|
2973 { |
|
2974 vertexAttribfImpl(index, 3, v0, v1, v2, 1.0f); |
|
2975 } |
|
2976 |
|
2977 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, Float32Array* v) |
|
2978 { |
|
2979 vertexAttribfvImpl(index, v, 3); |
|
2980 } |
|
2981 |
|
2982 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, float* v, int size) |
|
2983 { |
|
2984 vertexAttribfvImpl(index, v, size, 3); |
|
2985 } |
|
2986 |
|
2987 void WebGLRenderingContext::vertexAttrib4f(unsigned long index, float v0, float v1, float v2, float v3) |
|
2988 { |
|
2989 vertexAttribfImpl(index, 4, v0, v1, v2, v3); |
|
2990 } |
|
2991 |
|
2992 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, Float32Array* v) |
|
2993 { |
|
2994 vertexAttribfvImpl(index, v, 4); |
|
2995 } |
|
2996 |
|
2997 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int size) |
|
2998 { |
|
2999 vertexAttribfvImpl(index, v, size, 4); |
|
3000 } |
|
3001 |
|
3002 void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, long offset, ExceptionCode& ec) |
|
3003 { |
|
3004 if (index >= m_maxVertexAttribs) { |
|
3005 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3006 return; |
|
3007 } |
|
3008 if (size < 1 || size > 4 || stride < 0 || offset < 0) { |
|
3009 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3010 return; |
|
3011 } |
|
3012 if (!m_boundArrayBuffer) { |
|
3013 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3014 return; |
|
3015 } |
|
3016 // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride |
|
3017 long bytesPerElement = size * sizeInBytes(type, ec); |
|
3018 if (bytesPerElement <= 0) |
|
3019 return; |
|
3020 |
|
3021 if (index >= m_vertexAttribState.size()) |
|
3022 m_vertexAttribState.resize(index + 1); |
|
3023 |
|
3024 long validatedStride = bytesPerElement; |
|
3025 if (stride != 0) { |
|
3026 if ((long) stride < bytesPerElement) { |
|
3027 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3028 return; |
|
3029 } |
|
3030 validatedStride = stride; |
|
3031 } |
|
3032 m_vertexAttribState[index].bufferBinding = m_boundArrayBuffer; |
|
3033 m_vertexAttribState[index].bytesPerElement = bytesPerElement; |
|
3034 m_vertexAttribState[index].size = size; |
|
3035 m_vertexAttribState[index].type = type; |
|
3036 m_vertexAttribState[index].normalized = normalized; |
|
3037 m_vertexAttribState[index].stride = validatedStride; |
|
3038 m_vertexAttribState[index].originalStride = stride; |
|
3039 m_vertexAttribState[index].offset = offset; |
|
3040 m_context->vertexAttribPointer(index, size, type, normalized, stride, offset); |
|
3041 cleanupAfterGraphicsCall(false); |
|
3042 } |
|
3043 |
|
3044 void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height) |
|
3045 { |
|
3046 if (isnan(x)) |
|
3047 x = 0; |
|
3048 if (isnan(y)) |
|
3049 y = 0; |
|
3050 if (isnan(width)) |
|
3051 width = 100; |
|
3052 if (isnan(height)) |
|
3053 height = 100; |
|
3054 m_context->viewport(x, y, width, height); |
|
3055 cleanupAfterGraphicsCall(false); |
|
3056 } |
|
3057 |
|
3058 void WebGLRenderingContext::removeObject(CanvasObject* object) |
|
3059 { |
|
3060 m_canvasObjects.remove(object); |
|
3061 } |
|
3062 |
|
3063 void WebGLRenderingContext::addObject(CanvasObject* object) |
|
3064 { |
|
3065 removeObject(object); |
|
3066 m_canvasObjects.add(object); |
|
3067 } |
|
3068 |
|
3069 void WebGLRenderingContext::detachAndRemoveAllObjects() |
|
3070 { |
|
3071 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end(); |
|
3072 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) |
|
3073 (*it)->detachContext(); |
|
3074 |
|
3075 m_canvasObjects.clear(); |
|
3076 } |
|
3077 |
|
3078 WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj) |
|
3079 { |
|
3080 if (!obj) |
|
3081 return 0; |
|
3082 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end(); |
|
3083 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) { |
|
3084 if ((*it)->isTexture() && (*it)->object() == obj) |
|
3085 return reinterpret_cast<WebGLTexture*>((*it).get()); |
|
3086 } |
|
3087 return 0; |
|
3088 } |
|
3089 |
|
3090 WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj) |
|
3091 { |
|
3092 if (!obj) |
|
3093 return 0; |
|
3094 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end(); |
|
3095 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) { |
|
3096 if ((*it)->isRenderbuffer() && (*it)->object() == obj) |
|
3097 return reinterpret_cast<WebGLRenderbuffer*>((*it).get()); |
|
3098 } |
|
3099 return 0; |
|
3100 } |
|
3101 |
|
3102 WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj) |
|
3103 { |
|
3104 if (!obj) |
|
3105 return 0; |
|
3106 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end(); |
|
3107 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) { |
|
3108 if ((*it)->isBuffer() && (*it)->object() == obj) |
|
3109 return reinterpret_cast<WebGLBuffer*>((*it).get()); |
|
3110 } |
|
3111 return 0; |
|
3112 } |
|
3113 |
|
3114 WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj) |
|
3115 { |
|
3116 if (!obj) |
|
3117 return 0; |
|
3118 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end(); |
|
3119 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) { |
|
3120 if ((*it)->isShader() && (*it)->object() == obj) |
|
3121 return reinterpret_cast<WebGLShader*>((*it).get()); |
|
3122 } |
|
3123 return 0; |
|
3124 } |
|
3125 |
|
3126 WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname) |
|
3127 { |
|
3128 unsigned char value; |
|
3129 m_context->getBooleanv(pname, &value); |
|
3130 return WebGLGetInfo(static_cast<bool>(value)); |
|
3131 } |
|
3132 |
|
3133 WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(unsigned long pname) |
|
3134 { |
|
3135 if (pname != GraphicsContext3D::COLOR_WRITEMASK) { |
|
3136 notImplemented(); |
|
3137 return WebGLGetInfo(0, 0); |
|
3138 } |
|
3139 unsigned char value[4] = {0}; |
|
3140 m_context->getBooleanv(pname, value); |
|
3141 bool boolValue[4]; |
|
3142 for (int ii = 0; ii < 4; ++ii) |
|
3143 boolValue[ii] = static_cast<bool>(value[ii]); |
|
3144 return WebGLGetInfo(boolValue, 4); |
|
3145 } |
|
3146 |
|
3147 WebGLGetInfo WebGLRenderingContext::getFloatParameter(unsigned long pname) |
|
3148 { |
|
3149 float value; |
|
3150 m_context->getFloatv(pname, &value); |
|
3151 return WebGLGetInfo(static_cast<float>(value)); |
|
3152 } |
|
3153 |
|
3154 WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname) |
|
3155 { |
|
3156 return getLongParameter(pname); |
|
3157 } |
|
3158 |
|
3159 WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname) |
|
3160 { |
|
3161 int value; |
|
3162 m_context->getIntegerv(pname, &value); |
|
3163 return WebGLGetInfo(static_cast<long>(value)); |
|
3164 } |
|
3165 |
|
3166 WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname) |
|
3167 { |
|
3168 int value; |
|
3169 m_context->getIntegerv(pname, &value); |
|
3170 return WebGLGetInfo(static_cast<unsigned long>(value)); |
|
3171 } |
|
3172 |
|
3173 WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname) |
|
3174 { |
|
3175 float value[4] = {0}; |
|
3176 m_context->getFloatv(pname, value); |
|
3177 unsigned length = 0; |
|
3178 switch (pname) { |
|
3179 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE: |
|
3180 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE: |
|
3181 case GraphicsContext3D::DEPTH_RANGE: |
|
3182 length = 2; |
|
3183 break; |
|
3184 case GraphicsContext3D::BLEND_COLOR: |
|
3185 case GraphicsContext3D::COLOR_CLEAR_VALUE: |
|
3186 length = 4; |
|
3187 break; |
|
3188 default: |
|
3189 notImplemented(); |
|
3190 } |
|
3191 return WebGLGetInfo(Float32Array::create(value, length)); |
|
3192 } |
|
3193 |
|
3194 WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(unsigned long pname) |
|
3195 { |
|
3196 int value[4] = {0}; |
|
3197 m_context->getIntegerv(pname, value); |
|
3198 unsigned length = 0; |
|
3199 switch (pname) { |
|
3200 case GraphicsContext3D::MAX_VIEWPORT_DIMS: |
|
3201 length = 2; |
|
3202 break; |
|
3203 case GraphicsContext3D::SCISSOR_BOX: |
|
3204 case GraphicsContext3D::VIEWPORT: |
|
3205 length = 4; |
|
3206 break; |
|
3207 default: |
|
3208 notImplemented(); |
|
3209 } |
|
3210 return WebGLGetInfo(Int32Array::create(value, length)); |
|
3211 } |
|
3212 |
|
3213 bool WebGLRenderingContext::isGLES2Compliant() |
|
3214 { |
|
3215 return m_context->isGLES2Compliant(); |
|
3216 } |
|
3217 |
|
3218 void WebGLRenderingContext::handleNPOTTextures(bool prepareToDraw) |
|
3219 { |
|
3220 bool resetActiveUnit = false; |
|
3221 for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) { |
|
3222 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture() |
|
3223 || m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture()) { |
|
3224 if (ii != m_activeTextureUnit) { |
|
3225 m_context->activeTexture(ii); |
|
3226 resetActiveUnit = true; |
|
3227 } else if (resetActiveUnit) { |
|
3228 m_context->activeTexture(ii); |
|
3229 resetActiveUnit = false; |
|
3230 } |
|
3231 WebGLTexture* tex2D; |
|
3232 WebGLTexture* texCubeMap; |
|
3233 if (prepareToDraw) { |
|
3234 tex2D = m_blackTexture2D.get(); |
|
3235 texCubeMap = m_blackTextureCubeMap.get(); |
|
3236 } else { |
|
3237 tex2D = m_textureUnits[ii].m_texture2DBinding.get(); |
|
3238 texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get(); |
|
3239 } |
|
3240 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture()) |
|
3241 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, tex2D); |
|
3242 if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture()) |
|
3243 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, texCubeMap); |
|
3244 } |
|
3245 } |
|
3246 if (resetActiveUnit) |
|
3247 m_context->activeTexture(m_activeTextureUnit); |
|
3248 } |
|
3249 |
|
3250 void WebGLRenderingContext::createFallbackBlackTextures1x1() |
|
3251 { |
|
3252 unsigned char black[] = {0, 0, 0, 255}; |
|
3253 m_blackTexture2D = createTexture(); |
|
3254 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D.get()); |
|
3255 m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3256 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3257 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); |
|
3258 m_blackTextureCubeMap = createTexture(); |
|
3259 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap.get()); |
|
3260 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3261 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3262 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3263 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3264 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3265 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3266 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3267 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3268 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3269 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3270 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1, |
|
3271 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black); |
|
3272 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0); |
|
3273 } |
|
3274 |
|
3275 bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(unsigned long texInternalFormat, |
|
3276 unsigned long colorBufferFormat) |
|
3277 { |
|
3278 switch (colorBufferFormat) { |
|
3279 case GraphicsContext3D::ALPHA: |
|
3280 if (texInternalFormat == GraphicsContext3D::ALPHA) |
|
3281 return true; |
|
3282 break; |
|
3283 case GraphicsContext3D::RGB: |
|
3284 if (texInternalFormat == GraphicsContext3D::LUMINANCE |
|
3285 || texInternalFormat == GraphicsContext3D::RGB) |
|
3286 return true; |
|
3287 break; |
|
3288 case GraphicsContext3D::RGBA: |
|
3289 return true; |
|
3290 } |
|
3291 return false; |
|
3292 } |
|
3293 |
|
3294 WebGLTexture* WebGLRenderingContext::getTextureBinding(unsigned long target) |
|
3295 { |
|
3296 RefPtr<WebGLTexture> tex = 0; |
|
3297 switch (target) { |
|
3298 case GraphicsContext3D::TEXTURE_2D: |
|
3299 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding; |
|
3300 break; |
|
3301 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X: |
|
3302 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X: |
|
3303 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y: |
|
3304 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y: |
|
3305 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: |
|
3306 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: |
|
3307 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding; |
|
3308 break; |
|
3309 } |
|
3310 if (tex && tex->object()) |
|
3311 return tex.get(); |
|
3312 return 0; |
|
3313 } |
|
3314 |
|
3315 bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type) |
|
3316 { |
|
3317 switch (format) { |
|
3318 case GraphicsContext3D::ALPHA: |
|
3319 case GraphicsContext3D::LUMINANCE: |
|
3320 case GraphicsContext3D::LUMINANCE_ALPHA: |
|
3321 case GraphicsContext3D::RGB: |
|
3322 case GraphicsContext3D::RGBA: |
|
3323 break; |
|
3324 default: |
|
3325 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3326 return false; |
|
3327 } |
|
3328 |
|
3329 switch (type) { |
|
3330 case GraphicsContext3D::UNSIGNED_BYTE: |
|
3331 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: |
|
3332 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: |
|
3333 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: |
|
3334 break; |
|
3335 default: |
|
3336 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3337 return false; |
|
3338 } |
|
3339 |
|
3340 // Verify that the combination of format and type is supported. |
|
3341 switch (format) { |
|
3342 case GraphicsContext3D::ALPHA: |
|
3343 case GraphicsContext3D::LUMINANCE: |
|
3344 case GraphicsContext3D::LUMINANCE_ALPHA: |
|
3345 if (type != GraphicsContext3D::UNSIGNED_BYTE) { |
|
3346 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3347 return false; |
|
3348 } |
|
3349 break; |
|
3350 case GraphicsContext3D::RGB: |
|
3351 if (type != GraphicsContext3D::UNSIGNED_BYTE |
|
3352 && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5) { |
|
3353 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3354 return false; |
|
3355 } |
|
3356 break; |
|
3357 case GraphicsContext3D::RGBA: |
|
3358 if (type != GraphicsContext3D::UNSIGNED_BYTE |
|
3359 && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4 |
|
3360 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1) { |
|
3361 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3362 return false; |
|
3363 } |
|
3364 break; |
|
3365 default: |
|
3366 ASSERT_NOT_REACHED(); |
|
3367 } |
|
3368 |
|
3369 return true; |
|
3370 } |
|
3371 |
|
3372 bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long level, |
|
3373 unsigned long internalformat, |
|
3374 long width, long height, long border, |
|
3375 unsigned long format, unsigned long type) |
|
3376 { |
|
3377 // We absolutely have to validate the format and type combination. |
|
3378 // The texImage2D entry points taking HTMLImage, etc. will produce |
|
3379 // temporary data based on this combination, so it must be legal. |
|
3380 if (!validateTexFuncFormatAndType(format, type)) |
|
3381 return false; |
|
3382 |
|
3383 if (width < 0 || height < 0 || level < 0) { |
|
3384 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3385 return false; |
|
3386 } |
|
3387 |
|
3388 switch (target) { |
|
3389 case GraphicsContext3D::TEXTURE_2D: |
|
3390 if (width > m_maxTextureSize || height > m_maxTextureSize || level > m_maxTextureLevel) { |
|
3391 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3392 return false; |
|
3393 } |
|
3394 break; |
|
3395 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X: |
|
3396 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X: |
|
3397 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y: |
|
3398 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y: |
|
3399 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: |
|
3400 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: |
|
3401 if (width != height || width > m_maxCubeMapTextureSize || level > m_maxCubeMapTextureLevel) { |
|
3402 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3403 return false; |
|
3404 } |
|
3405 break; |
|
3406 default: |
|
3407 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3408 return false; |
|
3409 } |
|
3410 |
|
3411 if (format != internalformat) { |
|
3412 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3413 return false; |
|
3414 } |
|
3415 |
|
3416 if (border) { |
|
3417 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3418 return false; |
|
3419 } |
|
3420 |
|
3421 return true; |
|
3422 } |
|
3423 |
|
3424 bool WebGLRenderingContext::validateTexFuncData(long width, long height, |
|
3425 unsigned long format, unsigned long type, |
|
3426 ArrayBufferView* pixels) |
|
3427 { |
|
3428 if (!pixels) |
|
3429 return true; |
|
3430 |
|
3431 if (!validateTexFuncFormatAndType(format, type)) |
|
3432 return false; |
|
3433 |
|
3434 switch (type) { |
|
3435 case GraphicsContext3D::UNSIGNED_BYTE: |
|
3436 if (!pixels->isUnsignedByteArray()) { |
|
3437 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3438 return false; |
|
3439 } |
|
3440 break; |
|
3441 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: |
|
3442 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: |
|
3443 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: |
|
3444 if (!pixels->isUnsignedShortArray()) { |
|
3445 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3446 return false; |
|
3447 } |
|
3448 break; |
|
3449 default: |
|
3450 ASSERT_NOT_REACHED(); |
|
3451 } |
|
3452 |
|
3453 unsigned long componentsPerPixel, bytesPerComponent; |
|
3454 if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) { |
|
3455 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3456 return false; |
|
3457 } |
|
3458 |
|
3459 if (!width || !height) |
|
3460 return true; |
|
3461 unsigned int validRowBytes = width * componentsPerPixel * bytesPerComponent; |
|
3462 unsigned int totalRowBytes = validRowBytes; |
|
3463 unsigned int remainder = validRowBytes % m_unpackAlignment; |
|
3464 if (remainder) |
|
3465 totalRowBytes += (m_unpackAlignment - remainder); |
|
3466 unsigned int totalBytesRequired = (height - 1) * totalRowBytes + validRowBytes; |
|
3467 if (pixels->byteLength() < totalBytesRequired) { |
|
3468 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3469 return false; |
|
3470 } |
|
3471 return true; |
|
3472 } |
|
3473 |
|
3474 bool WebGLRenderingContext::validateDrawMode(unsigned long mode) |
|
3475 { |
|
3476 switch (mode) { |
|
3477 case GraphicsContext3D::POINTS: |
|
3478 case GraphicsContext3D::LINE_STRIP: |
|
3479 case GraphicsContext3D::LINE_LOOP: |
|
3480 case GraphicsContext3D::LINES: |
|
3481 case GraphicsContext3D::TRIANGLE_STRIP: |
|
3482 case GraphicsContext3D::TRIANGLE_FAN: |
|
3483 case GraphicsContext3D::TRIANGLES: |
|
3484 return true; |
|
3485 default: |
|
3486 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3487 return false; |
|
3488 } |
|
3489 } |
|
3490 |
|
3491 void WebGLRenderingContext::printWarningToConsole(const String& message) |
|
3492 { |
|
3493 canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, |
|
3494 message, 0, canvas()->document()->url().string()); |
|
3495 } |
|
3496 |
|
3497 bool WebGLRenderingContext::validateFramebufferFuncParameters(unsigned long target, unsigned long attachment) |
|
3498 { |
|
3499 if (target != GraphicsContext3D::FRAMEBUFFER) { |
|
3500 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3501 return false; |
|
3502 } |
|
3503 switch (attachment) { |
|
3504 case GraphicsContext3D::COLOR_ATTACHMENT0: |
|
3505 case GraphicsContext3D::DEPTH_ATTACHMENT: |
|
3506 case GraphicsContext3D::STENCIL_ATTACHMENT: |
|
3507 case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: |
|
3508 break; |
|
3509 default: |
|
3510 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3511 return false; |
|
3512 } |
|
3513 return true; |
|
3514 } |
|
3515 |
|
3516 bool WebGLRenderingContext::validateBlendEquation(unsigned long mode) |
|
3517 { |
|
3518 switch (mode) { |
|
3519 case GraphicsContext3D::FUNC_ADD: |
|
3520 case GraphicsContext3D::FUNC_SUBTRACT: |
|
3521 case GraphicsContext3D::FUNC_REVERSE_SUBTRACT: |
|
3522 return true; |
|
3523 default: |
|
3524 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3525 return false; |
|
3526 } |
|
3527 } |
|
3528 |
|
3529 bool WebGLRenderingContext::validateCapability(unsigned long cap) |
|
3530 { |
|
3531 switch (cap) { |
|
3532 case GraphicsContext3D::BLEND: |
|
3533 case GraphicsContext3D::CULL_FACE: |
|
3534 case GraphicsContext3D::DEPTH_TEST: |
|
3535 case GraphicsContext3D::DITHER: |
|
3536 case GraphicsContext3D::POLYGON_OFFSET_FILL: |
|
3537 case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE: |
|
3538 case GraphicsContext3D::SAMPLE_COVERAGE: |
|
3539 case GraphicsContext3D::SCISSOR_TEST: |
|
3540 case GraphicsContext3D::STENCIL_TEST: |
|
3541 return true; |
|
3542 default: |
|
3543 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3544 return false; |
|
3545 } |
|
3546 } |
|
3547 |
|
3548 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, int requiredMinSize) |
|
3549 { |
|
3550 if (!v) { |
|
3551 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3552 return false; |
|
3553 } |
|
3554 return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize); |
|
3555 } |
|
3556 |
|
3557 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, int requiredMinSize) |
|
3558 { |
|
3559 if (!v) { |
|
3560 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3561 return false; |
|
3562 } |
|
3563 return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize); |
|
3564 } |
|
3565 |
|
3566 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, int size, int requiredMinSize) |
|
3567 { |
|
3568 return validateUniformMatrixParameters(location, false, v, size, requiredMinSize); |
|
3569 } |
|
3570 |
|
3571 bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, Float32Array* v, int requiredMinSize) |
|
3572 { |
|
3573 if (!v) { |
|
3574 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3575 return false; |
|
3576 } |
|
3577 return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize); |
|
3578 } |
|
3579 |
|
3580 bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, void* v, int size, int requiredMinSize) |
|
3581 { |
|
3582 if (!location) |
|
3583 return false; |
|
3584 if (location->program() != m_currentProgram) { |
|
3585 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3586 return false; |
|
3587 } |
|
3588 if (!v) { |
|
3589 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3590 return false; |
|
3591 } |
|
3592 if (transpose) { |
|
3593 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3594 return false; |
|
3595 } |
|
3596 if (size < requiredMinSize) { |
|
3597 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3598 return false; |
|
3599 } |
|
3600 return true; |
|
3601 } |
|
3602 |
|
3603 WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(unsigned long target, unsigned long usage) |
|
3604 { |
|
3605 WebGLBuffer* buffer = 0; |
|
3606 switch (target) { |
|
3607 case GraphicsContext3D::ELEMENT_ARRAY_BUFFER: |
|
3608 buffer = m_boundElementArrayBuffer.get(); |
|
3609 break; |
|
3610 case GraphicsContext3D::ARRAY_BUFFER: |
|
3611 buffer = m_boundArrayBuffer.get(); |
|
3612 break; |
|
3613 default: |
|
3614 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3615 return 0; |
|
3616 } |
|
3617 if (!buffer) { |
|
3618 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
|
3619 return 0; |
|
3620 } |
|
3621 switch (usage) { |
|
3622 case GraphicsContext3D::STREAM_DRAW: |
|
3623 case GraphicsContext3D::STATIC_DRAW: |
|
3624 case GraphicsContext3D::DYNAMIC_DRAW: |
|
3625 return buffer; |
|
3626 } |
|
3627 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); |
|
3628 return 0; |
|
3629 } |
|
3630 |
|
3631 void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3) |
|
3632 { |
|
3633 if (index >= m_maxVertexAttribs) { |
|
3634 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3635 return; |
|
3636 } |
|
3637 // In GL, we skip setting vertexAttrib0 values. |
|
3638 if (index || isGLES2Compliant()) { |
|
3639 switch (expectedSize) { |
|
3640 case 1: |
|
3641 m_context->vertexAttrib1f(index, v0); |
|
3642 break; |
|
3643 case 2: |
|
3644 m_context->vertexAttrib2f(index, v0, v1); |
|
3645 break; |
|
3646 case 3: |
|
3647 m_context->vertexAttrib3f(index, v0, v1, v2); |
|
3648 break; |
|
3649 case 4: |
|
3650 m_context->vertexAttrib4f(index, v0, v1, v2, v3); |
|
3651 break; |
|
3652 } |
|
3653 cleanupAfterGraphicsCall(false); |
|
3654 } |
|
3655 if (index >= m_vertexAttribState.size()) |
|
3656 m_vertexAttribState.resize(index + 1); |
|
3657 m_vertexAttribState[index].value[0] = v0; |
|
3658 m_vertexAttribState[index].value[1] = v1; |
|
3659 m_vertexAttribState[index].value[2] = v2; |
|
3660 m_vertexAttribState[index].value[3] = v3; |
|
3661 } |
|
3662 |
|
3663 void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array* v, int expectedSize) |
|
3664 { |
|
3665 if (!v) { |
|
3666 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3667 return; |
|
3668 } |
|
3669 vertexAttribfvImpl(index, v->data(), v->length(), expectedSize); |
|
3670 } |
|
3671 |
|
3672 void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, float* v, int size, int expectedSize) |
|
3673 { |
|
3674 if (!v) { |
|
3675 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3676 return; |
|
3677 } |
|
3678 if (size < expectedSize) { |
|
3679 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3680 return; |
|
3681 } |
|
3682 if (index >= m_maxVertexAttribs) { |
|
3683 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); |
|
3684 return; |
|
3685 } |
|
3686 // In GL, we skip setting vertexAttrib0 values. |
|
3687 if (index || isGLES2Compliant()) { |
|
3688 switch (expectedSize) { |
|
3689 case 1: |
|
3690 m_context->vertexAttrib1fv(index, v); |
|
3691 break; |
|
3692 case 2: |
|
3693 m_context->vertexAttrib2fv(index, v); |
|
3694 break; |
|
3695 case 3: |
|
3696 m_context->vertexAttrib3fv(index, v); |
|
3697 break; |
|
3698 case 4: |
|
3699 m_context->vertexAttrib4fv(index, v); |
|
3700 break; |
|
3701 } |
|
3702 cleanupAfterGraphicsCall(false); |
|
3703 } |
|
3704 if (index >= m_vertexAttribState.size()) |
|
3705 m_vertexAttribState.resize(index + 1); |
|
3706 m_vertexAttribState[index].initValue(); |
|
3707 for (int ii = 0; ii < expectedSize; ++ii) |
|
3708 m_vertexAttribState[index].value[ii] = v[ii]; |
|
3709 } |
|
3710 |
|
3711 void WebGLRenderingContext::initVertexAttrib0() |
|
3712 { |
|
3713 m_vertexAttribState.resize(1); |
|
3714 m_vertexAttrib0Buffer = createBuffer(); |
|
3715 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer.get()); |
|
3716 m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW); |
|
3717 m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0); |
|
3718 m_vertexAttribState[0].bufferBinding = m_vertexAttrib0Buffer; |
|
3719 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0); |
|
3720 m_context->enableVertexAttribArray(0); |
|
3721 m_vertexAttrib0BufferSize = 0; |
|
3722 m_vertexAttrib0BufferValue[0] = 0.0f; |
|
3723 m_vertexAttrib0BufferValue[1] = 0.0f; |
|
3724 m_vertexAttrib0BufferValue[2] = 0.0f; |
|
3725 m_vertexAttrib0BufferValue[3] = 1.0f; |
|
3726 } |
|
3727 |
|
3728 bool WebGLRenderingContext::simulateVertexAttrib0(long numVertex) |
|
3729 { |
|
3730 const VertexAttribState& state = m_vertexAttribState[0]; |
|
3731 if (state.enabled || !m_currentProgram || !m_currentProgram->object() |
|
3732 || !m_currentProgram->isUsingVertexAttrib0()) |
|
3733 return false; |
|
3734 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer.get()); |
|
3735 long bufferDataSize = (numVertex + 1) * 4 * sizeof(float); |
|
3736 if (bufferDataSize > m_vertexAttrib0BufferSize |
|
3737 || state.value[0] != m_vertexAttrib0BufferValue[0] |
|
3738 || state.value[1] != m_vertexAttrib0BufferValue[1] |
|
3739 || state.value[2] != m_vertexAttrib0BufferValue[2] |
|
3740 || state.value[3] != m_vertexAttrib0BufferValue[3]) { |
|
3741 RefPtr<Float32Array> bufferData = Float32Array::create((numVertex + 1) * 4); |
|
3742 for (long ii = 0; ii < numVertex + 1; ++ii) { |
|
3743 bufferData->set(ii * 4, state.value[0]); |
|
3744 bufferData->set(ii * 4 + 1, state.value[1]); |
|
3745 bufferData->set(ii * 4 + 2, state.value[2]); |
|
3746 bufferData->set(ii * 4 + 3, state.value[3]); |
|
3747 } |
|
3748 m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW); |
|
3749 m_vertexAttrib0BufferSize = bufferDataSize; |
|
3750 m_vertexAttrib0BufferValue[0] = state.value[0]; |
|
3751 m_vertexAttrib0BufferValue[1] = state.value[1]; |
|
3752 m_vertexAttrib0BufferValue[2] = state.value[2]; |
|
3753 m_vertexAttrib0BufferValue[3] = state.value[3]; |
|
3754 } |
|
3755 m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0); |
|
3756 return true; |
|
3757 } |
|
3758 |
|
3759 void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation() |
|
3760 { |
|
3761 const VertexAttribState& state = m_vertexAttribState[0]; |
|
3762 if (state.bufferBinding != m_vertexAttrib0Buffer) { |
|
3763 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, state.bufferBinding.get()); |
|
3764 m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset); |
|
3765 } |
|
3766 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_boundArrayBuffer.get()); |
|
3767 } |
|
3768 |
|
3769 } // namespace WebCore |
|
3770 |
|
3771 #endif // ENABLE(3D_CANVAS) |