| Index: Source/core/html/canvas/WebGLRenderingContext.cpp
|
| diff --git a/Source/core/html/canvas/WebGLRenderingContext.cpp b/Source/core/html/canvas/WebGLRenderingContext.cpp
|
| index f6071a6e5e5a61480e4ed9508e6a072dc4292705..e25e4b9dc8feb3af1bfef7244c4d77d4a3fc1286 100644
|
| --- a/Source/core/html/canvas/WebGLRenderingContext.cpp
|
| +++ b/Source/core/html/canvas/WebGLRenderingContext.cpp
|
| @@ -43,6 +43,7 @@
|
| #include "core/html/canvas/OESTextureHalfFloat.h"
|
| #include "core/html/canvas/OESTextureHalfFloatLinear.h"
|
| #include "core/html/canvas/OESVertexArrayObject.h"
|
| +#include "core/html/canvas/WebGLAcquireSharedResourceCallback.h"
|
| #include "core/html/canvas/WebGLActiveInfo.h"
|
| #include "core/html/canvas/WebGLBuffer.h"
|
| #include "core/html/canvas/WebGLCompressedTextureATC.h"
|
| @@ -61,6 +62,8 @@
|
| #include "core/html/canvas/WebGLRenderbuffer.h"
|
| #include "core/html/canvas/WebGLShader.h"
|
| #include "core/html/canvas/WebGLShaderPrecisionFormat.h"
|
| +#include "core/html/canvas/WebGLShareGroup.h"
|
| +#include "core/html/canvas/WebGLSharedResources.h"
|
| #include "core/html/canvas/WebGLTexture.h"
|
| #include "core/html/canvas/WebGLUniformLocation.h"
|
| #include "core/inspector/InspectorInstrumentation.h"
|
| @@ -524,7 +527,11 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
|
| if (extensions->supports("GL_EXT_debug_marker"))
|
| extensions->pushGroupMarkerEXT("WebGLRenderingContext");
|
|
|
| - OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes, requestedAttributes));
|
| + RefPtr<WebGLContextGroup> contextGroup(attrs->group()
|
| + ? attrs->group()->contextGroup()
|
| + : WebGLContextGroup::create());
|
| +
|
| + OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes, requestedAttributes, contextGroup));
|
| renderingContext->suspendIfNeeded();
|
|
|
| if (renderingContext->m_drawingBuffer->isZeroSized()) {
|
| @@ -535,10 +542,11 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
|
| return renderingContext.release();
|
| }
|
|
|
| -WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context, GraphicsContext3D::Attributes attributes, GraphicsContext3D::Attributes requestedAttributes)
|
| +WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context, GraphicsContext3D::Attributes attributes, GraphicsContext3D::Attributes requestedAttributes, PassRefPtr<WebGLContextGroup> contextGroup)
|
| : CanvasRenderingContext(passedCanvas)
|
| , ActiveDOMObject(passedCanvas->document())
|
| , m_context(context)
|
| + , m_contextGroup(contextGroup)
|
| , m_drawingBuffer(0)
|
| , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
|
| , m_restoreAllowed(false)
|
| @@ -556,7 +564,6 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
|
| ASSERT(m_context);
|
| ScriptWrappable::init(this);
|
|
|
| - m_contextGroup = WebGLContextGroup::create();
|
| m_contextGroup->addContext(this);
|
|
|
| m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
|
| @@ -597,6 +604,7 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
|
| registerExtension<ANGLEInstancedArrays>(m_angleInstancedArrays, false, true, false, unprefixed);
|
| registerExtension<EXTFragDepth>(m_extFragDepth, false, true, false, unprefixed);
|
| registerExtension<WebGLDrawBuffers>(m_webglDrawBuffers, false, true, false, unprefixed);
|
| + registerExtension<WebGLSharedResources>(m_webglSharedResources, false, true, false, unprefixed);
|
|
|
| // Register privileged extensions.
|
| registerExtension<WebGLDebugRendererInfo>(m_webglDebugRendererInfo, true, false, false, unprefixed);
|
| @@ -1002,20 +1010,33 @@ void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec)
|
| void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
|
| + bool boundSinceLastAcquire;
|
| + bool deleted;
|
| + if (isContextLost()
|
| + || !validateWebGLSharedObject("attachShader", program, WebGLSharedObject::Exclusive)
|
| + || !checkSharedObjectToBeBound("attachShader", shader, deleted, boundSinceLastAcquire)) {
|
| return;
|
| + }
|
| + if (deleted) {
|
| + shader = 0;
|
| + }
|
| if (!program->attachShader(shader)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader");
|
| return;
|
| }
|
| m_context->attachShader(objectOrZero(program), objectOrZero(shader));
|
| - shader->onAttached();
|
| + if (shader) {
|
| + shader->onAttached();
|
| + if (!boundSinceLastAcquire) {
|
| + shader->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| + }
|
| }
|
|
|
| void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("bindAttribLocation", program, WebGLSharedObject::Exclusive))
|
| return;
|
| if (!validateLocationLength("bindAttribLocation", name))
|
| return;
|
| @@ -1032,14 +1053,28 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint i
|
| m_context->bindAttribLocation(objectOrZero(program), index, name);
|
| }
|
|
|
| -bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
|
| +bool WebGLRenderingContext::checkContextObjectToBeBound(const char* functionName, WebGLContextObject* object, bool& deleted)
|
| {
|
| deleted = false;
|
| if (isContextLost())
|
| return false;
|
| if (object) {
|
| if (!object->validate(contextGroup(), this)) {
|
| - synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context");
|
| + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this share group");
|
| + return false;
|
| + }
|
| + deleted = !object->object();
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool WebGLRenderingContext::checkSharedObjectToBeBound(const char* functionName, WebGLSharedObject* object, bool& deleted, bool& boundSinceLastAcquire)
|
| +{
|
| + deleted = false;
|
| + if (isContextLost())
|
| + return false;
|
| + if (object) {
|
| + if (!object->validate(functionName, this, WebGLSharedObject::ReadOnly, false, &boundSinceLastAcquire)) {
|
| return false;
|
| }
|
| deleted = !object->object();
|
| @@ -1051,7 +1086,8 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc
|
| {
|
| UNUSED_PARAM(ec);
|
| bool deleted;
|
| - if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
|
| + bool boundSinceLastAcquire;
|
| + if (!checkSharedObjectToBeBound("bindBuffer", buffer, deleted, boundSinceLastAcquire))
|
| return;
|
| if (deleted)
|
| buffer = 0;
|
| @@ -1069,15 +1105,19 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc
|
| }
|
|
|
| m_context->bindBuffer(target, objectOrZero(buffer));
|
| - if (buffer)
|
| + if (buffer) {
|
| buffer->setTarget(target);
|
| + if (!boundSinceLastAcquire) {
|
| + buffer->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| + }
|
| }
|
|
|
| void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| bool deleted;
|
| - if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
|
| + if (!checkContextObjectToBeBound("bindFramebuffer", buffer, deleted))
|
| return;
|
| if (deleted)
|
| buffer = 0;
|
| @@ -1101,7 +1141,8 @@ void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*
|
| {
|
| UNUSED_PARAM(ec);
|
| bool deleted;
|
| - if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
|
| + bool boundSinceLastAcquire;
|
| + if (!checkSharedObjectToBeBound("bindRenderbuffer", renderBuffer, deleted, boundSinceLastAcquire))
|
| return;
|
| if (deleted)
|
| renderBuffer = 0;
|
| @@ -1111,15 +1152,20 @@ void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*
|
| }
|
| m_renderbufferBinding = renderBuffer;
|
| m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
|
| - if (renderBuffer)
|
| + if (renderBuffer) {
|
| renderBuffer->setHasEverBeenBound();
|
| + if (!boundSinceLastAcquire) {
|
| + renderBuffer->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| + }
|
| }
|
|
|
| void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| bool deleted;
|
| - if (!checkObjectToBeBound("bindTexture", texture, deleted))
|
| + bool boundSinceLastAcquire;
|
| + if (!checkSharedObjectToBeBound("bindTexture", texture, deleted, boundSinceLastAcquire))
|
| return;
|
| if (deleted)
|
| texture = 0;
|
| @@ -1143,8 +1189,12 @@ void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture,
|
| return;
|
| }
|
| m_context->bindTexture(target, objectOrZero(texture));
|
| - if (texture)
|
| + if (texture) {
|
| texture->setTarget(target, maxLevel);
|
| + if (!boundSinceLastAcquire) {
|
| + texture->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| + }
|
|
|
| // Note: previously we used to automatically set the TEXTURE_WRAP_R
|
| // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
|
| @@ -1285,14 +1335,20 @@ GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
|
| {
|
| if (isContextLost())
|
| return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
|
| - if (target != GraphicsContext3D::FRAMEBUFFER) {
|
| + switch (target) {
|
| + case GraphicsContext3D::FRAMEBUFFER:
|
| + case Extensions3D::READ_FRAMEBUFFER:
|
| + case Extensions3D::DRAW_FRAMEBUFFER:
|
| + break;
|
| + default:
|
| synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target");
|
| return 0;
|
| }
|
| if (!m_framebufferBinding || !m_framebufferBinding->object())
|
| return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
|
| const char* reason = "framebuffer incomplete";
|
| - GC3Denum result = m_framebufferBinding->checkStatus(&reason);
|
| + WebGLSharedObject::AcquireMode neededAccessMode = (target == Extensions3D::READ_FRAMEBUFFER) ? WebGLSharedObject::ReadOnly : WebGLSharedObject::Exclusive;
|
| + GC3Denum result = m_framebufferBinding->checkStatus(this, neededAccessMode, &reason);
|
| if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
|
| printGLWarningToConsole("checkFramebufferStatus", reason);
|
| return result;
|
| @@ -1310,7 +1366,7 @@ void WebGLRenderingContext::clear(GC3Dbitfield mask)
|
| return;
|
| }
|
| const char* reason = "framebuffer incomplete";
|
| - if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
|
| + if (m_framebufferBinding && !m_framebufferBinding->onAccess(this, WebGLSharedObject::Exclusive, &reason)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
|
| return;
|
| }
|
| @@ -1368,7 +1424,7 @@ void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dbo
|
| void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("compileShader", shader))
|
| + if (isContextLost() || !validateWebGLSharedObject("compileShader", shader, WebGLSharedObject::Exclusive))
|
| return;
|
| m_context->compileShader(objectOrZero(shader));
|
| }
|
| @@ -1394,7 +1450,7 @@ void WebGLRenderingContext::compressedTexImage2D(GC3Denum target, GC3Dint level,
|
| if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
|
| return;
|
|
|
| - WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
|
| + WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true, WebGLSharedObject::Exclusive);
|
| if (!tex)
|
| return;
|
| if (!isGLES2NPOTStrict()) {
|
| @@ -1422,7 +1478,7 @@ void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum target, GC3Dint lev
|
| if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
|
| return;
|
|
|
| - WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
|
| + WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true, WebGLSharedObject::Exclusive);
|
| if (!tex)
|
| return;
|
|
|
| @@ -1455,7 +1511,7 @@ void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3De
|
| return;
|
| if (!validateSettableTexFormat("copyTexImage2D", internalformat))
|
| return;
|
| - WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
|
| + WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true, WebGLSharedObject::Exclusive);
|
| if (!tex)
|
| return;
|
| if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
|
| @@ -1467,7 +1523,7 @@ void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3De
|
| return;
|
| }
|
| const char* reason = "framebuffer incomplete";
|
| - if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
|
| + if (m_framebufferBinding && !m_framebufferBinding->onAccess(this, WebGLSharedObject::ReadOnly, &reason)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
|
| return;
|
| }
|
| @@ -1484,7 +1540,7 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC
|
| return;
|
| if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
|
| return;
|
| - WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
|
| + WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true, WebGLSharedObject::Exclusive);
|
| if (!tex)
|
| return;
|
| if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
|
| @@ -1506,7 +1562,7 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC
|
| return;
|
| }
|
| const char* reason = "framebuffer incomplete";
|
| - if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
|
| + if (m_framebufferBinding && !m_framebufferBinding->onAccess(this, WebGLSharedObject::ReadOnly, &reason)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
|
| return;
|
| }
|
| @@ -1594,12 +1650,27 @@ void WebGLRenderingContext::cullFace(GC3Denum mode)
|
| m_context->cullFace(mode);
|
| }
|
|
|
| -bool WebGLRenderingContext::deleteObject(WebGLObject* object)
|
| +bool WebGLRenderingContext::deleteContextObject(const char* functionName, WebGLContextObject* object)
|
| {
|
| if (isContextLost() || !object)
|
| return false;
|
| if (!object->validate(contextGroup(), this)) {
|
| - synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context");
|
| + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this share group");
|
| + return false;
|
| + }
|
| + if (object->object()) {
|
| + // We need to pass in context here because we want
|
| + // things in this context unbound.
|
| + object->deleteObject(graphicsContext3D());
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool WebGLRenderingContext::deleteSharedObject(const char* functionName, WebGLSharedObject* object)
|
| +{
|
| + if (isContextLost() || !object)
|
| + return false;
|
| + if (!object->validate(functionName, this, WebGLSharedObject::Exclusive, true, 0)) {
|
| return false;
|
| }
|
| if (object->object())
|
| @@ -1611,7 +1682,7 @@ bool WebGLRenderingContext::deleteObject(WebGLObject* object)
|
|
|
| void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
|
| {
|
| - if (!deleteObject(buffer))
|
| + if (!deleteSharedObject("deleteBuffer", buffer))
|
| return;
|
| if (m_boundArrayBuffer == buffer)
|
| m_boundArrayBuffer = 0;
|
| @@ -1621,7 +1692,7 @@ void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
|
|
|
| void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
|
| {
|
| - if (!deleteObject(framebuffer))
|
| + if (!deleteContextObject("deleteFramebuffer", framebuffer))
|
| return;
|
| if (framebuffer == m_framebufferBinding) {
|
| m_framebufferBinding = 0;
|
| @@ -1633,14 +1704,14 @@ void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
|
|
|
| void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
|
| {
|
| - deleteObject(program);
|
| + deleteSharedObject("deleteProgram", program);
|
| // We don't reset m_currentProgram to 0 here because the deletion of the
|
| // current program is delayed.
|
| }
|
|
|
| void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
|
| {
|
| - if (!deleteObject(renderbuffer))
|
| + if (!deleteSharedObject("deleteRenderbuffer", renderbuffer))
|
| return;
|
| if (renderbuffer == m_renderbufferBinding)
|
| m_renderbufferBinding = 0;
|
| @@ -1650,12 +1721,12 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
|
|
|
| void WebGLRenderingContext::deleteShader(WebGLShader* shader)
|
| {
|
| - deleteObject(shader);
|
| + deleteSharedObject("deleteShader", shader);
|
| }
|
|
|
| void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
|
| {
|
| - if (!deleteObject(texture))
|
| + if (!deleteSharedObject("deleteTexture", texture))
|
| return;
|
| for (size_t i = 0; i < m_textureUnits.size(); ++i) {
|
| if (texture == m_textureUnits[i].m_texture2DBinding)
|
| @@ -1696,8 +1767,20 @@ void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
|
| void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
|
| + bool boundSinceLastAcquire;
|
| + bool deleted;
|
| + // NOTE: We explicitly don't check the shader has been bound since the only way to mark a shader as bound is to attach it which means
|
| + // there would be no way to detach a shader in context other than the one
|
| + // that attached it.
|
| + if (isContextLost()
|
| + || !validateWebGLSharedObject("detachShader", program, WebGLSharedObject::Exclusive)
|
| + || !checkSharedObjectToBeBound("detachShader", shader, deleted, boundSinceLastAcquire)) {
|
| return;
|
| + }
|
| + if (deleted) {
|
| + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader deleted");
|
| + return;
|
| + }
|
| if (!program->detachShader(shader)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached");
|
| return;
|
| @@ -1753,19 +1836,62 @@ bool WebGLRenderingContext::validateRenderingState()
|
| return true;
|
| }
|
|
|
| -bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
|
| +bool WebGLRenderingContext::isAcquiredForModification(const char* functionName, WebGLSharedObject* object)
|
| +{
|
| + return validateWebGLSharedObject(functionName, object, WebGLSharedObject::Exclusive);
|
| +}
|
| +
|
| +bool WebGLRenderingContext::isAcquiredForReading(const char* functionName, WebGLSharedObject* object)
|
| +{
|
| + return validateWebGLSharedObject(functionName, object, WebGLSharedObject::ReadOnly);
|
| +}
|
| +
|
| +bool WebGLRenderingContext::validateWebGLSharedObject(const char* functionName, WebGLSharedObject* object, WebGLSharedObject::AcquireMode acquireMode)
|
| {
|
| if (!object || !object->object()) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted");
|
| return false;
|
| }
|
| - if (!object->validate(contextGroup(), this)) {
|
| - synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context");
|
| + if (!object->validate(functionName, this, acquireMode, true, 0)) {
|
| return false;
|
| }
|
| return true;
|
| }
|
|
|
| +long WebGLRenderingContext::acquireSharedResource(WebGLSharedObject* object, WebGLSharedObject::AcquireMode desiredMode, PassRefPtr<WebGLAcquireSharedResourceCallback> callback, ExceptionCode& ec)
|
| +{
|
| + UNUSED_PARAM(ec);
|
| + if (!object) {
|
| + return 0;
|
| + }
|
| +
|
| + long id;
|
| + if (!object->addAcquireRequest(this, desiredMode, callback, id)) {
|
| + return 0;
|
| + }
|
| +
|
| + return id;
|
| +}
|
| +
|
| +void WebGLRenderingContext::releaseSharedResource(WebGLSharedObject* object, ExceptionCode& ec)
|
| +{
|
| + UNUSED_PARAM(ec);
|
| +
|
| + if (!object) {
|
| + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "releaseSharedResource", "no resource");
|
| + return;
|
| + }
|
| +
|
| + if (!object->release(this)) {
|
| + synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "releaseSharedResource", "resource not acquired");
|
| + }
|
| +}
|
| +
|
| +void WebGLRenderingContext::cancelAcquireSharedResource(long id)
|
| +{
|
| + m_contextGroup->cancelAcquireSharedResource(this, id);
|
| +}
|
| +
|
| void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| @@ -1883,8 +2009,8 @@ void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum at
|
| synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
|
| return;
|
| }
|
| - if (buffer && !buffer->validate(contextGroup(), this)) {
|
| - synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
|
| + bool hasBeenBoundSinceLastAcquire;
|
| + if (buffer && !buffer->validate("framebufferRenderbuffer", this, WebGLSharedObject::Exclusive, false, &hasBeenBoundSinceLastAcquire)) {
|
| return;
|
| }
|
| // Don't allow the default framebuffer to be mutated; all current
|
| @@ -1895,6 +2021,9 @@ void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum at
|
| return;
|
| }
|
| Platform3DObject bufferObject = objectOrZero(buffer);
|
| + if (buffer && !hasBeenBoundSinceLastAcquire) {
|
| + buffer->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| switch (attachment) {
|
| case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
|
| if (isDepthStencilSupported() || !buffer) {
|
| @@ -1926,8 +2055,8 @@ void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attac
|
| synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0");
|
| return;
|
| }
|
| - if (texture && !texture->validate(contextGroup(), this)) {
|
| - synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
|
| + bool hasBeenBoundSinceLastAcquire;
|
| + if (texture && !texture->validate("framebufferTexture2D", this, WebGLSharedObject::Exclusive, false, &hasBeenBoundSinceLastAcquire)) {
|
| return;
|
| }
|
| // Don't allow the default framebuffer to be mutated; all current
|
| @@ -1938,6 +2067,9 @@ void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attac
|
| return;
|
| }
|
| Platform3DObject textureObject = objectOrZero(texture);
|
| + if (texture && !hasBeenBoundSinceLastAcquire) {
|
| + texture->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| switch (attachment) {
|
| case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
|
| m_context->framebufferTexture2D(target, GraphicsContext3D::DEPTH_ATTACHMENT, textarget, textureObject, level);
|
| @@ -1967,7 +2099,7 @@ void WebGLRenderingContext::generateMipmap(GC3Denum target)
|
| {
|
| if (isContextLost())
|
| return;
|
| - WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
|
| + WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false, WebGLSharedObject::Exclusive);
|
| if (!tex)
|
| return;
|
| if (!tex->canGenerateMipmaps()) {
|
| @@ -1997,7 +2129,7 @@ void WebGLRenderingContext::generateMipmap(GC3Denum target)
|
| PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getActiveAttrib", program, WebGLSharedObject::ReadOnly))
|
| return 0;
|
| ActiveInfo info;
|
| if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
|
| @@ -2008,7 +2140,7 @@ PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram*
|
| PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getActiveUniform", program, WebGLSharedObject::ReadOnly))
|
| return 0;
|
| ActiveInfo info;
|
| if (!m_context->getActiveUniform(objectOrZero(program), index, info))
|
| @@ -2020,7 +2152,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Ref
|
| {
|
| UNUSED_PARAM(ec);
|
| shaderObjects.clear();
|
| - if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getAttachedShaders", program, WebGLSharedObject::ReadOnly))
|
| return false;
|
|
|
| const GC3Denum shaderType[] = {
|
| @@ -2037,7 +2169,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Ref
|
|
|
| GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
|
| {
|
| - if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getAttribLocation", program, WebGLSharedObject::ReadOnly))
|
| return -1;
|
| if (!validateLocationLength("getAttribLocation", name))
|
| return -1;
|
| @@ -2045,7 +2177,7 @@ GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const St
|
| return -1;
|
| if (isPrefixReserved(name))
|
| return -1;
|
| - if (!program->getLinkStatus()) {
|
| + if (!program->getLinkStatus(this)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getAttribLocation", "program not linked");
|
| return 0;
|
| }
|
| @@ -2057,8 +2189,9 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum
|
| UNUSED_PARAM(ec);
|
| if (isContextLost())
|
| return WebGLGetInfo();
|
| - if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
|
| - synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target");
|
| +
|
| + WebGLBuffer* buffer = getBufferForTarget("getBufferParameter", target);
|
| + if (!buffer) {
|
| return WebGLGetInfo();
|
| }
|
|
|
| @@ -2067,6 +2200,10 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum
|
| return WebGLGetInfo();
|
| }
|
|
|
| + if (!isAcquiredForReading("getBufferParameter", buffer)) {
|
| + return WebGLGetInfo();
|
| + }
|
| +
|
| GC3Dint value = 0;
|
| m_context->getBufferParameteriv(target, pname, &value);
|
| if (pname == GraphicsContext3D::BUFFER_SIZE)
|
| @@ -2435,7 +2572,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
|
| WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getProgramParameter", program, WebGLSharedObject::ReadOnly))
|
| return WebGLGetInfo();
|
|
|
| GC3Dint value = 0;
|
| @@ -2446,7 +2583,7 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, G
|
| m_context->getProgramiv(objectOrZero(program), pname, &value);
|
| return WebGLGetInfo(static_cast<bool>(value));
|
| case GraphicsContext3D::LINK_STATUS:
|
| - return WebGLGetInfo(program->getLinkStatus());
|
| + return WebGLGetInfo(program->getLinkStatus(this));
|
| case GraphicsContext3D::ATTACHED_SHADERS:
|
| case GraphicsContext3D::ACTIVE_ATTRIBUTES:
|
| case GraphicsContext3D::ACTIVE_UNIFORMS:
|
| @@ -2463,7 +2600,7 @@ String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, Exception
|
| UNUSED_PARAM(ec);
|
| if (isContextLost())
|
| return String();
|
| - if (!validateWebGLObject("getProgramInfoLog", program))
|
| + if (!validateWebGLSharedObject("getProgramInfoLog", program, WebGLSharedObject::ReadOnly))
|
| return "";
|
| return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
|
| }
|
| @@ -2482,6 +2619,10 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC
|
| return WebGLGetInfo();
|
| }
|
|
|
| + if (!isAcquiredForReading("getRenderbufferParameter", m_renderbufferBinding.get())) {
|
| + return WebGLGetInfo();
|
| + }
|
| +
|
| GC3Dint value = 0;
|
| switch (pname) {
|
| case GraphicsContext3D::RENDERBUFFER_WIDTH:
|
| @@ -2513,7 +2654,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC
|
| WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
|
| + if (isContextLost() || !validateWebGLSharedObject("getShaderParameter", shader, WebGLSharedObject::ReadOnly))
|
| return WebGLGetInfo();
|
| GC3Dint value = 0;
|
| switch (pname) {
|
| @@ -2536,7 +2677,7 @@ String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCod
|
| UNUSED_PARAM(ec);
|
| if (isContextLost())
|
| return String();
|
| - if (!validateWebGLObject("getShaderInfoLog", shader))
|
| + if (!validateWebGLSharedObject("getShaderInfoLog", shader, WebGLSharedObject::ReadOnly))
|
| return "";
|
| return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
|
| }
|
| @@ -2578,7 +2719,7 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode
|
| UNUSED_PARAM(ec);
|
| if (isContextLost())
|
| return String();
|
| - if (!validateWebGLObject("getShaderSource", shader))
|
| + if (!validateWebGLSharedObject("getShaderSource", shader, WebGLSharedObject::ReadOnly))
|
| return "";
|
| return ensureNotNull(shader->getSource());
|
| }
|
| @@ -2607,7 +2748,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn
|
| UNUSED_PARAM(ec);
|
| if (isContextLost())
|
| return WebGLGetInfo();
|
| - WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
|
| + WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false, WebGLSharedObject::ReadOnly);
|
| if (!tex)
|
| return WebGLGetInfo();
|
| GC3Dint value = 0;
|
| @@ -2634,7 +2775,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn
|
| WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("getUniform", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getUniform", program, WebGLSharedObject::ReadOnly))
|
| return WebGLGetInfo();
|
| if (!uniformLocation || uniformLocation->program() != program) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
|
| @@ -2777,7 +2918,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
|
| PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("getUniformLocation", program, WebGLSharedObject::ReadOnly))
|
| return 0;
|
| if (!validateLocationLength("getUniformLocation", name))
|
| return 0;
|
| @@ -2785,7 +2926,7 @@ PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGL
|
| return 0;
|
| if (isPrefixReserved(name))
|
| return 0;
|
| - if (!program->getLinkStatus()) {
|
| + if (!program->getLinkStatus(this)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniformLocation", "program not linked");
|
| return 0;
|
| }
|
| @@ -2872,7 +3013,7 @@ GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
|
| return m_context->isBuffer(buffer->object());
|
| }
|
|
|
| -bool WebGLRenderingContext::isContextLost()
|
| +bool WebGLRenderingContext::isContextLost() const
|
| {
|
| return m_contextLost;
|
| }
|
| @@ -2945,7 +3086,7 @@ void WebGLRenderingContext::lineWidth(GC3Dfloat width)
|
| void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("linkProgram", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("linkProgram", program, WebGLSharedObject::Exclusive))
|
| return;
|
|
|
| m_context->linkProgram(objectOrZero(program));
|
| @@ -3038,7 +3179,7 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC
|
| return;
|
| }
|
| const char* reason = "framebuffer incomplete";
|
| - if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
|
| + if (m_framebufferBinding && !m_framebufferBinding->onAccess(this, WebGLSharedObject::ReadOnly, &reason)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
|
| return;
|
| }
|
| @@ -3091,6 +3232,8 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
|
| return;
|
| }
|
| + if (!isAcquiredForModification("renderbufferStorage", m_renderbufferBinding.get()))
|
| + return;
|
| if (!validateSize("renderbufferStorage", width, height))
|
| return;
|
| switch (internalformat) {
|
| @@ -3149,7 +3292,7 @@ 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("shaderSource", shader))
|
| + if (isContextLost() || !validateWebGLSharedObject("shaderSource", shader, WebGLSharedObject::Exclusive))
|
| return;
|
| String stringWithoutComments = StripComments(string).result();
|
| if (!validateString("shaderSource", stringWithoutComments))
|
| @@ -3249,7 +3392,7 @@ void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3De
|
| // All calling functions check isContextLost, so a duplicate check is not needed here.
|
| // FIXME: For now we ignore any errors returned
|
| ec = 0;
|
| - WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
|
| + WebGLTexture* tex = validateTextureBinding("texImage2D", target, true, WebGLSharedObject::Exclusive);
|
| ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
|
| ASSERT(tex);
|
| ASSERT(!level || !WebGLTexture::isNPOT(width, height));
|
| @@ -3295,7 +3438,7 @@ bool WebGLRenderingContext::validateTexFunc(const char* functionName, TexFuncVal
|
| if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
|
| return false;
|
|
|
| - WebGLTexture* texture = validateTextureBinding(functionName, target, true);
|
| + WebGLTexture* texture = validateTextureBinding(functionName, target, true, WebGLSharedObject::Exclusive);
|
| if (!texture)
|
| return false;
|
|
|
| @@ -3406,7 +3549,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
|
| if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
|
| return;
|
|
|
| - WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
|
| + WebGLTexture* texture = validateTextureBinding("texImage2D", target, true, WebGLSharedObject::Exclusive);
|
| // If possible, copy from the canvas element directly to the texture
|
| // via the GPU, without a read-back to system memory.
|
| if (GraphicsContext3D::TEXTURE_2D == target && texture) {
|
| @@ -3448,7 +3591,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
|
|
|
| // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
|
| // Otherwise, it will fall back to the normal SW path.
|
| - WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
|
| + WebGLTexture* texture = validateTextureBinding("texImage2D", target, true, WebGLSharedObject::Exclusive);
|
| if (GraphicsContext3D::TEXTURE_2D == target && texture) {
|
| if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
|
| texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
|
| @@ -3467,7 +3610,7 @@ void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfl
|
| {
|
| if (isContextLost())
|
| return;
|
| - WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
|
| + WebGLTexture* tex = validateTextureBinding("texParameter", target, false, WebGLSharedObject::Exclusive);
|
| if (!tex)
|
| return;
|
| switch (pname) {
|
| @@ -3519,7 +3662,7 @@ void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC
|
| ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
|
| ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
|
| ASSERT(validateSettableTexFormat("texSubImage2D", format));
|
| - WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
|
| + WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true, WebGLSharedObject::Exclusive);
|
| if (!tex) {
|
| ASSERT_NOT_REACHED();
|
| return;
|
| @@ -3967,11 +4110,12 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| bool deleted;
|
| - if (!checkObjectToBeBound("useProgram", program, deleted))
|
| + bool boundSinceLastAcquire;
|
| + if (!checkSharedObjectToBeBound("useProgram", program, deleted, boundSinceLastAcquire))
|
| return;
|
| if (deleted)
|
| program = 0;
|
| - if (program && !program->getLinkStatus()) {
|
| + if (program && !program->getLinkStatus(this)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid");
|
| return;
|
| }
|
| @@ -3983,12 +4127,15 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
|
| if (program)
|
| program->onAttached();
|
| }
|
| + if (program && !boundSinceLastAcquire) {
|
| + program->markAsBoundSinceLastAcquireForContext(this);
|
| + }
|
| }
|
|
|
| void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
|
| {
|
| UNUSED_PARAM(ec);
|
| - if (isContextLost() || !validateWebGLObject("validateProgram", program))
|
| + if (isContextLost() || !validateWebGLSharedObject("validateProgram", program, WebGLSharedObject::ReadOnly))
|
| return;
|
| m_context->validateProgram(objectOrZero(program));
|
| }
|
| @@ -4093,6 +4240,9 @@ void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC
|
| }
|
| GC3Dsizei bytesPerElement = size * typeSize;
|
|
|
| + if (!isAcquiredForReading("vertexAttribPointer", m_boundArrayBuffer.get())) {
|
| + return;
|
| + }
|
| m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), m_boundArrayBuffer);
|
| m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
|
| }
|
| @@ -4426,7 +4576,7 @@ int WebGLRenderingContext::getBoundFramebufferHeight()
|
| return m_drawingBuffer->size().height();
|
| }
|
|
|
| -WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
|
| +WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap, WebGLSharedObject::AcquireMode mode)
|
| {
|
| WebGLTexture* tex = 0;
|
| switch (target) {
|
| @@ -4458,6 +4608,21 @@ WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* function
|
| }
|
| if (!tex)
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
|
| + switch (mode) {
|
| + case WebGLSharedObject::ReadOnly:
|
| + if (!isAcquiredForReading(functionName, tex)) {
|
| + return 0;
|
| + }
|
| + break;
|
| + case WebGLSharedObject::Exclusive:
|
| + if (!isAcquiredForModification(functionName, tex)) {
|
| + return 0;
|
| + }
|
| + break;
|
| + default:
|
| + notImplemented();
|
| + break;
|
| + }
|
| return tex;
|
| }
|
|
|
| @@ -5091,7 +5256,7 @@ bool WebGLRenderingContext::validateUniformMatrixParameters(const char* function
|
| return true;
|
| }
|
|
|
| -WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
|
| +WebGLBuffer* WebGLRenderingContext::getBufferForTarget(const char* functionName, GC3Denum target)
|
| {
|
| WebGLBuffer* buffer = 0;
|
| switch (target) {
|
| @@ -5109,6 +5274,18 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* fun
|
| synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer");
|
| return 0;
|
| }
|
| + return buffer;
|
| +}
|
| +
|
| +WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
|
| +{
|
| + WebGLBuffer* buffer = getBufferForTarget(functionName, target);
|
| + if (!buffer) {
|
| + return 0;
|
| + }
|
| +
|
| + if (!isAcquiredForModification(functionName, buffer))
|
| + return 0;
|
| switch (usage) {
|
| case GraphicsContext3D::STREAM_DRAW:
|
| case GraphicsContext3D::STATIC_DRAW:
|
| @@ -5187,7 +5364,7 @@ bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GC3Denu
|
| }
|
|
|
| const char* reason = "framebuffer incomplete";
|
| - if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
|
| + if (m_framebufferBinding && !m_framebufferBinding->onAccess(this, WebGLSharedObject::Exclusive, &reason)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
|
| return false;
|
| }
|
| @@ -5238,7 +5415,7 @@ bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3De
|
| }
|
|
|
| const char* reason = "framebuffer incomplete";
|
| - if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
|
| + if (m_framebufferBinding && !m_framebufferBinding->onAccess(this, WebGLSharedObject::Exclusive, &reason)) {
|
| synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
|
| return false;
|
| }
|
|
|