Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(930)

Unified Diff: Source/core/html/canvas/WebGLRenderingContext.cpp

Issue 17230006: Implement WEBGL_shared_resources Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContext.h ('k') | Source/core/html/canvas/WebGLShader.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/canvas/WebGLRenderingContext.cpp
diff --git a/Source/core/html/canvas/WebGLRenderingContext.cpp b/Source/core/html/canvas/WebGLRenderingContext.cpp
index a65cf1b79f41705bd4f2f6afd709cc433a8a2903..248616dd80ee3ac8d083d8df51214cdd7eac9310 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);
@@ -1005,20 +1013,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;
@@ -1035,14 +1056,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();
@@ -1054,7 +1089,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;
@@ -1072,15 +1108,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;
@@ -1104,7 +1144,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;
@@ -1114,15 +1155,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;
@@ -1146,8 +1192,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
@@ -1288,14 +1338,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;
@@ -1313,7 +1369,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;
}
@@ -1371,7 +1427,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));
}
@@ -1397,7 +1453,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()) {
@@ -1425,7 +1481,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;
@@ -1458,7 +1514,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())) {
@@ -1470,7 +1526,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;
}
@@ -1487,7 +1543,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))
@@ -1509,7 +1565,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;
}
@@ -1597,12 +1653,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())
@@ -1614,7 +1685,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;
@@ -1624,7 +1695,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;
@@ -1636,14 +1707,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;
@@ -1653,12 +1724,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)
@@ -1699,8 +1770,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;
@@ -1740,35 +1823,88 @@ void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCo
m_context->disableVertexAttribArray(index);
}
-bool WebGLRenderingContext::validateRenderingState()
+bool WebGLRenderingContext::validateRenderingState(const char* functionName)
{
if (!m_currentProgram)
return false;
+ if (!isAcquiredForReading(functionName, m_currentProgram.get())) {
+ return false;
+ }
+
// Look in each enabled vertex attrib and check if they've been bound to a buffer.
for (unsigned i = 0; i < m_maxVertexAttribs; ++i) {
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
- if (state.enabled
- && (!state.bufferBinding || !state.bufferBinding->object()))
- return false;
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+ if (state.enabled) {
+ if (!state.bufferBinding || !state.bufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs enabled with no buffer bound");
+ return false;
+ }
+ if (!isAcquiredForReading(functionName, state.bufferBinding.get())) {
+ return false;
+ }
+ }
}
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);
@@ -1776,12 +1912,15 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c
if (!validateDrawArrays("drawArrays", mode, first, count))
return;
- clearIfComposited();
-
- handleTextureCompleteness("drawArrays", true);
- m_context->drawArrays(mode, first, count);
- handleTextureCompleteness("drawArrays", false);
- markContextChanged();
+ bool texturesReplaced;
+ if (handleTextureCompleteness("drawArrays", true, &texturesReplaced)) {
+ clearIfComposited();
+ m_context->drawArrays(mode, first, count);
+ markContextChanged();
+ }
+ if (texturesReplaced) {
+ handleTextureCompleteness("drawArrays", false, 0);
+ }
}
void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode& ec)
@@ -1791,12 +1930,15 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
if (!validateDrawElements("drawElements", mode, count, type, offset))
return;
- clearIfComposited();
-
- handleTextureCompleteness("drawElements", true);
- m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
- handleTextureCompleteness("drawElements", false);
- markContextChanged();
+ bool texturesReplaced;
+ if (handleTextureCompleteness("drawElements", true, &texturesReplaced)) {
+ clearIfComposited();
+ m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
+ markContextChanged();
+ }
+ if (texturesReplaced) {
+ handleTextureCompleteness("drawElements", false, 0);
+ }
}
void WebGLRenderingContext::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
@@ -1807,12 +1949,15 @@ void WebGLRenderingContext::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint firs
if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
return;
- clearIfComposited();
-
- handleTextureCompleteness("drawArraysInstancedANGLE", true);
- m_context->getExtensions()->drawArraysInstancedANGLE(mode, first, count, primcount);
- handleTextureCompleteness("drawArraysInstancedANGLE", false);
- markContextChanged();
+ bool texturesReplaced;
+ if (handleTextureCompleteness("drawArraysInstancedANGLE", true, &texturesReplaced)) {
+ clearIfComposited();
+ m_context->getExtensions()->drawArraysInstancedANGLE(mode, first, count, primcount);
+ markContextChanged();
+ }
+ if (texturesReplaced) {
+ handleTextureCompleteness("drawArraysInstancedANGLE", false, 0);
+ }
}
void WebGLRenderingContext::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
@@ -1823,12 +1968,15 @@ void WebGLRenderingContext::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei
if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
return;
- clearIfComposited();
-
- handleTextureCompleteness("drawElementsInstancedANGLE", true);
- m_context->getExtensions()->drawElementsInstancedANGLE(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
- handleTextureCompleteness("drawElementsInstancedANGLE", false);
- markContextChanged();
+ bool texturesReplaced;
+ if (handleTextureCompleteness("drawElementsInstancedANGLE", true, &texturesReplaced)) {
+ clearIfComposited();
+ m_context->getExtensions()->drawElementsInstancedANGLE(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
+ markContextChanged();
+ }
+ if (texturesReplaced) {
+ handleTextureCompleteness("drawElementsInstancedANGLE", false, 0);
+ }
}
void WebGLRenderingContext::enable(GC3Denum cap)
@@ -1886,8 +2034,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::ReadOnly, false, &hasBeenBoundSinceLastAcquire)) {
return;
}
// Don't allow the default framebuffer to be mutated; all current
@@ -1898,6 +2046,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) {
@@ -1929,8 +2080,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::ReadOnly, false, &hasBeenBoundSinceLastAcquire)) {
return;
}
// Don't allow the default framebuffer to be mutated; all current
@@ -1941,6 +2092,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);
@@ -1970,7 +2124,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()) {
@@ -2000,7 +2154,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))
@@ -2011,7 +2165,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))
@@ -2023,7 +2177,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[] = {
@@ -2040,7 +2194,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;
@@ -2048,7 +2202,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;
}
@@ -2060,8 +2214,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();
}
@@ -2070,6 +2225,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)
@@ -2438,7 +2597,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;
@@ -2449,7 +2608,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:
@@ -2466,7 +2625,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)));
}
@@ -2485,6 +2644,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:
@@ -2516,7 +2679,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) {
@@ -2539,7 +2702,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)));
}
@@ -2581,7 +2744,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());
}
@@ -2610,7 +2773,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;
@@ -2637,7 +2800,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");
@@ -2780,7 +2943,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;
@@ -2788,7 +2951,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;
}
@@ -2875,7 +3038,7 @@ GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
return m_context->isBuffer(buffer->object());
}
-bool WebGLRenderingContext::isContextLost()
+bool WebGLRenderingContext::isContextLost() const
{
return m_contextLost;
}
@@ -2948,7 +3111,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));
@@ -3041,7 +3204,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;
}
@@ -3094,6 +3257,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) {
@@ -3152,7 +3317,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))
@@ -3252,7 +3417,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));
@@ -3298,7 +3463,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;
@@ -3409,7 +3574,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) {
@@ -3451,7 +3616,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);
@@ -3470,7 +3635,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) {
@@ -3522,7 +3687,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;
@@ -3665,7 +3830,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform1f", location))
return;
if (location->program() != m_currentProgram) {
@@ -3679,7 +3844,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
+ if (!validateUniformParameters("uniform1fv", location, v, 1))
return;
m_context->uniform1fv(location->location(), v->length(), v->data());
@@ -3688,7 +3853,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("uniform1fv", location, v, size, 1))
+ if (!validateUniformParameters("uniform1fv", location, v, size, 1))
return;
m_context->uniform1fv(location->location(), size, v);
@@ -3697,7 +3862,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform1i", location))
return;
if (location->program() != m_currentProgram) {
@@ -3705,45 +3870,43 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3D
return;
}
+ m_currentProgram->conditionallyRecordTextureUnitsAssignedToSamplers(this, location->location(), 1, &x);
m_context->uniform1i(location->location(), x);
}
void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
+ if (!validateUniformParameters("uniform1iv", location, v, 1))
return;
+ m_currentProgram->conditionallyRecordTextureUnitsAssignedToSamplers(this, location->location(), v->length(), v->data());
m_context->uniform1iv(location->location(), v->length(), v->data());
}
void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
+ if (!validateUniformParameters("uniform1iv", location, v, size, 1))
return;
+ m_currentProgram->conditionallyRecordTextureUnitsAssignedToSamplers(this, location->location(), size, v);
m_context->uniform1iv(location->location(), size, v);
}
void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform2f", location))
return;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program");
- return;
- }
-
m_context->uniform2f(location->location(), x, y);
}
void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
+ if (!validateUniformParameters("uniform2fv", location, v, 2))
return;
m_context->uniform2fv(location->location(), v->length() / 2, v->data());
@@ -3752,7 +3915,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("uniform2fv", location, v, size, 2))
+ if (!validateUniformParameters("uniform2fv", location, v, size, 2))
return;
m_context->uniform2fv(location->location(), size / 2, v);
@@ -3761,13 +3924,8 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program");
+ if (!validateUniformParameters("uniform2i", location))
return;
- }
m_context->uniform2i(location->location(), x, y);
}
@@ -3775,7 +3933,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
+ if (!validateUniformParameters("uniform2iv", location, v, 2))
return;
m_context->uniform2iv(location->location(), v->length() / 2, v->data());
@@ -3784,7 +3942,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("uniform2iv", location, v, size, 2))
+ if (!validateUniformParameters("uniform2iv", location, v, size, 2))
return;
m_context->uniform2iv(location->location(), size / 2, v);
@@ -3793,21 +3951,16 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform3f", location))
return;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program");
- return;
- }
-
m_context->uniform3f(location->location(), x, y, z);
}
void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
+ if (!validateUniformParameters("uniform3fv", location, v, 3))
return;
m_context->uniform3fv(location->location(), v->length() / 3, v->data());
@@ -3816,7 +3969,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("uniform3fv", location, v, size, 3))
+ if (!validateUniformParameters("uniform3fv", location, v, size, 3))
return;
m_context->uniform3fv(location->location(), size / 3, v);
@@ -3825,21 +3978,16 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform3i", location))
return;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program");
- return;
- }
-
m_context->uniform3i(location->location(), x, y, z);
}
void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
+ if (!validateUniformParameters("uniform3iv", location, v, 3))
return;
m_context->uniform3iv(location->location(), v->length() / 3, v->data());
@@ -3848,7 +3996,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("uniform3iv", location, v, size, 3))
+ if (!validateUniformParameters("uniform3iv", location, v, size, 3))
return;
m_context->uniform3iv(location->location(), size / 3, v);
@@ -3857,21 +4005,16 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform4f", location))
return;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program");
- return;
- }
-
m_context->uniform4f(location->location(), x, y, z, w);
}
void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
+ if (!validateUniformParameters("uniform4fv", location, v, 4))
return;
m_context->uniform4fv(location->location(), v->length() / 4, v->data());
@@ -3880,7 +4023,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("uniform4fv", location, v, size, 4))
+ if (!validateUniformParameters("uniform4fv", location, v, size, 4))
return;
m_context->uniform4fv(location->location(), size / 4, v);
@@ -3889,21 +4032,16 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !location)
+ if (!validateUniformParameters("uniform4i", location))
return;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program");
- return;
- }
-
m_context->uniform4i(location->location(), x, y, z, w);
}
void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
+ if (!validateUniformParameters("uniform4iv", location, v, 4))
return;
m_context->uniform4iv(location->location(), v->length() / 4, v->data());
@@ -3912,7 +4050,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("uniform4iv", location, v, size, 4))
+ if (!validateUniformParameters("uniform4iv", location, v, size, 4))
return;
m_context->uniform4iv(location->location(), size / 4, v);
@@ -3921,7 +4059,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("uniformMatrix2fv", location, transpose, v, 4))
+ if (!validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
return;
m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
}
@@ -3929,7 +4067,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("uniformMatrix2fv", location, transpose, v, size, 4))
+ if (!validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
return;
m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
}
@@ -3937,7 +4075,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("uniformMatrix3fv", location, transpose, v, 9))
+ if (!validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
return;
m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
}
@@ -3945,7 +4083,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("uniformMatrix3fv", location, transpose, v, size, 9))
+ if (!validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
return;
m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
}
@@ -3953,7 +4091,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("uniformMatrix4fv", location, transpose, v, 16))
+ if (!validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
return;
m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
}
@@ -3961,7 +4099,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("uniformMatrix4fv", location, transpose, v, size, 16))
+ if (!validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
return;
m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
}
@@ -3970,11 +4108,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;
}
@@ -3986,12 +4125,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));
}
@@ -4096,6 +4238,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));
}
@@ -4333,43 +4478,72 @@ WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(GC3Denum pname)
return WebGLGetInfo(Int32Array::create(value, length));
}
-void WebGLRenderingContext::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
+bool WebGLRenderingContext::handleTextureCompleteness(const char* functionName, bool prepareToDraw, bool* texturesReplaced)
{
+ if (texturesReplaced) {
+ *texturesReplaced = false;
+ }
// All calling functions check isContextLost, so a duplicate check is not needed here.
bool resetActiveUnit = false;
WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
| (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
- for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
- if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
- || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
- if (ii != m_activeTextureUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = true;
- } else if (resetActiveUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = false;
+
+ const WebGLProgram::SamplerTextureUnitMap& samplerMap = m_currentProgram->samplerLocationTextureUnitMap();
+ for (WebGLProgram::SamplerTextureUnitMap::const_iterator it = samplerMap.begin(); it != samplerMap.end(); ++it) {
+ GC3Dint unit = it->value.unit;
+ GC3Denum type = it->value.type;
+ WebGLTexture* texture;
+ WebGLTexture* blackTexture;
+ GC3Denum target;
+ switch (it->value.type) {
+ case GraphicsContext3D::SAMPLER_2D:
+ target = GraphicsContext3D::TEXTURE_2D;
+ texture = m_textureUnits[unit].m_texture2DBinding.get();
+ blackTexture = m_blackTexture2D.get();
+ break;
+ case GraphicsContext3D::SAMPLER_CUBE:
+ target = GraphicsContext3D::TEXTURE_CUBE_MAP;
+ texture = m_textureUnits[unit].m_textureCubeMapBinding.get();
+ blackTexture = m_blackTextureCubeMap.get();
+ break;
+ default:
+ notImplemented();
+ }
+
+ if (!texture) {
+ continue;
+ }
+
+ if (prepareToDraw && !isAcquiredForReading(functionName, texture)) {
+ // We don't restore any state here but instead expect this function will be called
+ // again with prepareToDraw false which will restore any state we changed while
+ // prepareToDraw was true.
+ return false;
+ }
+
+ if (texture->needToUseBlackTexture(flag)) {
+ if (texturesReplaced) {
+ *texturesReplaced = true;
}
- WebGLTexture* tex2D;
- WebGLTexture* texCubeMap;
+ m_context->activeTexture(GraphicsContext3D::TEXTURE0 + unit);
+ resetActiveUnit = true;
+ WebGLTexture* tex;
if (prepareToDraw) {
- String msg(String("texture bound to texture unit ") + String::number(ii)
+ String msg(String("texture bound to texture unit ") + String::number(unit)
+ " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
+ " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
printGLWarningToConsole(functionName, msg.utf8().data());
- tex2D = m_blackTexture2D.get();
- texCubeMap = m_blackTextureCubeMap.get();
+ tex = blackTexture;
} else {
- tex2D = m_textureUnits[ii].m_texture2DBinding.get();
- texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
+ tex = texture;
}
- if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
- if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+ m_context->bindTexture(target, objectOrZero(tex));
}
}
if (resetActiveUnit)
- m_context->activeTexture(m_activeTextureUnit);
+ m_context->activeTexture(GraphicsContext3D::TEXTURE0 + m_activeTextureUnit);
+
+ return true;
}
void WebGLRenderingContext::createFallbackBlackTextures1x1()
@@ -4429,7 +4603,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) {
@@ -4461,6 +4635,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;
}
@@ -5039,7 +5228,25 @@ bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denu
}
}
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location)
+{
+ if (isContextLost() || !location) {
+ return false;
+ }
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
+ return false;
+ }
+
+ if (!isAcquiredForModification(functionName, m_currentProgram.get())) {
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
{
if (!v) {
synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
@@ -5048,7 +5255,7 @@ bool WebGLRenderingContext::validateUniformParameters(const char* functionName,
return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
}
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
{
if (!v) {
synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
@@ -5073,12 +5280,16 @@ bool WebGLRenderingContext::validateUniformMatrixParameters(const char* function
bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
{
- if (!location)
+ if (isContextLost() || !location)
return false;
if (location->program() != m_currentProgram) {
synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
return false;
}
+ if (!isAcquiredForModification(functionName, m_currentProgram.get())) {
+ return false;
+ }
+
if (!v) {
synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return false;
@@ -5094,7 +5305,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) {
@@ -5112,6 +5323,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:
@@ -5184,13 +5407,12 @@ bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GC3Denu
return false;
}
- if (!validateRenderingState()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
+ if (!validateRenderingState(functionName)) {
return false;
}
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;
}
@@ -5235,13 +5457,16 @@ bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3De
return false;
}
- if (!validateRenderingState()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
+ if (!isAcquiredForReading(functionName, m_boundVertexArrayObject->getElementArrayBuffer().get())) {
+ return false;
+ }
+
+ if (!validateRenderingState(functionName)) {
return false;
}
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;
}
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContext.h ('k') | Source/core/html/canvas/WebGLShader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698