| 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 70d454fe26280c8b1fb0f5a6742bb196a21fb48d..eade37630f9772559f0b98528c14a1f1366124e1 100644
|
| --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| @@ -1413,7 +1413,7 @@ void WebGLRenderingContextBase::attachShader(ScriptState* scriptState, WebGLProg
|
| }
|
| contextGL()->AttachShader(objectOrZero(program), objectOrZero(shader));
|
| shader->onAttached();
|
| - preserveObjectWrapper(scriptState, program, V8HiddenValue::webglShaders(scriptState->isolate()), program->getPersistentCache(), static_cast<uint32_t>(shader->type()), shader);
|
| + preserveObjectWrapper(scriptState, program, V8PrivateProperty::getWebGLProgramShaders(scriptState->isolate()), program->getPersistentCache(), static_cast<uint32_t>(shader->type()), shader);
|
| }
|
|
|
| void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name)
|
| @@ -1492,7 +1492,7 @@ void WebGLRenderingContextBase::bindBuffer(ScriptState* scriptState, GLenum targ
|
| break;
|
| }
|
|
|
| - preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(idx), buffer);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(idx), buffer);
|
| maybePreserveDefaultVAOObjectWrapper(scriptState);
|
| }
|
|
|
| @@ -1514,7 +1514,7 @@ void WebGLRenderingContextBase::bindFramebuffer(ScriptState* scriptState, GLenum
|
| // This is called both internally and externally (from JavaScript). We only update which wrapper
|
| // is preserved when it's called from JavaScript.
|
| if (scriptState) {
|
| - preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedFramebuffer), buffer);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedFramebuffer), buffer);
|
| }
|
| }
|
|
|
| @@ -1531,7 +1531,7 @@ void WebGLRenderingContextBase::bindRenderbuffer(ScriptState* scriptState, GLenu
|
| }
|
| m_renderbufferBinding = renderBuffer;
|
| contextGL()->BindRenderbuffer(target, objectOrZero(renderBuffer));
|
| - preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptState->isolate()), &m_miscWrappers, PreservedRenderbuffer, renderBuffer);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextMisc(scriptState->isolate()), &m_miscWrappers, PreservedRenderbuffer, renderBuffer);
|
|
|
| drawingBuffer()->setRenderbufferBinding(objectOrZero(renderBuffer));
|
|
|
| @@ -1554,7 +1554,7 @@ void WebGLRenderingContextBase::bindTexture(ScriptState* scriptState, GLenum tar
|
| // ScriptState may be null if this method is called internally
|
| // during restoration of texture unit bindings. Skip the
|
| // preserveObjectWrapper work in this case.
|
| - v8::Local<v8::String> hiddenValueName;
|
| + V8PrivateProperty::Symbol (*privateSymbolFn)(v8::Isolate* isolate) = nullptr;
|
| ScopedPersistent<v8::Array>* persistentCache = nullptr;
|
| if (target == GL_TEXTURE_2D) {
|
| m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
|
| @@ -1562,26 +1562,26 @@ void WebGLRenderingContextBase::bindTexture(ScriptState* scriptState, GLenum tar
|
| if (!m_activeTextureUnit)
|
| drawingBuffer()->setTexture2DBinding(objectOrZero(texture));
|
| if (scriptState) {
|
| - hiddenValueName = V8HiddenValue::webgl2DTextures(scriptState->isolate());
|
| persistentCache = &m_2DTextureWrappers;
|
| + privateSymbolFn = &V8PrivateProperty::getWebGLRenderingContextTextures2D;
|
| }
|
| } else if (target == GL_TEXTURE_CUBE_MAP) {
|
| m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
|
| if (scriptState) {
|
| - hiddenValueName = V8HiddenValue::webglCubeMapTextures(scriptState->isolate());
|
| persistentCache = &m_cubeMapTextureWrappers;
|
| + privateSymbolFn = &V8PrivateProperty::getWebGLRenderingContextTexturesCubeMap;
|
| }
|
| } else if (isWebGL2OrHigher() && target == GL_TEXTURE_2D_ARRAY) {
|
| m_textureUnits[m_activeTextureUnit].m_texture2DArrayBinding = texture;
|
| if (scriptState) {
|
| - hiddenValueName = V8HiddenValue::webgl2DArrayTextures(scriptState->isolate());
|
| persistentCache = &m_2DArrayTextureWrappers;
|
| + privateSymbolFn = &V8PrivateProperty::getWebGLRenderingContextTextures2DArray;
|
| }
|
| } else if (isWebGL2OrHigher() && target == GL_TEXTURE_3D) {
|
| m_textureUnits[m_activeTextureUnit].m_texture3DBinding = texture;
|
| if (scriptState) {
|
| - hiddenValueName = V8HiddenValue::webgl3DTextures(scriptState->isolate());
|
| persistentCache = &m_3DTextureWrappers;
|
| + privateSymbolFn = &V8PrivateProperty::getWebGLRenderingContextTextures3D;
|
| }
|
| } else {
|
| synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
|
| @@ -1592,7 +1592,7 @@ void WebGLRenderingContextBase::bindTexture(ScriptState* scriptState, GLenum tar
|
| // This is called both internally and externally (from JavaScript). We only update which wrapper
|
| // is preserved when it's called from JavaScript.
|
| if (scriptState) {
|
| - preserveObjectWrapper(scriptState, this, hiddenValueName, persistentCache, m_activeTextureUnit, texture);
|
| + preserveObjectWrapper(scriptState, this, privateSymbolFn(scriptState->isolate()), persistentCache, m_activeTextureUnit, texture);
|
| }
|
| if (texture) {
|
| texture->setTarget(target);
|
| @@ -1995,7 +1995,7 @@ void WebGLRenderingContextBase::setBoundVertexArrayObject(ScriptState* scriptSta
|
| else
|
| m_boundVertexArrayObject = m_defaultVertexArrayObject;
|
|
|
| - preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedVAO), arrayObject);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedVAO), arrayObject);
|
| }
|
|
|
| WebGLShader* WebGLRenderingContextBase::createShader(GLenum type)
|
| @@ -2156,7 +2156,7 @@ void WebGLRenderingContextBase::detachShader(ScriptState* scriptState, WebGLProg
|
| }
|
| contextGL()->DetachShader(objectOrZero(program), objectOrZero(shader));
|
| shader->onDetached(contextGL());
|
| - preserveObjectWrapper(scriptState, program, V8HiddenValue::webglShaders(scriptState->isolate()), program->getPersistentCache(), static_cast<uint32_t>(shader->type()), nullptr);
|
| + preserveObjectWrapper(scriptState, program, V8PrivateProperty::getWebGLProgramShaders(scriptState->isolate()), program->getPersistentCache(), static_cast<uint32_t>(shader->type()), nullptr);
|
| }
|
|
|
| void WebGLRenderingContextBase::disable(GLenum cap)
|
| @@ -2330,12 +2330,12 @@ void WebGLRenderingContextBase::framebufferRenderbuffer(ScriptState* scriptState
|
| contextGL()->FramebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
|
| framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_DEPTH_ATTACHMENT, buffer);
|
| framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_STENCIL_ATTACHMENT, buffer);
|
| - preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::webglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_DEPTH_ATTACHMENT, buffer);
|
| - preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::webglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_STENCIL_ATTACHMENT, buffer);
|
| + preserveObjectWrapper(scriptState, framebufferBinding, V8PrivateProperty::getWebGLFramebufferAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_DEPTH_ATTACHMENT, buffer);
|
| + preserveObjectWrapper(scriptState, framebufferBinding, V8PrivateProperty::getWebGLFramebufferAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_STENCIL_ATTACHMENT, buffer);
|
| } else {
|
| contextGL()->FramebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
|
| framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buffer);
|
| - preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::webglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), attachment, buffer);
|
| + preserveObjectWrapper(scriptState, framebufferBinding, V8PrivateProperty::getWebGLFramebufferAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), attachment, buffer);
|
| }
|
| applyStencilTest();
|
| }
|
| @@ -2364,12 +2364,12 @@ void WebGLRenderingContextBase::framebufferTexture2D(ScriptState* scriptState, G
|
| contextGL()->FramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
|
| framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_DEPTH_ATTACHMENT, textarget, texture, level, 0);
|
| framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_STENCIL_ATTACHMENT, textarget, texture, level, 0);
|
| - preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::webglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_DEPTH_ATTACHMENT, texture);
|
| - preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::webglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_STENCIL_ATTACHMENT, texture);
|
| + preserveObjectWrapper(scriptState, framebufferBinding, V8PrivateProperty::getWebGLFramebufferAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_DEPTH_ATTACHMENT, texture);
|
| + preserveObjectWrapper(scriptState, framebufferBinding, V8PrivateProperty::getWebGLFramebufferAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), GL_STENCIL_ATTACHMENT, texture);
|
| } else {
|
| contextGL()->FramebufferTexture2D(target, attachment, textarget, textureObject, level);
|
| framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, textarget, texture, level, 0);
|
| - preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::webglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), attachment, texture);
|
| + preserveObjectWrapper(scriptState, framebufferBinding, V8PrivateProperty::getWebGLFramebufferAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache(), attachment, texture);
|
| }
|
| applyStencilTest();
|
| }
|
| @@ -2600,7 +2600,7 @@ ScriptValue WebGLRenderingContextBase::getExtension(ScriptState* scriptState, co
|
| 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, V8HiddenValue::webglExtensions(scriptState->isolate()), &m_extensionWrappers, static_cast<uint32_t>(extension->name()), extension);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextExtensions(scriptState->isolate()), &m_extensionWrappers, static_cast<uint32_t>(extension->name()), extension);
|
| }
|
|
|
| return ScriptValue(scriptState, wrappedExtension);
|
| @@ -4925,7 +4925,7 @@ void WebGLRenderingContextBase::useProgram(ScriptState* scriptState, WebGLProgra
|
| contextGL()->UseProgram(objectOrZero(program));
|
| if (program)
|
| program->onAttached();
|
| - preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedProgram), program);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedProgram), program);
|
| }
|
| }
|
|
|
| @@ -5088,7 +5088,7 @@ void WebGLRenderingContextBase::vertexAttribPointer(ScriptState* scriptState, GL
|
| m_boundVertexArrayObject->setArrayBufferForAttrib(index, m_boundArrayBuffer.get());
|
| contextGL()->VertexAttribPointer(index, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
|
| maybePreserveDefaultVAOObjectWrapper(scriptState);
|
| - preserveObjectWrapper(scriptState, m_boundVertexArrayObject, V8HiddenValue::webglBuffers(scriptState->isolate()), m_boundVertexArrayObject->getPersistentCache(), index, m_boundArrayBuffer);
|
| + preserveObjectWrapper(scriptState, m_boundVertexArrayObject, V8PrivateProperty::getWebGLVertexArrayObjectBaseBuffers(scriptState->isolate()), m_boundVertexArrayObject->getPersistentCache(), index, m_boundArrayBuffer);
|
| }
|
|
|
| void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
|
| @@ -6324,31 +6324,52 @@ void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit()
|
| m_onePlusMaxNonDefaultTextureUnit = 0;
|
| }
|
|
|
| -void WebGLRenderingContextBase::preserveObjectWrapper(ScriptState* scriptState, ScriptWrappable* sourceObject, v8::Local<v8::String> hiddenValueName, ScopedPersistent<v8::Array>* persistentCache, uint32_t index, ScriptWrappable* targetObject)
|
| +void WebGLRenderingContextBase::preserveObjectWrapper(ScriptState* scriptState, ScriptWrappable* sourceObject, const V8PrivateProperty::Symbol& privateSymbol, ScopedPersistent<v8::Array>* persistentCache, uint32_t index, ScriptWrappable* targetObject)
|
| {
|
| v8::Isolate* isolate = scriptState->isolate();
|
| - if (persistentCache->isEmpty()) {
|
| - // TODO(kbr): eliminate the persistent caches and just use
|
| - // V8HiddenValue::getHiddenValue. Unfortunately, it's
|
| - // currently too slow to use. crbug.com/611864
|
| - persistentCache->set(isolate, v8::Array::New(isolate));
|
| - V8HiddenValue::setHiddenValue(
|
| - scriptState,
|
| - sourceObject->mainWorldWrapper(isolate),
|
| - hiddenValueName,
|
| - persistentCache->newLocal(isolate));
|
| - // It is important to mark the persistent cache as weak
|
| - // (phantom, actually). Otherwise there will be a reference
|
| - // cycle between it and its JavaScript wrapper, and currently
|
| - // there are problems collecting such cycles.
|
| - persistentCache->setPhantom();
|
| - }
|
| -
|
| - v8::Local<v8::Array> localCache = persistentCache->newLocal(isolate);
|
| - if (targetObject) {
|
| - v8CallOrCrash(localCache->Set(scriptState->context(), index, targetObject->mainWorldWrapper(isolate)));
|
| + v8::Local<v8::Context> context = scriptState->context();
|
| + if (scriptState->world().isMainWorld()) {
|
| + // This code path is very hot, especially for applications
|
| + // that make a lot of draw calls per frame, so it's crucial to
|
| + // optimize it as much as possible. The persistent caches are
|
| + // used in the main world because fetching from them is faster
|
| + // than calling V8PrivateProperty::Symbol::getOrUndefined.
|
| + v8::Local<v8::Array> localCache;
|
| + if (persistentCache->isEmpty()) {
|
| + localCache = v8::Array::New(isolate);
|
| + persistentCache->set(isolate, localCache);
|
| + privateSymbol.set(context, sourceObject->mainWorldWrapper(isolate), localCache);
|
| + // It is important to mark the persistent cache as weak
|
| + // (phantom, actually). Otherwise there will be a reference
|
| + // cycle between it and its JavaScript wrapper, and currently
|
| + // there are problems collecting such cycles.
|
| + persistentCache->setPhantom();
|
| + } else {
|
| + localCache = persistentCache->newLocal(isolate);
|
| + }
|
| + if (targetObject) {
|
| + v8CallOrCrash(localCache->Set(context, index, targetObject->mainWorldWrapper(isolate)));
|
| + } else {
|
| + v8CallOrCrash(localCache->Set(context, index, v8::Null(isolate)));
|
| + }
|
| } else {
|
| - v8CallOrCrash(localCache->Set(scriptState->context(), index, v8::Null(isolate)));
|
| + // Not in the main world; either a content script, or running
|
| + // in a worker. Ideally this would be made as efficient as the
|
| + // code path above.
|
| + v8::Local<v8::Object> sourceWrapper = v8::Local<v8::Object>::Cast(toV8(
|
| + sourceObject, context->Global(), isolate));
|
| + v8::Local<v8::Value> currentValue =
|
| + privateSymbol.getOrUndefined(context, sourceWrapper);
|
| + if (currentValue.IsEmpty() || !currentValue->IsArray()) {
|
| + currentValue = v8::Array::New(isolate);
|
| + privateSymbol.set(context, sourceWrapper, currentValue);
|
| + }
|
| + v8::Local<v8::Array> localCache = v8::Local<v8::Array>::Cast(currentValue);
|
| + if (targetObject) {
|
| + v8CallOrCrash(localCache->Set(context, index, toV8(targetObject, sourceWrapper, isolate)));
|
| + } else {
|
| + v8CallOrCrash(localCache->Set(context, index, v8::Null(isolate)));
|
| + }
|
| }
|
| }
|
|
|
| @@ -6360,7 +6381,7 @@ void WebGLRenderingContextBase::maybePreserveDefaultVAOObjectWrapper(ScriptState
|
| // The default VAO does not have a JavaScript wrapper created for it, but one is needed to
|
| // link up the WebGLBuffers associated with the vertex attributes.
|
| toV8(m_defaultVertexArrayObject, scriptState->context()->Global(), scriptState->isolate());
|
| - preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedDefaultVAO), m_defaultVertexArrayObject);
|
| + preserveObjectWrapper(scriptState, this, V8PrivateProperty::getWebGLRenderingContextMisc(scriptState->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedDefaultVAO), m_defaultVertexArrayObject);
|
| m_preservedDefaultVAOObjectWrapper = true;
|
| }
|
| }
|
|
|