2 * Copyright (C) 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "WebGLRenderingContext.h"
32 #include "CanvasPixelArray.h"
34 #include "DOMWindow.h"
35 #include "FrameView.h"
36 #include "HTMLCanvasElement.h"
37 #include "HTMLImageElement.h"
38 #include "ImageBuffer.h"
39 #include "ImageData.h"
40 #include "NotImplemented.h"
41 #include "RenderBox.h"
42 #include "RenderLayer.h"
43 #include "WebGLActiveInfo.h"
44 #include "Uint16Array.h"
45 #include "WebGLBuffer.h"
46 #include "WebGLContextAttributes.h"
47 #include "WebGLFramebuffer.h"
48 #include "WebGLProgram.h"
49 #include "WebGLRenderbuffer.h"
50 #include "WebGLTexture.h"
51 #include "WebGLShader.h"
52 #include "WebGLUniformLocation.h"
54 #include <wtf/ByteArray.h>
55 #include <wtf/OwnArrayPtr.h>
59 class WebGLStateRestorer {
61 WebGLStateRestorer(WebGLRenderingContext* context,
70 m_context->cleanupAfterGraphicsCall(m_changed);
74 WebGLRenderingContext* m_context;
78 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
80 HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow();
81 OwnPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs->attributes(), hostWindow));
86 return new WebGLRenderingContext(canvas, context.release());
89 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<GraphicsContext3D> context)
90 : CanvasRenderingContext(passedCanvas)
93 , m_markedCanvasDirty(false)
94 , m_activeTextureUnit(0)
96 , m_unpackAlignment(4)
97 , m_unpackFlipY(false)
98 , m_unpackPremultiplyAlpha(false)
102 int numCombinedTextureImageUnits = 0;
103 m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
104 m_textureUnits.resize(numCombinedTextureImageUnits);
106 int numVertexAttribs = 0;
107 m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
108 m_maxVertexAttribs = numVertexAttribs;
110 int implementationColorReadFormat = GraphicsContext3D::RGBA;
111 m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT, &implementationColorReadFormat);
112 m_implementationColorReadFormat = implementationColorReadFormat;
113 int implementationColorReadType = GraphicsContext3D::UNSIGNED_BYTE;
114 m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType);
115 m_implementationColorReadType = implementationColorReadType;
117 int maxTextureSize = 0;
118 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
119 m_maxTextureSize = maxTextureSize;
120 int maxCubeMapTextureSize = 0;
121 m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapTextureSize);
122 m_maxCubeMapTextureSize = maxCubeMapTextureSize;
124 if (!isGLES2Compliant())
125 createFallbackBlackTextures1x1();
126 m_context->reshape(canvas()->width(), canvas()->height());
127 m_context->viewport(0, 0, canvas()->width(), canvas()->height());
130 WebGLRenderingContext::~WebGLRenderingContext()
132 detachAndRemoveAllObjects();
135 void WebGLRenderingContext::markContextChanged()
137 #if USE(ACCELERATED_COMPOSITING)
138 RenderBox* renderBox = canvas()->renderBox();
139 if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
140 renderBox->layer()->rendererContentChanged();
143 if (!m_markedCanvasDirty) {
144 // Make sure the canvas's image buffer is allocated.
146 canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
147 m_markedCanvasDirty = true;
149 #if USE(ACCELERATED_COMPOSITING)
154 void WebGLRenderingContext::beginPaint()
156 if (m_markedCanvasDirty) {
157 m_context->beginPaint(this);
161 void WebGLRenderingContext::endPaint()
163 if (m_markedCanvasDirty) {
164 m_markedCanvasDirty = false;
165 m_context->endPaint();
169 void WebGLRenderingContext::reshape(int width, int height)
172 #if USE(ACCELERATED_COMPOSITING)
173 RenderBox* renderBox = canvas()->renderBox();
174 if (renderBox && renderBox->hasLayer())
175 renderBox->layer()->rendererContentChanged();
177 m_needsUpdate = false;
180 m_context->reshape(width, height);
183 int WebGLRenderingContext::sizeInBytes(int type, ExceptionCode& ec)
186 int result = m_context->sizeInBytes(type);
188 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
193 void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec)
196 if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
197 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
200 m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
201 m_context->activeTexture(texture);
202 cleanupAfterGraphicsCall(false);
205 void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
208 if (!validateWebGLObject(program) || !validateWebGLObject(shader))
210 m_context->attachShader(program, shader);
211 cleanupAfterGraphicsCall(false);
214 void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec)
217 if (!validateWebGLObject(program))
219 m_context->bindAttribLocation(program, index, name);
220 cleanupAfterGraphicsCall(false);
223 void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec)
226 if (buffer && buffer->context() != this) {
227 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
230 if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
231 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
235 if (target == GraphicsContext3D::ARRAY_BUFFER)
236 m_boundArrayBuffer = buffer;
237 else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
238 m_boundElementArrayBuffer = buffer;
240 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
244 m_context->bindBuffer(target, buffer);
246 buffer->setTarget(target);
247 cleanupAfterGraphicsCall(false);
251 void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec)
254 if (buffer && buffer->context() != this) {
255 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
258 if (target != GraphicsContext3D::FRAMEBUFFER) {
259 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
262 m_framebufferBinding = buffer;
263 m_context->bindFramebuffer(target, buffer);
264 if (m_framebufferBinding)
265 m_framebufferBinding->onBind();
266 cleanupAfterGraphicsCall(false);
269 void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
272 if (renderBuffer && renderBuffer->context() != this) {
273 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
276 if (target != GraphicsContext3D::RENDERBUFFER) {
277 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
280 m_renderbufferBinding = renderBuffer;
281 m_context->bindRenderbuffer(target, renderBuffer);
282 cleanupAfterGraphicsCall(false);
286 void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec)
289 if (texture && texture->context() != this) {
290 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
293 if (target == GraphicsContext3D::TEXTURE_2D)
294 m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
295 else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
296 m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
298 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
301 m_context->bindTexture(target, texture);
302 if (!isGLES2Compliant() && texture)
303 texture->setTarget(target);
304 cleanupAfterGraphicsCall(false);
307 void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha)
309 m_context->blendColor(red, green, blue, alpha);
310 cleanupAfterGraphicsCall(false);
313 void WebGLRenderingContext::blendEquation( unsigned long mode )
315 if (!isGLES2Compliant()) {
316 if (!validateBlendEquation(mode))
319 m_context->blendEquation(mode);
320 cleanupAfterGraphicsCall(false);
323 void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
325 if (!isGLES2Compliant()) {
326 if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
329 m_context->blendEquationSeparate(modeRGB, modeAlpha);
330 cleanupAfterGraphicsCall(false);
334 void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor)
336 m_context->blendFunc(sfactor, dfactor);
337 cleanupAfterGraphicsCall(false);
340 void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
342 m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
343 cleanupAfterGraphicsCall(false);
346 void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
349 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
350 if (!m_boundElementArrayBuffer->associateBufferData(size)) {
351 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
354 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
355 if (!m_boundArrayBuffer->associateBufferData(size)) {
356 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
360 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
364 m_context->bufferData(target, size, usage);
365 cleanupAfterGraphicsCall(false);
368 void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
371 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
372 if (!m_boundElementArrayBuffer->associateBufferData(data)) {
373 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
376 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
377 if (!m_boundArrayBuffer->associateBufferData(data)) {
378 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
382 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
386 m_context->bufferData(target, data, usage);
387 cleanupAfterGraphicsCall(false);
390 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec)
393 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
394 if (!m_boundElementArrayBuffer->associateBufferSubData(offset, data)) {
395 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
398 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
399 if (!m_boundArrayBuffer->associateBufferSubData(offset, data)) {
400 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
404 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
408 m_context->bufferSubData(target, offset, data);
409 cleanupAfterGraphicsCall(false);
412 unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target)
414 if (!isGLES2Compliant()) {
415 if (target != GraphicsContext3D::FRAMEBUFFER) {
416 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
420 if (!m_framebufferBinding || !m_framebufferBinding->object())
421 return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
422 return m_context->checkFramebufferStatus(target);
423 cleanupAfterGraphicsCall(false);
426 void WebGLRenderingContext::clear(unsigned long mask)
428 m_context->clear(mask);
429 cleanupAfterGraphicsCall(true);
432 void WebGLRenderingContext::clearColor(double r, double g, double b, double a)
442 m_context->clearColor(r, g, b, a);
443 cleanupAfterGraphicsCall(false);
446 void WebGLRenderingContext::clearDepth(double depth)
448 m_context->clearDepth(depth);
449 cleanupAfterGraphicsCall(false);
452 void WebGLRenderingContext::clearStencil(long s)
454 m_context->clearStencil(s);
455 cleanupAfterGraphicsCall(false);
458 void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha)
460 m_context->colorMask(red, green, blue, alpha);
461 cleanupAfterGraphicsCall(false);
464 void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
467 if (!validateWebGLObject(shader))
469 m_context->compileShader(shader);
470 cleanupAfterGraphicsCall(false);
473 void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
475 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
477 if (!isGLES2Compliant()) {
478 if (m_framebufferBinding && m_framebufferBinding->object()
479 && !isTexInternalFormatColorBufferCombinationValid(internalformat,
480 m_framebufferBinding->getColorBufferFormat())) {
481 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
484 if (level && WebGLTexture::isNPOT(width, height)) {
485 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
489 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
490 // FIXME: if the framebuffer is not complete, none of the below should be executed.
491 WebGLTexture* tex = getTextureBinding(target);
492 if (!isGLES2Compliant()) {
493 if (tex && !level) // only for level 0
494 tex->setSize(target, width, height);
496 tex->setInternalFormat(internalformat);
498 if (m_framebufferBinding && tex)
499 m_framebufferBinding->onAttachedObjectChange(tex);
500 cleanupAfterGraphicsCall(false);
503 void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
505 if (!isGLES2Compliant()) {
506 WebGLTexture* tex = getTextureBinding(target);
507 if (m_framebufferBinding && m_framebufferBinding->object() && tex
508 && !isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(),
509 m_framebufferBinding->getColorBufferFormat())) {
510 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
514 m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
515 cleanupAfterGraphicsCall(false);
518 PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
520 RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
525 PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
527 RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
532 PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
534 RefPtr<WebGLTexture> o = WebGLTexture::create(this);
539 PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
541 RefPtr<WebGLProgram> o = WebGLProgram::create(this);
546 PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
548 RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
553 PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec)
556 if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
557 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
561 RefPtr<WebGLShader> o = WebGLShader::create(this, static_cast<GraphicsContext3D::WebGLEnumType>(type));
566 void WebGLRenderingContext::cullFace(unsigned long mode)
568 m_context->cullFace(mode);
569 cleanupAfterGraphicsCall(false);
572 void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
577 buffer->deleteObject();
580 void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
585 framebuffer->deleteObject();
588 void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
593 program->deleteObject();
596 void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
601 renderbuffer->deleteObject();
602 if (m_framebufferBinding)
603 m_framebufferBinding->onAttachedObjectChange(renderbuffer);
606 void WebGLRenderingContext::deleteShader(WebGLShader* shader)
611 shader->deleteObject();
614 void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
619 texture->deleteObject();
620 if (m_framebufferBinding)
621 m_framebufferBinding->onAttachedObjectChange(texture);
624 void WebGLRenderingContext::depthFunc(unsigned long func)
626 m_context->depthFunc(func);
627 cleanupAfterGraphicsCall(false);
630 void WebGLRenderingContext::depthMask(bool flag)
632 m_context->depthMask(flag);
633 cleanupAfterGraphicsCall(false);
636 void WebGLRenderingContext::depthRange(double zNear, double zFar)
638 m_context->depthRange(zNear, zFar);
639 cleanupAfterGraphicsCall(false);
642 void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
645 if (!validateWebGLObject(program) || !validateWebGLObject(shader))
647 m_context->detachShader(program, shader);
648 cleanupAfterGraphicsCall(false);
652 void WebGLRenderingContext::disable(unsigned long cap)
654 if (!isGLES2Compliant()) {
655 if (!validateCapability(cap))
658 m_context->disable(cap);
659 cleanupAfterGraphicsCall(false);
662 void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec)
665 if (index >= m_maxVertexAttribs) {
666 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
670 if (index < m_vertexAttribState.size())
671 m_vertexAttribState[index].enabled = false;
673 m_context->disableVertexAttribArray(index);
674 cleanupAfterGraphicsCall(false);
677 bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset)
679 if (!m_boundElementArrayBuffer)
685 unsigned long uoffset = static_cast<unsigned long>(offset);
687 if (type == GraphicsContext3D::UNSIGNED_SHORT) {
688 // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
692 // Make uoffset an element offset.
695 unsigned long n = m_boundElementArrayBuffer->byteLength() / 2;
696 if (uoffset > n || count > n - uoffset)
698 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
699 unsigned long n = m_boundElementArrayBuffer->byteLength();
700 if (uoffset > n || count > n - uoffset)
706 bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& numElementsRequired)
708 // Performs conservative validation by caching a maximum index of
709 // the given type per element array buffer. If all of the bound
710 // array buffers have enough elements to satisfy that maximum
711 // index, skips the expensive per-draw-call iteration in
712 // validateIndexArrayPrecise.
714 long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type);
716 // Compute the maximum index in the entire buffer for the given type of index.
718 case GraphicsContext3D::UNSIGNED_BYTE: {
719 unsigned numElements = m_boundElementArrayBuffer->byteLength();
720 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
721 for (unsigned i = 0; i < numElements; i++)
722 maxIndex = max(maxIndex, static_cast<long>(p[i]));
725 case GraphicsContext3D::UNSIGNED_SHORT: {
726 unsigned numElements = m_boundElementArrayBuffer->byteLength() / sizeof(unsigned short);
727 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
728 for (unsigned i = 0; i < numElements; i++)
729 maxIndex = max(maxIndex, static_cast<long>(p[i]));
735 m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex);
739 // The number of required elements is one more than the maximum
740 // index that will be accessed.
741 numElementsRequired = maxIndex + 1;
748 bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired)
752 if (!m_boundElementArrayBuffer)
755 unsigned long uoffset = static_cast<unsigned long>(offset);
756 unsigned long n = count;
758 if (type == GraphicsContext3D::UNSIGNED_SHORT) {
759 // Make uoffset an element offset.
761 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
767 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
768 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
776 // Then set the last index in the index array and make sure it is valid.
777 numElementsRequired = lastIndex + 1;
778 return numElementsRequired > 0;
781 bool WebGLRenderingContext::validateRenderingState(long numElementsRequired)
783 if (!m_currentProgram)
786 int numAttribStates = static_cast<int>(m_vertexAttribState.size());
788 // Look in each enabled vertex attrib and check if they've been bound to a buffer.
789 for (int i = 0; i < numAttribStates; ++i) {
790 if (m_vertexAttribState[i].enabled
791 && (!m_vertexAttribState[i].bufferBinding || !m_vertexAttribState[i].bufferBinding->object()))
795 // Look in each consumed vertex attrib (by the current program) and find the smallest buffer size
796 long smallestNumElements = LONG_MAX;
797 int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
798 for (int i = 0; i < numActiveAttribLocations; ++i) {
799 int loc = m_currentProgram->getActiveAttribLocation(i);
800 if (loc >=0 && loc < numAttribStates) {
801 const VertexAttribState& state = m_vertexAttribState[loc];
803 // Avoid off-by-one errors in numElements computation.
804 // For the last element, we will only touch the data for the
805 // element and nothing beyond it.
806 long bytesRemaining = state.bufferBinding->byteLength() - state.offset;
807 long numElements = 0;
808 if (bytesRemaining >= state.bytesPerElement)
809 numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
810 if (numElements < smallestNumElements)
811 smallestNumElements = numElements;
816 if (smallestNumElements == LONG_MAX)
817 smallestNumElements = 0;
819 return numElementsRequired <= smallestNumElements;
822 bool WebGLRenderingContext::validateWebGLObject(CanvasObject* object)
825 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
828 if (object->context() != this) {
829 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
835 void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec)
839 if (!validateDrawMode(mode))
842 if (first < 0 || count < 0) {
843 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
850 // Ensure we have a valid rendering state
851 if (!validateRenderingState(first + count)) {
852 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
856 handleNPOTTextures(true);
857 m_context->drawArrays(mode, first, count);
858 handleNPOTTextures(false);
859 cleanupAfterGraphicsCall(true);
862 void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigned long type, long offset, ExceptionCode& ec)
866 if (!validateDrawMode(mode))
870 case GraphicsContext3D::UNSIGNED_BYTE:
871 case GraphicsContext3D::UNSIGNED_SHORT:
874 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
878 if (count < 0 || offset < 0) {
879 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
886 // Ensure we have a valid rendering state
889 if (!validateElementArraySize(count, type, offset)) {
890 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
894 if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements))
895 if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
896 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
900 handleNPOTTextures(true);
901 m_context->drawElements(mode, count, type, offset);
902 handleNPOTTextures(false);
903 cleanupAfterGraphicsCall(true);
906 void WebGLRenderingContext::enable(unsigned long cap)
908 if (!isGLES2Compliant()) {
909 if (!validateCapability(cap))
912 m_context->enable(cap);
913 cleanupAfterGraphicsCall(false);
916 void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec)
919 if (index >= m_maxVertexAttribs) {
920 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
924 if (index >= m_vertexAttribState.size())
925 m_vertexAttribState.resize(index + 1);
927 m_vertexAttribState[index].enabled = true;
929 m_context->enableVertexAttribArray(index);
930 cleanupAfterGraphicsCall(false);
933 void WebGLRenderingContext::finish()
936 cleanupAfterGraphicsCall(true);
940 void WebGLRenderingContext::flush()
943 cleanupAfterGraphicsCall(true);
946 void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
949 if (!validateFramebufferFuncParameters(target, attachment))
951 if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
952 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
955 if (buffer && buffer->context() != this) {
956 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
959 // Don't allow the default framebuffer to be mutated; all current
960 // implementations use an FBO internally in place of the default
962 if (!m_framebufferBinding || !m_framebufferBinding->object()) {
963 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
966 if (buffer && buffer->object()) {
967 bool isConflicted = false;
968 switch (attachment) {
969 case GraphicsContext3D::DEPTH_ATTACHMENT:
970 if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached())
972 if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
975 case GraphicsContext3D::STENCIL_ATTACHMENT:
976 if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached())
978 if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
981 case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
982 if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached())
984 if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
989 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
993 m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer);
994 m_framebufferBinding->setAttachment(attachment, buffer);
995 cleanupAfterGraphicsCall(false);
998 void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec)
1001 if (!validateFramebufferFuncParameters(target, attachment))
1004 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1007 if (texture && texture->context() != this) {
1008 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1011 // Don't allow the default framebuffer to be mutated; all current
1012 // implementations use an FBO internally in place of the default
1014 if (!m_framebufferBinding || !m_framebufferBinding->object()) {
1015 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1018 m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
1019 m_framebufferBinding->setAttachment(attachment, texture);
1020 cleanupAfterGraphicsCall(false);
1023 void WebGLRenderingContext::frontFace(unsigned long mode)
1025 m_context->frontFace(mode);
1026 cleanupAfterGraphicsCall(false);
1029 void WebGLRenderingContext::generateMipmap(unsigned long target)
1031 if (!isGLES2Compliant()) {
1032 RefPtr<WebGLTexture> tex = 0;
1033 if (target == GraphicsContext3D::TEXTURE_2D)
1034 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
1035 else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
1036 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
1037 if (tex && tex->isNPOT()) {
1038 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1042 m_context->generateMipmap(target);
1043 cleanupAfterGraphicsCall(false);
1046 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
1050 if (!validateWebGLObject(program))
1052 if (!m_context->getActiveAttrib(program, index, info)) {
1055 return WebGLActiveInfo::create(info.name, info.type, info.size);
1058 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
1062 if (!validateWebGLObject(program))
1064 if (!m_context->getActiveUniform(program, index, info)) {
1067 if (!isGLES2Compliant()) {
1068 if (info.size > 1 && !info.name.endsWith("[0]"))
1069 info.name.append("[0]");
1071 return WebGLActiveInfo::create(info.name, info.type, info.size);
1074 bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<WebGLShader*>& shaderObjects, ExceptionCode& ec)
1077 shaderObjects.clear();
1078 if (!validateWebGLObject(program))
1081 m_context->getProgramiv(program, GraphicsContext3D::ATTACHED_SHADERS, &numShaders);
1083 OwnArrayPtr<unsigned int> shaders(new unsigned int[numShaders]);
1085 m_context->getAttachedShaders(program, numShaders, &count, shaders.get());
1086 if (count != numShaders)
1088 shaderObjects.resize(numShaders);
1089 for (int ii = 0; ii < numShaders; ++ii) {
1090 WebGLShader* shader = findShader(shaders[ii]);
1092 shaderObjects.clear();
1095 shaderObjects[ii] = shader;
1101 int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
1103 return m_context->getAttribLocation(program, name);
1106 WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1109 if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
1110 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1111 return WebGLGetInfo();
1114 if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
1115 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1116 return WebGLGetInfo();
1119 WebGLStateRestorer(this, false);
1121 m_context->getBufferParameteriv(target, pname, &value);
1122 if (pname == GraphicsContext3D::BUFFER_SIZE)
1123 return WebGLGetInfo(static_cast<long>(value));
1125 return WebGLGetInfo(static_cast<unsigned long>(value));
1128 PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
1130 // We always need to return a new WebGLContextAttributes object to
1131 // prevent the user from mutating any cached version.
1132 return WebGLContextAttributes::create(m_context->getContextAttributes());
1135 unsigned long WebGLRenderingContext::getError()
1137 return m_context->getError();
1140 WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec)
1143 if (!validateFramebufferFuncParameters(target, attachment))
1144 return WebGLGetInfo();
1146 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1147 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1148 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1149 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1152 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1153 return WebGLGetInfo();
1156 if (!m_framebufferBinding || !m_framebufferBinding->object()) {
1157 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1158 return WebGLGetInfo();
1161 if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
1162 WebGLStateRestorer(this, false);
1164 m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
1165 if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
1166 return WebGLGetInfo(static_cast<unsigned long>(value));
1168 return WebGLGetInfo(static_cast<long>(value));
1170 WebGLStateRestorer(this, false);
1172 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
1174 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value);
1176 case GraphicsContext3D::RENDERBUFFER:
1177 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(findRenderbuffer(static_cast<Platform3DObject>(value))));
1178 case GraphicsContext3D::TEXTURE:
1179 return WebGLGetInfo(PassRefPtr<WebGLTexture>(findTexture(static_cast<Platform3DObject>(value))));
1181 // FIXME: raise exception?
1182 return WebGLGetInfo();
1187 WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec)
1190 WebGLStateRestorer(this, false);
1192 case GraphicsContext3D::ACTIVE_TEXTURE:
1193 return getUnsignedLongParameter(pname);
1194 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
1195 return getWebGLFloatArrayParameter(pname);
1196 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
1197 return getWebGLFloatArrayParameter(pname);
1198 case GraphicsContext3D::ALPHA_BITS:
1199 return getLongParameter(pname);
1200 case GraphicsContext3D::ARRAY_BUFFER_BINDING:
1201 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
1202 case GraphicsContext3D::BLEND:
1203 return getBooleanParameter(pname);
1204 case GraphicsContext3D::BLEND_COLOR:
1205 return getWebGLFloatArrayParameter(pname);
1206 case GraphicsContext3D::BLEND_DST_ALPHA:
1207 return getUnsignedLongParameter(pname);
1208 case GraphicsContext3D::BLEND_DST_RGB:
1209 return getUnsignedLongParameter(pname);
1210 case GraphicsContext3D::BLEND_EQUATION_ALPHA:
1211 return getUnsignedLongParameter(pname);
1212 case GraphicsContext3D::BLEND_EQUATION_RGB:
1213 return getUnsignedLongParameter(pname);
1214 case GraphicsContext3D::BLEND_SRC_ALPHA:
1215 return getUnsignedLongParameter(pname);
1216 case GraphicsContext3D::BLEND_SRC_RGB:
1217 return getUnsignedLongParameter(pname);
1218 case GraphicsContext3D::BLUE_BITS:
1219 return getLongParameter(pname);
1220 case GraphicsContext3D::COLOR_CLEAR_VALUE:
1221 return getWebGLFloatArrayParameter(pname);
1222 case GraphicsContext3D::COLOR_WRITEMASK:
1223 return getBooleanArrayParameter(pname);
1224 case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
1225 // Defined as null in the spec
1226 return WebGLGetInfo();
1227 case GraphicsContext3D::CULL_FACE:
1228 return getBooleanParameter(pname);
1229 case GraphicsContext3D::CULL_FACE_MODE:
1230 return getUnsignedLongParameter(pname);
1231 case GraphicsContext3D::CURRENT_PROGRAM:
1232 return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
1233 case GraphicsContext3D::DEPTH_BITS:
1234 return getLongParameter(pname);
1235 case GraphicsContext3D::DEPTH_CLEAR_VALUE:
1236 return getFloatParameter(pname);
1237 case GraphicsContext3D::DEPTH_FUNC:
1238 return getUnsignedLongParameter(pname);
1239 case GraphicsContext3D::DEPTH_RANGE:
1240 return getWebGLFloatArrayParameter(pname);
1241 case GraphicsContext3D::DEPTH_TEST:
1242 return getBooleanParameter(pname);
1243 case GraphicsContext3D::DEPTH_WRITEMASK:
1244 return getBooleanParameter(pname);
1245 case GraphicsContext3D::DITHER:
1246 return getBooleanParameter(pname);
1247 case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
1248 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundElementArrayBuffer));
1249 case GraphicsContext3D::FRAMEBUFFER_BINDING:
1250 return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
1251 case GraphicsContext3D::FRONT_FACE:
1252 return getUnsignedLongParameter(pname);
1253 case GraphicsContext3D::GENERATE_MIPMAP_HINT:
1254 return getUnsignedLongParameter(pname);
1255 case GraphicsContext3D::GREEN_BITS:
1256 return getLongParameter(pname);
1257 case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
1258 return getLongParameter(pname);
1259 case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
1260 return getLongParameter(pname);
1261 case GraphicsContext3D::LINE_WIDTH:
1262 return getFloatParameter(pname);
1263 case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1264 return getLongParameter(pname);
1265 case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
1266 return getLongParameter(pname);
1267 case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
1268 return getLongParameter(pname);
1269 case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
1270 return getLongParameter(pname);
1271 case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
1272 return getLongParameter(pname);
1273 case GraphicsContext3D::MAX_TEXTURE_SIZE:
1274 return getLongParameter(pname);
1275 case GraphicsContext3D::MAX_VARYING_VECTORS:
1276 return getLongParameter(pname);
1277 case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
1278 return getLongParameter(pname);
1279 case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1280 return getLongParameter(pname);
1281 case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
1282 return getLongParameter(pname);
1283 case GraphicsContext3D::MAX_VIEWPORT_DIMS:
1284 return getWebGLIntArrayParameter(pname);
1285 case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS:
1286 return getLongParameter(pname);
1287 case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
1288 // FIXME: should we always return 0 for this?
1289 return getLongParameter(pname);
1290 case GraphicsContext3D::PACK_ALIGNMENT:
1291 return getLongParameter(pname);
1292 case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
1293 return getFloatParameter(pname);
1294 case GraphicsContext3D::POLYGON_OFFSET_FILL:
1295 return getBooleanParameter(pname);
1296 case GraphicsContext3D::POLYGON_OFFSET_UNITS:
1297 return getFloatParameter(pname);
1298 case GraphicsContext3D::RED_BITS:
1299 return getLongParameter(pname);
1300 case GraphicsContext3D::RENDERBUFFER_BINDING:
1301 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
1302 case GraphicsContext3D::SAMPLE_BUFFERS:
1303 return getLongParameter(pname);
1304 case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
1305 return getBooleanParameter(pname);
1306 case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
1307 return getFloatParameter(pname);
1308 case GraphicsContext3D::SAMPLES:
1309 return getLongParameter(pname);
1310 case GraphicsContext3D::SCISSOR_BOX:
1311 return getWebGLIntArrayParameter(pname);
1312 case GraphicsContext3D::SCISSOR_TEST:
1313 return getBooleanParameter(pname);
1314 case GraphicsContext3D::STENCIL_BACK_FAIL:
1315 return getUnsignedLongParameter(pname);
1316 case GraphicsContext3D::STENCIL_BACK_FUNC:
1317 return getUnsignedLongParameter(pname);
1318 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
1319 return getUnsignedLongParameter(pname);
1320 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
1321 return getUnsignedLongParameter(pname);
1322 case GraphicsContext3D::STENCIL_BACK_REF:
1323 return getLongParameter(pname);
1324 case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
1325 return getUnsignedLongParameter(pname);
1326 case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
1327 return getUnsignedLongParameter(pname);
1328 case GraphicsContext3D::STENCIL_BITS:
1329 return getLongParameter(pname);
1330 case GraphicsContext3D::STENCIL_CLEAR_VALUE:
1331 return getLongParameter(pname);
1332 case GraphicsContext3D::STENCIL_FAIL:
1333 return getUnsignedLongParameter(pname);
1334 case GraphicsContext3D::STENCIL_FUNC:
1335 return getUnsignedLongParameter(pname);
1336 case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
1337 return getUnsignedLongParameter(pname);
1338 case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
1339 return getUnsignedLongParameter(pname);
1340 case GraphicsContext3D::STENCIL_REF:
1341 return getLongParameter(pname);
1342 case GraphicsContext3D::STENCIL_TEST:
1343 return getBooleanParameter(pname);
1344 case GraphicsContext3D::STENCIL_VALUE_MASK:
1345 return getUnsignedLongParameter(pname);
1346 case GraphicsContext3D::STENCIL_WRITEMASK:
1347 return getUnsignedLongParameter(pname);
1348 case GraphicsContext3D::SUBPIXEL_BITS:
1349 return getLongParameter(pname);
1350 case GraphicsContext3D::TEXTURE_BINDING_2D:
1351 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
1352 case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
1353 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
1354 case GraphicsContext3D::UNPACK_ALIGNMENT:
1355 // FIXME: should this be "long" in the spec?
1356 return getIntParameter(pname);
1357 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1358 return WebGLGetInfo(m_unpackFlipY);
1359 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1360 return WebGLGetInfo(m_unpackPremultiplyAlpha);
1361 case GraphicsContext3D::VIEWPORT:
1362 return getWebGLIntArrayParameter(pname);
1364 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1365 return WebGLGetInfo();
1369 WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec)
1372 if (!validateWebGLObject(program))
1373 return WebGLGetInfo();
1375 WebGLStateRestorer(this, false);
1378 case GraphicsContext3D::DELETE_STATUS:
1379 case GraphicsContext3D::LINK_STATUS:
1380 case GraphicsContext3D::VALIDATE_STATUS:
1381 m_context->getProgramiv(program, pname, &value);
1382 return WebGLGetInfo(static_cast<bool>(value));
1383 case GraphicsContext3D::INFO_LOG_LENGTH:
1384 case GraphicsContext3D::ATTACHED_SHADERS:
1385 case GraphicsContext3D::ACTIVE_ATTRIBUTES:
1386 case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH:
1387 case GraphicsContext3D::ACTIVE_UNIFORMS:
1388 case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH:
1389 m_context->getProgramiv(program, pname, &value);
1390 return WebGLGetInfo(static_cast<long>(value));
1392 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1393 return WebGLGetInfo();
1397 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
1400 if (!validateWebGLObject(program))
1402 WebGLStateRestorer(this, false);
1403 return m_context->getProgramInfoLog(program);
1406 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1409 if (target != GraphicsContext3D::RENDERBUFFER) {
1410 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1411 return WebGLGetInfo();
1414 WebGLStateRestorer(this, false);
1417 case GraphicsContext3D::RENDERBUFFER_WIDTH:
1418 case GraphicsContext3D::RENDERBUFFER_HEIGHT:
1419 case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
1420 case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
1421 case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
1422 case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
1423 case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
1424 case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
1425 m_context->getRenderbufferParameteriv(target, pname, &value);
1426 return WebGLGetInfo(static_cast<long>(value));
1427 case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
1428 if (!m_renderbufferBinding) {
1429 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1430 return WebGLGetInfo();
1432 return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
1434 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1435 return WebGLGetInfo();
1439 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
1442 if (!validateWebGLObject(shader))
1443 return WebGLGetInfo();
1444 WebGLStateRestorer(this, false);
1447 case GraphicsContext3D::DELETE_STATUS:
1448 case GraphicsContext3D::COMPILE_STATUS:
1449 m_context->getShaderiv(shader, pname, &value);
1450 return WebGLGetInfo(static_cast<bool>(value));
1451 case GraphicsContext3D::SHADER_TYPE:
1452 m_context->getShaderiv(shader, pname, &value);
1453 return WebGLGetInfo(static_cast<unsigned long>(value));
1454 case GraphicsContext3D::INFO_LOG_LENGTH:
1455 case GraphicsContext3D::SHADER_SOURCE_LENGTH:
1456 m_context->getShaderiv(shader, pname, &value);
1457 return WebGLGetInfo(static_cast<long>(value));
1459 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1460 return WebGLGetInfo();
1464 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
1467 if (!validateWebGLObject(shader))
1469 WebGLStateRestorer(this, false);
1470 return m_context->getShaderInfoLog(shader);
1473 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
1476 if (!validateWebGLObject(shader))
1478 WebGLStateRestorer(this, false);
1479 return m_context->getShaderSource(shader);
1482 String WebGLRenderingContext::getString(unsigned long name)
1484 WebGLStateRestorer(this, false);
1485 return m_context->getString(name);
1488 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1491 if (target != GraphicsContext3D::TEXTURE_2D
1492 && target != GraphicsContext3D::TEXTURE_CUBE_MAP) {
1493 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1494 return WebGLGetInfo();
1496 WebGLStateRestorer(this, false);
1499 case GraphicsContext3D::TEXTURE_MAG_FILTER:
1500 case GraphicsContext3D::TEXTURE_MIN_FILTER:
1501 case GraphicsContext3D::TEXTURE_WRAP_S:
1502 case GraphicsContext3D::TEXTURE_WRAP_T:
1503 m_context->getTexParameteriv(target, pname, &value);
1504 return WebGLGetInfo(static_cast<unsigned long>(value));
1506 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1507 return WebGLGetInfo();
1511 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
1514 if (!validateWebGLObject(program))
1515 return WebGLGetInfo();
1516 if (uniformLocation->program() != program) {
1517 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1518 return WebGLGetInfo();
1520 long location = uniformLocation->location();
1522 WebGLStateRestorer(this, false);
1523 // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
1524 int activeUniforms = 0;
1525 m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
1526 for (int i = 0; i < activeUniforms; i++) {
1528 if (!m_context->getActiveUniform(program, i, info))
1529 return WebGLGetInfo();
1530 // Strip "[0]" from the name if it's an array.
1532 info.name = info.name.left(info.name.length() - 3);
1533 // If it's an array, we need to iterate through each element, appending "[index]" to the name.
1534 for (int index = 0; index < info.size; ++index) {
1535 String name = info.name;
1536 if (info.size > 1 && index >= 1) {
1538 name.append(String::number(index));
1541 // Now need to look this up by name again to find its location
1542 long loc = m_context->getUniformLocation(program, name);
1543 if (loc == location) {
1544 // Found it. Use the type in the ActiveInfo to determine the return type.
1545 GraphicsContext3D::WebGLEnumType baseType;
1547 switch (info.type) {
1548 case GraphicsContext3D::BOOL:
1549 baseType = GraphicsContext3D::BOOL;
1552 case GraphicsContext3D::BOOL_VEC2:
1553 baseType = GraphicsContext3D::BOOL;
1556 case GraphicsContext3D::BOOL_VEC3:
1557 baseType = GraphicsContext3D::BOOL;
1560 case GraphicsContext3D::BOOL_VEC4:
1561 baseType = GraphicsContext3D::BOOL;
1564 case GraphicsContext3D::INT:
1565 baseType = GraphicsContext3D::INT;
1568 case GraphicsContext3D::INT_VEC2:
1569 baseType = GraphicsContext3D::INT;
1572 case GraphicsContext3D::INT_VEC3:
1573 baseType = GraphicsContext3D::INT;
1576 case GraphicsContext3D::INT_VEC4:
1577 baseType = GraphicsContext3D::INT;
1580 case GraphicsContext3D::FLOAT:
1581 baseType = GraphicsContext3D::FLOAT;
1584 case GraphicsContext3D::FLOAT_VEC2:
1585 baseType = GraphicsContext3D::FLOAT;
1588 case GraphicsContext3D::FLOAT_VEC3:
1589 baseType = GraphicsContext3D::FLOAT;
1592 case GraphicsContext3D::FLOAT_VEC4:
1593 baseType = GraphicsContext3D::FLOAT;
1596 case GraphicsContext3D::FLOAT_MAT2:
1597 baseType = GraphicsContext3D::FLOAT;
1600 case GraphicsContext3D::FLOAT_MAT3:
1601 baseType = GraphicsContext3D::FLOAT;
1604 case GraphicsContext3D::FLOAT_MAT4:
1605 baseType = GraphicsContext3D::FLOAT;
1609 // Can't handle this type
1610 // FIXME: what to do about samplers?
1611 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1612 return WebGLGetInfo();
1615 case GraphicsContext3D::FLOAT: {
1616 float value[16] = {0};
1617 m_context->getUniformfv(program, location, value);
1619 return WebGLGetInfo(value[0]);
1620 return WebGLGetInfo(Float32Array::create(value, length));
1622 case GraphicsContext3D::INT: {
1623 int value[16] = {0};
1624 m_context->getUniformiv(program, location, value);
1626 return WebGLGetInfo(static_cast<long>(value[0]));
1627 return WebGLGetInfo(Int32Array::create(value, length));
1629 case GraphicsContext3D::BOOL: {
1630 int value[16] = {0};
1631 m_context->getUniformiv(program, location, value);
1633 unsigned char boolValue[16] = {0};
1634 for (unsigned j = 0; j < length; j++)
1635 boolValue[j] = static_cast<bool>(value[j]);
1636 return WebGLGetInfo(Uint8Array::create(boolValue, length));
1638 return WebGLGetInfo(static_cast<bool>(value[0]));
1646 // If we get here, something went wrong in our unfortunately complex logic above
1647 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1648 return WebGLGetInfo();
1651 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
1654 if (!validateWebGLObject(program))
1656 WebGLStateRestorer(this, false);
1657 long uniformLocation = m_context->getUniformLocation(program, name);
1658 if (uniformLocation == -1)
1660 return WebGLUniformLocation::create(program, uniformLocation);
1663 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
1666 WebGLStateRestorer(this, false);
1668 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
1670 m_context->getVertexAttribiv(index, pname, &name);
1671 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(findBuffer(static_cast<Platform3DObject>(name))));
1673 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
1674 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED: {
1676 m_context->getVertexAttribiv(index, pname, &value);
1677 return WebGLGetInfo(static_cast<bool>(value));
1679 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
1680 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE: {
1682 m_context->getVertexAttribiv(index, pname, &value);
1683 return WebGLGetInfo(static_cast<long>(value));
1685 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE: {
1687 m_context->getVertexAttribiv(index, pname, &value);
1688 return WebGLGetInfo(static_cast<unsigned long>(value));
1690 case GraphicsContext3D::CURRENT_VERTEX_ATTRIB: {
1691 float value[4] = {0};
1692 m_context->getVertexAttribfv(index, pname, value);
1693 return WebGLGetInfo(Float32Array::create(value, 4));
1696 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1697 return WebGLGetInfo();
1702 long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname)
1704 long result = m_context->getVertexAttribOffset(index, pname);
1705 cleanupAfterGraphicsCall(false);
1709 void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
1711 if (!isGLES2Compliant()) {
1712 if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
1713 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1717 m_context->hint(target, mode);
1718 cleanupAfterGraphicsCall(false);
1721 bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
1726 return m_context->isBuffer(buffer);
1729 bool WebGLRenderingContext::isEnabled(unsigned long cap)
1731 if (!isGLES2Compliant()) {
1732 if (!validateCapability(cap))
1735 return m_context->isEnabled(cap);
1738 bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
1743 return m_context->isFramebuffer(framebuffer);
1746 bool WebGLRenderingContext::isProgram(WebGLProgram* program)
1751 return m_context->isProgram(program);
1754 bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
1759 return m_context->isRenderbuffer(renderbuffer);
1762 bool WebGLRenderingContext::isShader(WebGLShader* shader)
1767 return m_context->isShader(shader);
1770 bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
1775 return m_context->isTexture(texture);
1778 void WebGLRenderingContext::lineWidth(double width)
1780 m_context->lineWidth((float) width);
1781 cleanupAfterGraphicsCall(false);
1784 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
1787 if (!validateWebGLObject(program))
1789 m_context->linkProgram(program);
1790 program->cacheActiveAttribLocations();
1791 cleanupAfterGraphicsCall(false);
1794 void WebGLRenderingContext::pixelStorei(unsigned long pname, long param)
1797 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1798 m_unpackFlipY = param;
1800 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1801 m_unpackPremultiplyAlpha = param;
1803 case GraphicsContext3D::PACK_ALIGNMENT:
1804 case GraphicsContext3D::UNPACK_ALIGNMENT:
1805 m_context->pixelStorei(pname, param);
1806 if (param == 1 || param == 2 || param == 4 || param == 8) {
1807 if (pname == GraphicsContext3D::PACK_ALIGNMENT)
1808 m_packAlignment = static_cast<int>(param);
1809 else // GraphicsContext3D::UNPACK_ALIGNMENT:
1810 m_unpackAlignment = static_cast<int>(param);
1814 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1817 cleanupAfterGraphicsCall(false);
1820 void WebGLRenderingContext::polygonOffset(double factor, double units)
1822 m_context->polygonOffset((float) factor, (float) units);
1823 cleanupAfterGraphicsCall(false);
1826 void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels)
1828 // Validate input parameters.
1829 unsigned long componentsPerPixel, bytesPerComponent;
1830 if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
1831 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1835 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1838 if (width < 0 || height < 0) {
1839 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1842 if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) {
1843 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1846 // Validate array type against pixel type.
1847 if (type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray()
1848 || type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray()) {
1849 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1852 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
1853 unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
1854 unsigned long padding = 0;
1855 unsigned long residualBytes = bytesPerRow % m_packAlignment;
1856 if (residualBytes) {
1857 padding = m_packAlignment - residualBytes;
1858 bytesPerRow += padding;
1860 // The last row needs no padding.
1861 unsigned long totalBytes = bytesPerRow * height - padding;
1862 unsigned long num = totalBytes / bytesPerComponent;
1863 if (pixels->length() < num) {
1864 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1867 void* data = pixels->baseAddress();
1868 m_context->readPixels(x, y, width, height, format, type, data);
1870 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
1871 // when alpha is off, readPixels should set alpha to 255 instead of 0.
1872 if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) {
1873 if (type == GraphicsContext3D::UNSIGNED_BYTE) {
1874 unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
1875 for (long iy = 0; iy < height; ++iy) {
1876 for (long ix = 0; ix < width; ++ix) {
1877 pixels[componentsPerPixel - 1] = 255;
1878 pixels += componentsPerPixel;
1883 // FIXME: check whether we need to do the same with UNSIGNED_SHORT.
1886 cleanupAfterGraphicsCall(false);
1889 void WebGLRenderingContext::releaseShaderCompiler()
1891 m_context->releaseShaderCompiler();
1892 cleanupAfterGraphicsCall(false);
1895 void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
1897 switch (internalformat) {
1898 case GraphicsContext3D::DEPTH_COMPONENT16:
1899 case GraphicsContext3D::RGBA4:
1900 case GraphicsContext3D::RGB5_A1:
1901 case GraphicsContext3D::RGB565:
1902 case GraphicsContext3D::STENCIL_INDEX8:
1903 case GraphicsContext3D::DEPTH_STENCIL:
1904 m_context->renderbufferStorage(target, internalformat, width, height);
1905 if (m_renderbufferBinding) {
1906 m_renderbufferBinding->setInternalFormat(internalformat);
1907 if (m_framebufferBinding)
1908 m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get());
1910 cleanupAfterGraphicsCall(false);
1913 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1917 void WebGLRenderingContext::sampleCoverage(double value, bool invert)
1919 m_context->sampleCoverage((float) value, invert);
1920 cleanupAfterGraphicsCall(false);
1923 void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height)
1925 m_context->scissor(x, y, width, height);
1926 cleanupAfterGraphicsCall(false);
1929 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
1932 if (!validateWebGLObject(shader))
1934 m_context->shaderSource(shader, string);
1935 cleanupAfterGraphicsCall(false);
1938 void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask)
1940 m_context->stencilFunc(func, ref, mask);
1941 cleanupAfterGraphicsCall(false);
1944 void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
1946 m_context->stencilFuncSeparate(face, func, ref, mask);
1947 cleanupAfterGraphicsCall(false);
1950 void WebGLRenderingContext::stencilMask(unsigned long mask)
1952 m_context->stencilMask(mask);
1953 cleanupAfterGraphicsCall(false);
1956 void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask)
1958 m_context->stencilMaskSeparate(face, mask);
1959 cleanupAfterGraphicsCall(false);
1962 void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
1964 m_context->stencilOp(fail, zfail, zpass);
1965 cleanupAfterGraphicsCall(false);
1968 void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
1970 m_context->stencilOpSeparate(face, fail, zfail, zpass);
1971 cleanupAfterGraphicsCall(false);
1974 void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsigned internalformat,
1975 unsigned width, unsigned height, unsigned border,
1976 unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
1978 // FIXME: For now we ignore any errors returned
1980 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
1982 if (!isGLES2Compliant()) {
1983 if (level && WebGLTexture::isNPOT(width, height)) {
1984 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1988 m_context->texImage2D(target, level, internalformat, width, height,
1989 border, format, type, pixels);
1990 WebGLTexture* tex = getTextureBinding(target);
1991 if (!isGLES2Compliant()) {
1992 if (tex && !level) // only for level 0
1993 tex->setSize(target, width, height);
1995 tex->setInternalFormat(internalformat);
1997 if (m_framebufferBinding && tex)
1998 m_framebufferBinding->onAttachedObjectChange(tex);
1999 cleanupAfterGraphicsCall(false);
2002 void WebGLRenderingContext::texImage2DImpl(unsigned target, unsigned level, unsigned internalformat,
2003 unsigned format, unsigned type, Image* image,
2004 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2007 Vector<uint8_t> data;
2008 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
2009 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2012 if (m_unpackAlignment != 1)
2013 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2014 texImage2DBase(target, level, internalformat, image->width(), image->height(), 0,
2015 format, type, data.data(), ec);
2016 if (m_unpackAlignment != 1)
2017 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2020 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2021 unsigned width, unsigned height, unsigned border,
2022 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
2024 if (!validateTexFuncData(width, height, format, type, pixels))
2026 void* data = pixels ? pixels->baseAddress() : 0;
2027 Vector<uint8_t> tempData;
2028 bool changeUnpackAlignment = false;
2029 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
2030 if (!m_context->extractTextureData(width, height, format, type,
2032 m_unpackFlipY, m_unpackPremultiplyAlpha,
2036 data = tempData.data();
2037 changeUnpackAlignment = true;
2039 if (changeUnpackAlignment)
2040 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2041 texImage2DBase(target, level, internalformat, width, height, border,
2042 format, type, data, ec);
2043 if (changeUnpackAlignment)
2044 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2047 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2048 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
2051 Vector<uint8_t> data;
2052 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
2053 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2056 if (m_unpackAlignment != 1)
2057 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2058 texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0,
2059 format, type, data.data(), ec);
2060 if (m_unpackAlignment != 1)
2061 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2064 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2065 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
2068 if (!image || !image->cachedImage()) {
2069 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2072 texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
2073 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2076 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2077 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
2080 if (!canvas || !canvas->buffer()) {
2081 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2084 texImage2DImpl(target, level, internalformat, format, type, canvas->buffer()->image(),
2085 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2088 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2089 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
2091 // FIXME: Need to implement this call
2092 UNUSED_PARAM(target);
2093 UNUSED_PARAM(level);
2094 UNUSED_PARAM(internalformat);
2095 UNUSED_PARAM(format);
2097 UNUSED_PARAM(video);
2100 cleanupAfterGraphicsCall(false);
2103 // Obsolete texImage2D entry points -- to be removed shortly. (FIXME)
2105 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2108 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels)");
2109 texImage2D(target, level, pixels, 0, 0, ec);
2112 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2113 bool flipY, ExceptionCode& ec)
2115 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY)");
2116 texImage2D(target, level, pixels, flipY, 0, ec);
2119 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2120 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2122 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
2124 Vector<uint8_t> data;
2125 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
2126 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2129 texImage2DBase(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0,
2130 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
2134 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2137 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image)");
2138 texImage2D(target, level, image, 0, 0, ec);
2141 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2142 bool flipY, ExceptionCode& ec)
2144 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY)");
2145 texImage2D(target, level, image, flipY, 0, ec);
2148 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2149 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2151 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
2153 if (!image || !image->cachedImage()) {
2154 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2157 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(), flipY, premultiplyAlpha, ec);
2160 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2163 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas)");
2164 texImage2D(target, level, canvas, 0, 0, ec);
2167 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2168 bool flipY, ExceptionCode& ec)
2170 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY)");
2171 texImage2D(target, level, canvas, flipY, 0, ec);
2174 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2175 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2177 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
2179 if (!canvas || !canvas->buffer()) {
2180 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2183 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(), flipY, premultiplyAlpha, ec);
2186 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2189 texImage2D(target, level, video, 0, 0, ec);
2192 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2193 bool flipY, ExceptionCode& ec)
2195 texImage2D(target, level, video, flipY, 0, ec);
2198 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2199 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2201 // FIXME: Need implement this call
2202 UNUSED_PARAM(target);
2203 UNUSED_PARAM(level);
2204 UNUSED_PARAM(video);
2205 UNUSED_PARAM(flipY);
2206 UNUSED_PARAM(premultiplyAlpha);
2209 cleanupAfterGraphicsCall(false);
2212 void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
2214 if (!isGLES2Compliant()) {
2215 RefPtr<WebGLTexture> tex = 0;
2217 case GraphicsContext3D::TEXTURE_2D:
2218 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
2220 case GraphicsContext3D::TEXTURE_CUBE_MAP:
2221 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
2224 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2228 case GraphicsContext3D::TEXTURE_MIN_FILTER:
2229 case GraphicsContext3D::TEXTURE_MAG_FILTER:
2231 case GraphicsContext3D::TEXTURE_WRAP_S:
2232 case GraphicsContext3D::TEXTURE_WRAP_T:
2233 if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT
2234 || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) {
2235 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2240 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2245 tex->setParameterf(pname, paramf);
2247 tex->setParameteri(pname, parami);
2251 m_context->texParameterf(target, pname, paramf);
2253 m_context->texParameteri(target, pname, parami);
2254 cleanupAfterGraphicsCall(false);
2257 void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param)
2259 texParameter(target, pname, param, 0, true);
2262 void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param)
2264 texParameter(target, pname, 0, param, false);
2267 void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2268 unsigned width, unsigned height,
2269 unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
2271 // FIXME: For now we ignore any errors returned
2273 if (!validateTexFuncFormatAndType(format, type))
2276 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
2277 cleanupAfterGraphicsCall(false);
2280 void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2281 unsigned format, unsigned type,
2282 Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2285 Vector<uint8_t> data;
2286 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
2287 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2290 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
2291 format, type, data.data(), ec);
2294 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2295 unsigned width, unsigned height,
2296 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
2298 if (!validateTexFuncData(width, height, format, type, pixels))
2300 void* data = pixels ? pixels->baseAddress() : 0;
2301 Vector<uint8_t> tempData;
2302 bool changeUnpackAlignment = false;
2303 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
2304 if (!m_context->extractTextureData(width, height, format, type,
2306 m_unpackFlipY, m_unpackPremultiplyAlpha,
2310 data = tempData.data();
2311 changeUnpackAlignment = true;
2313 if (changeUnpackAlignment)
2314 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2315 texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
2316 if (changeUnpackAlignment)
2317 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2320 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2321 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
2324 Vector<uint8_t> data;
2325 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
2326 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2329 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
2330 format, type, data.data(), ec);
2333 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2334 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
2337 if (!image || !image->cachedImage()) {
2338 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2341 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
2342 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2345 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2346 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
2349 if (!canvas || !canvas->buffer()) {
2350 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2353 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->buffer()->image(),
2354 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2357 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2358 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
2360 // FIXME: Need to implement this call
2361 UNUSED_PARAM(target);
2362 UNUSED_PARAM(level);
2363 UNUSED_PARAM(xoffset);
2364 UNUSED_PARAM(yoffset);
2365 UNUSED_PARAM(format);
2367 UNUSED_PARAM(video);
2369 cleanupAfterGraphicsCall(false);
2372 // Obsolete texSubImage2D entry points -- to be removed shortly. (FIXME)
2374 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2375 ImageData* pixels, ExceptionCode& ec)
2377 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels)");
2378 texSubImage2D(target, level, xoffset, yoffset, pixels, 0, 0, ec);
2381 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2382 ImageData* pixels, bool flipY, ExceptionCode& ec)
2384 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY)");
2385 texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, 0, ec);
2388 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2389 ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2391 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
2393 Vector<uint8_t> data;
2394 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
2395 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2398 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
2399 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
2402 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2403 HTMLImageElement* image, ExceptionCode& ec)
2405 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image)");
2406 texSubImage2D(target, level, xoffset, yoffset, image, 0, 0, ec);
2409 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2410 HTMLImageElement* image, bool flipY, ExceptionCode& ec)
2412 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY)");
2413 texSubImage2D(target, level, xoffset, yoffset, image, flipY, 0, ec);
2416 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2417 HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2419 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
2421 if (!image || !image->cachedImage()) {
2422 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2425 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(),
2426 flipY, premultiplyAlpha, ec);
2429 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2430 HTMLCanvasElement* canvas, ExceptionCode& ec)
2432 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas)");
2433 texSubImage2D(target, level, xoffset, yoffset, canvas, 0, 0, ec);
2436 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2437 HTMLCanvasElement* canvas, bool flipY, ExceptionCode& ec)
2439 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY)");
2440 texSubImage2D(target, level, xoffset, yoffset, canvas, flipY, 0, ec);
2443 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2444 HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2446 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
2448 if (!canvas || !canvas->buffer()) {
2449 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2452 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(),
2453 flipY, premultiplyAlpha, ec);
2456 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2457 HTMLVideoElement* video, ExceptionCode& ec)
2459 texSubImage2D(target, level, xoffset, yoffset, video, 0, 0, ec);
2462 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2463 HTMLVideoElement* video, bool flipY, ExceptionCode& ec)
2465 texSubImage2D(target, level, xoffset, yoffset, video, flipY, 0, ec);
2468 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2469 HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2471 // FIXME: Need to implement this call
2472 UNUSED_PARAM(target);
2473 UNUSED_PARAM(level);
2474 UNUSED_PARAM(xoffset);
2475 UNUSED_PARAM(yoffset);
2476 UNUSED_PARAM(video);
2477 UNUSED_PARAM(flipY);
2478 UNUSED_PARAM(premultiplyAlpha);
2480 cleanupAfterGraphicsCall(false);
2483 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
2489 if (location->program() != m_currentProgram) {
2490 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2494 m_context->uniform1f(location->location(), x);
2495 cleanupAfterGraphicsCall(false);
2498 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2504 if (location->program() != m_currentProgram) {
2505 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2510 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2513 m_context->uniform1fv(location->location(), v->data(), v->length());
2514 cleanupAfterGraphicsCall(false);
2517 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2523 if (location->program() != m_currentProgram) {
2524 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2529 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2532 m_context->uniform1fv(location->location(), v, size);
2533 cleanupAfterGraphicsCall(false);
2536 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
2542 if (location->program() != m_currentProgram) {
2543 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2547 m_context->uniform1i(location->location(), x);
2548 cleanupAfterGraphicsCall(false);
2551 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2557 if (location->program() != m_currentProgram) {
2558 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2563 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2566 m_context->uniform1iv(location->location(), v->data(), v->length());
2567 cleanupAfterGraphicsCall(false);
2570 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2576 if (location->program() != m_currentProgram) {
2577 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2582 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2585 m_context->uniform1iv(location->location(), v, size);
2586 cleanupAfterGraphicsCall(false);
2589 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
2595 if (location->program() != m_currentProgram) {
2596 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2600 m_context->uniform2f(location->location(), x, y);
2601 cleanupAfterGraphicsCall(false);
2604 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2610 if (location->program() != m_currentProgram) {
2611 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2616 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2619 // FIXME: length needs to be a multiple of 2
2620 m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
2621 cleanupAfterGraphicsCall(false);
2624 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2630 if (location->program() != m_currentProgram) {
2631 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2636 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2639 // FIXME: length needs to be a multiple of 2
2640 m_context->uniform2fv(location->location(), v, size / 2);
2641 cleanupAfterGraphicsCall(false);
2644 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
2650 if (location->program() != m_currentProgram) {
2651 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2655 m_context->uniform2i(location->location(), x, y);
2656 cleanupAfterGraphicsCall(false);
2659 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2665 if (location->program() != m_currentProgram) {
2666 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2671 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2674 // FIXME: length needs to be a multiple of 2
2675 m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
2676 cleanupAfterGraphicsCall(false);
2679 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2685 if (location->program() != m_currentProgram) {
2686 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2691 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2694 // FIXME: length needs to be a multiple of 2
2695 m_context->uniform2iv(location->location(), v, size / 2);
2696 cleanupAfterGraphicsCall(false);
2699 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
2705 if (location->program() != m_currentProgram) {
2706 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2710 m_context->uniform3f(location->location(), x, y, z);
2711 cleanupAfterGraphicsCall(false);
2714 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2720 if (location->program() != m_currentProgram) {
2721 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2726 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2729 // FIXME: length needs to be a multiple of 3
2730 m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
2731 cleanupAfterGraphicsCall(false);
2734 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2740 if (location->program() != m_currentProgram) {
2741 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2746 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2749 // FIXME: length needs to be a multiple of 3
2750 m_context->uniform3fv(location->location(), v, size / 3);
2751 cleanupAfterGraphicsCall(false);
2754 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
2760 if (location->program() != m_currentProgram) {
2761 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2765 m_context->uniform3i(location->location(), x, y, z);
2766 cleanupAfterGraphicsCall(false);
2769 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2775 if (location->program() != m_currentProgram) {
2776 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2781 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2784 // FIXME: length needs to be a multiple of 3
2785 m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
2786 cleanupAfterGraphicsCall(false);
2789 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2795 if (location->program() != m_currentProgram) {
2796 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2801 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2804 // FIXME: length needs to be a multiple of 3
2805 m_context->uniform3iv(location->location(), v, size / 3);
2806 cleanupAfterGraphicsCall(false);
2809 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
2815 if (location->program() != m_currentProgram) {
2816 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2820 m_context->uniform4f(location->location(), x, y, z, w);
2821 cleanupAfterGraphicsCall(false);
2824 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2830 if (location->program() != m_currentProgram) {
2831 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2836 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2839 // FIXME: length needs to be a multiple of 4
2840 m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
2841 cleanupAfterGraphicsCall(false);
2844 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2850 if (location->program() != m_currentProgram) {
2851 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2856 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2859 // FIXME: length needs to be a multiple of 4
2860 m_context->uniform4fv(location->location(), v, size / 4);
2861 cleanupAfterGraphicsCall(false);
2864 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
2870 if (location->program() != m_currentProgram) {
2871 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2875 m_context->uniform4i(location->location(), x, y, z, w);
2876 cleanupAfterGraphicsCall(false);
2879 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2885 if (location->program() != m_currentProgram) {
2886 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2891 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2894 // FIXME: length needs to be a multiple of 4
2895 m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
2896 cleanupAfterGraphicsCall(false);
2899 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2905 if (location->program() != m_currentProgram) {
2906 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2911 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2914 // FIXME: length needs to be a multiple of 4
2915 m_context->uniform4iv(location->location(), v, size / 4);
2916 cleanupAfterGraphicsCall(false);
2919 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2922 if (!validateUniformMatrixParameters(location, transpose, v))
2924 // FIXME: length needs to be a multiple of 4
2925 m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
2926 cleanupAfterGraphicsCall(false);
2929 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2932 if (!validateUniformMatrixParameters(location, transpose, v))
2934 // FIXME: length needs to be a multiple of 4
2935 m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
2936 cleanupAfterGraphicsCall(false);
2939 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2942 if (!validateUniformMatrixParameters(location, transpose, v))
2944 // FIXME: length needs to be a multiple of 9
2945 m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
2946 cleanupAfterGraphicsCall(false);
2949 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2952 if (!validateUniformMatrixParameters(location, transpose, v))
2954 // FIXME: length needs to be a multiple of 9
2955 m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
2956 cleanupAfterGraphicsCall(false);
2959 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2962 if (!validateUniformMatrixParameters(location, transpose, v))
2964 // FIXME: length needs to be a multiple of 16
2965 m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
2966 cleanupAfterGraphicsCall(false);
2969 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2972 if (!validateUniformMatrixParameters(location, transpose, v))
2974 // FIXME: length needs to be a multiple of 16
2975 m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
2976 cleanupAfterGraphicsCall(false);
2979 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
2982 if (program && program->context() != this) {
2983 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2986 m_currentProgram = program;
2987 m_context->useProgram(program);
2988 cleanupAfterGraphicsCall(false);
2991 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
2994 if (!validateWebGLObject(program))
2996 m_context->validateProgram(program);
2997 cleanupAfterGraphicsCall(false);
3000 void WebGLRenderingContext::vertexAttrib1f(unsigned long indx, float v0)
3002 m_context->vertexAttrib1f(indx, v0);
3003 cleanupAfterGraphicsCall(false);
3006 void WebGLRenderingContext::vertexAttrib1fv(unsigned long indx, Float32Array* v)
3008 // FIXME: Need to make sure array is big enough for attribute being set
3009 m_context->vertexAttrib1fv(indx, v->data());
3010 cleanupAfterGraphicsCall(false);
3013 void WebGLRenderingContext::vertexAttrib1fv(unsigned long indx, float* v, int size)
3015 // FIXME: Need to make sure array is big enough for attribute being set
3018 m_context->vertexAttrib1fv(indx, v);
3019 cleanupAfterGraphicsCall(false);
3022 void WebGLRenderingContext::vertexAttrib2f(unsigned long indx, float v0, float v1)
3024 m_context->vertexAttrib2f(indx, v0, v1);
3025 cleanupAfterGraphicsCall(false);
3028 void WebGLRenderingContext::vertexAttrib2fv(unsigned long indx, Float32Array* v)
3030 // FIXME: Need to make sure array is big enough for attribute being set
3031 m_context->vertexAttrib2fv(indx, v->data());
3032 cleanupAfterGraphicsCall(false);
3035 void WebGLRenderingContext::vertexAttrib2fv(unsigned long indx, float* v, int size)
3037 // FIXME: Need to make sure array is big enough for attribute being set
3040 m_context->vertexAttrib2fv(indx, v);
3041 cleanupAfterGraphicsCall(false);
3044 void WebGLRenderingContext::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2)
3046 m_context->vertexAttrib3f(indx, v0, v1, v2);
3047 cleanupAfterGraphicsCall(false);
3050 void WebGLRenderingContext::vertexAttrib3fv(unsigned long indx, Float32Array* v)
3052 // FIXME: Need to make sure array is big enough for attribute being set
3053 m_context->vertexAttrib3fv(indx, v->data());
3054 cleanupAfterGraphicsCall(false);
3057 void WebGLRenderingContext::vertexAttrib3fv(unsigned long indx, float* v, int size)
3059 // FIXME: Need to make sure array is big enough for attribute being set
3062 m_context->vertexAttrib3fv(indx, v);
3063 cleanupAfterGraphicsCall(false);
3066 void WebGLRenderingContext::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3)
3068 m_context->vertexAttrib4f(indx, v0, v1, v2, v3);
3069 cleanupAfterGraphicsCall(false);
3072 void WebGLRenderingContext::vertexAttrib4fv(unsigned long indx, Float32Array* v)
3074 // FIXME: Need to make sure array is big enough for attribute being set
3075 m_context->vertexAttrib4fv(indx, v->data());
3076 cleanupAfterGraphicsCall(false);
3079 void WebGLRenderingContext::vertexAttrib4fv(unsigned long indx, float* v, int size)
3081 // FIXME: Need to make sure array is big enough for attribute being set
3084 m_context->vertexAttrib4fv(indx, v);
3085 cleanupAfterGraphicsCall(false);
3088 void WebGLRenderingContext::vertexAttribPointer(unsigned long indx, long size, unsigned long type, bool normalized, unsigned long stride, unsigned long offset, ExceptionCode& ec)
3091 if (!m_boundArrayBuffer || indx >= m_maxVertexAttribs) {
3092 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3096 if (indx >= m_vertexAttribState.size())
3097 m_vertexAttribState.resize(indx + 1);
3099 // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
3100 long bytesPerElement = size * sizeInBytes(type, ec);
3101 if (bytesPerElement <= 0)
3103 long validatedStride = bytesPerElement;
3105 if ((long) stride < bytesPerElement) {
3106 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3110 validatedStride = stride;
3112 m_vertexAttribState[indx].bufferBinding = m_boundArrayBuffer;
3113 m_vertexAttribState[indx].bytesPerElement = bytesPerElement;
3114 m_vertexAttribState[indx].stride = validatedStride;
3115 m_vertexAttribState[indx].offset = offset;
3116 m_context->vertexAttribPointer(indx, size, type, normalized, stride, offset);
3117 cleanupAfterGraphicsCall(false);
3120 void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height)
3130 m_context->viewport(x, y, width, height);
3131 cleanupAfterGraphicsCall(false);
3134 void WebGLRenderingContext::removeObject(CanvasObject* object)
3136 m_canvasObjects.remove(object);
3139 void WebGLRenderingContext::addObject(CanvasObject* object)
3141 removeObject(object);
3142 m_canvasObjects.add(object);
3145 void WebGLRenderingContext::detachAndRemoveAllObjects()
3147 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3148 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it)
3149 (*it)->detachContext();
3151 m_canvasObjects.clear();
3154 WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj)
3158 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3159 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3160 if ((*it)->isTexture() && (*it)->object() == obj)
3161 return reinterpret_cast<WebGLTexture*>((*it).get());
3166 WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj)
3170 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3171 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3172 if ((*it)->isRenderbuffer() && (*it)->object() == obj)
3173 return reinterpret_cast<WebGLRenderbuffer*>((*it).get());
3178 WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj)
3182 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3183 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3184 if ((*it)->isBuffer() && (*it)->object() == obj)
3185 return reinterpret_cast<WebGLBuffer*>((*it).get());
3190 WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj)
3194 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3195 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3196 if ((*it)->isShader() && (*it)->object() == obj)
3197 return reinterpret_cast<WebGLShader*>((*it).get());
3202 WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname)
3204 unsigned char value;
3205 m_context->getBooleanv(pname, &value);
3206 return WebGLGetInfo(static_cast<bool>(value));
3209 WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(unsigned long pname)
3211 if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
3213 return WebGLGetInfo(0, 0);
3215 unsigned char value[4] = {0};
3216 m_context->getBooleanv(pname, value);
3218 for (int ii = 0; ii < 4; ++ii)
3219 boolValue[ii] = static_cast<bool>(value[ii]);
3220 return WebGLGetInfo(boolValue, 4);
3223 WebGLGetInfo WebGLRenderingContext::getFloatParameter(unsigned long pname)
3226 m_context->getFloatv(pname, &value);
3227 return WebGLGetInfo(static_cast<float>(value));
3230 WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname)
3232 return getLongParameter(pname);
3235 WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname)
3238 m_context->getIntegerv(pname, &value);
3239 return WebGLGetInfo(static_cast<long>(value));
3242 WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname)
3245 m_context->getIntegerv(pname, &value);
3246 return WebGLGetInfo(static_cast<unsigned long>(value));
3249 WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname)
3251 float value[4] = {0};
3252 m_context->getFloatv(pname, value);
3253 unsigned length = 0;
3255 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
3256 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
3257 case GraphicsContext3D::DEPTH_RANGE:
3260 case GraphicsContext3D::BLEND_COLOR:
3261 case GraphicsContext3D::COLOR_CLEAR_VALUE:
3267 return WebGLGetInfo(Float32Array::create(value, length));
3270 WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(unsigned long pname)
3273 m_context->getIntegerv(pname, value);
3274 unsigned length = 0;
3276 case GraphicsContext3D::MAX_VIEWPORT_DIMS:
3279 case GraphicsContext3D::SCISSOR_BOX:
3280 case GraphicsContext3D::VIEWPORT:
3286 return WebGLGetInfo(Int32Array::create(value, length));
3289 bool WebGLRenderingContext::isGLES2Compliant()
3291 return m_context->isGLES2Compliant();
3294 void WebGLRenderingContext::handleNPOTTextures(bool prepareToDraw)
3296 if (isGLES2Compliant())
3298 bool resetActiveUnit = false;
3299 for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
3300 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture()
3301 || m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture()) {
3302 if (ii != m_activeTextureUnit) {
3303 m_context->activeTexture(ii);
3304 resetActiveUnit = true;
3305 } else if (resetActiveUnit) {
3306 m_context->activeTexture(ii);
3307 resetActiveUnit = false;
3309 WebGLTexture* tex2D;
3310 WebGLTexture* texCubeMap;
3311 if (prepareToDraw) {
3312 tex2D = m_blackTexture2D.get();
3313 texCubeMap = m_blackTextureCubeMap.get();
3315 tex2D = m_textureUnits[ii].m_texture2DBinding.get();
3316 texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
3318 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
3319 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, tex2D);
3320 if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())
3321 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, texCubeMap);
3324 if (resetActiveUnit)
3325 m_context->activeTexture(m_activeTextureUnit);
3328 void WebGLRenderingContext::createFallbackBlackTextures1x1()
3330 unsigned char black[] = {0, 0, 0, 255};
3331 m_blackTexture2D = createTexture();
3332 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D.get());
3333 m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
3334 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3335 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
3336 m_blackTextureCubeMap = createTexture();
3337 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap.get());
3338 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
3339 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3340 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
3341 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3342 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
3343 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3344 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
3345 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3346 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
3347 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3348 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
3349 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3350 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
3353 bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(unsigned long texInternalFormat,
3354 unsigned long colorBufferFormat)
3356 switch (colorBufferFormat) {
3357 case GraphicsContext3D::ALPHA:
3358 if (texInternalFormat == GraphicsContext3D::ALPHA)
3361 case GraphicsContext3D::RGB:
3362 if (texInternalFormat == GraphicsContext3D::LUMINANCE
3363 || texInternalFormat == GraphicsContext3D::RGB)
3366 case GraphicsContext3D::RGBA:
3372 WebGLTexture* WebGLRenderingContext::getTextureBinding(unsigned long target)
3374 RefPtr<WebGLTexture> tex = 0;
3376 case GraphicsContext3D::TEXTURE_2D:
3377 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
3379 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
3380 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
3381 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
3382 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
3383 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
3384 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
3385 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
3388 if (tex && tex->object())
3393 bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type)
3396 case GraphicsContext3D::ALPHA:
3397 case GraphicsContext3D::LUMINANCE:
3398 case GraphicsContext3D::LUMINANCE_ALPHA:
3399 case GraphicsContext3D::RGB:
3400 case GraphicsContext3D::RGBA:
3403 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3408 case GraphicsContext3D::UNSIGNED_BYTE:
3409 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
3410 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
3411 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
3414 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3418 // Verify that the combination of format and type is supported.
3420 case GraphicsContext3D::ALPHA:
3421 case GraphicsContext3D::LUMINANCE:
3422 case GraphicsContext3D::LUMINANCE_ALPHA:
3423 if (type != GraphicsContext3D::UNSIGNED_BYTE) {
3424 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3428 case GraphicsContext3D::RGB:
3429 if (type != GraphicsContext3D::UNSIGNED_BYTE
3430 && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5) {
3431 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3435 case GraphicsContext3D::RGBA:
3436 if (type != GraphicsContext3D::UNSIGNED_BYTE
3437 && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
3438 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1) {
3439 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);