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

Unified Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 1387743002: Fixed expando-loss.html test. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cache ScriptState and use it to wrap m_defaultVertexArrayObject. Created 5 years, 2 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
Index: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index 81cd3abc1cd0eca2654cb88649430961c3f67a18..008269f639f4d8a5d6522757f29fa0276498b891 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -866,8 +866,9 @@ static const FormatType kSupportedFormatTypesES3[] = {
} // namespace anonymous
-WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, PassOwnPtr<WebGraphicsContext3D> context, const WebGLContextAttributes& requestedAttributes)
+WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, ScriptState* scriptState, PassOwnPtr<WebGraphicsContext3D> context, const WebGLContextAttributes& requestedAttributes)
: CanvasRenderingContext(passedCanvas)
+ , m_scriptState(scriptState)
, m_contextLostMode(NotLostContext)
, m_autoRecoveryMethod(Manual)
, m_dispatchContextLostEventTimer(this, &WebGLRenderingContextBase::dispatchContextLostEvent)
@@ -993,6 +994,12 @@ void WebGLRenderingContextBase::initializeNewContext()
m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectBase::VaoTypeDefault);
}
addContextObject(m_defaultVertexArrayObject.get());
+ // The default VAO is never exposed to JavaScript, but a wrapper is needed in order to link
+ // buffer objects' wrappers to it. The wrapper for the context itself might not have been
+ // created by this point.
+ toV8(this, m_scriptState->context()->Global(), m_scriptState->isolate());
+ toV8(m_defaultVertexArrayObject, m_scriptState->context()->Global(), m_scriptState->isolate());
haraken 2015/10/13 02:02:04 Just for the record: We don't need to enter the Sc
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 Actually, this code is called from a timer after t
+ preserveObjectWrapper(m_scriptState.get(), this, "defaultvao", 0, m_defaultVertexArrayObject);
m_boundVertexArrayObject = m_defaultVertexArrayObject;
m_vertexAttribValue.resize(m_maxVertexAttribs);
@@ -1364,7 +1371,7 @@ void WebGLRenderingContextBase::activeTexture(GLenum texture)
}
-void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader* shader)
+void WebGLRenderingContextBase::attachShader(ScriptState* scriptState, WebGLProgram* program, WebGLShader* shader)
{
if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
return;
@@ -1374,6 +1381,7 @@ void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader*
}
webContext()->attachShader(objectOrZero(program), objectOrZero(shader));
shader->onAttached();
+ preserveObjectWrapper(scriptState, program, "shader", shader->type(), shader);
}
void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name)
@@ -1437,7 +1445,7 @@ bool WebGLRenderingContextBase::validateAndUpdateBufferBindTarget(const char* fu
return true;
}
-void WebGLRenderingContextBase::bindBuffer(GLenum target, WebGLBuffer* buffer)
+void WebGLRenderingContextBase::bindBuffer(ScriptState* scriptState, GLenum target, WebGLBuffer* buffer)
{
bool deleted;
if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
@@ -1448,9 +1456,10 @@ void WebGLRenderingContextBase::bindBuffer(GLenum target, WebGLBuffer* buffer)
return;
webContext()->bindBuffer(target, objectOrZero(buffer));
+ preserveObjectWrapper(scriptState, this, "buffer", target, buffer);
}
-void WebGLRenderingContextBase::bindFramebuffer(GLenum target, WebGLFramebuffer* buffer)
+void WebGLRenderingContextBase::bindFramebuffer(ScriptState* scriptState, GLenum target, WebGLFramebuffer* buffer)
{
bool deleted;
if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
@@ -1465,9 +1474,11 @@ void WebGLRenderingContextBase::bindFramebuffer(GLenum target, WebGLFramebuffer*
}
setFramebuffer(target, buffer);
+ if (scriptState)
haraken 2015/10/13 02:02:04 It would be great if we could remove the null chec
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 There's no need to do this work if we're calling t
+ preserveObjectWrapper(scriptState, this, "framebuffer", 0, buffer);
}
-void WebGLRenderingContextBase::bindRenderbuffer(GLenum target, WebGLRenderbuffer* renderBuffer)
+void WebGLRenderingContextBase::bindRenderbuffer(ScriptState* scriptState, GLenum target, WebGLRenderbuffer* renderBuffer)
{
bool deleted;
if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
@@ -1480,11 +1491,12 @@ void WebGLRenderingContextBase::bindRenderbuffer(GLenum target, WebGLRenderbuffe
}
m_renderbufferBinding = renderBuffer;
webContext()->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ preserveObjectWrapper(scriptState, this, "renderbuffer", 0, renderBuffer);
if (renderBuffer)
renderBuffer->setHasEverBeenBound();
}
-void WebGLRenderingContextBase::bindTexture(GLenum target, WebGLTexture* texture)
+void WebGLRenderingContextBase::bindTexture(ScriptState* scriptState, GLenum target, WebGLTexture* texture)
{
bool deleted;
if (!checkObjectToBeBound("bindTexture", texture, deleted))
@@ -1495,23 +1507,34 @@ void WebGLRenderingContextBase::bindTexture(GLenum target, WebGLTexture* texture
synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
return;
}
+
+ const char* bindingPointName = nullptr;
if (target == GL_TEXTURE_2D) {
m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
if (!m_activeTextureUnit)
drawingBuffer()->setTexture2DBinding(objectOrZero(texture));
+ bindingPointName = "texture_2d";
} else if (target == GL_TEXTURE_CUBE_MAP) {
m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
+ bindingPointName = "texture_cube_map";
} else if (isWebGL2OrHigher() && target == GL_TEXTURE_2D_ARRAY) {
m_textureUnits[m_activeTextureUnit].m_texture2DArrayBinding = texture;
+ bindingPointName = "texture_2d_array";
} else if (isWebGL2OrHigher() && target == GL_TEXTURE_3D) {
m_textureUnits[m_activeTextureUnit].m_texture3DBinding = texture;
+ bindingPointName = "texture_3d";
} else {
synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
return;
}
webContext()->bindTexture(target, objectOrZero(texture));
+ // This is called both internally and externally (from JavaScript). We only update which wrapper
+ // is preserved when it's called from JavaScript.
+ if (scriptState) {
haraken 2015/10/13 02:02:04 Ditto.
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 Same answer.
+ preserveObjectWrapper(scriptState, this, bindingPointName, m_activeTextureUnit, texture);
+ }
if (texture) {
texture->setTarget(target, getMaxTextureLevelForTarget(target));
m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
@@ -1945,6 +1968,16 @@ WebGLRenderbuffer* WebGLRenderingContextBase::ensureEmulatedStencilBuffer(GLenum
return renderbuffer->emulatedStencilBuffer();
}
+void WebGLRenderingContextBase::setBoundVertexArrayObject(ScriptState* scriptState, WebGLVertexArrayObjectBase* arrayObject)
+{
+ if (arrayObject)
+ m_boundVertexArrayObject = arrayObject;
+ else
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+
+ preserveObjectWrapper(scriptState, this, "boundvao", 0, arrayObject);
+}
+
WebGLShader* WebGLRenderingContextBase::createShader(GLenum type)
{
if (isContextLost())
@@ -2101,7 +2134,7 @@ void WebGLRenderingContextBase::depthRange(GLfloat zNear, GLfloat zFar)
webContext()->depthRange(zNear, zFar);
}
-void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader* shader)
+void WebGLRenderingContextBase::detachShader(ScriptState* scriptState, WebGLProgram* program, WebGLShader* shader)
{
if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
return;
@@ -2111,6 +2144,7 @@ void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader*
}
webContext()->detachShader(objectOrZero(program), objectOrZero(shader));
shader->onDetached(webContext());
+ preserveObjectWrapper(scriptState, program, "shader", shader->type(), nullptr);
}
void WebGLRenderingContextBase::disable(GLenum cap)
@@ -2270,7 +2304,7 @@ void WebGLRenderingContextBase::flush()
webContext()->flush();
}
-void WebGLRenderingContextBase::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer* buffer)
+void WebGLRenderingContextBase::framebufferRenderbuffer(ScriptState* scriptState, GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer* buffer)
{
if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
return;
@@ -2318,9 +2352,10 @@ void WebGLRenderingContextBase::framebufferRenderbuffer(GLenum target, GLenum at
framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buffer);
}
applyStencilTest();
+ preserveObjectWrapper(scriptState, framebufferBinding, "renderbuffer", attachment, buffer);
}
-void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level)
+void WebGLRenderingContextBase::framebufferTexture2D(ScriptState* scriptState, GLenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level)
{
if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
return;
@@ -2360,6 +2395,7 @@ void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attac
}
framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, textarget, texture, level);
applyStencilTest();
+ preserveObjectWrapper(scriptState, framebufferBinding, "texture2d", attachment, texture);
}
void WebGLRenderingContextBase::frontFace(GLenum mode)
@@ -2564,6 +2600,7 @@ bool WebGLRenderingContextBase::extensionSupportedAndAllowed(const ExtensionTrac
ScriptValue WebGLRenderingContextBase::getExtension(ScriptState* scriptState, const String& name)
{
WebGLExtension* extension = nullptr;
+ bool linkContextToExtension = false;
if (!isContextLost()) {
for (size_t i = 0; i < m_extensions.size(); ++i) {
@@ -2571,15 +2608,27 @@ ScriptValue WebGLRenderingContextBase::getExtension(ScriptState* scriptState, co
if (tracker->matchesNameWithPrefixes(name)) {
if (extensionSupportedAndAllowed(tracker)) {
extension = tracker->getExtension(this);
- if (extension)
- m_extensionEnabled[extension->name()] = true;
+ if (extension) {
+ if (!m_extensionEnabled[extension->name()]) {
+ linkContextToExtension = true;
+ m_extensionEnabled[extension->name()] = true;
+ }
+ }
}
break;
}
}
}
- return ScriptValue(scriptState, toV8(extension, scriptState->context()->Global(), scriptState->isolate()));
+ v8::Local<v8::Value> wrappedExtension = toV8(extension, scriptState->context()->Global(), scriptState->isolate());
haraken 2015/10/13 02:02:04 toV8 does ScriptState-dependent operations, so we
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 This function is always called from JavaScript, so
+
+ if (linkContextToExtension) {
+ // Keep the extension's JavaScript wrapper alive as long as the context is alive, so that
+ // expando properties that are added to the extension persist.
+ preserveObjectWrapper(scriptState, this, "extension", static_cast<unsigned long>(extension->name()), extension);
+ }
+
+ return ScriptValue(scriptState, wrappedExtension);
}
ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter(ScriptState* scriptState, GLenum target, GLenum attachment, GLenum pname)
@@ -4857,7 +4906,7 @@ void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* loc
webContext()->uniformMatrix4fv(location->location(), v.size() >> 4, transpose, v.data());
}
-void WebGLRenderingContextBase::useProgram(WebGLProgram* program)
+void WebGLRenderingContextBase::useProgram(ScriptState* scriptState, WebGLProgram* program)
{
bool deleted;
if (!checkObjectToBeBound("useProgram", program, deleted))
@@ -4875,6 +4924,7 @@ void WebGLRenderingContextBase::useProgram(WebGLProgram* program)
webContext()->useProgram(objectOrZero(program));
if (program)
program->onAttached();
+ preserveObjectWrapper(scriptState, this, "program", 0, program);
}
}
@@ -4945,7 +4995,7 @@ void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, const Vector<GLflo
vertexAttribfvImpl("vertexAttrib4fv", index, v.data(), v.size(), 4);
}
-void WebGLRenderingContextBase::vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, long long offset)
+void WebGLRenderingContextBase::vertexAttribPointer(ScriptState* scriptState, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, long long offset)
{
if (isContextLost())
return;
@@ -4984,6 +5034,7 @@ void WebGLRenderingContextBase::vertexAttribPointer(GLuint index, GLint size, GL
m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GLintptr>(offset), m_boundArrayBuffer);
webContext()->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GLintptr>(offset));
+ preserveObjectWrapper(scriptState, m_boundVertexArrayObject, "arraybuffer", index, m_boundArrayBuffer);
}
void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
@@ -6646,12 +6697,12 @@ void WebGLRenderingContextBase::setFramebuffer(GLenum target, WebGLFramebuffer*
void WebGLRenderingContextBase::restoreCurrentFramebuffer()
{
- bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
+ bindFramebuffer(nullptr, GL_FRAMEBUFFER, m_framebufferBinding.get());
haraken 2015/10/13 02:02:04 I'm wondering why we can't use m_scriptState.
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 There's no need to update the references between t
}
void WebGLRenderingContextBase::restoreCurrentTexture2D()
{
- bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
+ bindTexture(nullptr, GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
haraken 2015/10/13 02:02:04 Ditto.
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 Same thing for the TEXTURE_2D binding on the activ
}
void WebGLRenderingContextBase::multisamplingChanged(bool enabled)
@@ -6676,6 +6727,33 @@ void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit()
m_onePlusMaxNonDefaultTextureUnit = 0;
}
+void WebGLRenderingContextBase::preserveObjectWrapper(ScriptState* scriptState, ScriptWrappable* sourceObject, const char* baseName, unsigned long index, ScriptWrappable* targetObject)
haraken 2015/10/13 02:02:04 Actually preserveObjectWrapper doesn't need to tak
Ken Russell (switch to Gerrit) 2015/10/13 06:11:43 Thanks for that hint. I'll change its signature.
+{
+ v8::Local<v8::Value> value;
+
+ StringBuilder builder;
haraken 2015/10/13 02:02:04 Add a TODO: This logic should be moved to V8Hidden
Ken Russell (switch to Gerrit) 2015/10/13 06:11:44 OK.
+ builder.append(baseName);
+ builder.appendNumber(static_cast<unsigned>(index));
+ CString name = builder.toString().utf8();
+ v8::Local<v8::String> jsName = v8::String::NewFromUtf8(
+ scriptState->isolate(),
+ name.data(),
+ v8::NewStringType::kNormal,
+ name.length()).ToLocalChecked();
+ if (targetObject) {
+ V8HiddenValue::setHiddenValue(
+ scriptState->isolate(),
+ sourceObject->newLocalWrapper(scriptState->isolate()),
+ jsName,
+ targetObject->newLocalWrapper(scriptState->isolate()));
+ } else {
+ V8HiddenValue::deleteHiddenValue(
+ scriptState->isolate(),
+ sourceObject->newLocalWrapper(scriptState->isolate()),
+ jsName);
+ }
+}
+
DEFINE_TRACE(WebGLRenderingContextBase::TextureUnitState)
{
visitor->trace(m_texture2DBinding);

Powered by Google App Engine
This is Rietveld 408576698