diff options
Diffstat (limited to 'Source/WebCore/html/canvas/WebGLRenderingContext.cpp')
-rw-r--r-- | Source/WebCore/html/canvas/WebGLRenderingContext.cpp | 812 |
1 files changed, 461 insertions, 351 deletions
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp index d17741fb3..945c17e74 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -57,6 +57,7 @@ #include "WebGLCompressedTextures.h" #include "WebGLContextAttributes.h" #include "WebGLContextEvent.h" +#include "WebGLContextGroup.h" #include "WebGLDebugRendererInfo.h" #include "WebGLDebugShaders.h" #include "WebGLFramebuffer.h" @@ -373,6 +374,15 @@ private: WebGLRenderingContext* m_context; }; +class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback { +public: + explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { } + virtual void onErrorMessage(const String& message, GC3Dint) { m_context->printWarningToConsole(message); } + virtual ~WebGLRenderingContextErrorMessageCallback() { } +private: + WebGLRenderingContext* m_context; +}; + PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs) { HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow(); @@ -414,8 +424,11 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa , m_contextLost(false) , m_contextLostMode(SyntheticLostContext) , m_attributes(attributes) + , m_synthesizedErrorsToConsole(false) { ASSERT(m_context); + m_contextGroup = WebGLContextGroup::create(); + m_contextGroup->addContext(this); #if PLATFORM(CHROMIUM) // Create the DrawingBuffer and initialize the platform layer. @@ -480,7 +493,7 @@ void WebGLRenderingContext::initializeNewContext() m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims); m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault); - addObject(m_defaultVertexArrayObject.get()); + addContextObject(m_defaultVertexArrayObject.get()); m_boundVertexArrayObject = m_defaultVertexArrayObject; m_vertexAttribValue.resize(m_maxVertexAttribs); @@ -497,6 +510,7 @@ void WebGLRenderingContext::initializeNewContext() m_context->viewport(0, 0, canvas()->width(), canvas()->height()); m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this))); + m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this))); } void WebGLRenderingContext::setupFlags() @@ -525,8 +539,28 @@ bool WebGLRenderingContext::allowPrivilegedExtensions() const WebGLRenderingContext::~WebGLRenderingContext() { + // Remove all references to WebGLObjects so if they are the last reference + // they will be freed before the last context is removed from the context group. + m_boundArrayBuffer = 0; + m_defaultVertexArrayObject = 0; + m_boundVertexArrayObject = 0; + m_vertexAttrib0Buffer = 0; + m_currentProgram = 0; + m_framebufferBinding = 0; + m_renderbufferBinding = 0; + + for (size_t i = 0; i < m_textureUnits.size(); ++i) { + m_textureUnits[i].m_texture2DBinding = 0; + m_textureUnits[i].m_textureCubeMapBinding = 0; + } + + m_blackTexture2D = 0; + m_blackTextureCubeMap = 0; + detachAndRemoveAllObjects(); m_context->setContextLostCallback(nullptr); + m_context->setErrorMessageCallback(nullptr); + m_contextGroup->removeContext(this); } void WebGLRenderingContext::markContextChanged() @@ -753,7 +787,7 @@ void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec) if (isContextLost()) return; if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "activeTexture", "texture unit out of range"); return; } m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0; @@ -768,10 +802,10 @@ void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec) void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader)) return; if (!program->attachShader(shader)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader"); return; } m_context->attachShader(objectOrZero(program), objectOrZero(shader)); @@ -782,24 +816,24 @@ void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* sha void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("bindAttribLocation", program)) return; - if (!validateLocationLength(name)) + if (!validateLocationLength("bindAttribLocation", name)) return; - if (!validateString(name)) + if (!validateString("bindAttribLocation", name)) return; m_context->bindAttribLocation(objectOrZero(program), index, name); cleanupAfterGraphicsCall(false); } -bool WebGLRenderingContext::checkObjectToBeBound(WebGLObject* object, bool& deleted) +bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted) { deleted = false; if (isContextLost()) return false; if (object) { - if (object->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + if (!object->validate(contextGroup(), this)) { + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context"); return false; } deleted = !object->object(); @@ -811,12 +845,12 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc { UNUSED_PARAM(ec); bool deleted; - if (!checkObjectToBeBound(buffer, deleted)) + if (!checkObjectToBeBound("bindBuffer", buffer, deleted)) return; if (deleted) buffer = 0; if (buffer && buffer->getTarget() && buffer->getTarget() != target) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets"); return; } if (target == GraphicsContext3D::ARRAY_BUFFER) @@ -824,7 +858,7 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) m_boundVertexArrayObject->setElementArrayBuffer(buffer); else { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindBuffer", "invalid target"); return; } @@ -838,12 +872,12 @@ void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* b { UNUSED_PARAM(ec); bool deleted; - if (!checkObjectToBeBound(buffer, deleted)) + if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted)) return; if (deleted) buffer = 0; if (target != GraphicsContext3D::FRAMEBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindFramebuffer", "invalid target"); return; } m_framebufferBinding = buffer; @@ -861,12 +895,12 @@ void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* { UNUSED_PARAM(ec); bool deleted; - if (!checkObjectToBeBound(renderBuffer, deleted)) + if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted)) return; if (deleted) renderBuffer = 0; if (target != GraphicsContext3D::RENDERBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindRenderbuffer", "invalid target"); return; } m_renderbufferBinding = renderBuffer; @@ -880,12 +914,12 @@ void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture, { UNUSED_PARAM(ec); bool deleted; - if (!checkObjectToBeBound(texture, deleted)) + if (!checkObjectToBeBound("bindTexture", texture, deleted)) return; if (deleted) texture = 0; if (texture && texture->getTarget() && texture->getTarget() != target) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets"); return; } GC3Dint maxLevel = 0; @@ -900,7 +934,7 @@ void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture, m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture; maxLevel = m_maxCubeMapTextureLevel; } else { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target"); return; } m_context->bindTexture(target, objectOrZero(texture)); @@ -929,7 +963,7 @@ void WebGLRenderingContext::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat void WebGLRenderingContext::blendEquation(GC3Denum mode) { - if (isContextLost() || !validateBlendEquation(mode)) + if (isContextLost() || !validateBlendEquation("blendEquation", mode)) return; m_context->blendEquation(mode); cleanupAfterGraphicsCall(false); @@ -937,7 +971,7 @@ void WebGLRenderingContext::blendEquation(GC3Denum mode) void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha) { - if (isContextLost() || !validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha)) + if (isContextLost() || !validateBlendEquation("blendEquation", modeRGB) || !validateBlendEquation("blendEquation", modeAlpha)) return; m_context->blendEquationSeparate(modeRGB, modeAlpha); cleanupAfterGraphicsCall(false); @@ -946,7 +980,7 @@ void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum mod void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor) { - if (isContextLost() || !validateBlendFuncFactors(sfactor, dfactor)) + if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor)) return; m_context->blendFunc(sfactor, dfactor); cleanupAfterGraphicsCall(false); @@ -954,7 +988,8 @@ void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor) void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha) { - if (isContextLost() || !validateBlendFuncFactors(srcRGB, dstRGB)) + // Note: Alpha does not have the same restrictions as RGB. + if (isContextLost() || !validateBlendFuncFactors("blendFunc", srcRGB, dstRGB)) return; m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); cleanupAfterGraphicsCall(false); @@ -965,16 +1000,16 @@ void WebGLRenderingContext::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3De UNUSED_PARAM(ec); if (isContextLost()) return; - WebGLBuffer* buffer = validateBufferDataParameters(target, usage); + WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage); if (!buffer) return; if (size < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size < 0"); return; } if (!isErrorGeneratedOnOutOfBoundsAccesses()) { if (!buffer->associateBufferData(size)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer"); return; } } @@ -988,16 +1023,16 @@ void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3De UNUSED_PARAM(ec); if (isContextLost()) return; - WebGLBuffer* buffer = validateBufferDataParameters(target, usage); + WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage); if (!buffer) return; if (!data) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data"); return; } if (!isErrorGeneratedOnOutOfBoundsAccesses()) { if (!buffer->associateBufferData(data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer"); return; } } @@ -1011,16 +1046,16 @@ void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, G UNUSED_PARAM(ec); if (isContextLost()) return; - WebGLBuffer* buffer = validateBufferDataParameters(target, usage); + WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage); if (!buffer) return; if (!data) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data"); return; } if (!isErrorGeneratedOnOutOfBoundsAccesses()) { if (!buffer->associateBufferData(data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer"); return; } } @@ -1034,18 +1069,18 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar UNUSED_PARAM(ec); if (isContextLost()) return; - WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); + WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW); if (!buffer) return; if (offset < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0"); return; } if (!data) return; if (!isErrorGeneratedOnOutOfBoundsAccesses()) { if (!buffer->associateBufferSubData(offset, data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range"); return; } } @@ -1059,18 +1094,18 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar UNUSED_PARAM(ec); if (isContextLost()) return; - WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); + WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW); if (!buffer) return; if (offset < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0"); return; } if (!data) return; if (!isErrorGeneratedOnOutOfBoundsAccesses()) { if (!buffer->associateBufferSubData(offset, data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range"); return; } } @@ -1084,7 +1119,7 @@ GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target) if (isContextLost()) return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; if (target != GraphicsContext3D::FRAMEBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target"); return 0; } if (!m_framebufferBinding || !m_framebufferBinding->object()) @@ -1102,11 +1137,11 @@ void WebGLRenderingContext::clear(GC3Dbitfield mask) if (isContextLost()) return; if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask"); return; } - if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) { + synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", "can not render to framebuffer"); return; } if (!clearIfComposited(mask)) @@ -1167,31 +1202,51 @@ void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dbo void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject("compileShader", shader)) return; m_context->compileShader(objectOrZero(shader)); cleanupAfterGraphicsCall(false); } +void WebGLRenderingContext::compressedTexImage2D(GC3Denum /*target*/, GC3Dint /*level*/, GC3Denum /*internalformat*/, GC3Dsizei /*width*/, + GC3Dsizei /*height*/, GC3Dint /*border*/, ArrayBufferView* /*data*/) +{ + if (isContextLost()) + return; + + // FIXME: implement this. + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat"); +} + +void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum /*target*/, GC3Dint /*level*/, GC3Dint /*xoffset*/, GC3Dint /*yoffset*/, + GC3Dsizei /*width*/, GC3Dsizei /*height*/, GC3Denum /*format*/, ArrayBufferView* /*data*/) +{ + if (isContextLost()) + return; + + // FIXME: implement this. + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format"); +} + void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) { if (isContextLost()) return; - if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE)) + if (!validateTexFuncParameters("copyTexImage2D", target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE)) return; - WebGLTexture* tex = validateTextureBinding(target, true); + WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true); if (!tex) return; if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format"); return; } if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2"); return; } - if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) { + synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", "framebuffer not readable"); return; } clearIfComposited(); @@ -1221,23 +1276,23 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC { if (isContextLost()) return; - if (!validateTexFuncLevel(target, level)) + if (!validateTexFuncLevel("copyTexSubImage2D", target, level)) return; - WebGLTexture* tex = validateTextureBinding(target, true); + WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true); if (!tex) return; - if (!validateSize(xoffset, yoffset) || !validateSize(width, height)) + if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height)) return; if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range"); return; } if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(target, level), getBoundFramebufferColorFormat())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format"); return; } - if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) { + synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", "framebuffer not readable"); return; } clearIfComposited(); @@ -1255,12 +1310,12 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC unsigned int size; GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0); if (error != GraphicsContext3D::NO_ERROR) { - m_context->synthesizeGLError(error); + synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions"); return; } zero = adoptArrayPtr(new unsigned char[size]); if (!zero) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "out of memory"); return; } memset(zero.get(), 0, size); @@ -1284,7 +1339,7 @@ PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer() if (isContextLost()) return 0; RefPtr<WebGLBuffer> o = WebGLBuffer::create(this); - addObject(o.get()); + addSharedObject(o.get()); return o; } @@ -1293,7 +1348,7 @@ PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer() if (isContextLost()) return 0; RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this); - addObject(o.get()); + addContextObject(o.get()); return o; } @@ -1302,7 +1357,7 @@ PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture() if (isContextLost()) return 0; RefPtr<WebGLTexture> o = WebGLTexture::create(this); - addObject(o.get()); + addSharedObject(o.get()); return o; } @@ -1311,7 +1366,7 @@ PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram() if (isContextLost()) return 0; RefPtr<WebGLProgram> o = WebGLProgram::create(this); - addObject(o.get()); + addSharedObject(o.get()); return o; } @@ -1320,7 +1375,7 @@ PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer() if (isContextLost()) return 0; RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this); - addObject(o.get()); + addSharedObject(o.get()); return o; } @@ -1330,12 +1385,12 @@ PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type, Excep if (isContextLost()) return 0; if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "createShader", "invalid shader type"); return 0; } RefPtr<WebGLShader> o = WebGLShader::create(this, type); - addObject(o.get()); + addSharedObject(o.get()); return o; } @@ -1351,12 +1406,14 @@ bool WebGLRenderingContext::deleteObject(WebGLObject* object) { if (isContextLost() || !object) return false; - if (object->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + if (!object->validate(contextGroup(), this)) { + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context"); return false; } if (object->object()) - object->deleteObject(); + // We need to pass in context here because we want + // things in this context unbound. + object->deleteObject(graphicsContext3D()); return true; } @@ -1456,7 +1513,7 @@ void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar) if (isContextLost()) return; if (zNear > zFar) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "depthRange", "zNear > zFar"); return; } m_context->depthRange(zNear, zFar); @@ -1466,20 +1523,20 @@ void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar) void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader)) return; if (!program->detachShader(shader)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached"); return; } m_context->detachShader(objectOrZero(program), objectOrZero(shader)); - shader->onDetached(); + shader->onDetached(graphicsContext3D()); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::disable(GC3Denum cap) { - if (isContextLost() || !validateCapability(cap)) + if (isContextLost() || !validateCapability("disable", cap)) return; if (cap == GraphicsContext3D::SCISSOR_TEST) { m_scissorEnabled = false; @@ -1496,7 +1553,7 @@ void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCo if (isContextLost()) return; if (index >= m_maxVertexAttribs) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "disableVertexAttribArray", "index out of range"); return; } @@ -1679,14 +1736,14 @@ bool WebGLRenderingContext::validateRenderingState(int numElementsRequired) return numElementsRequired <= smallestNumElements; } -bool WebGLRenderingContext::validateWebGLObject(WebGLObject* object) +bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object) { if (!object || !object->object()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted"); return false; } - if (object->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + if (!object->validate(contextGroup(), this)) { + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context"); return false; } return true; @@ -1696,14 +1753,14 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c { UNUSED_PARAM(ec); - if (isContextLost() || !validateDrawMode(mode)) + if (isContextLost() || !validateDrawMode("drawArrays", mode)) return; - if (!validateStencilSettings()) + if (!validateStencilSettings("drawArrays")) return; if (first < 0 || count < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawArrays", "first or count < 0"); return; } @@ -1716,18 +1773,18 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c CheckedInt<GC3Dint> checkedCount(count); CheckedInt<GC3Dint> checkedSum = checkedFirst + checkedCount; if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawArrays", "attempt to access out of bounds arrays"); return; } } else { if (!validateRenderingState(0)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawArrays", "attribs not setup correctly"); return; } } - if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) { + synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawArrays", "framebuffer can not be rendered to"); return; } @@ -1750,10 +1807,10 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu { UNUSED_PARAM(ec); - if (isContextLost() || !validateDrawMode(mode)) + if (isContextLost() || !validateDrawMode("drawElements", mode)) return; - if (!validateStencilSettings()) + if (!validateStencilSettings("drawElements")) return; switch (type) { @@ -1761,12 +1818,12 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu case GraphicsContext3D::UNSIGNED_SHORT: break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "drawElements", "invalid type"); return; } if (count < 0 || offset < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawElements", "count or offset < 0"); return; } @@ -1774,7 +1831,7 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu return; if (!m_boundVertexArrayObject->getElementArrayBuffer()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "no ELEMENT_ARRAY_BUFFER bound"); return; } @@ -1782,26 +1839,26 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu if (!isErrorGeneratedOnOutOfBoundsAccesses()) { // Ensure we have a valid rendering state if (!validateElementArraySize(count, type, offset)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "request out of bounds for current ELEMENT_ARRAY_BUFFER"); return; } if (!count) return; if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) { if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "attempt to access out of bounds arrays"); return; } } } else { if (!validateRenderingState(0)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "attribs not setup correctly"); return; } } - if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) { + synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawElements", "framebuffer can not be rendered to"); return; } clearIfComposited(); @@ -1824,7 +1881,7 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu void WebGLRenderingContext::enable(GC3Denum cap) { - if (isContextLost() || !validateCapability(cap)) + if (isContextLost() || !validateCapability("enable", cap)) return; if (cap == GraphicsContext3D::SCISSOR_TEST) { m_scissorEnabled = true; @@ -1841,7 +1898,7 @@ void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index, ExceptionCod if (isContextLost()) return; if (index >= m_maxVertexAttribs) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "enableVertexAttribArray", "index out of range"); return; } @@ -1871,21 +1928,21 @@ void WebGLRenderingContext::flush() void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateFramebufferFuncParameters(target, attachment)) + if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment)) return; if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target"); return; } - if (buffer && buffer->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + if (buffer && !buffer->validate(contextGroup(), this)) { + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context"); return; } // Don't allow the default framebuffer to be mutated; all current // implementations use an FBO internally in place of the default // FBO. if (!m_framebufferBinding || !m_framebufferBinding->object()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound"); return; } Platform3DObject bufferObject = objectOrZero(buffer); @@ -1942,21 +1999,21 @@ void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum at void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateFramebufferFuncParameters(target, attachment)) + if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment)) return; if (level) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0"); return; } - if (texture && texture->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + if (texture && !texture->validate(contextGroup(), this)) { + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context"); return; } // Don't allow the default framebuffer to be mutated; all current // implementations use an FBO internally in place of the default // FBO. if (!m_framebufferBinding || !m_framebufferBinding->object()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound"); return; } m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level); @@ -1976,11 +2033,11 @@ void WebGLRenderingContext::generateMipmap(GC3Denum target) { if (isContextLost()) return; - WebGLTexture* tex = validateTextureBinding(target, false); + WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false); if (!tex) return; if (!tex->canGenerateMipmaps()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size"); return; } // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR @@ -2004,7 +2061,7 @@ void WebGLRenderingContext::generateMipmap(GC3Denum target) PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("getActiveAttrib", program)) return 0; ActiveInfo info; if (!m_context->getActiveAttrib(objectOrZero(program), index, info)) @@ -2015,7 +2072,7 @@ PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GC3Duint index, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("getActiveUniform", program)) return 0; ActiveInfo info; if (!m_context->getActiveUniform(objectOrZero(program), index, info)) @@ -2030,7 +2087,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Ref { UNUSED_PARAM(ec); shaderObjects.clear(); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("getAttachedShaders", program)) return false; const GC3Denum shaderType[] = { @@ -2049,9 +2106,9 @@ GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const St { if (isContextLost()) return -1; - if (!validateLocationLength(name)) + if (!validateLocationLength("getAttribLocation", name)) return -1; - if (!validateString(name)) + if (!validateString("getAttribLocation", name)) return -1; return m_context->getAttribLocation(objectOrZero(program), name); } @@ -2062,12 +2119,12 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum if (isContextLost()) return WebGLGetInfo(); if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target"); return WebGLGetInfo(); } if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid parameter name"); return WebGLGetInfo(); } @@ -2156,21 +2213,21 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateFramebufferFuncParameters(target, attachment)) + if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment)) return WebGLGetInfo(); if (!m_framebufferBinding || !m_framebufferBinding->object()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound"); return WebGLGetInfo(); } - WebGLObject* object = m_framebufferBinding->getAttachment(attachment); + WebGLSharedObject* object = m_framebufferBinding->getAttachment(attachment); if (!object) { if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) return WebGLGetInfo(GraphicsContext3D::NONE); // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL // specifies INVALID_OPERATION. - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name"); return WebGLGetInfo(); } @@ -2190,7 +2247,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum t return WebGLGetInfo(value); } default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment"); return WebGLGetInfo(); } } else { @@ -2200,7 +2257,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum t case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object))); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); return WebGLGetInfo(); } } @@ -2395,17 +2452,17 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives if (m_oesStandardDerivatives) return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES); - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled"); return WebGLGetInfo(); case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL: if (m_webglDebugRendererInfo) return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER)); - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled"); return WebGLGetInfo(); case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL: if (m_webglDebugRendererInfo) return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR)); - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled"); return WebGLGetInfo(); case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object if (m_oesVertexArrayObject) { @@ -2413,10 +2470,10 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject)); return WebGLGetInfo(); } - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled"); return WebGLGetInfo(); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name"); return WebGLGetInfo(); } } @@ -2424,7 +2481,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("getProgramParameter", program)) return WebGLGetInfo(); WebGLStateRestorer(this, false); @@ -2443,7 +2500,7 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, G m_context->getProgramiv(objectOrZero(program), pname, &value); return WebGLGetInfo(value); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getProgramParameter", "invalid parameter name"); return WebGLGetInfo(); } } @@ -2453,7 +2510,7 @@ String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, Exception UNUSED_PARAM(ec); if (isContextLost()) return String(); - if (!validateWebGLObject(program)) + if (!validateWebGLObject("getProgramInfoLog", program)) return ""; WebGLStateRestorer(this, false); return m_context->getProgramInfoLog(objectOrZero(program)); @@ -2465,11 +2522,11 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC if (isContextLost()) return WebGLGetInfo(); if (target != GraphicsContext3D::RENDERBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid target"); return WebGLGetInfo(); } if (!m_renderbufferBinding || !m_renderbufferBinding->object()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound"); return WebGLGetInfo(); } @@ -2499,7 +2556,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name"); return WebGLGetInfo(); } return WebGLGetInfo(value); @@ -2521,7 +2578,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name"); return WebGLGetInfo(); } } @@ -2529,7 +2586,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject("getShaderParameter", shader)) return WebGLGetInfo(); WebGLStateRestorer(this, false); GC3Dint value = 0; @@ -2543,7 +2600,7 @@ WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3D m_context->getShaderiv(objectOrZero(shader), pname, &value); return WebGLGetInfo(static_cast<unsigned int>(value)); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderParameter", "invalid parameter name"); return WebGLGetInfo(); } } @@ -2553,7 +2610,7 @@ String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCod UNUSED_PARAM(ec); if (isContextLost()) return String(); - if (!validateWebGLObject(shader)) + if (!validateWebGLObject("getShaderInfoLog", shader)) return ""; WebGLStateRestorer(this, false); return m_context->getShaderInfoLog(objectOrZero(shader)); @@ -2564,7 +2621,7 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode UNUSED_PARAM(ec); if (isContextLost()) return String(); - if (!validateWebGLObject(shader)) + if (!validateWebGLObject("getShaderSource", shader)) return ""; return shader->getSource(); } @@ -2596,7 +2653,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn UNUSED_PARAM(ec); if (isContextLost()) return WebGLGetInfo(); - WebGLTexture* tex = validateTextureBinding(target, false); + WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false); if (!tex) return WebGLGetInfo(); WebGLStateRestorer(this, false); @@ -2609,7 +2666,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn m_context->getTexParameteriv(target, pname, &value); return WebGLGetInfo(static_cast<unsigned int>(value)); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name"); return WebGLGetInfo(); } } @@ -2617,10 +2674,10 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("getUniform", program)) return WebGLGetInfo(); if (!uniformLocation || uniformLocation->program() != program) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program"); return WebGLGetInfo(); } GC3Dint location = uniformLocation->location(); @@ -2718,7 +2775,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG break; default: // Can't handle this type - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unhandled type"); return WebGLGetInfo(); } switch (baseType) { @@ -2754,18 +2811,18 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG } } // If we get here, something went wrong in our unfortunately complex logic above - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unknown error"); return WebGLGetInfo(); } PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("getUniformLocation", program)) return 0; - if (!validateLocationLength(name)) + if (!validateLocationLength("getUniformLocation", name)) return 0; - if (!validateString(name)) + if (!validateString("getUniformLocation", name)) return 0; WebGLStateRestorer(this, false); GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name); @@ -2781,7 +2838,7 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna return WebGLGetInfo(); WebGLStateRestorer(this, false); if (index >= m_maxVertexAttribs) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getVertexAttrib", "index out of range"); return WebGLGetInfo(); } const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index); @@ -2805,7 +2862,7 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna case GraphicsContext3D::CURRENT_VERTEX_ATTRIB: return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4)); default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getVertexAttrib", "invalid parameter name"); return WebGLGetInfo(); } } @@ -2834,7 +2891,7 @@ void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode) break; } if (!isValid) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target"); return; } m_context->hint(target, mode); @@ -2859,7 +2916,7 @@ bool WebGLRenderingContext::isContextLost() GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap) { - if (!validateCapability(cap) || isContextLost()) + if (isContextLost() || !validateCapability("isEnabled", cap)) return 0; return m_context->isEnabled(cap); } @@ -2924,7 +2981,7 @@ void WebGLRenderingContext::lineWidth(GC3Dfloat width) void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("linkProgram", program)) return; if (!isGLES2Compliant()) { if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) { @@ -2940,7 +2997,7 @@ void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::LINK_STATUS, &value); program->setLinkStatus(static_cast<bool>(value)); // Need to cache link status before caching active attribute locations. - program->cacheActiveAttribLocations(); + program->cacheActiveAttribLocations(graphicsContext3D()); cleanupAfterGraphicsCall(false); } @@ -2959,7 +3016,7 @@ void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param) if (param == GraphicsContext3D::BROWSER_DEFAULT_WEBGL || param == GraphicsContext3D::NONE) m_unpackColorspaceConversion = static_cast<GC3Denum>(param); else { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL"); return; } break; @@ -2973,12 +3030,12 @@ void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param) m_context->pixelStorei(pname, param); cleanupAfterGraphicsCall(false); } else { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for alignment"); return; } break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "pixelStorei", "invalid parameter name"); return; } } @@ -3000,7 +3057,7 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC ASSERT(canvas()->originClean()); // Validate input parameters. if (!pixels) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "readPixels", "no destination ArrayBufferView"); return; } switch (format) { @@ -3009,7 +3066,7 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC case GraphicsContext3D::RGBA: break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid format"); return; } switch (type) { @@ -3019,20 +3076,20 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid type"); return; } if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE"); return; } // Validate array type against pixel type. if (!pixels->isUnsignedByteArray()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array"); return; } - if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) { + synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", "framebuffer not readable"); return; } // Calculate array size, taking into consideration of PACK_ALIGNMENT. @@ -3040,11 +3097,11 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC unsigned int padding; GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding); if (error != GraphicsContext3D::NO_ERROR) { - m_context->synthesizeGLError(error); + synthesizeGLError(error, "readPixels", "invalid dimensions"); return; } if (pixels->byteLength() < totalBytesRequired) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions"); return; } clearIfComposited(); @@ -3085,14 +3142,14 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern if (isContextLost()) return; if (target != GraphicsContext3D::RENDERBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target"); return; } if (!m_renderbufferBinding || !m_renderbufferBinding->object()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer"); return; } - if (!validateSize(width, height)) + if (!validateSize("renderbufferStorage", width, height)) return; switch (internalformat) { case GraphicsContext3D::DEPTH_COMPONENT16: @@ -3116,7 +3173,7 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern m_renderbufferBinding->setInternalFormat(internalformat); break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat"); } } @@ -3132,7 +3189,7 @@ void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Ds { if (isContextLost()) return; - if (!validateSize(width, height)) + if (!validateSize("scissor", width, height)) return; m_context->scissor(x, y, width, height); cleanupAfterGraphicsCall(false); @@ -3141,10 +3198,10 @@ void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Ds void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject("shaderSource", shader)) return; String stringWithoutComments = StripComments(string).result(); - if (!validateString(stringWithoutComments)) + if (!validateString("shaderSource", stringWithoutComments)) return; shader->setSource(string); m_context->shaderSource(objectOrZero(shader), stringWithoutComments); @@ -3155,7 +3212,7 @@ void WebGLRenderingContext::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mas { if (isContextLost()) return; - if (!validateStencilFunc(func)) + if (!validateStencilFunc("stencilFunc", func)) return; m_stencilFuncRef = ref; m_stencilFuncRefBack = ref; @@ -3169,7 +3226,7 @@ void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC { if (isContextLost()) return; - if (!validateStencilFunc(func)) + if (!validateStencilFunc("stencilFuncSeparate", func)) return; switch (face) { case GraphicsContext3D::FRONT_AND_BACK: @@ -3187,7 +3244,7 @@ void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC m_stencilFuncMaskBack = mask; break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilFuncSeparate", "invalid face"); return; } m_context->stencilFuncSeparate(face, func, ref, mask); @@ -3220,7 +3277,7 @@ void WebGLRenderingContext::stencilMaskSeparate(GC3Denum face, GC3Duint mask) m_stencilMaskBack = mask; break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilMaskSeparate", "invalid face"); return; } m_context->stencilMaskSeparate(face, mask); @@ -3249,14 +3306,14 @@ void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3De { // FIXME: For now we ignore any errors returned ec = 0; - if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type)) + if (!validateTexFuncParameters("texImage2D", target, level, internalformat, width, height, border, format, type)) return; - WebGLTexture* tex = validateTextureBinding(target, true); + WebGLTexture* tex = validateTextureBinding("texImage2D", target, true); if (!tex) return; if (!isGLES2NPOTStrict()) { if (level && WebGLTexture::isNPOT(width, height)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "level > 0 not power of 2"); return; } } @@ -3280,7 +3337,7 @@ void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3De ec = 0; Vector<uint8_t> data; if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data"); return; } if (m_unpackAlignment != 1) @@ -3295,7 +3352,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) { - if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels)) + if (isContextLost() || !validateTexFuncData("texImage2D", width, height, format, type, pixels)) return; void* data = pixels ? pixels->baseAddress() : 0; Vector<uint8_t> tempData; @@ -3326,7 +3383,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum return; Vector<uint8_t> data; if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data"); return; } if (m_unpackAlignment != 1) @@ -3343,7 +3400,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum ec = 0; if (isContextLost()) return; - if (!validateHTMLImageElement(image)) + if (!validateHTMLImageElement("texImage2D", image)) return; if (wouldTaintOrigin(image)) { ec = SECURITY_ERR; @@ -3361,7 +3418,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum if (isContextLost()) return; if (!canvas || !canvas->buffer()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "no canvas"); return; } if (wouldTaintOrigin(canvas)) { @@ -3380,13 +3437,13 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec) { if (!video || !video->videoWidth() || !video->videoHeight()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "no video"); return 0; } IntSize size(video->videoWidth(), video->videoHeight()); ImageBuffer* buf = m_videoCache.imageBuffer(size); if (!buf) { - m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY); + synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory"); return 0; } if (wouldTaintOrigin(video)) { @@ -3416,7 +3473,7 @@ void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfl { if (isContextLost()) return; - WebGLTexture* tex = validateTextureBinding(target, false); + WebGLTexture* tex = validateTextureBinding("texParameter", target, false); if (!tex) return; switch (pname) { @@ -3427,12 +3484,12 @@ void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfl case GraphicsContext3D::TEXTURE_WRAP_T: if ((isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT) || (!isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter"); return; } break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter name"); return; } if (isFloat) { @@ -3463,19 +3520,19 @@ void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC ec = 0; if (isContextLost()) return; - if (!validateTexFuncParameters(target, level, format, width, height, 0, format, type)) + if (!validateTexFuncParameters("texSubImage2D", target, level, format, width, height, 0, format, type)) return; - if (!validateSize(xoffset, yoffset)) + if (!validateSize("texSubImage2D", xoffset, yoffset)) return; - WebGLTexture* tex = validateTextureBinding(target, true); + WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true); if (!tex) return; if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "dimensions out of range"); return; } if (tex->getInternalFormat(target, level) != format || tex->getType(target, level) != type) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "texSubImage2D", "type and format do not match texture"); return; } m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); @@ -3491,7 +3548,7 @@ void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC return; Vector<uint8_t> data; if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image"); return; } texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), @@ -3502,7 +3559,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) { - if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels)) + if (isContextLost() || !validateTexFuncData("texSubImage2D", width, height, format, type, pixels)) return; void* data = pixels ? pixels->baseAddress() : 0; Vector<uint8_t> tempData; @@ -3532,7 +3589,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din return; Vector<uint8_t> data; if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data"); return; } texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), @@ -3545,7 +3602,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din ec = 0; if (isContextLost()) return; - if (!validateHTMLImageElement(image)) + if (!validateHTMLImageElement("texSubImage2D", image)) return; if (wouldTaintOrigin(image)) { ec = SECURITY_ERR; @@ -3562,7 +3619,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din if (isContextLost()) return; if (!canvas || !canvas->buffer()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "no canvas"); return; } if (wouldTaintOrigin(canvas)) { @@ -3598,7 +3655,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1f", "location not for current program"); return; } @@ -3609,7 +3666,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 1)) + if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1)) return; m_context->uniform1fv(location->location(), v->data(), v->length()); @@ -3619,7 +3676,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 1)) + if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1)) return; m_context->uniform1fv(location->location(), v, size); @@ -3633,7 +3690,7 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1i", "location not for current program"); return; } @@ -3644,7 +3701,7 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 1)) + if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1)) return; m_context->uniform1iv(location->location(), v->data(), v->length()); @@ -3654,7 +3711,7 @@ void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 1)) + if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1)) return; m_context->uniform1iv(location->location(), v, size); @@ -3668,7 +3725,7 @@ void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program"); return; } @@ -3679,7 +3736,7 @@ void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 2)) + if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2)) return; m_context->uniform2fv(location->location(), v->data(), v->length() / 2); @@ -3689,7 +3746,7 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 2)) + if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2)) return; m_context->uniform2fv(location->location(), v, size / 2); @@ -3703,7 +3760,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program"); return; } @@ -3714,7 +3771,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 2)) + if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2)) return; m_context->uniform2iv(location->location(), v->data(), v->length() / 2); @@ -3724,7 +3781,7 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 2)) + if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2)) return; m_context->uniform2iv(location->location(), v, size / 2); @@ -3738,7 +3795,7 @@ void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program"); return; } @@ -3749,7 +3806,7 @@ void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 3)) + if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3)) return; m_context->uniform3fv(location->location(), v->data(), v->length() / 3); @@ -3759,7 +3816,7 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 3)) + if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3)) return; m_context->uniform3fv(location->location(), v, size / 3); @@ -3773,7 +3830,7 @@ void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program"); return; } @@ -3784,7 +3841,7 @@ void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 3)) + if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3)) return; m_context->uniform3iv(location->location(), v->data(), v->length() / 3); @@ -3794,7 +3851,7 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 3)) + if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3)) return; m_context->uniform3iv(location->location(), v, size / 3); @@ -3808,7 +3865,7 @@ void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program"); return; } @@ -3819,7 +3876,7 @@ void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 4)) + if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4)) return; m_context->uniform4fv(location->location(), v->data(), v->length() / 4); @@ -3829,7 +3886,7 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 4)) + if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4)) return; m_context->uniform4fv(location->location(), v, size / 4); @@ -3843,7 +3900,7 @@ void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3D return; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program"); return; } @@ -3854,7 +3911,7 @@ void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3D void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, 4)) + if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4)) return; m_context->uniform4iv(location->location(), v->data(), v->length() / 4); @@ -3864,7 +3921,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformParameters(location, v, size, 4)) + if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4)) return; m_context->uniform4iv(location->location(), v, size / 4); @@ -3874,7 +3931,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 4)) + if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4)) return; m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4); cleanupAfterGraphicsCall(false); @@ -3883,7 +3940,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 4)) + if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4)) return; m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4); cleanupAfterGraphicsCall(false); @@ -3892,7 +3949,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 9)) + if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9)) return; m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9); cleanupAfterGraphicsCall(false); @@ -3901,7 +3958,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 9)) + if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9)) return; m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9); cleanupAfterGraphicsCall(false); @@ -3910,7 +3967,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 16)) + if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16)) return; m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16); cleanupAfterGraphicsCall(false); @@ -3919,7 +3976,7 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 16)) + if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16)) return; m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16); cleanupAfterGraphicsCall(false); @@ -3929,18 +3986,18 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); bool deleted; - if (!checkObjectToBeBound(program, deleted)) + if (!checkObjectToBeBound("useProgram", program, deleted)) return; if (deleted) program = 0; if (program && !program->getLinkStatus()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid"); cleanupAfterGraphicsCall(false); return; } if (m_currentProgram != program) { if (m_currentProgram) - m_currentProgram->onDetached(); + m_currentProgram->onDetached(graphicsContext3D()); m_currentProgram = program; m_context->useProgram(objectOrZero(program)); if (program) @@ -3952,7 +4009,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost() || !validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject("validateProgram", program)) return; m_context->validateProgram(objectOrZero(program)); cleanupAfterGraphicsCall(false); @@ -3960,62 +4017,62 @@ void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0) { - vertexAttribfImpl(index, 1, v0, 0.0f, 0.0f, 1.0f); + vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f); } void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v) { - vertexAttribfvImpl(index, v, 1); + vertexAttribfvImpl("vertexAttrib1fv", index, v, 1); } void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size) { - vertexAttribfvImpl(index, v, size, 1); + vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1); } void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1) { - vertexAttribfImpl(index, 2, v0, v1, 0.0f, 1.0f); + vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f); } void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v) { - vertexAttribfvImpl(index, v, 2); + vertexAttribfvImpl("vertexAttrib2fv", index, v, 2); } void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size) { - vertexAttribfvImpl(index, v, size, 2); + vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2); } void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2) { - vertexAttribfImpl(index, 3, v0, v1, v2, 1.0f); + vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f); } void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v) { - vertexAttribfvImpl(index, v, 3); + vertexAttribfvImpl("vertexAttrib3fv", index, v, 3); } void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size) { - vertexAttribfvImpl(index, v, size, 3); + vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3); } void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3) { - vertexAttribfImpl(index, 4, v0, v1, v2, v3); + vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3); } void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v) { - vertexAttribfvImpl(index, v, 4); + vertexAttribfvImpl("vertexAttrib4fv", index, v, 4); } void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size) { - vertexAttribfvImpl(index, v, size, 4); + vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4); } void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, ExceptionCode& ec) @@ -4031,29 +4088,29 @@ void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC case GraphicsContext3D::FLOAT: break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type"); return; } if (index >= m_maxVertexAttribs) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "index out of range"); return; } if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset"); return; } if (!m_boundArrayBuffer) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER"); return; } // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride unsigned int typeSize = sizeInBytes(type); if (!typeSize) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type"); return; } if ((stride % typeSize) || (offset % typeSize)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type"); return; } GC3Dsizei bytesPerElement = size * typeSize; @@ -4077,7 +4134,7 @@ void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3D { if (isContextLost()) return; - if (!validateSize(width, height)) + if (!validateSize("viewport", width, height)) return; m_context->viewport(x, y, width, height); cleanupAfterGraphicsCall(false); @@ -4086,10 +4143,18 @@ void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3D void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode) { if (isContextLost()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "loseContext", "context already lost"); return; } + m_contextGroup->loseContextGroup(mode); +} + +void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode) +{ + if (isContextLost()) + return; + m_contextLost = true; m_contextLostMode = mode; @@ -4103,7 +4168,7 @@ void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextM if (m_context->getError() == GraphicsContext3D::NO_ERROR) break; } - m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL); + synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL, "loseContext", "context lost"); // Don't allow restoration unless the context lost event has both been // dispatched and its default behavior prevented. @@ -4117,13 +4182,13 @@ void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextM void WebGLRenderingContext::forceRestoreContext() { if (!isContextLost()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context not lost"); return; } if (!m_restoreAllowed) { if (m_contextLostMode == SyntheticLostContext) - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context restoration not allowed"); return; } @@ -4143,22 +4208,32 @@ PlatformLayer* WebGLRenderingContext::platformLayer() const } #endif -void WebGLRenderingContext::removeObject(WebGLObject* object) +void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object) { - m_canvasObjects.remove(object); + m_contextGroup->removeObject(object); } -void WebGLRenderingContext::addObject(WebGLObject* object) +void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object) { ASSERT(!isContextLost()); - removeObject(object); - m_canvasObjects.add(object); + m_contextGroup->addObject(object); +} + +void WebGLRenderingContext::removeContextObject(WebGLContextObject* object) +{ + m_contextObjects.remove(object); +} + +void WebGLRenderingContext::addContextObject(WebGLContextObject* object) +{ + ASSERT(!isContextLost()); + m_contextObjects.add(object); } void WebGLRenderingContext::detachAndRemoveAllObjects() { - while (m_canvasObjects.size() > 0) { - HashSet<WebGLObject*>::iterator it = m_canvasObjects.begin(); + while (m_contextObjects.size() > 0) { + HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin(); (*it)->detachContext(); } } @@ -4344,7 +4419,7 @@ int WebGLRenderingContext::getBoundFramebufferHeight() return m_drawingBuffer ? m_drawingBuffer->size().height() : m_context->getInternalFramebufferSize().height(); } -WebGLTexture* WebGLRenderingContext::validateTextureBinding(GC3Denum target, bool useSixEnumsForCubeMap) +WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap) { WebGLTexture* tex = 0; switch (target) { @@ -4358,58 +4433,58 @@ WebGLTexture* WebGLRenderingContext::validateTextureBinding(GC3Denum target, boo case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: if (!useSixEnumsForCubeMap) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target"); return 0; } tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get(); break; case GraphicsContext3D::TEXTURE_CUBE_MAP: if (useSixEnumsForCubeMap) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target"); return 0; } tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get(); break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target"); return 0; } if (!tex) - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture"); return tex; } -bool WebGLRenderingContext::validateLocationLength(const String& string) +bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string) { const unsigned maxWebGLLocationLength = 256; if (string.length() > maxWebGLLocationLength) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "location length > 256"); return false; } return true; } -bool WebGLRenderingContext::validateSize(GC3Dint x, GC3Dint y) +bool WebGLRenderingContext::validateSize(const char* functionName, GC3Dint x, GC3Dint y) { if (x < 0 || y < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "size < 0"); return false; } return true; } -bool WebGLRenderingContext::validateString(const String& string) +bool WebGLRenderingContext::validateString(const char* functionName, const String& string) { for (size_t i = 0; i < string.length(); ++i) { if (!validateCharacter(string[i])) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "string not ASCII"); return false; } } return true; } -bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Denum type) +bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type) { switch (format) { case GraphicsContext3D::ALPHA: @@ -4419,7 +4494,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den case GraphicsContext3D::RGBA: break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format"); return false; } @@ -4432,10 +4507,10 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den case GraphicsContext3D::FLOAT: if (m_oesTextureFloat) break; - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); return false; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); return false; } @@ -4446,7 +4521,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den case GraphicsContext3D::LUMINANCE_ALPHA: if (type != GraphicsContext3D::UNSIGNED_BYTE && type != GraphicsContext3D::FLOAT) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format"); return false; } break; @@ -4454,7 +4529,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den if (type != GraphicsContext3D::UNSIGNED_BYTE && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5 && type != GraphicsContext3D::FLOAT) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format"); return false; } break; @@ -4463,7 +4538,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1 && type != GraphicsContext3D::FLOAT) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format"); return false; } break; @@ -4474,16 +4549,16 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den return true; } -bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level) +bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level) { if (level < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level < 0"); return false; } switch (target) { case GraphicsContext3D::TEXTURE_2D: if (level > m_maxTextureLevel) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range"); return false; } break; @@ -4494,7 +4569,7 @@ bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level) case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: if (level > m_maxCubeMapTextureLevel) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range"); return false; } break; @@ -4504,7 +4579,8 @@ bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level) return true; } -bool WebGLRenderingContext::validateTexFuncParameters(GC3Denum target, GC3Dint level, +bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName, + GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type) @@ -4512,18 +4588,18 @@ bool WebGLRenderingContext::validateTexFuncParameters(GC3Denum target, GC3Dint l // We absolutely have to validate the format and type combination. // The texImage2D entry points taking HTMLImage, etc. will produce // temporary data based on this combination, so it must be legal. - if (!validateTexFuncFormatAndType(format, type) || !validateTexFuncLevel(target, level)) + if (!validateTexFuncFormatAndType(functionName, format, type) || !validateTexFuncLevel(functionName, target, level)) return false; if (width < 0 || height < 0) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0"); return false; } switch (target) { case GraphicsContext3D::TEXTURE_2D: if (width > m_maxTextureSize || height > m_maxTextureSize) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range"); return false; } break; @@ -4534,42 +4610,43 @@ bool WebGLRenderingContext::validateTexFuncParameters(GC3Denum target, GC3Dint l case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: if (width != height || width > m_maxCubeMapTextureSize) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height or width or height out of range for cube map"); return false; } break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target"); return false; } if (format != internalformat) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat"); return false; } if (border) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0"); return false; } return true; } -bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei height, +bool WebGLRenderingContext::validateTexFuncData(const char* functionName, + GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels) { if (!pixels) return true; - if (!validateTexFuncFormatAndType(format, type)) + if (!validateTexFuncFormatAndType(functionName, format, type)) return false; switch (type) { case GraphicsContext3D::UNSIGNED_BYTE: if (!pixels->isUnsignedByteArray()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array"); return false; } break; @@ -4577,13 +4654,13 @@ bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei heigh case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: if (!pixels->isUnsignedShortArray()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array"); return false; } break; case GraphicsContext3D::FLOAT: // OES_texture_float if (!pixels->isFloatArray()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array"); return false; } break; @@ -4594,17 +4671,17 @@ bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei heigh unsigned int totalBytesRequired; GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0); if (error != GraphicsContext3D::NO_ERROR) { - m_context->synthesizeGLError(error); + synthesizeGLError(error, functionName, "invalid texture dimensions"); return false; } if (pixels->byteLength() < totalBytesRequired) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request"); return false; } return true; } -bool WebGLRenderingContext::validateDrawMode(GC3Denum mode) +bool WebGLRenderingContext::validateDrawMode(const char* functionName, GC3Denum mode) { switch (mode) { case GraphicsContext3D::POINTS: @@ -4616,21 +4693,21 @@ bool WebGLRenderingContext::validateDrawMode(GC3Denum mode) case GraphicsContext3D::TRIANGLES: return true; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid draw mode"); return false; } } -bool WebGLRenderingContext::validateStencilSettings() +bool WebGLRenderingContext::validateStencilSettings(const char* functionName) { if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "front and back stencils settings do not match"); return false; } return true; } -bool WebGLRenderingContext::validateStencilFunc(GC3Denum func) +bool WebGLRenderingContext::validateStencilFunc(const char* functionName, GC3Denum func) { switch (func) { case GraphicsContext3D::NEVER: @@ -4643,21 +4720,20 @@ bool WebGLRenderingContext::validateStencilFunc(GC3Denum func) case GraphicsContext3D::ALWAYS: return true; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid function"); return false; } } void WebGLRenderingContext::printWarningToConsole(const String& message) { - canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, - message, 0, canvas()->document()->url().string()); + canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message, canvas()->document()->url().string()); } -bool WebGLRenderingContext::validateFramebufferFuncParameters(GC3Denum target, GC3Denum attachment) +bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) { if (target != GraphicsContext3D::FRAMEBUFFER) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target"); return false; } switch (attachment) { @@ -4667,13 +4743,13 @@ bool WebGLRenderingContext::validateFramebufferFuncParameters(GC3Denum target, G case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment"); return false; } return true; } -bool WebGLRenderingContext::validateBlendEquation(GC3Denum mode) +bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode) { switch (mode) { case GraphicsContext3D::FUNC_ADD: @@ -4681,24 +4757,24 @@ bool WebGLRenderingContext::validateBlendEquation(GC3Denum mode) case GraphicsContext3D::FUNC_REVERSE_SUBTRACT: return true; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode"); return false; } } -bool WebGLRenderingContext::validateBlendFuncFactors(GC3Denum src, GC3Denum dst) +bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst) { if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR) && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA)) || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR) && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "incompatible src and dst"); return false; } return true; } -bool WebGLRenderingContext::validateCapability(GC3Denum cap) +bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap) { switch (cap) { case GraphicsContext3D::BLEND: @@ -4712,67 +4788,67 @@ bool WebGLRenderingContext::validateCapability(GC3Denum cap) case GraphicsContext3D::STENCIL_TEST: return true; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid capability"); return false; } } -bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize) +bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize) { if (!v) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array"); return false; } - return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize); + return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize); } -bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize) +bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize) { if (!v) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array"); return false; } - return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize); + return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize); } -bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize) +bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize) { - return validateUniformMatrixParameters(location, false, v, size, requiredMinSize); + return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize); } -bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize) +bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize) { if (!v) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array"); return false; } - return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize); + return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize); } -bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize) +bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize) { if (!location) return false; if (location->program() != m_currentProgram) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program"); return false; } if (!v) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array"); return false; } if (transpose) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "transpose not FALSE"); return false; } if (size < requiredMinSize || (size % requiredMinSize)) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size"); return false; } return true; } -WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target, GC3Denum usage) +WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage) { WebGLBuffer* buffer = 0; switch (target) { @@ -4783,11 +4859,11 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target buffer = m_boundArrayBuffer.get(); break; default: - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target"); return 0; } if (!buffer) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer"); return 0; } switch (usage) { @@ -4796,30 +4872,30 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target case GraphicsContext3D::DYNAMIC_DRAW: return buffer; } - m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid usage"); return 0; } -bool WebGLRenderingContext::validateHTMLImageElement(HTMLImageElement* image) +bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image) { if (!image || !image->cachedImage()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no image"); return false; } const KURL& url = image->cachedImage()->response().url(); if (url.isNull() || url.isEmpty() || !url.isValid()) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid image"); return false; } return true; } -void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3) +void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3) { if (isContextLost()) return; if (index >= m_maxVertexAttribs) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range"); return; } // In GL, we skip setting vertexAttrib0 values. @@ -4847,31 +4923,31 @@ void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expected attribValue.value[3] = v3; } -void WebGLRenderingContext::vertexAttribfvImpl(GC3Duint index, Float32Array* v, GC3Dsizei expectedSize) +void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize) { if (isContextLost()) return; if (!v) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array"); return; } - vertexAttribfvImpl(index, v->data(), v->length(), expectedSize); + vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize); } -void WebGLRenderingContext::vertexAttribfvImpl(GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize) +void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize) { if (isContextLost()) return; if (!v) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array"); return; } if (size < expectedSize) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size"); return; } if (index >= m_maxVertexAttribs) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range"); return; } // In GL, we skip setting vertexAttrib0 values. @@ -5030,7 +5106,7 @@ void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts); else // This likely shouldn't happen but is the best way to report it to the WebGL app. - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error restoring context"); return; } @@ -5083,6 +5159,40 @@ void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx) m_buffers[i].swap(m_buffers[i-1]); } +namespace { + + String GetErrorString(GC3Denum error) + { + switch (error) { + case GraphicsContext3D::INVALID_ENUM: + return "INVALID_ENUM"; + case GraphicsContext3D::INVALID_VALUE: + return "INVALID_VALUE"; + case GraphicsContext3D::INVALID_OPERATION: + return "INVALID_OPERATION"; + case GraphicsContext3D::OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + case GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION: + return "INVALID_FRAMEBUFFER_OPERATION"; + case GraphicsContext3D::CONTEXT_LOST_WEBGL: + return "CONTEXT_LOST_WEBGL"; + default: + return String::format("WebGL ERROR(%04x)", error); + } + } + +} // namespace anonymous + +void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functionName, const char* description) +{ + if (m_synthesizedErrorsToConsole) { + String str = String("WebGL: ") + GetErrorString(error) + ": " + String(functionName) + ": " + String(description); + printWarningToConsole(str); + } + m_context->synthesizeGLError(error); +} + + } // namespace WebCore #endif // ENABLE(WEBGL) |