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::VALIDATE_STATUS:
1414 m_context->getProgramiv(program, pname, &value);
1415 return WebGLGetInfo(static_cast<bool>(value));
1416 case GraphicsContext3D::LINK_STATUS:
1417 if (program->isLinkFailureFlagSet())
1418 return WebGLGetInfo(false);
1419 m_context->getProgramiv(program, pname, &value);
1420 return WebGLGetInfo(static_cast<bool>(value));
1421 case GraphicsContext3D::INFO_LOG_LENGTH:
1422 case GraphicsContext3D::ATTACHED_SHADERS:
1423 case GraphicsContext3D::ACTIVE_ATTRIBUTES:
1424 case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH:
1425 case GraphicsContext3D::ACTIVE_UNIFORMS:
1426 case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH:
1427 m_context->getProgramiv(program, pname, &value);
1428 return WebGLGetInfo(static_cast<long>(value));
1430 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1431 return WebGLGetInfo();
1435 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
1438 if (!validateWebGLObject(program))
1440 WebGLStateRestorer(this, false);
1441 return m_context->getProgramInfoLog(program);
1444 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1447 if (target != GraphicsContext3D::RENDERBUFFER) {
1448 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1449 return WebGLGetInfo();
1452 WebGLStateRestorer(this, false);
1455 case GraphicsContext3D::RENDERBUFFER_WIDTH:
1456 case GraphicsContext3D::RENDERBUFFER_HEIGHT:
1457 case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
1458 case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
1459 case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
1460 case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
1461 case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
1462 case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
1463 m_context->getRenderbufferParameteriv(target, pname, &value);
1464 return WebGLGetInfo(static_cast<long>(value));
1465 case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
1466 if (!m_renderbufferBinding) {
1467 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1468 return WebGLGetInfo();
1470 return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
1472 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1473 return WebGLGetInfo();
1477 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
1480 if (!validateWebGLObject(shader))
1481 return WebGLGetInfo();
1482 WebGLStateRestorer(this, false);
1485 case GraphicsContext3D::DELETE_STATUS:
1486 case GraphicsContext3D::COMPILE_STATUS:
1487 m_context->getShaderiv(shader, pname, &value);
1488 return WebGLGetInfo(static_cast<bool>(value));
1489 case GraphicsContext3D::SHADER_TYPE:
1490 m_context->getShaderiv(shader, pname, &value);
1491 return WebGLGetInfo(static_cast<unsigned long>(value));
1492 case GraphicsContext3D::INFO_LOG_LENGTH:
1493 case GraphicsContext3D::SHADER_SOURCE_LENGTH:
1494 m_context->getShaderiv(shader, pname, &value);
1495 return WebGLGetInfo(static_cast<long>(value));
1497 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1498 return WebGLGetInfo();
1502 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
1505 if (!validateWebGLObject(shader))
1507 WebGLStateRestorer(this, false);
1508 return m_context->getShaderInfoLog(shader);
1511 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
1514 if (!validateWebGLObject(shader))
1516 WebGLStateRestorer(this, false);
1517 return m_context->getShaderSource(shader);
1520 String WebGLRenderingContext::getString(unsigned long name)
1522 WebGLStateRestorer(this, false);
1523 return m_context->getString(name);
1526 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
1529 if (target != GraphicsContext3D::TEXTURE_2D
1530 && target != GraphicsContext3D::TEXTURE_CUBE_MAP) {
1531 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1532 return WebGLGetInfo();
1534 WebGLStateRestorer(this, false);
1537 case GraphicsContext3D::TEXTURE_MAG_FILTER:
1538 case GraphicsContext3D::TEXTURE_MIN_FILTER:
1539 case GraphicsContext3D::TEXTURE_WRAP_S:
1540 case GraphicsContext3D::TEXTURE_WRAP_T:
1541 m_context->getTexParameteriv(target, pname, &value);
1542 return WebGLGetInfo(static_cast<unsigned long>(value));
1544 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1545 return WebGLGetInfo();
1549 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
1552 if (!validateWebGLObject(program))
1553 return WebGLGetInfo();
1554 if (uniformLocation->program() != program) {
1555 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1556 return WebGLGetInfo();
1558 long location = uniformLocation->location();
1560 WebGLStateRestorer(this, false);
1561 // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
1562 int activeUniforms = 0;
1563 m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
1564 for (int i = 0; i < activeUniforms; i++) {
1566 if (!m_context->getActiveUniform(program, i, info))
1567 return WebGLGetInfo();
1568 // Strip "[0]" from the name if it's an array.
1570 info.name = info.name.left(info.name.length() - 3);
1571 // If it's an array, we need to iterate through each element, appending "[index]" to the name.
1572 for (int index = 0; index < info.size; ++index) {
1573 String name = info.name;
1574 if (info.size > 1 && index >= 1) {
1576 name.append(String::number(index));
1579 // Now need to look this up by name again to find its location
1580 long loc = m_context->getUniformLocation(program, name);
1581 if (loc == location) {
1582 // Found it. Use the type in the ActiveInfo to determine the return type.
1583 GraphicsContext3D::WebGLEnumType baseType;
1585 switch (info.type) {
1586 case GraphicsContext3D::BOOL:
1587 baseType = GraphicsContext3D::BOOL;
1590 case GraphicsContext3D::BOOL_VEC2:
1591 baseType = GraphicsContext3D::BOOL;
1594 case GraphicsContext3D::BOOL_VEC3:
1595 baseType = GraphicsContext3D::BOOL;
1598 case GraphicsContext3D::BOOL_VEC4:
1599 baseType = GraphicsContext3D::BOOL;
1602 case GraphicsContext3D::INT:
1603 baseType = GraphicsContext3D::INT;
1606 case GraphicsContext3D::INT_VEC2:
1607 baseType = GraphicsContext3D::INT;
1610 case GraphicsContext3D::INT_VEC3:
1611 baseType = GraphicsContext3D::INT;
1614 case GraphicsContext3D::INT_VEC4:
1615 baseType = GraphicsContext3D::INT;
1618 case GraphicsContext3D::FLOAT:
1619 baseType = GraphicsContext3D::FLOAT;
1622 case GraphicsContext3D::FLOAT_VEC2:
1623 baseType = GraphicsContext3D::FLOAT;
1626 case GraphicsContext3D::FLOAT_VEC3:
1627 baseType = GraphicsContext3D::FLOAT;
1630 case GraphicsContext3D::FLOAT_VEC4:
1631 baseType = GraphicsContext3D::FLOAT;
1634 case GraphicsContext3D::FLOAT_MAT2:
1635 baseType = GraphicsContext3D::FLOAT;
1638 case GraphicsContext3D::FLOAT_MAT3:
1639 baseType = GraphicsContext3D::FLOAT;
1642 case GraphicsContext3D::FLOAT_MAT4:
1643 baseType = GraphicsContext3D::FLOAT;
1647 // Can't handle this type
1648 // FIXME: what to do about samplers?
1649 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1650 return WebGLGetInfo();
1653 case GraphicsContext3D::FLOAT: {
1654 float value[16] = {0};
1655 m_context->getUniformfv(program, location, value);
1657 return WebGLGetInfo(value[0]);
1658 return WebGLGetInfo(Float32Array::create(value, length));
1660 case GraphicsContext3D::INT: {
1661 int value[16] = {0};
1662 m_context->getUniformiv(program, location, value);
1664 return WebGLGetInfo(static_cast<long>(value[0]));
1665 return WebGLGetInfo(Int32Array::create(value, length));
1667 case GraphicsContext3D::BOOL: {
1668 int value[16] = {0};
1669 m_context->getUniformiv(program, location, value);
1671 unsigned char boolValue[16] = {0};
1672 for (unsigned j = 0; j < length; j++)
1673 boolValue[j] = static_cast<bool>(value[j]);
1674 return WebGLGetInfo(Uint8Array::create(boolValue, length));
1676 return WebGLGetInfo(static_cast<bool>(value[0]));
1684 // If we get here, something went wrong in our unfortunately complex logic above
1685 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1686 return WebGLGetInfo();
1689 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
1692 if (!validateWebGLObject(program))
1694 WebGLStateRestorer(this, false);
1695 long uniformLocation = m_context->getUniformLocation(program, name);
1696 if (uniformLocation == -1)
1698 return WebGLUniformLocation::create(program, uniformLocation);
1701 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
1704 WebGLStateRestorer(this, false);
1705 if (index >= m_maxVertexAttribs) {
1706 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1707 return WebGLGetInfo();
1710 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
1711 if (!isGLES2Compliant() && !index && m_vertexAttribState[0].bufferBinding == m_vertexAttrib0Buffer
1712 || index >= m_vertexAttribState.size()
1713 || !m_vertexAttribState[index].bufferBinding
1714 || !m_vertexAttribState[index].bufferBinding->object())
1715 return WebGLGetInfo();
1716 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_vertexAttribState[index].bufferBinding));
1717 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
1718 if (index >= m_vertexAttribState.size())
1719 return WebGLGetInfo(false);
1720 return WebGLGetInfo(m_vertexAttribState[index].enabled);
1721 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
1722 if (index >= m_vertexAttribState.size())
1723 return WebGLGetInfo(false);
1724 return WebGLGetInfo(m_vertexAttribState[index].normalized);
1725 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
1726 if (index >= m_vertexAttribState.size())
1727 return WebGLGetInfo(static_cast<long>(4));
1728 return WebGLGetInfo(m_vertexAttribState[index].size);
1729 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
1730 if (index >= m_vertexAttribState.size())
1731 return WebGLGetInfo(static_cast<long>(0));
1732 return WebGLGetInfo(m_vertexAttribState[index].originalStride);
1733 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
1734 if (index >= m_vertexAttribState.size())
1735 return WebGLGetInfo(static_cast<unsigned long>(GraphicsContext3D::FLOAT));
1736 return WebGLGetInfo(m_vertexAttribState[index].type);
1737 case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
1738 if (index >= m_vertexAttribState.size()) {
1739 float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
1740 return WebGLGetInfo(Float32Array::create(value, 4));
1742 return WebGLGetInfo(Float32Array::create(m_vertexAttribState[index].value, 4));
1744 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1745 return WebGLGetInfo();
1749 long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname)
1751 long result = m_context->getVertexAttribOffset(index, pname);
1752 cleanupAfterGraphicsCall(false);
1756 void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
1758 if (!isGLES2Compliant()) {
1759 if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
1760 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1764 m_context->hint(target, mode);
1765 cleanupAfterGraphicsCall(false);
1768 bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
1773 return m_context->isBuffer(buffer);
1776 bool WebGLRenderingContext::isEnabled(unsigned long cap)
1778 if (!isGLES2Compliant()) {
1779 if (!validateCapability(cap))
1782 return m_context->isEnabled(cap);
1785 bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
1790 return m_context->isFramebuffer(framebuffer);
1793 bool WebGLRenderingContext::isProgram(WebGLProgram* program)
1798 return m_context->isProgram(program);
1801 bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
1806 return m_context->isRenderbuffer(renderbuffer);
1809 bool WebGLRenderingContext::isShader(WebGLShader* shader)
1814 return m_context->isShader(shader);
1817 bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
1822 return m_context->isTexture(texture);
1825 void WebGLRenderingContext::lineWidth(double width)
1827 m_context->lineWidth((float) width);
1828 cleanupAfterGraphicsCall(false);
1831 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
1834 if (!validateWebGLObject(program))
1836 if (!isGLES2Compliant()) {
1837 Vector<WebGLShader*> shaders;
1838 bool succeed = getAttachedShaders(program, shaders, ec);
1840 bool vShader = false;
1841 bool fShader = false;
1842 for (size_t ii = 0; ii < shaders.size() && (!vShader || !fShader); ++ii) {
1843 if (shaders[ii]->getType() == GraphicsContext3D::VERTEX_SHADER)
1845 else if (shaders[ii]->getType() == GraphicsContext3D::FRAGMENT_SHADER)
1848 if (!vShader || !fShader)
1852 program->setLinkFailureFlag(true);
1855 program->setLinkFailureFlag(false);
1858 m_context->linkProgram(program);
1859 program->cacheActiveAttribLocations();
1860 cleanupAfterGraphicsCall(false);
1863 void WebGLRenderingContext::pixelStorei(unsigned long pname, long param)
1866 case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1867 m_unpackFlipY = param;
1869 case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1870 m_unpackPremultiplyAlpha = param;
1872 case GraphicsContext3D::PACK_ALIGNMENT:
1873 case GraphicsContext3D::UNPACK_ALIGNMENT:
1874 m_context->pixelStorei(pname, param);
1875 if (param == 1 || param == 2 || param == 4 || param == 8) {
1876 if (pname == GraphicsContext3D::PACK_ALIGNMENT)
1877 m_packAlignment = static_cast<int>(param);
1878 else // GraphicsContext3D::UNPACK_ALIGNMENT:
1879 m_unpackAlignment = static_cast<int>(param);
1883 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1886 cleanupAfterGraphicsCall(false);
1889 void WebGLRenderingContext::polygonOffset(double factor, double units)
1891 m_context->polygonOffset((float) factor, (float) units);
1892 cleanupAfterGraphicsCall(false);
1895 void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels)
1897 // Validate input parameters.
1898 unsigned long componentsPerPixel, bytesPerComponent;
1899 if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
1900 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1904 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1907 if (width < 0 || height < 0) {
1908 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
1911 if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) {
1912 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1915 // Validate array type against pixel type.
1916 if (type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray()
1917 || type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray()) {
1918 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1921 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
1922 unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
1923 unsigned long padding = 0;
1924 unsigned long residualBytes = bytesPerRow % m_packAlignment;
1925 if (residualBytes) {
1926 padding = m_packAlignment - residualBytes;
1927 bytesPerRow += padding;
1929 // The last row needs no padding.
1930 unsigned long totalBytes = bytesPerRow * height - padding;
1931 unsigned long num = totalBytes / bytesPerComponent;
1932 if (pixels->length() < num) {
1933 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1936 void* data = pixels->baseAddress();
1937 m_context->readPixels(x, y, width, height, format, type, data);
1939 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
1940 // when alpha is off, readPixels should set alpha to 255 instead of 0.
1941 if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) {
1942 if (type == GraphicsContext3D::UNSIGNED_BYTE) {
1943 unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
1944 for (long iy = 0; iy < height; ++iy) {
1945 for (long ix = 0; ix < width; ++ix) {
1946 pixels[componentsPerPixel - 1] = 255;
1947 pixels += componentsPerPixel;
1952 // FIXME: check whether we need to do the same with UNSIGNED_SHORT.
1955 cleanupAfterGraphicsCall(false);
1958 void WebGLRenderingContext::releaseShaderCompiler()
1960 m_context->releaseShaderCompiler();
1961 cleanupAfterGraphicsCall(false);
1964 void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
1966 switch (internalformat) {
1967 case GraphicsContext3D::DEPTH_COMPONENT16:
1968 case GraphicsContext3D::RGBA4:
1969 case GraphicsContext3D::RGB5_A1:
1970 case GraphicsContext3D::RGB565:
1971 case GraphicsContext3D::STENCIL_INDEX8:
1972 case GraphicsContext3D::DEPTH_STENCIL:
1973 m_context->renderbufferStorage(target, internalformat, width, height);
1974 if (m_renderbufferBinding) {
1975 m_renderbufferBinding->setInternalFormat(internalformat);
1976 if (m_framebufferBinding)
1977 m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get());
1979 cleanupAfterGraphicsCall(false);
1982 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
1986 void WebGLRenderingContext::sampleCoverage(double value, bool invert)
1988 m_context->sampleCoverage((float) value, invert);
1989 cleanupAfterGraphicsCall(false);
1992 void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height)
1994 m_context->scissor(x, y, width, height);
1995 cleanupAfterGraphicsCall(false);
1998 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
2001 if (!validateWebGLObject(shader))
2003 m_context->shaderSource(shader, string);
2004 cleanupAfterGraphicsCall(false);
2007 void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask)
2009 m_context->stencilFunc(func, ref, mask);
2010 cleanupAfterGraphicsCall(false);
2013 void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
2015 m_context->stencilFuncSeparate(face, func, ref, mask);
2016 cleanupAfterGraphicsCall(false);
2019 void WebGLRenderingContext::stencilMask(unsigned long mask)
2021 m_context->stencilMask(mask);
2022 cleanupAfterGraphicsCall(false);
2025 void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask)
2027 m_context->stencilMaskSeparate(face, mask);
2028 cleanupAfterGraphicsCall(false);
2031 void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
2033 m_context->stencilOp(fail, zfail, zpass);
2034 cleanupAfterGraphicsCall(false);
2037 void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
2039 m_context->stencilOpSeparate(face, fail, zfail, zpass);
2040 cleanupAfterGraphicsCall(false);
2043 void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsigned internalformat,
2044 unsigned width, unsigned height, unsigned border,
2045 unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
2047 // FIXME: For now we ignore any errors returned
2049 if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
2051 if (!isGLES2Compliant()) {
2052 if (level && WebGLTexture::isNPOT(width, height)) {
2053 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2057 m_context->texImage2D(target, level, internalformat, width, height,
2058 border, format, type, pixels);
2059 WebGLTexture* tex = getTextureBinding(target);
2060 if (!isGLES2Compliant()) {
2061 if (tex && !level) // only for level 0
2062 tex->setSize(target, width, height);
2064 tex->setInternalFormat(internalformat);
2066 if (m_framebufferBinding && tex)
2067 m_framebufferBinding->onAttachedObjectChange(tex);
2068 cleanupAfterGraphicsCall(false);
2071 void WebGLRenderingContext::texImage2DImpl(unsigned target, unsigned level, unsigned internalformat,
2072 unsigned format, unsigned type, Image* image,
2073 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2076 Vector<uint8_t> data;
2077 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
2078 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2081 if (m_unpackAlignment != 1)
2082 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2083 texImage2DBase(target, level, internalformat, image->width(), image->height(), 0,
2084 format, type, data.data(), ec);
2085 if (m_unpackAlignment != 1)
2086 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2089 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2090 unsigned width, unsigned height, unsigned border,
2091 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
2093 if (!validateTexFuncData(width, height, format, type, pixels))
2095 void* data = pixels ? pixels->baseAddress() : 0;
2096 Vector<uint8_t> tempData;
2097 bool changeUnpackAlignment = false;
2098 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
2099 if (!m_context->extractTextureData(width, height, format, type,
2101 m_unpackFlipY, m_unpackPremultiplyAlpha,
2105 data = tempData.data();
2106 changeUnpackAlignment = true;
2108 if (changeUnpackAlignment)
2109 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2110 texImage2DBase(target, level, internalformat, width, height, border,
2111 format, type, data, ec);
2112 if (changeUnpackAlignment)
2113 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2116 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2117 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
2120 Vector<uint8_t> data;
2121 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
2122 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2125 if (m_unpackAlignment != 1)
2126 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2127 texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0,
2128 format, type, data.data(), ec);
2129 if (m_unpackAlignment != 1)
2130 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2133 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2134 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
2137 if (!image || !image->cachedImage()) {
2138 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2141 texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
2142 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2145 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2146 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
2149 if (!canvas || !canvas->buffer()) {
2150 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2153 texImage2DImpl(target, level, internalformat, format, type, canvas->buffer()->image(),
2154 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2157 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
2158 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
2160 // FIXME: Need to implement this call
2161 UNUSED_PARAM(target);
2162 UNUSED_PARAM(level);
2163 UNUSED_PARAM(internalformat);
2164 UNUSED_PARAM(format);
2166 UNUSED_PARAM(video);
2169 cleanupAfterGraphicsCall(false);
2172 // Obsolete texImage2D entry points -- to be removed shortly. (FIXME)
2174 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2177 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels)");
2178 texImage2D(target, level, pixels, 0, 0, ec);
2181 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2182 bool flipY, ExceptionCode& ec)
2184 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY)");
2185 texImage2D(target, level, pixels, flipY, 0, ec);
2188 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
2189 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2191 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
2193 Vector<uint8_t> data;
2194 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
2195 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2198 texImage2DBase(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0,
2199 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
2203 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2206 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image)");
2207 texImage2D(target, level, image, 0, 0, ec);
2210 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2211 bool flipY, ExceptionCode& ec)
2213 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY)");
2214 texImage2D(target, level, image, flipY, 0, ec);
2217 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
2218 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2220 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
2222 if (!image || !image->cachedImage()) {
2223 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2226 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(), flipY, premultiplyAlpha, ec);
2229 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2232 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas)");
2233 texImage2D(target, level, canvas, 0, 0, ec);
2236 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2237 bool flipY, ExceptionCode& ec)
2239 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY)");
2240 texImage2D(target, level, canvas, flipY, 0, ec);
2243 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
2244 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2246 printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
2248 if (!canvas || !canvas->buffer()) {
2249 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2252 texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(), flipY, premultiplyAlpha, ec);
2255 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2258 texImage2D(target, level, video, 0, 0, ec);
2261 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2262 bool flipY, ExceptionCode& ec)
2264 texImage2D(target, level, video, flipY, 0, ec);
2267 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
2268 bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2270 // FIXME: Need implement this call
2271 UNUSED_PARAM(target);
2272 UNUSED_PARAM(level);
2273 UNUSED_PARAM(video);
2274 UNUSED_PARAM(flipY);
2275 UNUSED_PARAM(premultiplyAlpha);
2278 cleanupAfterGraphicsCall(false);
2281 void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
2283 if (!isGLES2Compliant()) {
2284 RefPtr<WebGLTexture> tex = 0;
2286 case GraphicsContext3D::TEXTURE_2D:
2287 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
2289 case GraphicsContext3D::TEXTURE_CUBE_MAP:
2290 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
2293 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2297 case GraphicsContext3D::TEXTURE_MIN_FILTER:
2298 case GraphicsContext3D::TEXTURE_MAG_FILTER:
2300 case GraphicsContext3D::TEXTURE_WRAP_S:
2301 case GraphicsContext3D::TEXTURE_WRAP_T:
2302 if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT
2303 || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) {
2304 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2309 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
2314 tex->setParameterf(pname, paramf);
2316 tex->setParameteri(pname, parami);
2320 m_context->texParameterf(target, pname, paramf);
2322 m_context->texParameteri(target, pname, parami);
2323 cleanupAfterGraphicsCall(false);
2326 void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param)
2328 texParameter(target, pname, param, 0, true);
2331 void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param)
2333 texParameter(target, pname, 0, param, false);
2336 void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2337 unsigned width, unsigned height,
2338 unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
2340 // FIXME: For now we ignore any errors returned
2342 if (!validateTexFuncFormatAndType(format, type))
2345 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
2346 cleanupAfterGraphicsCall(false);
2349 void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2350 unsigned format, unsigned type,
2351 Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2354 Vector<uint8_t> data;
2355 if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
2356 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2359 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
2360 format, type, data.data(), ec);
2363 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2364 unsigned width, unsigned height,
2365 unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
2367 if (!validateTexFuncData(width, height, format, type, pixels))
2369 void* data = pixels ? pixels->baseAddress() : 0;
2370 Vector<uint8_t> tempData;
2371 bool changeUnpackAlignment = false;
2372 if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
2373 if (!m_context->extractTextureData(width, height, format, type,
2375 m_unpackFlipY, m_unpackPremultiplyAlpha,
2379 data = tempData.data();
2380 changeUnpackAlignment = true;
2382 if (changeUnpackAlignment)
2383 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
2384 texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
2385 if (changeUnpackAlignment)
2386 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
2389 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2390 unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
2393 Vector<uint8_t> data;
2394 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
2395 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2398 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
2399 format, type, data.data(), ec);
2402 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2403 unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
2406 if (!image || !image->cachedImage()) {
2407 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2410 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
2411 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2414 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2415 unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
2418 if (!canvas || !canvas->buffer()) {
2419 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2422 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->buffer()->image(),
2423 m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
2426 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2427 unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
2429 // FIXME: Need to implement this call
2430 UNUSED_PARAM(target);
2431 UNUSED_PARAM(level);
2432 UNUSED_PARAM(xoffset);
2433 UNUSED_PARAM(yoffset);
2434 UNUSED_PARAM(format);
2436 UNUSED_PARAM(video);
2438 cleanupAfterGraphicsCall(false);
2441 // Obsolete texSubImage2D entry points -- to be removed shortly. (FIXME)
2443 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2444 ImageData* pixels, ExceptionCode& ec)
2446 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels)");
2447 texSubImage2D(target, level, xoffset, yoffset, pixels, 0, 0, ec);
2450 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2451 ImageData* pixels, bool flipY, ExceptionCode& ec)
2453 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY)");
2454 texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, 0, ec);
2457 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2458 ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2460 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
2462 Vector<uint8_t> data;
2463 if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
2464 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2467 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
2468 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
2471 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2472 HTMLImageElement* image, ExceptionCode& ec)
2474 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image)");
2475 texSubImage2D(target, level, xoffset, yoffset, image, 0, 0, ec);
2478 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2479 HTMLImageElement* image, bool flipY, ExceptionCode& ec)
2481 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY)");
2482 texSubImage2D(target, level, xoffset, yoffset, image, flipY, 0, ec);
2485 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2486 HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2488 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
2490 if (!image || !image->cachedImage()) {
2491 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2494 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(),
2495 flipY, premultiplyAlpha, ec);
2498 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2499 HTMLCanvasElement* canvas, ExceptionCode& ec)
2501 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas)");
2502 texSubImage2D(target, level, xoffset, yoffset, canvas, 0, 0, ec);
2505 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2506 HTMLCanvasElement* canvas, bool flipY, ExceptionCode& ec)
2508 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY)");
2509 texSubImage2D(target, level, xoffset, yoffset, canvas, flipY, 0, ec);
2512 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2513 HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2515 printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
2517 if (!canvas || !canvas->buffer()) {
2518 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
2521 texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(),
2522 flipY, premultiplyAlpha, ec);
2525 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2526 HTMLVideoElement* video, ExceptionCode& ec)
2528 texSubImage2D(target, level, xoffset, yoffset, video, 0, 0, ec);
2531 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2532 HTMLVideoElement* video, bool flipY, ExceptionCode& ec)
2534 texSubImage2D(target, level, xoffset, yoffset, video, flipY, 0, ec);
2537 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
2538 HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
2540 // FIXME: Need to implement this call
2541 UNUSED_PARAM(target);
2542 UNUSED_PARAM(level);
2543 UNUSED_PARAM(xoffset);
2544 UNUSED_PARAM(yoffset);
2545 UNUSED_PARAM(video);
2546 UNUSED_PARAM(flipY);
2547 UNUSED_PARAM(premultiplyAlpha);
2549 cleanupAfterGraphicsCall(false);
2552 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
2558 if (location->program() != m_currentProgram) {
2559 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2563 m_context->uniform1f(location->location(), x);
2564 cleanupAfterGraphicsCall(false);
2567 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2570 if (!validateUniformParameters(location, v, 1))
2573 m_context->uniform1fv(location->location(), v->data(), v->length());
2574 cleanupAfterGraphicsCall(false);
2577 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2580 if (!validateUniformParameters(location, v, size, 1))
2583 m_context->uniform1fv(location->location(), v, size);
2584 cleanupAfterGraphicsCall(false);
2587 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
2593 if (location->program() != m_currentProgram) {
2594 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2598 m_context->uniform1i(location->location(), x);
2599 cleanupAfterGraphicsCall(false);
2602 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2605 if (!validateUniformParameters(location, v, 1))
2608 m_context->uniform1iv(location->location(), v->data(), v->length());
2609 cleanupAfterGraphicsCall(false);
2612 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2615 if (!validateUniformParameters(location, v, size, 1))
2618 m_context->uniform1iv(location->location(), v, size);
2619 cleanupAfterGraphicsCall(false);
2622 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
2628 if (location->program() != m_currentProgram) {
2629 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2633 m_context->uniform2f(location->location(), x, y);
2634 cleanupAfterGraphicsCall(false);
2637 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2640 if (!validateUniformParameters(location, v, 2))
2643 m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
2644 cleanupAfterGraphicsCall(false);
2647 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2650 if (!validateUniformParameters(location, v, size, 2))
2653 m_context->uniform2fv(location->location(), v, size / 2);
2654 cleanupAfterGraphicsCall(false);
2657 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
2663 if (location->program() != m_currentProgram) {
2664 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2668 m_context->uniform2i(location->location(), x, y);
2669 cleanupAfterGraphicsCall(false);
2672 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2675 if (!validateUniformParameters(location, v, 2))
2678 m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
2679 cleanupAfterGraphicsCall(false);
2682 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2685 if (!validateUniformParameters(location, v, size, 2))
2688 m_context->uniform2iv(location->location(), v, size / 2);
2689 cleanupAfterGraphicsCall(false);
2692 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
2698 if (location->program() != m_currentProgram) {
2699 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2703 m_context->uniform3f(location->location(), x, y, z);
2704 cleanupAfterGraphicsCall(false);
2707 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2710 if (!validateUniformParameters(location, v, 3))
2713 m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
2714 cleanupAfterGraphicsCall(false);
2717 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2720 if (!validateUniformParameters(location, v, size, 3))
2723 m_context->uniform3fv(location->location(), v, size / 3);
2724 cleanupAfterGraphicsCall(false);
2727 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
2733 if (location->program() != m_currentProgram) {
2734 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2738 m_context->uniform3i(location->location(), x, y, z);
2739 cleanupAfterGraphicsCall(false);
2742 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2745 if (!validateUniformParameters(location, v, 3))
2748 m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
2749 cleanupAfterGraphicsCall(false);
2752 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2755 if (!validateUniformParameters(location, v, size, 3))
2758 m_context->uniform3iv(location->location(), v, size / 3);
2759 cleanupAfterGraphicsCall(false);
2762 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
2768 if (location->program() != m_currentProgram) {
2769 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2773 m_context->uniform4f(location->location(), x, y, z, w);
2774 cleanupAfterGraphicsCall(false);
2777 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
2780 if (!validateUniformParameters(location, v, 4))
2783 m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
2784 cleanupAfterGraphicsCall(false);
2787 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
2790 if (!validateUniformParameters(location, v, size, 4))
2793 m_context->uniform4fv(location->location(), v, size / 4);
2794 cleanupAfterGraphicsCall(false);
2797 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
2803 if (location->program() != m_currentProgram) {
2804 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2808 m_context->uniform4i(location->location(), x, y, z, w);
2809 cleanupAfterGraphicsCall(false);
2812 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
2815 if (!validateUniformParameters(location, v, 4))
2818 m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
2819 cleanupAfterGraphicsCall(false);
2822 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
2825 if (!validateUniformParameters(location, v, size, 4))
2828 m_context->uniform4iv(location->location(), v, size / 4);
2829 cleanupAfterGraphicsCall(false);
2832 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2835 if (!validateUniformMatrixParameters(location, transpose, v, 4))
2837 m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
2838 cleanupAfterGraphicsCall(false);
2841 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2844 if (!validateUniformMatrixParameters(location, transpose, v, size, 4))
2846 m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
2847 cleanupAfterGraphicsCall(false);
2850 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2853 if (!validateUniformMatrixParameters(location, transpose, v, 9))
2855 m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
2856 cleanupAfterGraphicsCall(false);
2859 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2862 if (!validateUniformMatrixParameters(location, transpose, v, size, 9))
2864 m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
2865 cleanupAfterGraphicsCall(false);
2868 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
2871 if (!validateUniformMatrixParameters(location, transpose, v, 16))
2873 m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
2874 cleanupAfterGraphicsCall(false);
2877 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
2880 if (!validateUniformMatrixParameters(location, transpose, v, size, 16))
2882 m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
2883 cleanupAfterGraphicsCall(false);
2886 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
2889 if (program && program->context() != this) {
2890 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
2893 m_currentProgram = program;
2894 m_context->useProgram(program);
2895 cleanupAfterGraphicsCall(false);
2898 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
2901 if (!validateWebGLObject(program))
2903 m_context->validateProgram(program);
2904 cleanupAfterGraphicsCall(false);
2907 void WebGLRenderingContext::vertexAttrib1f(unsigned long index, float v0)
2909 // In GL, we skip setting vertexAttrib0 values.
2910 if (index || isGLES2Compliant()) {
2911 m_context->vertexAttrib1f(index, v0);
2912 cleanupAfterGraphicsCall(false);
2914 m_vertexAttribState[index].value[0] = v0;
2915 m_vertexAttribState[index].value[1] = 0.0f;
2916 m_vertexAttribState[index].value[2] = 0.0f;
2917 m_vertexAttribState[index].value[3] = 1.0f;
2920 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, Float32Array* v)
2922 vertexAttribImpl(index, v, 1);
2925 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, float* v, int size)
2927 vertexAttribImpl(index, v, size, 1);
2930 void WebGLRenderingContext::vertexAttrib2f(unsigned long index, float v0, float v1)
2932 // In GL, we skip setting vertexAttrib0 values.
2933 if (index || isGLES2Compliant()) {
2934 m_context->vertexAttrib2f(index, v0, v1);
2935 cleanupAfterGraphicsCall(false);
2937 m_vertexAttribState[index].value[0] = v0;
2938 m_vertexAttribState[index].value[1] = v1;
2939 m_vertexAttribState[index].value[2] = 0.0f;
2940 m_vertexAttribState[index].value[3] = 1.0f;
2943 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, Float32Array* v)
2945 vertexAttribImpl(index, v, 2);
2948 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, float* v, int size)
2950 vertexAttribImpl(index, v, size, 2);
2953 void WebGLRenderingContext::vertexAttrib3f(unsigned long index, float v0, float v1, float v2)
2955 // In GL, we skip setting vertexAttrib0 values.
2956 if (index || isGLES2Compliant()) {
2957 m_context->vertexAttrib3f(index, v0, v1, v2);
2958 cleanupAfterGraphicsCall(false);
2960 m_vertexAttribState[index].value[0] = v0;
2961 m_vertexAttribState[index].value[1] = v1;
2962 m_vertexAttribState[index].value[2] = v2;
2963 m_vertexAttribState[index].value[3] = 1.0f;
2966 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, Float32Array* v)
2968 vertexAttribImpl(index, v, 3);
2971 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, float* v, int size)
2973 vertexAttribImpl(index, v, size, 3);
2976 void WebGLRenderingContext::vertexAttrib4f(unsigned long index, float v0, float v1, float v2, float v3)
2978 // In GL, we skip setting vertexAttrib0 values.
2979 if (index || isGLES2Compliant()) {
2980 m_context->vertexAttrib4f(index, v0, v1, v2, v3);
2981 cleanupAfterGraphicsCall(false);
2983 m_vertexAttribState[index].value[0] = v0;
2984 m_vertexAttribState[index].value[1] = v1;
2985 m_vertexAttribState[index].value[2] = v2;
2986 m_vertexAttribState[index].value[3] = v3;
2989 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, Float32Array* v)
2991 vertexAttribImpl(index, v, 4);
2994 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int size)
2996 vertexAttribImpl(index, v, size, 4);
2999 void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, long offset, ExceptionCode& ec)
3001 if (index >= m_maxVertexAttribs) {
3002 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3005 if (size < 1 || size > 4 || stride < 0 || offset < 0) {
3006 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3009 if (!m_boundArrayBuffer) {
3010 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3013 // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
3014 long bytesPerElement = size * sizeInBytes(type, ec);
3015 if (bytesPerElement <= 0)
3018 if (index >= m_vertexAttribState.size())
3019 m_vertexAttribState.resize(index + 1);
3021 long validatedStride = bytesPerElement;
3023 if ((long) stride < bytesPerElement) {
3024 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3027 validatedStride = stride;
3029 m_vertexAttribState[index].bufferBinding = m_boundArrayBuffer;
3030 m_vertexAttribState[index].bytesPerElement = bytesPerElement;
3031 m_vertexAttribState[index].size = size;
3032 m_vertexAttribState[index].type = type;
3033 m_vertexAttribState[index].normalized = normalized;
3034 m_vertexAttribState[index].stride = validatedStride;
3035 m_vertexAttribState[index].originalStride = stride;
3036 m_vertexAttribState[index].offset = offset;
3037 m_context->vertexAttribPointer(index, size, type, normalized, stride, offset);
3038 cleanupAfterGraphicsCall(false);
3041 void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height)
3051 m_context->viewport(x, y, width, height);
3052 cleanupAfterGraphicsCall(false);
3055 void WebGLRenderingContext::removeObject(CanvasObject* object)
3057 m_canvasObjects.remove(object);
3060 void WebGLRenderingContext::addObject(CanvasObject* object)
3062 removeObject(object);
3063 m_canvasObjects.add(object);
3066 void WebGLRenderingContext::detachAndRemoveAllObjects()
3068 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3069 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it)
3070 (*it)->detachContext();
3072 m_canvasObjects.clear();
3075 WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj)
3079 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3080 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3081 if ((*it)->isTexture() && (*it)->object() == obj)
3082 return reinterpret_cast<WebGLTexture*>((*it).get());
3087 WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj)
3091 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3092 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3093 if ((*it)->isRenderbuffer() && (*it)->object() == obj)
3094 return reinterpret_cast<WebGLRenderbuffer*>((*it).get());
3099 WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj)
3103 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3104 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3105 if ((*it)->isBuffer() && (*it)->object() == obj)
3106 return reinterpret_cast<WebGLBuffer*>((*it).get());
3111 WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj)
3115 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
3116 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
3117 if ((*it)->isShader() && (*it)->object() == obj)
3118 return reinterpret_cast<WebGLShader*>((*it).get());
3123 WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname)
3125 unsigned char value;
3126 m_context->getBooleanv(pname, &value);
3127 return WebGLGetInfo(static_cast<bool>(value));
3130 WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(unsigned long pname)
3132 if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
3134 return WebGLGetInfo(0, 0);
3136 unsigned char value[4] = {0};
3137 m_context->getBooleanv(pname, value);
3139 for (int ii = 0; ii < 4; ++ii)
3140 boolValue[ii] = static_cast<bool>(value[ii]);
3141 return WebGLGetInfo(boolValue, 4);
3144 WebGLGetInfo WebGLRenderingContext::getFloatParameter(unsigned long pname)
3147 m_context->getFloatv(pname, &value);
3148 return WebGLGetInfo(static_cast<float>(value));
3151 WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname)
3153 return getLongParameter(pname);
3156 WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname)
3159 m_context->getIntegerv(pname, &value);
3160 return WebGLGetInfo(static_cast<long>(value));
3163 WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname)
3166 m_context->getIntegerv(pname, &value);
3167 return WebGLGetInfo(static_cast<unsigned long>(value));
3170 WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname)
3172 float value[4] = {0};
3173 m_context->getFloatv(pname, value);
3174 unsigned length = 0;
3176 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
3177 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
3178 case GraphicsContext3D::DEPTH_RANGE:
3181 case GraphicsContext3D::BLEND_COLOR:
3182 case GraphicsContext3D::COLOR_CLEAR_VALUE:
3188 return WebGLGetInfo(Float32Array::create(value, length));
3191 WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(unsigned long pname)
3194 m_context->getIntegerv(pname, value);
3195 unsigned length = 0;
3197 case GraphicsContext3D::MAX_VIEWPORT_DIMS:
3200 case GraphicsContext3D::SCISSOR_BOX:
3201 case GraphicsContext3D::VIEWPORT:
3207 return WebGLGetInfo(Int32Array::create(value, length));
3210 bool WebGLRenderingContext::isGLES2Compliant()
3212 return m_context->isGLES2Compliant();
3215 void WebGLRenderingContext::handleNPOTTextures(bool prepareToDraw)
3217 bool resetActiveUnit = false;
3218 for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
3219 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture()
3220 || m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture()) {
3221 if (ii != m_activeTextureUnit) {
3222 m_context->activeTexture(ii);
3223 resetActiveUnit = true;
3224 } else if (resetActiveUnit) {
3225 m_context->activeTexture(ii);
3226 resetActiveUnit = false;
3228 WebGLTexture* tex2D;
3229 WebGLTexture* texCubeMap;
3230 if (prepareToDraw) {
3231 tex2D = m_blackTexture2D.get();
3232 texCubeMap = m_blackTextureCubeMap.get();
3234 tex2D = m_textureUnits[ii].m_texture2DBinding.get();
3235 texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
3237 if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
3238 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, tex2D);
3239 if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())
3240 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, texCubeMap);
3243 if (resetActiveUnit)
3244 m_context->activeTexture(m_activeTextureUnit);
3247 void WebGLRenderingContext::createFallbackBlackTextures1x1()
3249 unsigned char black[] = {0, 0, 0, 255};
3250 m_blackTexture2D = createTexture();
3251 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D.get());
3252 m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
3253 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3254 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
3255 m_blackTextureCubeMap = createTexture();
3256 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap.get());
3257 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
3258 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3259 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
3260 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3261 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
3262 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3263 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
3264 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3265 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
3266 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3267 m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
3268 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
3269 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
3272 bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(unsigned long texInternalFormat,
3273 unsigned long colorBufferFormat)
3275 switch (colorBufferFormat) {
3276 case GraphicsContext3D::ALPHA:
3277 if (texInternalFormat == GraphicsContext3D::ALPHA)
3280 case GraphicsContext3D::RGB:
3281 if (texInternalFormat == GraphicsContext3D::LUMINANCE
3282 || texInternalFormat == GraphicsContext3D::RGB)
3285 case GraphicsContext3D::RGBA:
3291 WebGLTexture* WebGLRenderingContext::getTextureBinding(unsigned long target)
3293 RefPtr<WebGLTexture> tex = 0;
3295 case GraphicsContext3D::TEXTURE_2D:
3296 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
3298 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
3299 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
3300 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
3301 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
3302 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
3303 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
3304 tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
3307 if (tex && tex->object())
3312 bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type)
3315 case GraphicsContext3D::ALPHA:
3316 case GraphicsContext3D::LUMINANCE:
3317 case GraphicsContext3D::LUMINANCE_ALPHA:
3318 case GraphicsContext3D::RGB:
3319 case GraphicsContext3D::RGBA:
3322 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3327 case GraphicsContext3D::UNSIGNED_BYTE:
3328 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
3329 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
3330 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
3333 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3337 // Verify that the combination of format and type is supported.
3339 case GraphicsContext3D::ALPHA:
3340 case GraphicsContext3D::LUMINANCE:
3341 case GraphicsContext3D::LUMINANCE_ALPHA:
3342 if (type != GraphicsContext3D::UNSIGNED_BYTE) {
3343 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3347 case GraphicsContext3D::RGB:
3348 if (type != GraphicsContext3D::UNSIGNED_BYTE
3349 && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5) {
3350 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3354 case GraphicsContext3D::RGBA:
3355 if (type != GraphicsContext3D::UNSIGNED_BYTE
3356 && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
3357 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1) {
3358 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3363 ASSERT_NOT_REACHED();
3369 bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long level,
3370 unsigned long internalformat,
3371 long width, long height, long border,
3372 unsigned long format, unsigned long type)
3374 // We absolutely have to validate the format and type combination.
3375 // The texImage2D entry points taking HTMLImage, etc. will produce
3376 // temporary data based on this combination, so it must be legal.
3377 if (!validateTexFuncFormatAndType(format, type))
3380 if (isGLES2Compliant())
3383 if (width < 0 || height < 0 || level < 0) {
3384 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3389 case GraphicsContext3D::TEXTURE_2D:
3390 if (width > m_maxTextureSize || height > m_maxTextureSize) {
3391 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3395 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
3396 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
3397 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
3398 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
3399 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
3400 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
3401 if (width != height || width > m_maxCubeMapTextureSize) {
3402 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3407 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
3411 if (format != internalformat) {
3412 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
3417 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
3424 bool WebGLRenderingContext::validateTexFuncData(long width, long height,
3425 unsigned long format, unsigned long type,
3426 ArrayBufferView* pixels)