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; |
} |