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();
128 m_context->reshape(canvas()->width(), canvas()->height());
129 m_context->viewport(0, 0, canvas()->width(), canvas()->height());
132 WebGLRenderingContext::~WebGLRenderingContext()
134 detachAndRemoveAllObjects();
137 void WebGLRenderingContext::markContextChanged()
139 #if USE(ACCELERATED_COMPOSITING)
140 RenderBox* renderBox = canvas()->renderBox();
141 if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
142 renderBox->layer()->rendererContentChanged();
145 if (!m_markedCanvasDirty) {
146 // Make sure the canvas's image buffer is allocated.
148 canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
149 m_markedCanvasDirty = true;
151 #if USE(ACCELERATED_COMPOSITING)
156 void WebGLRenderingContext::beginPaint()
158 if (m_markedCanvasDirty) {
159 m_context->beginPaint(this);
163 void WebGLRenderingContext::endPaint()
165 if (m_markedCanvasDirty) {
166 m_markedCanvasDirty = false;
167 m_context->endPaint();
171 void WebGLRenderingContext::reshape(int width, int height)
174 #if USE(ACCELERATED_COMPOSITING)
175 RenderBox* renderBox = canvas()->renderBox();
176 if (renderBox && renderBox->hasLayer())
177 renderBox->layer()->rendererContentChanged();
179 m_needsUpdate = false;
182 m_context->reshape(width, height);
185 int WebGLRenderingContext::sizeInBytes(int type, ExceptionCode& ec)
188 int result = m_context->sizeInBytes(type);
190 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
195 void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec)
198 if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
199 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
202 m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
203 m_context->activeTexture(texture);
204 cleanupAfterGraphicsCall(false);
207 void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
210 if (!validateWebGLObject(program) || !validateWebGLObject(shader))
212 m_context->attachShader(program, shader);
213 cleanupAfterGraphicsCall(false);
216 void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec)
219 if (!validateWebGLObject(program))
221 m_context->bindAttribLocation(program, index, name);
222 cleanupAfterGraphicsCall(false);
225 void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec)
228 if (buffer && buffer->context() != this) {
229 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
232 if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
233 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
237 if (target == GraphicsContext3D::ARRAY_BUFFER)
238 m_boundArrayBuffer = buffer;
239 else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
240 m_boundElementArrayBuffer = buffer;
242 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
246 m_context->bindBuffer(target, buffer);
248 buffer->setTarget(target);
249 cleanupAfterGraphicsCall(false);
253 void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec)
256 if (buffer && buffer->context() != this) {
257 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
260 if (target != GraphicsContext3D::FRAMEBUFFER) {
261 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
264 m_framebufferBinding = buffer;
265 m_context->bindFramebuffer(target, buffer);
266 if (m_framebufferBinding)
267 m_framebufferBinding->onBind();
268 cleanupAfterGraphicsCall(false);
271 void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
274 if (renderBuffer && renderBuffer->context() != this) {
275 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
278 if (target != GraphicsContext3D::RENDERBUFFER) {
279 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
282 m_renderbufferBinding = renderBuffer;
283 m_context->bindRenderbuffer(target, renderBuffer);
284 cleanupAfterGraphicsCall(false);
288 void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec)
291 if (texture && texture->context() != this) {
292 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
295 if (target == GraphicsContext3D::TEXTURE_2D)
296 m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
297 else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
298 m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
300 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
303 m_context->bindTexture(target, texture);
304 if (!isGLES2Compliant() && texture)
305 texture->setTarget(target);
306 cleanupAfterGraphicsCall(false);
309 void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha)
311 m_context->blendColor(red, green, blue, alpha);
312 cleanupAfterGraphicsCall(false);
315 void WebGLRenderingContext::blendEquation( unsigned long mode )
317 if (!isGLES2Compliant()) {
318 if (!validateBlendEquation(mode))
321 m_context->blendEquation(mode);
322 cleanupAfterGraphicsCall(false);
325 void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
327 if (!isGLES2Compliant()) {
328 if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
331 m_context->blendEquationSeparate(modeRGB, modeAlpha);
332 cleanupAfterGraphicsCall(false);
336 void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor)
338 m_context->blendFunc(sfactor, dfactor);
339 cleanupAfterGraphicsCall(false);
342 void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
344 m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
345 cleanupAfterGraphicsCall(false);
348 void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
351 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
352 if (!m_boundElementArrayBuffer->associateBufferData(size)) {
353 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
356 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
357 if (!m_boundArrayBuffer->associateBufferData(size)) {
358 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
362 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
366 m_context->bufferData(target, size, usage);
367 cleanupAfterGraphicsCall(false);
370 void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
373 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
374 if (!m_boundElementArrayBuffer->associateBufferData(data)) {
375 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
378 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
379 if (!m_boundArrayBuffer->associateBufferData(data)) {
380 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
384 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
388 m_context->bufferData(target, data, usage);
389 cleanupAfterGraphicsCall(false);
392 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec)
395 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) {
396 if (!m_boundElementArrayBuffer->associateBufferSubData(offset, data)) {
397 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
400 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) {
401 if (!m_boundArrayBuffer->associateBufferSubData(offset, data)) {
402 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
406 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
410 m_context->bufferSubData(target, offset, data);
411 cleanupAfterGraphicsCall(false);
414 unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target)
416 if (!isGLES2Compliant()) {
417 if (target != GraphicsContext3D::FRAMEBUFFER) {
418 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
422 if (!m_framebufferBinding || !m_framebufferBinding->object())
423 return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
424 return m_context->checkFramebufferStatus(target);
425 cleanupAfterGraphicsCall(false);
428 void WebGLRenderingContext::clear(unsigned long mask)
430 m_context->clear(mask);
431 cleanupAfterGraphicsCall(true);
434 void WebGLRenderingContext::clearColor(double r, double g, double b, double a)
444 m_context->clearColor(r, g, b, a);
445 cleanupAfterGraphicsCall(false);
448 void WebGLRenderingContext::clearDepth(double depth)
450 m_context->clearDepth(depth);
451 cleanupAfterGraphicsCall(false);
454 void WebGLRenderingContext::clearStencil(long s)
456 m_context->clearStencil(s);
457 cleanupAfterGraphicsCall(false);
460 void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha)
462 m_context->colorMask(red, green, blue, alpha);
463 cleanupAfterGraphicsCall(false);
466 void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
469 if (!validateWebGLObject(shader))
471 m_context->compileShader(shader);
472 cleanupAfterGraphicsCall(false);
475 void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
477 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
479 if (!isGLES2Compliant()) {
480 if (m_framebufferBinding && m_framebufferBinding->object()
481 && !isTexInternalFormatColorBufferCombinationValid(internalformat,
482 m_framebufferBinding->getColorBufferFormat())) {
483 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
486 if (level && WebGLTexture::isNPOT(width, height)) {
487 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
491 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
492 // FIXME: if the framebuffer is not complete, none of the below should be executed.
493 WebGLTexture* tex = getTextureBinding(target);
494 if (!isGLES2Compliant()) {
495 if (tex && !level) // only for level 0
496 tex->setSize(target, width, height);
498 tex->setInternalFormat(internalformat);
500 if (m_framebufferBinding && tex)
501 m_framebufferBinding->onAttachedObjectChange(tex);
502 cleanupAfterGraphicsCall(false);
505 void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
507 if (!isGLES2Compliant()) {
508 WebGLTexture* tex = getTextureBinding(target);
509 if (m_framebufferBinding && m_framebufferBinding->object() && tex
510 && !isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(),
511 m_framebufferBinding->getColorBufferFormat())) {
512 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
516 m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
517 cleanupAfterGraphicsCall(false);
520 PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
522 RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
527 PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
529 RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
534 PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
536 RefPtr<WebGLTexture> o = WebGLTexture::create(this);
541 PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
543 RefPtr<WebGLProgram> o = WebGLProgram::create(this);
548 PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
550 RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
555 PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec)
558 if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
559 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
563 RefPtr<WebGLShader> o = WebGLShader::create(this, static_cast<GraphicsContext3D::WebGLEnumType>(type));
568 void WebGLRenderingContext::cullFace(unsigned long mode)
570 m_context->cullFace(mode);
571 cleanupAfterGraphicsCall(false);
574 void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
579 buffer->deleteObject();
581 if (!isGLES2Compliant()) {
582 VertexAttribState& state = m_vertexAttribState[0];
583 if (buffer == state.bufferBinding) {
584 state.bufferBinding = m_vertexAttrib0Buffer;
585 state.bytesPerElement = 0;
587 state.type = GraphicsContext3D::FLOAT;
588 state.normalized = false;
590 state.originalStride = 0;
596 void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
601 framebuffer->deleteObject();
604 void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
609 program->deleteObject();
612 void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
617 renderbuffer->deleteObject();
618 if (m_framebufferBinding)
619 m_framebufferBinding->onAttachedObjectChange(renderbuffer);
622 void WebGLRenderingContext::deleteShader(WebGLShader* shader)
627 shader->deleteObject();
630 void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
635 texture->deleteObject();
636 if (m_framebufferBinding)
637 m_framebufferBinding->onAttachedObjectChange(texture);
640 void WebGLRenderingContext::depthFunc(unsigned long func)
642 m_context->depthFunc(func);
643 cleanupAfterGraphicsCall(false);
646 void WebGLRenderingContext::depthMask(bool flag)
648 m_context->depthMask(flag);
649 cleanupAfterGraphicsCall(false);
652 void WebGLRenderingContext::depthRange(double zNear, double zFar)
654 m_context->depthRange(zNear, zFar);
655 cleanupAfterGraphicsCall(false);
658 void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
661 if (!validateWebGLObject(program) || !validateWebGLObject(shader))
663 m_context->detachShader(program, shader);
664 cleanupAfterGraphicsCall(false);
668 void WebGLRenderingContext::disable(unsigned long cap)
670 if (!isGLES2Compliant()) {
671 if (!validateCapability(cap))
674 m_context->disable(cap);
675 cleanupAfterGraphicsCall(false);
678 void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec)
681 if (index >= m_maxVertexAttribs) {
682 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
686 if (index < m_vertexAttribState.size())
687 m_vertexAttribState[index].enabled = false;
689 if (index > 0 || isGLES2Compliant()) {
690 m_context->disableVertexAttribArray(index);
691 cleanupAfterGraphicsCall(false);
695 bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset)
697 if (!m_boundElementArrayBuffer)
703 unsigned long uoffset = static_cast<unsigned long>(offset);
705 if (type == GraphicsContext3D::UNSIGNED_SHORT) {
706 // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
710 // Make uoffset an element offset.
713 unsigned long n = m_boundElementArrayBuffer->byteLength() / 2;
714 if (uoffset > n || count > n - uoffset)
716 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
717 unsigned long n = m_boundElementArrayBuffer->byteLength();
718 if (uoffset > n || count > n - uoffset)
724 bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& numElementsRequired)
726 // Performs conservative validation by caching a maximum index of
727 // the given type per element array buffer. If all of the bound
728 // array buffers have enough elements to satisfy that maximum
729 // index, skips the expensive per-draw-call iteration in
730 // validateIndexArrayPrecise.
732 long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type);
734 // Compute the maximum index in the entire buffer for the given type of index.
736 case GraphicsContext3D::UNSIGNED_BYTE: {
737 unsigned numElements = m_boundElementArrayBuffer->byteLength();
738 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
739 for (unsigned i = 0; i < numElements; i++)
740 maxIndex = max(maxIndex, static_cast<long>(p[i]));
743 case GraphicsContext3D::UNSIGNED_SHORT: {
744 unsigned numElements = m_boundElementArrayBuffer->byteLength() / sizeof(unsigned short);
745 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
746 for (unsigned i = 0; i < numElements; i++)
747 maxIndex = max(maxIndex, static_cast<long>(p[i]));
753 m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex);
757 // The number of required elements is one more than the maximum
758 // index that will be accessed.
759 numElementsRequired = maxIndex + 1;
766 bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired)
770 if (!m_boundElementArrayBuffer)
773 unsigned long uoffset = static_cast<unsigned long>(offset);
774 unsigned long n = count;
776 if (type == GraphicsContext3D::UNSIGNED_SHORT) {
777 // Make uoffset an element offset.
779 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
785 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
786 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
794 // Then set the last index in the index array and make sure it is valid.
795 numElementsRequired = lastIndex + 1;
796 return numElementsRequired > 0;
799 bool WebGLRenderingContext::validateRenderingState(long numElementsRequired)
801 if (!m_currentProgram)
804 int numAttribStates = static_cast<int>(m_vertexAttribState.size());
806 // Look in each enabled vertex attrib and check if they've been bound to a buffer.
807 for (int i = 0; i < numAttribStates; ++i) {
808 if (m_vertexAttribState[i].enabled
809 && (!m_vertexAttribState[i].bufferBinding || !m_vertexAttribState[i].bufferBinding->object()))
813 // Look in each consumed vertex attrib (by the current program) and find the smallest buffer size
814 long smallestNumElements = LONG_MAX;
815 int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
816 for (int i = 0; i < numActiveAttribLocations; ++i) {
817 int loc = m_currentProgram->getActiveAttribLocation(i);
818 if (loc >=0 && loc < numAttribStates) {
819 const VertexAttribState& state = m_vertexAttribState[loc];
821 // Avoid off-by-one errors in numElements computation.
822 // For the last element, we will only touch the data for the
823 // element and nothing beyond it.
824 long bytesRemaining = state.bufferBinding->byteLength() - state.offset;
825 long numElements = 0;
826 if (bytesRemaining >= state.bytesPerElement)
827 numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
828 if (numElements < smallestNumElements)
829 smallestNumElements = numElements;
834 if (smallestNumElements == LONG_MAX)
835 smallestNumElements = 0;
837 return numElementsRequired <= smallestNumElements;
840 bool WebGLRenderingContext::validateWebGLObject(CanvasObject* object)
843 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
846 if (object->context() != this) {
847 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
853 void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec)
857 if (!validateDrawMode(mode))
860 if (first < 0 || count < 0) {
861 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
868 // Ensure we have a valid rendering state
869 if (!validateRenderingState(first + count)) {
870 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
874 bool vertexAttrib0Simulated = false;
875 if (!isGLES2Compliant()) {
876 vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
877 handleNPOTTextures(true);
879 m_context->drawArrays(mode, first, count);
880 if (!isGLES2Compliant()) {
881 handleNPOTTextures(false);
882 if (vertexAttrib0Simulated)
883 restoreStatesAfterVertexAttrib0Simulation();
885 cleanupAfterGraphicsCall(true);
888 void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigned long type, long offset, ExceptionCode& ec)
892 if (!validateDrawMode(mode))
896 case GraphicsContext3D::UNSIGNED_BYTE:
897 case GraphicsContext3D::UNSIGNED_SHORT:
900 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
904 if (count < 0 || offset < 0) {
905 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
912 // Ensure we have a valid rendering state
915 if (!validateElementArraySize(count, type, offset)) {
916 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
920 if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements))
921 if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
922 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
926 bool vertexAttrib0Simulated = false;
927 if (!isGLES2Compliant()) {
928 vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
929 handleNPOTTextures(true);
931 m_context->drawElements(mode, count, type, offset);
932 if (!isGLES2Compliant()) {
933 handleNPOTTextures(false);
934 if (vertexAttrib0Simulated)
935 restoreStatesAfterVertexAttrib0Simulation();
937 cleanupAfterGraphicsCall(true);
940 void WebGLRenderingContext::enable(unsigned long cap)
942 if (!isGLES2Compliant()) {
943 if (!validateCapability(cap))
946 m_context->enable(cap);
947 cleanupAfterGraphicsCall(false);
950 void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec)
953 if (index >= m_maxVertexAttribs) {
954 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
958 if (index >= m_vertexAttribState.size())
959 m_vertexAttribState.resize(index + 1);
961 m_vertexAttribState[index].enabled = true;
963 m_context->enableVertexAttribArray(index);
964 cleanupAfterGraphicsCall(false);
967 void WebGLRenderingContext::finish()
970 cleanupAfterGraphicsCall(true);
974 void WebGLRenderingContext::flush()
977 cleanupAfterGraphicsCall(true);
980 void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
983 if (!validateFramebufferFuncParameters(target, attachment))
985 if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
986 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
989 if (buffer && buffer->context() != this) {
990 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
993 // Don't allow the default framebuffer to be mutated; all current
994 // implementations use an FBO internally in place of the default
996 if (!m_framebufferBinding || !m_framebufferBinding->object()) {
997 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1000 if (buffer && buffer->object()) {
1001 bool isConflicted = false;
1002 switch (attachment) {
1003 case GraphicsContext3D::DEPTH_ATTACHMENT:
1004 if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached())
1005 isConflicted = true;
1006 if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
1007 isConflicted = true;
1009 case GraphicsContext3D::STENCIL_ATTACHMENT:
1010 if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached())
1011 isConflicted = true;
1012 if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
1013 isConflicted = true;
1015 case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
1016 if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached())
1017 isConflicted = true;
1018 if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
1019 isConflicted = true;
1023 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1027 m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer);
1028 m_framebufferBinding->setAttachment(attachment, buffer);
1029 cleanupAfterGraphicsCall(false);
1032 void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec)
1035 if (!validateFramebufferFuncParameters(target, attachment))
1038 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1041 if (texture && texture->context() != this) {
1042 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1045 // Don't allow the default framebuffer to be mutated; all current
1046 // implementations use an FBO internally in place of the default
1048 if (!m_framebufferBinding || !m_framebufferBinding->object()) {
1049 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1052 m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
1053 m_framebufferBinding->setAttachment(attachment, texture);
1054 cleanupAfterGraphicsCall(false);
1057 void WebGLRenderingContext::frontFace(unsigned long mode)
1059 m_context->frontFace(mode);
1060 cleanupAfterGraphicsCall(false);
1063 void WebGLRenderingContext::generateMipmap(unsigned long target)
1065 if (!isGLES2Compliant()) {
1066 RefPtr<WebGLTexture> tex = 0;
1067 if (target == GraphicsContext3D::TEXTURE_2D)
1068 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
1069 else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
1070 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
1071 if (tex && tex->isNPOT()) {
1072 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1076 m_context->generateMipmap(target);
1077 cleanupAfterGraphicsCall(false);
1080 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
1084 if (!validateWebGLObject(program))
1086 if (!m_context->getActiveAttrib(program, index, info)) {
1089 return WebGLActiveInfo::create(info.name, info.type, info.size);
1092 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
1096 if (!validateWebGLObject(program))
1098 if (!m_context->getActiveUniform(program, index, info)) {
1101 if (!isGLES2Compliant()) {
1102 if (info.size > 1 && !info.name.endsWith("[0]"))
1103 info.name.append("[0]");
1105 return WebGLActiveInfo::create(info.name, info.type, info.size);
1108 bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<WebGLShader*>& shaderObjects, ExceptionCode& ec)
1111 shaderObjects.clear();
1112 if (!validateWebGLObject(program))
1115 m_context->getProgramiv(program, GraphicsContext3D::ATTACHED_SHADERS, &numShaders);
1117 OwnArrayPtr<unsigned int> shaders(new unsigned int[numShaders]);
1119 m_context->getAttachedShaders(program, numShaders, &count, shaders.get());
1120 if (count != numShaders)
1122 shaderObjects.resize(numShaders);
1123 for (int ii = 0; ii < numShaders; ++ii) {
1124 WebGLShader* shader = findShader(shaders[ii]);
1126 shaderObjects.clear();
1129 shaderObjects[ii] = shader;
1135 int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
1137 return m_context->getAttribLocation(program, name);
1140 WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1143 if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
1144 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1145 return WebGLGetInfo();
1148 if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
1149 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1150 return WebGLGetInfo();
1153 WebGLStateRestorer(this, false);
1155 m_context->getBufferParameteriv(target, pname, &value);
1156 if (pname == GraphicsContext3D::BUFFER_SIZE)
1157 return WebGLGetInfo(static_cast<long>(value));
1159 return WebGLGetInfo(static_cast<unsigned long>(value));
1162 PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
1164 // We always need to return a new WebGLContextAttributes object to
1165 // prevent the user from mutating any cached version.
1166 return WebGLContextAttributes::create(m_context->getContextAttributes());
1169 unsigned long WebGLRenderingContext::getError()
1171 return m_context->getError();
1174 WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec)
1177 if (!validateFramebufferFuncParameters(target, attachment))
1178 return WebGLGetInfo();
1180 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1181 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1182 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1183 case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1186 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1187 return WebGLGetInfo();
1190 if (!m_framebufferBinding || !m_framebufferBinding->object()) {
1191 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1192 return WebGLGetInfo();
1195 if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
1196 WebGLStateRestorer(this, false);
1198 m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
1199 if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
1200 return WebGLGetInfo(static_cast<unsigned long>(value));
1202 return WebGLGetInfo(static_cast<long>(value));
1204 WebGLStateRestorer(this, false);
1206 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
1208 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value);
1210 case GraphicsContext3D::RENDERBUFFER:
1211 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(findRenderbuffer(static_cast<Platform3DObject>(value))));
1212 case GraphicsContext3D::TEXTURE:
1213 return WebGLGetInfo(PassRefPtr<WebGLTexture>(findTexture(static_cast<Platform3DObject>(value))));
1215 // FIXME: raise exception?
1216 return WebGLGetInfo();
1221 WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec)
1224 WebGLStateRestorer(this, false);
1226 case GraphicsContext3D::ACTIVE_TEXTURE:
1227 return getUnsignedLongParameter(pname);
1228 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
1229 return getWebGLFloatArrayParameter(pname);
1230 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
1231 return getWebGLFloatArrayParameter(pname);
1232 case GraphicsContext3D::ALPHA_BITS:
1233 return getLongParameter(pname);
1234 case GraphicsContext3D::ARRAY_BUFFER_BINDING:
1235 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
1236 case GraphicsContext3D::BLEND:
1237 return getBooleanParameter(pname);
1238 case GraphicsContext3D::BLEND_COLOR:
1239 return getWebGLFloatArrayParameter(pname);
1240 case GraphicsContext3D::BLEND_DST_ALPHA:
1241 return getUnsignedLongParameter(pname);
1242 case GraphicsContext3D::BLEND_DST_RGB:
1243 return getUnsignedLongParameter(pname);
1244 case GraphicsContext3D::BLEND_EQUATION_ALPHA:
1245 return getUnsignedLongParameter(pname);
1246 case GraphicsContext3D::BLEND_EQUATION_RGB:
1247 return getUnsignedLongParameter(pname);
1248 case GraphicsContext3D::BLEND_SRC_ALPHA:
1249 return getUnsignedLongParameter(pname);
1250 case GraphicsContext3D::BLEND_SRC_RGB:
1251 return getUnsignedLongParameter(pname);
1252 case GraphicsContext3D::BLUE_BITS:
1253 return getLongParameter(pname);
1254 case GraphicsContext3D::COLOR_CLEAR_VALUE:
1255 return getWebGLFloatArrayParameter(pname);
1256 case GraphicsContext3D::COLOR_WRITEMASK:
1257 return getBooleanArrayParameter(pname);
1258 case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
1259 // Defined as null in the spec
1260 return WebGLGetInfo();
1261 case GraphicsContext3D::CULL_FACE:
1262 return getBooleanParameter(pname);
1263 case GraphicsContext3D::CULL_FACE_MODE:
1264 return getUnsignedLongParameter(pname);
1265 case GraphicsContext3D::CURRENT_PROGRAM:
1266 return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
1267 case GraphicsContext3D::DEPTH_BITS:
1268 return getLongParameter(pname);
1269 case GraphicsContext3D::DEPTH_CLEAR_VALUE:
1270 return getFloatParameter(pname);
1271 case GraphicsContext3D::DEPTH_FUNC:
1272 return getUnsignedLongParameter(pname);
1273 case GraphicsContext3D::DEPTH_RANGE:
1274 return getWebGLFloatArrayParameter(pname);
1275 case GraphicsContext3D::DEPTH_TEST:
1276 return getBooleanParameter(pname);
1277 case GraphicsContext3D::DEPTH_WRITEMASK:
1278 return getBooleanParameter(pname);
1279 case GraphicsContext3D::DITHER:
1280 return getBooleanParameter(pname);
1281 case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
1282 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundElementArrayBuffer));
1283 case GraphicsContext3D::FRAMEBUFFER_BINDING:
1284 return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
1285 case GraphicsContext3D::FRONT_FACE:
1286 return getUnsignedLongParameter(pname);
1287 case GraphicsContext3D::GENERATE_MIPMAP_HINT:
1288 return getUnsignedLongParameter(pname);
1289 case GraphicsContext3D::GREEN_BITS:
1290 return getLongParameter(pname);
1291 case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
1292 return getLongParameter(pname);
1293 case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
1294 return getLongParameter(pname);
1295 case GraphicsContext3D::LINE_WIDTH:
1296 return getFloatParameter(pname);
1297 case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1298 return getLongParameter(pname);
1299 case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
1300 return getLongParameter(pname);
1301 case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
1302 return getLongParameter(pname);
1303 case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
1304 return getLongParameter(pname);
1305 case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
1306 return getLongParameter(pname);
1307 case GraphicsContext3D::MAX_TEXTURE_SIZE:
1308 return getLongParameter(pname);
1309 case GraphicsContext3D::MAX_VARYING_VECTORS:
1310 return getLongParameter(pname);
1311 case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
1312 return getLongParameter(pname);
1313 case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1314 return getLongParameter(pname);
1315 case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
1316 return getLongParameter(pname);
1317 case GraphicsContext3D::MAX_VIEWPORT_DIMS:
1318 return getWebGLIntArrayParameter(pname);
1319 case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS:
1320 return getLongParameter(pname);
1321 case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
1322 // FIXME: should we always return 0 for this?
1323 return getLongParameter(pname);
1324 case GraphicsContext3D::PACK_ALIGNMENT:
1325 return getLongParameter(pname);
1326 case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
1327 return getFloatParameter(pname);
1328 case GraphicsContext3D::POLYGON_OFFSET_FILL:
1329 return getBooleanParameter(pname);
1330 case GraphicsContext3D::POLYGON_OFFSET_UNITS:
1331 return getFloatParameter(pname);
1332 case GraphicsContext3D::RED_BITS:
1333 return getLongParameter(pname);
1334 case GraphicsContext3D::RENDERBUFFER_BINDING:
1335 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
1336 case GraphicsContext3D::SAMPLE_BUFFERS:
1337 return getLongParameter(pname);
1338 case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
1339 return getBooleanParameter(pname);
1340 case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
1341 return getFloatParameter(pname);
1342 case GraphicsContext3D::SAMPLES:
1343 return getLongParameter(pname);
1344 case GraphicsContext3D::SCISSOR_BOX:
1345 return getWebGLIntArrayParameter(pname);
1346 case GraphicsContext3D::SCISSOR_TEST:
1347 return getBooleanParameter(pname);
1348 case GraphicsContext3D::STENCIL_BACK_FAIL:
1349 return getUnsignedLongParameter(pname);
1350 case GraphicsContext3D::STENCIL_BACK_FUNC:
1351 return getUnsignedLongParameter(pname);
1352 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
1353 return getUnsignedLongParameter(pname);
1354 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
1355 return getUnsignedLongParameter(pname);
1356 case GraphicsContext3D::STENCIL_BACK_REF:
1357 return getLongParameter(pname);
1358 case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
1359 return getUnsignedLongParameter(pname);
1360 case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
1361 return getUnsignedLongParameter(pname);
1362 case GraphicsContext3D::STENCIL_BITS:
1363 return getLongParameter(pname);
1364 case GraphicsContext3D::STENCIL_CLEAR_VALUE:
1365 return getLongParameter(pname);
1366 case GraphicsContext3D::STENCIL_FAIL:
1367 return getUnsignedLongParameter(pname);
1368 case GraphicsContext3D::STENCIL_FUNC:
1369 return getUnsignedLongParameter(pname);
1370 case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
1371 return getUnsignedLongParameter(pname);
1372 case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
1373 return getUnsignedLongParameter(pname);
1374 case GraphicsContext3D::STENCIL_REF:
1375 return getLongParameter(pname);
1376 case GraphicsContext3D::STENCIL_TEST:
1377 return getBooleanParameter(pname);
1378 case GraphicsContext3D::STENCIL_VALUE_MASK:
1379 return getUnsignedLongParameter(pname);
1380 case GraphicsContext3D::STENCIL_WRITEMASK:
1381 return getUnsignedLongParameter(pname);
1382 case GraphicsContext3D::SUBPIXEL_BITS:
1383 return getLongParameter(pname);
1384 case GraphicsContext3D::TEXTURE_BINDING_2D:
1385 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
1386 case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
1387 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
1388 case GraphicsContext3D::UNPACK_ALIGNMENT:
1389 // FIXME: should this be "long" in the spec?
1390 return getIntParameter(pname);
1391 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1392 return WebGLGetInfo(m_unpackFlipY);
1393 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1394 return WebGLGetInfo(m_unpackPremultiplyAlpha);
1395 case GraphicsContext3D::VIEWPORT:
1396 return getWebGLIntArrayParameter(pname);
1398 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1399 return WebGLGetInfo();
1403 WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec)
1406 if (!validateWebGLObject(program))
1407 return WebGLGetInfo();
1409 WebGLStateRestorer(this, false);
1412 case GraphicsContext3D::DELETE_STATUS:
1413 case GraphicsContext3D::LINK_STATUS:
1414 case GraphicsContext3D::VALIDATE_STATUS:
1415 m_context->getProgramiv(program, pname, &value);
1416 return WebGLGetInfo(static_cast<bool>(value));
1417 case GraphicsContext3D::INFO_LOG_LENGTH:
1418 case GraphicsContext3D::ATTACHED_SHADERS:
1419 case GraphicsContext3D::ACTIVE_ATTRIBUTES:
1420 case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH:
1421 case GraphicsContext3D::ACTIVE_UNIFORMS:
1422 case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH:
1423 m_context->getProgramiv(program, pname, &value);
1424 return WebGLGetInfo(static_cast<long>(value));
1426 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1427 return WebGLGetInfo();
1431 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
1434 if (!validateWebGLObject(program))
1436 WebGLStateRestorer(this, false);
1437 return m_context->getProgramInfoLog(program);
1440 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1443 if (target != GraphicsContext3D::RENDERBUFFER) {
1444 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1445 return WebGLGetInfo();
1448 WebGLStateRestorer(this, false);
1451 case GraphicsContext3D::RENDERBUFFER_WIDTH:
1452 case GraphicsContext3D::RENDERBUFFER_HEIGHT:
1453 case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
1454 case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
1455 case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
1456 case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
1457 case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
1458 case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
1459 m_context->getRenderbufferParameteriv(target, pname, &value);
1460 return WebGLGetInfo(static_cast<long>(value));
1461 case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
1462 if (!m_renderbufferBinding) {
1463 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1464 return WebGLGetInfo();
1466 return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
1468 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1469 return WebGLGetInfo();
1473 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
1476 if (!validateWebGLObject(shader))
1477 return WebGLGetInfo();
1478 WebGLStateRestorer(this, false);
1481 case GraphicsContext3D::DELETE_STATUS:
1482 case GraphicsContext3D::COMPILE_STATUS:
1483 m_context->getShaderiv(shader, pname, &value);
1484 return WebGLGetInfo(static_cast<bool>(value));
1485 case GraphicsContext3D::SHADER_TYPE:
1486 m_context->getShaderiv(shader, pname, &value);
1487 return WebGLGetInfo(static_cast<unsigned long>(value));
1488 case GraphicsContext3D::INFO_LOG_LENGTH:
1489 case GraphicsContext3D::SHADER_SOURCE_LENGTH:
1490 m_context->getShaderiv(shader, pname, &value);
1491 return WebGLGetInfo(static_cast<long>(value));
1493 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1494 return WebGLGetInfo();
1498 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
1501 if (!validateWebGLObject(shader))
1503 WebGLStateRestorer(this, false);
1504 return m_context->getShaderInfoLog(shader);
1507 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
1510 if (!validateWebGLObject(shader))
1512 WebGLStateRestorer(this, false);
1513 return m_context->getShaderSource(shader);
1516 String WebGLRenderingContext::getString(unsigned long name)
1518 WebGLStateRestorer(this, false);
1519 return m_context->getString(name);
1522 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1525 if (target != GraphicsContext3D::TEXTURE_2D
1526 && target != GraphicsContext3D::TEXTURE_CUBE_MAP) {
1527 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1528 return WebGLGetInfo();
1530 WebGLStateRestorer(this, false);
1533 case GraphicsContext3D::TEXTURE_MAG_FILTER:
1534 case GraphicsContext3D::TEXTURE_MIN_FILTER:
1535 case GraphicsContext3D::TEXTURE_WRAP_S:
1536 case GraphicsContext3D::TEXTURE_WRAP_T:
1537 m_context->getTexParameteriv(target, pname, &value);
1538 return WebGLGetInfo(static_cast<unsigned long>(value));
1540 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1541 return WebGLGetInfo();
1545 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
1548 if (!validateWebGLObject(program))
1549 return WebGLGetInfo();
1550 if (uniformLocation->program() != program) {
1551 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1552 return WebGLGetInfo();
1554 long location = uniformLocation->location();
1556 WebGLStateRestorer(this, false);
1557 // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
1558 int activeUniforms = 0;
1559 m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
1560 for (int i = 0; i < activeUniforms; i++) {
1562 if (!m_context->getActiveUniform(program, i, info))
1563 return WebGLGetInfo();
1564 // Strip "[0]" from the name if it's an array.
1566 info.name = info.name.left(info.name.length() - 3);
1567 // If it's an array, we need to iterate through each element, appending "[index]" to the name.
1568 for (int index = 0; index < info.size; ++index) {
1569 String name = info.name;
1570 if (info.size > 1 && index >= 1) {
1572 name.append(String::number(index));
1575 // Now need to look this up by name again to find its location
1576 long loc = m_context->getUniformLocation(program, name);
1577 if (loc == location) {
1578 // Found it. Use the type in the ActiveInfo to determine the return type.
1579 GraphicsContext3D::WebGLEnumType baseType;
1581 switch (info.type) {
1582 case GraphicsContext3D::BOOL:
1583 baseType = GraphicsContext3D::BOOL;
1586 case GraphicsContext3D::BOOL_VEC2:
1587 baseType = GraphicsContext3D::BOOL;
1590 case GraphicsContext3D::BOOL_VEC3:
1591 baseType = GraphicsContext3D::BOOL;
1594 case GraphicsContext3D::BOOL_VEC4:
1595 baseType = GraphicsContext3D::BOOL;
1598 case GraphicsContext3D::INT:
1599 baseType = GraphicsContext3D::INT;
1602 case GraphicsContext3D::INT_VEC2:
1603 baseType = GraphicsContext3D::INT;
1606 case GraphicsContext3D::INT_VEC3:
1607 baseType = GraphicsContext3D::INT;
1610 case GraphicsContext3D::INT_VEC4:
1611 baseType = GraphicsContext3D::INT;
1614 case GraphicsContext3D::FLOAT:
1615 baseType = GraphicsContext3D::FLOAT;
1618 case GraphicsContext3D::FLOAT_VEC2:
1619 baseType = GraphicsContext3D::FLOAT;
1622 case GraphicsContext3D::FLOAT_VEC3:
1623 baseType = GraphicsContext3D::FLOAT;
1626 case GraphicsContext3D::FLOAT_VEC4:
1627 baseType = GraphicsContext3D::FLOAT;
1630 case GraphicsContext3D::FLOAT_MAT2:
1631 baseType = GraphicsContext3D::FLOAT;
1634 case GraphicsContext3D::FLOAT_MAT3:
1635 baseType = GraphicsContext3D::FLOAT;
1638 case GraphicsContext3D::FLOAT_MAT4:
1639 baseType = GraphicsContext3D::FLOAT;
1643 // Can't handle this type
1644 // FIXME: what to do about samplers?
1645 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1646 return WebGLGetInfo();
1649 case GraphicsContext3D::FLOAT: {
1650 float value[16] = {0};
1651 m_context->getUniformfv(program, location, value);
1653 return WebGLGetInfo(value[0]);
1654 return WebGLGetInfo(Float32Array::create(value, length));
1656 case GraphicsContext3D::INT: {
1657 int value[16] = {0};
1658 m_context->getUniformiv(program, location, value);
1660 return WebGLGetInfo(static_cast<long>(value[0]));
1661 return WebGLGetInfo(Int32Array::create(value, length));
1663 case GraphicsContext3D::BOOL: {
1664 int value[16] = {0};
1665 m_context->getUniformiv(program, location, value);
1667 unsigned char boolValue[16] = {0};
1668 for (unsigned j = 0; j < length; j++)
1669 boolValue[j] = static_cast<bool>(value[j]);
1670 return WebGLGetInfo(Uint8Array::create(boolValue, length));
1672 return WebGLGetInfo(static_cast<bool>(value[0]));
1680 // If we get here, something went wrong in our unfortunately complex logic above
1681 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1682 return WebGLGetInfo();
1685 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
1688 if (!validateWebGLObject(program))
1690 WebGLStateRestorer(this, false);
1691 long uniformLocation = m_context->getUniformLocation(program, name);
1692 if (uniformLocation == -1)
1694 return WebGLUniformLocation::create(program, uniformLocation);
1697 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
1700 WebGLStateRestorer(this, false);
1701 if (index >= m_maxVertexAttribs) {
1702 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1703 return WebGLGetInfo();
1706 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
1707 if (!isGLES2Compliant() && !index && m_vertexAttribState[0].bufferBinding == m_vertexAttrib0Buffer
1708 || index >= m_vertexAttribState.size()
1709 || !m_vertexAttribState[index].bufferBinding
1710 || !m_vertexAttribState[index].bufferBinding->object())
1711 return WebGLGetInfo();
1712 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_vertexAttribState[index].bufferBinding));
1713 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
1714 if (index >= m_vertexAttribState.size())
1715 return WebGLGetInfo(false);
1716 return WebGLGetInfo(m_vertexAttribState[index].enabled);
1717 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
1718 if (index >= m_vertexAttribState.size())
1719 return WebGLGetInfo(false);
1720 return WebGLGetInfo(m_vertexAttribState[index].normalized);
1721 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
1722 if (index >= m_vertexAttribState.size())
1723 return WebGLGetInfo(static_cast<long>(4));
1724 return WebGLGetInfo(m_vertexAttribState[index].size);
1725 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
1726 if (index >= m_vertexAttribState.size())
1727 return WebGLGetInfo(static_cast<long>(0));
1728 return WebGLGetInfo(m_vertexAttribState[index].originalStride);
1729 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
1730 if (index >= m_vertexAttribState.size())
1731 return WebGLGetInfo(static_cast<unsigned long>(GraphicsContext3D::FLOAT));
1732 return WebGLGetInfo(m_vertexAttribState[index].type);
1733 case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
1734 if (index >= m_vertexAttribState.size()) {
1735 float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
1736 return WebGLGetInfo(Float32Array::create(value, 4));
1738 return WebGLGetInfo(Float32Array::create(m_vertexAttribState[index].value, 4));
1740 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1741 return WebGLGetInfo();
1745 long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname)
1747 long result = m_context->getVertexAttribOffset(index, pname);
1748 cleanupAfterGraphicsCall(false);
1752 void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
1754 if (!isGLES2Compliant()) {
1755 if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
1756 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1760 m_context->hint(target, mode);
1761 cleanupAfterGraphicsCall(false);
1764 bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
1769 return m_context->isBuffer(buffer);
1772 bool WebGLRenderingContext::isEnabled(unsigned long cap)
1774 if (!isGLES2Compliant()) {
1775 if (!validateCapability(cap))
1778 return m_context->isEnabled(cap);
1781 bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
1786 return m_context->isFramebuffer(framebuffer);
1789 bool WebGLRenderingContext::isProgram(WebGLProgram* program)
1794 return m_context->isProgram(program);
1797 bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
1802 return m_context->isRenderbuffer(renderbuffer);
1805 bool WebGLRenderingContext::isShader(WebGLShader* shader)
1810 return m_context->isShader(shader);
1813 bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
1818 return m_context->isTexture(texture);
1821 void WebGLRenderingContext::lineWidth(double width)
1823 m_context->lineWidth((float) width);
1824 cleanupAfterGraphicsCall(false);
1827 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
1830 if (!validateWebGLObject(program))
1832 m_context->linkProgram(program);
1833 program->cacheActiveAttribLocations();
1834 cleanupAfterGraphicsCall(false);
1837 void WebGLRenderingContext::pixelStorei(unsigned long pname, long param)
1840 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1841 m_unpackFlipY = param;
1843 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1844 m_unpackPremultiplyAlpha = param;
1846 case GraphicsContext3D::PACK_ALIGNMENT:
1847 case GraphicsContext3D::UNPACK_ALIGNMENT:
1848 m_context->pixelStorei(pname, param);
1849 if (param == 1 || param == 2 || param == 4 || param == 8) {
1850 if (pname == GraphicsContext3D::PACK_ALIGNMENT)
1851 m_packAlignment = static_cast<int>(param);
1852 else // GraphicsContext3D::UNPACK_ALIGNMENT:
1853 m_unpackAlignment = static_cast<int>(param);
1857 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1860 cleanupAfterGraphicsCall(false);
1863 void WebGLRenderingContext::polygonOffset(double factor, double units)
1865 m_context->polygonOffset((float) factor, (float) units);
1866 cleanupAfterGraphicsCall(false);
1869 void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels)
1871 // Validate input parameters.
1872 unsigned long componentsPerPixel, bytesPerComponent;
1873 if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
1874 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1878 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1881 if (width < 0 || height < 0) {
1882 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1885 if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) {
1886 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1889 // Validate array type against pixel type.
1890 if (type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray()
1891 || type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray()) {
1892 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1895 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
1896 unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
1897 unsigned long padding = 0;
1898 unsigned long residualBytes = bytesPerRow % m_packAlignment;
1899 if (residualBytes) {
1900 padding = m_packAlignment - residualBytes;
1901 bytesPerRow += padding;
1903 // The last row needs no padding.
1904 unsigned long totalBytes = bytesPerRow * height - padding;
1905 unsigned long num = totalBytes / bytesPerComponent;
1906 if (pixels->length() < num) {
1907 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1910 void* data = pixels->baseAddress();
1911 m_context->readPixels(x, y, width, height, format, type, data);
1913 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
1914 // when alpha is off, readPixels should set alpha to 255 instead of 0.
1915 if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) {
1916 if (type == GraphicsContext3D::UNSIGNED_BYTE) {
1917 unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
1918 for (long iy = 0; iy < height; ++iy) {
1919 for (long ix = 0; ix < width; ++ix) {
1920 pixels[componentsPerPixel - 1] = 255;
1921 pixels += componentsPerPixel;
1926 // FIXME: check whether we need to do the same with UNSIGNED_SHORT.
1929 cleanupAfterGraphicsCall(false);
1932 void WebGLRenderingContext::releaseShaderCompiler()
1934 m_context->releaseShaderCompiler();
1935 cleanupAfterGraphicsCall(false);
1938 void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
1940 switch (internalformat) {
1941 case GraphicsContext3D::DEPTH_COMPONENT16:
1942 case GraphicsContext3D::RGBA4:
1943 case GraphicsContext3D::RGB5_A1:
1944 case GraphicsContext3D::RGB565:
1945 case GraphicsContext3D::STENCIL_INDEX8:
1946 case GraphicsContext3D::DEPTH_STENCIL:
1947 m_context->renderbufferStorage(target, internalformat, width, height);
1948 if (m_renderbufferBinding) {
1949 m_renderbufferBinding->setInternalFormat(internalformat);
1950 if (m_framebufferBinding)
1951 m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get());
1953 cleanupAfterGraphicsCall(false);
1956 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1960 void WebGLRenderingContext::sampleCoverage(double value, bool invert)
1962 m_context->sampleCoverage((float) value, invert);
1963 cleanupAfterGraphicsCall(false);
1966 void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height)
1968 m_context->scissor(x, y, width, height);
1969 cleanupAfterGraphicsCall(false);
1972 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
1975 if (!validateWebGLObject(shader))
1977 m_context->shaderSource(shader, string);
1978 cleanupAfterGraphicsCall(false);
1981 void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask)
1983 m_context->stencilFunc(func, ref, mask);
1984 cleanupAfterGraphicsCall(false);
1987 void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
1989 m_context->stencilFuncSeparate(face, func, ref, mask);
1990 cleanupAfterGraphicsCall(false);
1993 void WebGLRenderingContext::stencilMask(unsigned long mask)
1995 m_context->stencilMask(mask);
1996 cleanupAfterGraphicsCall(false);
1999 void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask)
2001 m_context->stencilMaskSeparate(face, mask);
2002 cleanupAfterGraphicsCall(false);
2005 void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
2007 m_context->stencilOp(fail, zfail, zpass);
2008 cleanupAfterGraphicsCall(false);
2011 void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
2013 m_context->stencilOpSeparate(face, fail, zfail, zpass);
2014 cleanupAfterGraphicsCall(false);
2017 void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsigned internalformat,
2018 unsigned width, unsigned height, unsigned border,
2019 unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
2021 // FIXME: For now we ignore any errors returned
2023 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
2025 if (!isGLES2Compliant()) {
2026 if (level && WebGLTexture::isNPOT(width, height)) {
2027 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2031 m_context->texImage2D(target, level, internalformat, width, height,
2032 border, format, type, pixels);
2033 WebGLTexture* tex = getTextureBinding(target);
2034 if (!isGLES2Compliant()) {
2035 if (tex && !level) // only for level 0
2036 tex->setSize(target, width, height);
2038 tex->setInternalFormat(internalformat);
2040 if (m_framebufferBinding && tex)
2041 m_framebufferBinding->onAttachedObjectChange(tex);
2042 cleanupAfterGraphicsCall(false);
2045 void WebGLRenderingContext::texImage2DImpl(unsigned target, unsigned level, unsigned internalformat,
2046 unsigned format, unsigned type, Image* image,
2047 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2050 Vector<uint8_t> data;
2051 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
2052 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2055 if (m_unpackAlignment != 1)
2056 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2057 texImage2DBase(target, level, internalformat, image->width(), image->height(), 0,
2058 format, type, data.data(), ec);
2059 if (m_unpackAlignment != 1)
2060 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2063 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2064 unsigned width, unsigned height, unsigned border,
2065 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
2067 if (!validateTexFuncData(width, height, format, type, pixels))
2069 void* data = pixels ? pixels->baseAddress() : 0;
2070 Vector<uint8_t> tempData;
2071 bool changeUnpackAlignment = false;
2072 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
2073 if (!m_context->extractTextureData(width, height, format, type,
2075 m_unpackFlipY, m_unpackPremultiplyAlpha,
2079 data = tempData.data();
2080 changeUnpackAlignment = true;
2082 if (changeUnpackAlignment)
2083 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2084 texImage2DBase(target, level, internalformat, width, height, border,
2085 format, type, data, ec);
2086 if (changeUnpackAlignment)
2087 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2090 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2091 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
2094 Vector<uint8_t> data;
2095 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
2096 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2099 if (m_unpackAlignment != 1)
2100 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2101 texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0,
2102 format, type, data.data(), ec);
2103 if (m_unpackAlignment != 1)
2104 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2107 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2108 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
2111 if (!image || !image->cachedImage()) {
2112 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2115 texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
2116 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2119 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2120 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
2123 if (!canvas || !canvas->buffer()) {
2124 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2127 texImage2DImpl(target, level, internalformat, format, type, canvas->buffer()->image(),
2128 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2131 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2132 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
2134 // FIXME: Need to implement this call
2135 UNUSED_PARAM(target);
2136 UNUSED_PARAM(level);
2137 UNUSED_PARAM(internalformat);
2138 UNUSED_PARAM(format);
2140 UNUSED_PARAM(video);
2143 cleanupAfterGraphicsCall(false);
2146 // Obsolete texImage2D entry points -- to be removed shortly. (FIXME)
2148 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2151 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels)");
2152 texImage2D(target, level, pixels, 0, 0, ec);
2155 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2156 bool flipY, ExceptionCode& ec)
2158 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY)");
2159 texImage2D(target, level, pixels, flipY, 0, ec);
2162 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2163 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2165 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
2167 Vector<uint8_t> data;
2168 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
2169 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2172 texImage2DBase(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0,
2173 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
2177 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2180 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image)");
2181 texImage2D(target, level, image, 0, 0, ec);
2184 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2185 bool flipY, ExceptionCode& ec)
2187 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY)");
2188 texImage2D(target, level, image, flipY, 0, ec);
2191 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2192 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2194 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
2196 if (!image || !image->cachedImage()) {
2197 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2200 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(), flipY, premultiplyAlpha, ec);
2203 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2206 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas)");
2207 texImage2D(target, level, canvas, 0, 0, ec);
2210 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2211 bool flipY, ExceptionCode& ec)
2213 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY)");
2214 texImage2D(target, level, canvas, flipY, 0, ec);
2217 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2218 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2220 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
2222 if (!canvas || !canvas->buffer()) {
2223 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2226 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(), flipY, premultiplyAlpha, ec);
2229 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2232 texImage2D(target, level, video, 0, 0, ec);
2235 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2236 bool flipY, ExceptionCode& ec)
2238 texImage2D(target, level, video, flipY, 0, ec);
2241 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2242 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2244 // FIXME: Need implement this call
2245 UNUSED_PARAM(target);
2246 UNUSED_PARAM(level);
2247 UNUSED_PARAM(video);
2248 UNUSED_PARAM(flipY);
2249 UNUSED_PARAM(premultiplyAlpha);
2252 cleanupAfterGraphicsCall(false);
2255 void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
2257 if (!isGLES2Compliant()) {
2258 RefPtr<WebGLTexture> tex = 0;
2260 case GraphicsContext3D::TEXTURE_2D:
2261 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
2263 case GraphicsContext3D::TEXTURE_CUBE_MAP:
2264 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
2267 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2271 case GraphicsContext3D::TEXTURE_MIN_FILTER:
2272 case GraphicsContext3D::TEXTURE_MAG_FILTER:
2274 case GraphicsContext3D::TEXTURE_WRAP_S:
2275 case GraphicsContext3D::TEXTURE_WRAP_T:
2276 if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT
2277 || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) {
2278 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2283 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2288 tex->setParameterf(pname, paramf);
2290 tex->setParameteri(pname, parami);
2294 m_context->texParameterf(target, pname, paramf);
2296 m_context->texParameteri(target, pname, parami);
2297 cleanupAfterGraphicsCall(false);
2300 void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param)
2302 texParameter(target, pname, param, 0, true);
2305 void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param)
2307 texParameter(target, pname, 0, param, false);
2310 void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2311 unsigned width, unsigned height,
2312 unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
2314 // FIXME: For now we ignore any errors returned
2316 if (!validateTexFuncFormatAndType(format, type))
2319 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
2320 cleanupAfterGraphicsCall(false);
2323 void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2324 unsigned format, unsigned type,
2325 Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2328 Vector<uint8_t> data;
2329 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
2330 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2333 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
2334 format, type, data.data(), ec);
2337 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2338 unsigned width, unsigned height,
2339 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
2341 if (!validateTexFuncData(width, height, format, type, pixels))
2343 void* data = pixels ? pixels->baseAddress() : 0;
2344 Vector<uint8_t> tempData;
2345 bool changeUnpackAlignment = false;
2346 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
2347 if (!m_context->extractTextureData(width, height, format, type,
2349 m_unpackFlipY, m_unpackPremultiplyAlpha,
2353 data = tempData.data();
2354 changeUnpackAlignment = true;
2356 if (changeUnpackAlignment)
2357 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2358 texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
2359 if (changeUnpackAlignment)
2360 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2363 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2364 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
2367 Vector<uint8_t> data;
2368 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
2369 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2372 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
2373 format, type, data.data(), ec);
2376 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2377 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
2380 if (!image || !image->cachedImage()) {
2381 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2384 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
2385 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2388 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2389 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
2392 if (!canvas || !canvas->buffer()) {
2393 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2396 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->buffer()->image(),
2397 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2400 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2401 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
2403 // FIXME: Need to implement this call
2404 UNUSED_PARAM(target);
2405 UNUSED_PARAM(level);
2406 UNUSED_PARAM(xoffset);
2407 UNUSED_PARAM(yoffset);
2408 UNUSED_PARAM(format);
2410 UNUSED_PARAM(video);
2412 cleanupAfterGraphicsCall(false);
2415 // Obsolete texSubImage2D entry points -- to be removed shortly. (FIXME)
2417 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2418 ImageData* pixels, ExceptionCode& ec)
2420 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels)");
2421 texSubImage2D(target, level, xoffset, yoffset, pixels, 0, 0, ec);
2424 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2425 ImageData* pixels, bool flipY, ExceptionCode& ec)
2427 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY)");
2428 texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, 0, ec);
2431 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2432 ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2434 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
2436 Vector<uint8_t> data;
2437 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
2438 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2441 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
2442 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
2445 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2446 HTMLImageElement* image, ExceptionCode& ec)
2448 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image)");
2449 texSubImage2D(target, level, xoffset, yoffset, image, 0, 0, ec);
2452 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2453 HTMLImageElement* image, bool flipY, ExceptionCode& ec)
2455 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY)");
2456 texSubImage2D(target, level, xoffset, yoffset, image, flipY, 0, ec);
2459 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2460 HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2462 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
2464 if (!image || !image->cachedImage()) {
2465 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2468 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(),
2469 flipY, premultiplyAlpha, ec);
2472 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2473 HTMLCanvasElement* canvas, ExceptionCode& ec)
2475 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas)");
2476 texSubImage2D(target, level, xoffset, yoffset, canvas, 0, 0, ec);
2479 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2480 HTMLCanvasElement* canvas, bool flipY, ExceptionCode& ec)
2482 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY)");
2483 texSubImage2D(target, level, xoffset, yoffset, canvas, flipY, 0, ec);
2486 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2487 HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2489 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
2491 if (!canvas || !canvas->buffer()) {
2492 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2495 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(),
2496 flipY, premultiplyAlpha, ec);
2499 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2500 HTMLVideoElement* video, ExceptionCode& ec)
2502 texSubImage2D(target, level, xoffset, yoffset, video, 0, 0, ec);
2505 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2506 HTMLVideoElement* video, bool flipY, ExceptionCode& ec)
2508 texSubImage2D(target, level, xoffset, yoffset, video, flipY, 0, ec);
2511 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2512 HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2514 // FIXME: Need to implement this call
2515 UNUSED_PARAM(target);
2516 UNUSED_PARAM(level);
2517 UNUSED_PARAM(xoffset);
2518 UNUSED_PARAM(yoffset);
2519 UNUSED_PARAM(video);
2520 UNUSED_PARAM(flipY);
2521 UNUSED_PARAM(premultiplyAlpha);
2523 cleanupAfterGraphicsCall(false);
2526 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
2532 if (location->program() != m_currentProgram) {
2533 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2537 m_context->uniform1f(location->location(), x);
2538 cleanupAfterGraphicsCall(false);
2541 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2544 if (!validateUniformParameters(location, v, 1))
2547 m_context->uniform1fv(location->location(), v->data(), v->length());
2548 cleanupAfterGraphicsCall(false);
2551 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2554 if (!validateUniformParameters(location, v, size, 1))
2557 m_context->uniform1fv(location->location(), v, size);
2558 cleanupAfterGraphicsCall(false);
2561 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
2567 if (location->program() != m_currentProgram) {
2568 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2572 m_context->uniform1i(location->location(), x);
2573 cleanupAfterGraphicsCall(false);
2576 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2579 if (!validateUniformParameters(location, v, 1))
2582 m_context->uniform1iv(location->location(), v->data(), v->length());
2583 cleanupAfterGraphicsCall(false);
2586 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2589 if (!validateUniformParameters(location, v, size, 1))
2592 m_context->uniform1iv(location->location(), v, size);
2593 cleanupAfterGraphicsCall(false);
2596 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
2602 if (location->program() != m_currentProgram) {
2603 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2607 m_context->uniform2f(location->location(), x, y);
2608 cleanupAfterGraphicsCall(false);
2611 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2614 if (!validateUniformParameters(location, v, 2))
2617 m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
2618 cleanupAfterGraphicsCall(false);
2621 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2624 if (!validateUniformParameters(location, v, size, 2))
2627 m_context->uniform2fv(location->location(), v, size / 2);
2628 cleanupAfterGraphicsCall(false);
2631 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
2637 if (location->program() != m_currentProgram) {
2638 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2642 m_context->uniform2i(location->location(), x, y);
2643 cleanupAfterGraphicsCall(false);
2646 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2649 if (!validateUniformParameters(location, v, 2))
2652 m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
2653 cleanupAfterGraphicsCall(false);
2656 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2659 if (!validateUniformParameters(location, v, size, 2))
2662 m_context->uniform2iv(location->location(), v, size / 2);
2663 cleanupAfterGraphicsCall(false);
2666 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
2672 if (location->program() != m_currentProgram) {
2673 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2677 m_context->uniform3f(location->location(), x, y, z);
2678 cleanupAfterGraphicsCall(false);
2681 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2684 if (!validateUniformParameters(location, v, 3))
2687 m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
2688 cleanupAfterGraphicsCall(false);
2691 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2694 if (!validateUniformParameters(location, v, size, 3))
2697 m_context->uniform3fv(location->location(), v, size / 3);
2698 cleanupAfterGraphicsCall(false);
2701 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
2707 if (location->program() != m_currentProgram) {
2708 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2712 m_context->uniform3i(location->location(), x, y, z);
2713 cleanupAfterGraphicsCall(false);
2716 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2719 if (!validateUniformParameters(location, v, 3))
2722 m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
2723 cleanupAfterGraphicsCall(false);
2726 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2729 if (!validateUniformParameters(location, v, size, 3))
2732 m_context->uniform3iv(location->location(), v, size / 3);
2733 cleanupAfterGraphicsCall(false);
2736 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
2742 if (location->program() != m_currentProgram) {
2743 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2747 m_context->uniform4f(location->location(), x, y, z, w);
2748 cleanupAfterGraphicsCall(false);
2751 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2754 if (!validateUniformParameters(location, v, 4))
2757 m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
2758 cleanupAfterGraphicsCall(false);
2761 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2764 if (!validateUniformParameters(location, v, size, 4))
2767 m_context->uniform4fv(location->location(), v, size / 4);
2768 cleanupAfterGraphicsCall(false);
2771 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
2777 if (location->program() != m_currentProgram) {
2778 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2782 m_context->uniform4i(location->location(), x, y, z, w);
2783 cleanupAfterGraphicsCall(false);
2786 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2789 if (!validateUniformParameters(location, v, 4))
2792 m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
2793 cleanupAfterGraphicsCall(false);
2796 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2799 if (!validateUniformParameters(location, v, size, 4))
2802 m_context->uniform4iv(location->location(), v, size / 4);
2803 cleanupAfterGraphicsCall(false);
2806 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2809 if (!validateUniformMatrixParameters(location, transpose, v, 4))
2811 m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
2812 cleanupAfterGraphicsCall(false);
2815 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2818 if (!validateUniformMatrixParameters(location, transpose, v, size, 4))
2820 m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
2821 cleanupAfterGraphicsCall(false);
2824 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2827 if (!validateUniformMatrixParameters(location, transpose, v, 9))
2829 m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
2830 cleanupAfterGraphicsCall(false);
2833 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2836 if (!validateUniformMatrixParameters(location, transpose, v, size, 9))
2838 m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
2839 cleanupAfterGraphicsCall(false);
2842 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2845 if (!validateUniformMatrixParameters(location, transpose, v, 16))
2847 m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
2848 cleanupAfterGraphicsCall(false);
2851 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2854 if (!validateUniformMatrixParameters(location, transpose, v, size, 16))
2856 m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
2857 cleanupAfterGraphicsCall(false);
2860 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
2863 if (program && program->context() != this) {
2864 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2867 m_currentProgram = program;
2868 m_context->useProgram(program);
2869 cleanupAfterGraphicsCall(false);
2872 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
2875 if (!validateWebGLObject(program))
2877 m_context->validateProgram(program);
2878 cleanupAfterGraphicsCall(false);
2881 void WebGLRenderingContext::vertexAttrib1f(unsigned long index, float v0)
2883 // In GL, we skip setting vertexAttrib0 values.
2884 if (index || isGLES2Compliant()) {
2885 m_context->vertexAttrib1f(index, v0);
2886 cleanupAfterGraphicsCall(false);
2888 m_vertexAttribState[index].value[0] = v0;
2889 m_vertexAttribState[index].value[1] = 0.0f;
2890 m_vertexAttribState[index].value[2] = 0.0f;
2891 m_vertexAttribState[index].value[3] = 1.0f;
2894 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, Float32Array* v)
2896 vertexAttribImpl(index, v, 1);
2899 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, float* v, int size)
2901 vertexAttribImpl(index, v, size, 1);
2904 void WebGLRenderingContext::vertexAttrib2f(unsigned long index, float v0, float v1)
2906 // In GL, we skip setting vertexAttrib0 values.
2907 if (index || isGLES2Compliant()) {
2908 m_context->vertexAttrib2f(index, v0, v1);
2909 cleanupAfterGraphicsCall(false);
2911 m_vertexAttribState[index].value[0] = v0;
2912 m_vertexAttribState[index].value[1] = v1;
2913 m_vertexAttribState[index].value[2] = 0.0f;
2914 m_vertexAttribState[index].value[3] = 1.0f;
2917 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, Float32Array* v)
2919 vertexAttribImpl(index, v, 2);
2922 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, float* v, int size)
2924 vertexAttribImpl(index, v, size, 2);
2927 void WebGLRenderingContext::vertexAttrib3f(unsigned long index, float v0, float v1, float v2)
2929 // In GL, we skip setting vertexAttrib0 values.
2930 if (index || isGLES2Compliant()) {
2931 m_context->vertexAttrib3f(index, v0, v1, v2);
2932 cleanupAfterGraphicsCall(false);
2934 m_vertexAttribState[index].value[0] = v0;
2935 m_vertexAttribState[index].value[1] = v1;
2936 m_vertexAttribState[index].value[2] = v2;
2937 m_vertexAttribState[index].value[3] = 1.0f;
2940 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, Float32Array* v)
2942 vertexAttribImpl(index, v, 3);
2945 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, float* v, int size)
2947 vertexAttribImpl(index, v, size, 3);
2950 void WebGLRenderingContext::vertexAttrib4f(unsigned long index, float v0, float v1, float v2, float v3)
2952 // In GL, we skip setting vertexAttrib0 values.
2953 if (index || isGLES2Compliant()) {
2954 m_context->vertexAttrib4f(index, v0, v1, v2, v3);
2955 cleanupAfterGraphicsCall(false);
2957 m_vertexAttribState[index].value[0] = v0;
2958 m_vertexAttribState[index].value[1] = v1;
2959 m_vertexAttribState[index].value[2] = v2;
2960 m_vertexAttribState[index].value[3] = v3;
2963 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, Float32Array* v)
2965 vertexAttribImpl(index, v, 4);
2968 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int size)
2970 vertexAttribImpl(index, v, size, 4);
2973 void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, long offset, ExceptionCode& ec)
2975 if (index >= m_maxVertexAttribs) {
2976 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2979 if (size < 1 || size > 4 || stride < 0 || offset < 0) {
2980 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2983 if (!m_boundArrayBuffer) {
2984 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2987 // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
2988 long bytesPerElement = size * sizeInBytes(type, ec);
2989 if (bytesPerElement <= 0)
2992 if (index >= m_vertexAttribState.size())
2993 m_vertexAttribState.resize(index + 1);
2995 long validatedStride = bytesPerElement;
2997 if ((long) stride < bytesPerElement) {
2998 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3001 validatedStride = stride;
3003 m_vertexAttribState[index].bufferBinding = m_boundArrayBuffer;
3004 m_vertexAttribState[index].bytesPerElement = bytesPerElement;
3005 m_vertexAttribState[index].size = size;
3006 m_vertexAttribState[index].type = type;
3007 m_vertexAttribState[index].normalized = normalized;
3008 m_vertexAttribState[index].stride = validatedStride;
3009 m_vertexAttribState[index].originalStride = stride;
3010 m_vertexAttribState[index].offset = offset;
3011 m_context->vertexAttribPointer(index, size, type, normalized, stride, offset);
3012 cleanupAfterGraphicsCall(false);
3015 void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height)
3025 m_context->viewport(x, y, width, height);
3026 cleanupAfterGraphicsCall(false);
3029 void WebGLRenderingContext::removeObject(CanvasObject* object)
3031 m_canvasObjects.remove(object);
3034 void WebGLRenderingContext::addObject(CanvasObject* object)
3036 removeObject(object);
3037 m_canvasObjects.add(object);
3040 void WebGLRenderingContext::detachAndRemoveAllObjects()
3042 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3043 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it)
3044 (*it)->detachContext();
3046 m_canvasObjects.clear();
3049 WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj)
3053 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3054 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3055 if ((*it)->isTexture() && (*it)->object() == obj)
3056 return reinterpret_cast<WebGLTexture*>((*it).get());
3061 WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj)
3065 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3066 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3067 if ((*it)->isRenderbuffer() && (*it)->object() == obj)
3068 return reinterpret_cast<WebGLRenderbuffer*>((*it).get());
3073 WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj)
3077 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3078 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3079 if ((*it)->isBuffer() && (*it)->object() == obj)
3080 return reinterpret_cast<WebGLBuffer*>((*it).get());
3085 WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj)
3089 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3090 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3091 if ((*it)->isShader() && (*it)->object() == obj)
3092 return reinterpret_cast<WebGLShader*>((*it).get());
3097 WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname)
3099 unsigned char value;
3100 m_context->getBooleanv(pname, &value);
3101 return WebGLGetInfo(static_cast<bool>(value));
3104 WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(unsigned long pname)
3106 if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
3108 return WebGLGetInfo(0, 0);
3110 unsigned char value[4] = {0};
3111 m_context->getBooleanv(pname, value);
3113 for (int ii = 0; ii < 4; ++ii)
3114 boolValue[ii] = static_cast<bool>(value[ii]);
3115 return WebGLGetInfo(boolValue, 4);
3118 WebGLGetInfo WebGLRenderingContext::getFloatParameter(unsigned long pname)
3121 m_context->getFloatv(pname, &value);
3122 return WebGLGetInfo(static_cast<float>(value));
3125 WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname)
3127 return getLongParameter(pname);
3130 WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname)
3133 m_context->getIntegerv(pname, &value);
3134 return WebGLGetInfo(static_cast<long>(value));
3137 WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname)
3140 m_context->getIntegerv(pname, &value);
3141 return WebGLGetInfo(static_cast<unsigned long>(value));
3144 WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname)
3146 float value[4] = {0};
3147 m_context->getFloatv(pname, value);
3148 unsigned length = 0;
3150 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
3151 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
3152 case GraphicsContext3D::DEPTH_RANGE:
3155 case GraphicsContext3D::BLEND_COLOR:
3156 case GraphicsContext3D::COLOR_CLEAR_VALUE:
3162 return WebGLGetInfo(Float32Array::create(value, length));
3165 WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(unsigned long pname)
3168 m_context->getIntegerv(pname, value);
3169 unsigned length = 0;
3171 case GraphicsContext3D::MAX_VIEWPORT_DIMS:
3174 case GraphicsContext3D::SCISSOR_BOX:
3175 case GraphicsContext3D::VIEWPORT:
3181 return WebGLGetInfo(Int32Array::create(value, length));
3184 bool WebGLRenderingContext::isGLES2Compliant()
3186 return m_context->isGLES2Compliant();
3189 void WebGLRenderingContext::handleNPOTTextures(bool prepareToDraw)
3191 bool resetActiveUnit = false;
3192 for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
3193 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture()
3194 || m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture()) {
3195 if (ii != m_activeTextureUnit) {
3196 m_context->activeTexture(ii);
3197 resetActiveUnit = true;
3198 } else if (resetActiveUnit) {
3199 m_context->activeTexture(ii);
3200 resetActiveUnit = false;
3202 WebGLTexture* tex2D;
3203 WebGLTexture* texCubeMap;
3204 if (prepareToDraw) {
3205 tex2D = m_blackTexture2D.get();
3206 texCubeMap = m_blackTextureCubeMap.get();
3208 tex2D = m_textureUnits[ii].m_texture2DBinding.get();
3209 texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
3211 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
3212 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, tex2D);
3213 if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())
3214 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, texCubeMap);
3217 if (resetActiveUnit)
3218 m_context->activeTexture(m_activeTextureUnit);
3221 void WebGLRenderingContext::createFallbackBlackTextures1x1()
3223 unsigned char black[] = {0, 0, 0, 255};
3224 m_blackTexture2D = createTexture();
3225 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D.get());
3226 m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
3227 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3228 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
3229 m_blackTextureCubeMap = createTexture();
3230 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap.get());
3231 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
3232 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3233 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
3234 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3235 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
3236 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3237 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
3238 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3239 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
3240 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3241 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
3242 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3243 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
3246 bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(unsigned long texInternalFormat,
3247 unsigned long colorBufferFormat)
3249 switch (colorBufferFormat) {
3250 case GraphicsContext3D::ALPHA:
3251 if (texInternalFormat == GraphicsContext3D::ALPHA)
3254 case GraphicsContext3D::RGB:
3255 if (texInternalFormat == GraphicsContext3D::LUMINANCE
3256 || texInternalFormat == GraphicsContext3D::RGB)
3259 case GraphicsContext3D::RGBA:
3265 WebGLTexture* WebGLRenderingContext::getTextureBinding(unsigned long target)
3267 RefPtr<WebGLTexture> tex = 0;
3269 case GraphicsContext3D::TEXTURE_2D:
3270 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
3272 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
3273 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
3274 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
3275 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
3276 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
3277 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
3278 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
3281 if (tex && tex->object())
3286 bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type)
3289 case GraphicsContext3D::ALPHA:
3290 case GraphicsContext3D::LUMINANCE:
3291 case GraphicsContext3D::LUMINANCE_ALPHA:
3292 case GraphicsContext3D::RGB:
3293 case GraphicsContext3D::RGBA:
3296 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3301 case GraphicsContext3D::UNSIGNED_BYTE:
3302 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
3303 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
3304 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
3307 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3311 // Verify that the combination of format and type is supported.
3313 case GraphicsContext3D::ALPHA:
3314 case GraphicsContext3D::LUMINANCE:
3315 case GraphicsContext3D::LUMINANCE_ALPHA:
3316 if (type != GraphicsContext3D::UNSIGNED_BYTE) {
3317 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3321 case GraphicsContext3D::RGB:
3322 if (type != GraphicsContext3D::UNSIGNED_BYTE
3323 && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5) {
3324 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3328 case GraphicsContext3D::RGBA:
3329 if (type != GraphicsContext3D::UNSIGNED_BYTE
3330 && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
3331 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1) {
3332 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3337 ASSERT_NOT_REACHED();
3343 bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long level,
3344 unsigned long internalformat,
3345 long width, long height, long border,
3346 unsigned long format, unsigned long type)
3348 // We absolutely have to validate the format and type combination.
3349 // The texImage2D entry points taking HTMLImage, etc. will produce
3350 // temporary data based on this combination, so it must be legal.
3351 if (!validateTexFuncFormatAndType(format, type))
3354 if (isGLES2Compliant())
3357 if (width < 0 || height < 0 || level < 0) {
3358 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3363 case GraphicsContext3D::TEXTURE_2D:
3364 if (width > m_maxTextureSize || height > m_maxTextureSize) {
3365 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3369 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
3370 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
3371 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
3372 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
3373 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
3374 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
3375 if (width != height || width > m_maxCubeMapTextureSize) {
3376 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3381 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3385 if (format != internalformat) {
3386 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3391 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3398 bool WebGLRenderingContext::validateTexFuncData(long width, long height,
3399 unsigned long format, unsigned long type,
3400 ArrayBufferView* pixels)
3405 if (!validateTexFuncFormatAndType(format, type))
3409 case GraphicsContext3D::UNSIGNED_BYTE:
3410 if (!pixels->isUnsignedByteArray()) {
3411 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3415 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
3416 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
3417 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
3418 if (!pixels->isUnsignedShortArray()) {
3419 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3424 ASSERT_NOT_REACHED();
3427 unsigned long componentsPerPixel, bytesPerComponent;
3428 if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
3429 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3433 if (!width || !height)
3435 unsigned int validRowBytes = width * componentsPerPixel * bytesPerComponent;
3436 unsigned int totalRowBytes = validRowBytes;
3437 unsigned int remainder = validRowBytes % m_unpackAlignment;
3439 totalRowBytes += (m_unpackAlignment - remainder);
3440 unsigned int totalBytesRequired = (height - 1) * totalRowBytes + validRowBytes;
3441 if (pixels->byteLength() < totalBytesRequired) {
3442 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3448 bool WebGLRenderingContext::validateDrawMode(unsigned long mode)
3451 case GraphicsContext3D::POINTS:
3452 case GraphicsContext3D::LINE_STRIP:
3453 case GraphicsContext3D::LINE_LOOP:
3454 case GraphicsContext3D::LINES:
3455 case GraphicsContext3D::TRIANGLE_STRIP:
3456 case GraphicsContext3D::TRIANGLE_FAN:
3457 case GraphicsContext3D::TRIANGLES:
3460 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3465 void WebGLRenderingContext::printWarningToConsole(const String& message)
3467 canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel,
3468 message, 0, canvas()->document()->url().string());
3471 bool WebGLRenderingContext::validateFramebufferFuncParameters(unsigned long target, unsigned long attachment)
3473 if (target != GraphicsContext3D::FRAMEBUFFER) {
3474 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3477 switch (attachment) {
3478 case GraphicsContext3D::COLOR_ATTACHMENT0:
3479 case GraphicsContext3D::DEPTH_ATTACHMENT:
3480 case GraphicsContext3D::STENCIL_ATTACHMENT:
3481 case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
3484 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3490 bool WebGLRenderingContext::validateBlendEquation(unsigned long mode)
3493 case GraphicsContext3D::FUNC_ADD:
3494 case GraphicsContext3D::FUNC_SUBTRACT:
3495 case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
3498 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3503 bool WebGLRenderingContext::validateCapability(unsigned long cap)
3506 case GraphicsContext3D::BLEND:
3507 case GraphicsContext3D::CULL_FACE:
3508 case GraphicsContext3D::DEPTH_TEST:
3509 case GraphicsContext3D::DITHER:
3510 case GraphicsContext3D::POLYGON_OFFSET_FILL:
3511 case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
3512 case GraphicsContext3D::SAMPLE_COVERAGE:
3513 case GraphicsContext3D::SCISSOR_TEST:
3514 case GraphicsContext3D::STENCIL_TEST:
3517 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3522 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, int requiredMinSize)
3525 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3528 return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
3531 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, int requiredMinSize)
3534 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3537 return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
3540 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, int size, int requiredMinSize)
3542 return validateUniformMatrixParameters(location, false, v, size, requiredMinSize);
3545 bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, Float32Array* v, int requiredMinSize)
3548 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3551 return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize);
3554 bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, void* v, int size, int requiredMinSize)
3558 if (location->program() != m_currentProgram) {
3559 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3563 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3567 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3570 if (size < requiredMinSize) {
3571 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3577 void WebGLRenderingContext::vertexAttribImpl(unsigned long index, Float32Array* v, int expectedSize)
3580 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3583 vertexAttribImpl(index, v->data(), v->length(), expectedSize);
3586 void WebGLRenderingContext::vertexAttribImpl(unsigned long index, float* v, int size, int expectedSize)
3589 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3592 if (size < expectedSize) {
3593 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3596 // In GL, we skip setting vertexAttrib0 values.
3597 if (index || isGLES2Compliant()) {
3598 switch (expectedSize) {
3600 m_context->vertexAttrib1fv(index, v);
3603 m_context->vertexAttrib2fv(index, v);
3606 m_context->vertexAttrib3fv(index, v);
3609 m_context->vertexAttrib4fv(index, v);
3612 cleanupAfterGraphicsCall(false);
3614 m_vertexAttribState[index].initValue();
3615 for (int ii = 0; ii < expectedSize; ++ii)
3616 m_vertexAttribState[index].value[ii] = v[ii];
3619 void WebGLRenderingContext::initVertexAttrib0()
3621 m_vertexAttribState.resize(1);
3622 m_vertexAttrib0Buffer = createBuffer();
3623 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer.get());
3624 m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW);
3625 m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
3626 m_vertexAttribState[0].bufferBinding = m_vertexAttrib0Buffer;
3627 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
3628 m_context->enableVertexAttribArray(0);
3629 m_vertexAttrib0BufferSize = 0;
3630 m_vertexAttrib0BufferValue[0] = 0.0f;
3631 m_vertexAttrib0BufferValue[1] = 0.0f;
3632 m_vertexAttrib0BufferValue[2] = 0.0f;
3633 m_vertexAttrib0BufferValue[3] = 1.0f;
3636 bool WebGLRenderingContext::simulateVertexAttrib0(long numVertex)
3638 const VertexAttribState& state = m_vertexAttribState[0];
3639 if (state.enabled || !m_currentProgram || !m_currentProgram->object()
3640 || !m_currentProgram->isUsingVertexAttrib0())
3642 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer.get());
3643 long bufferDataSize = (numVertex + 1) * 4 * sizeof(float);
3644 if (bufferDataSize > m_vertexAttrib0BufferSize
3645 || state.value[0] != m_vertexAttrib0BufferValue[0]
3646 || state.value[1] != m_vertexAttrib0BufferValue[1]
3647 || state.value[2] != m_vertexAttrib0BufferValue[2]
3648 || state.value[3] != m_vertexAttrib0BufferValue[3]) {
3649 RefPtr<Float32Array> bufferData = Float32Array::create((numVertex + 1) * 4);
3650 for (long ii = 0; ii < numVertex + 1; ++ii) {
3651 bufferData->set(ii * 4, state.value[0]);
3652 bufferData->set(ii * 4 + 1, state.value[1]);
3653 bufferData->set(ii * 4 + 2, state.value[2]);
3654 bufferData->set(ii * 4 + 3, state.value[3]);
3656 m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW);
3657 m_vertexAttrib0BufferSize = bufferDataSize;
3658 m_vertexAttrib0BufferValue[0] = state.value[0];
3659 m_vertexAttrib0BufferValue[1] = state.value[1];
3660 m_vertexAttrib0BufferValue[2] = state.value[2];
3661 m_vertexAttrib0BufferValue[3] = state.value[3];
3663 m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
3667 void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
3669 const VertexAttribState& state = m_vertexAttribState[0];
3670 if (state.bufferBinding != m_vertexAttrib0Buffer) {
3671 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, state.bufferBinding.get());
3672 m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset);
3674 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_boundArrayBuffer.get());
3677 } // namespace WebCore
3679 #endif // ENABLE(3D_CANVAS)