Chromium Code Reviews| 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 a2bd44a75698135a0d48e9ce905cb3a2a639ccbe..6bc0984e7937d893d17741dd5c32e44adb22fa62 100644 |
| --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| @@ -66,7 +66,6 @@ |
| #include "modules/webgl/WebGLCompressedTexturePVRTC.h" |
| #include "modules/webgl/WebGLCompressedTextureS3TC.h" |
| #include "modules/webgl/WebGLContextAttributeHelpers.h" |
| -#include "modules/webgl/WebGLContextAttributes.h" |
| #include "modules/webgl/WebGLContextEvent.h" |
| #include "modules/webgl/WebGLContextGroup.h" |
| #include "modules/webgl/WebGLDebugRendererInfo.h" |
| @@ -79,19 +78,18 @@ |
| #include "modules/webgl/WebGLRenderbuffer.h" |
| #include "modules/webgl/WebGLShader.h" |
| #include "modules/webgl/WebGLShaderPrecisionFormat.h" |
| -#include "modules/webgl/WebGLTexture.h" |
| #include "modules/webgl/WebGLUniformLocation.h" |
| #include "modules/webgl/WebGLVertexArrayObject.h" |
| #include "modules/webgl/WebGLVertexArrayObjectOES.h" |
| #include "platform/CheckedInt.h" |
| #include "platform/RuntimeEnabledFeatures.h" |
| +#include "platform/ThreadSafeFunctional.h" |
| +#include "platform/WaitableEvent.h" |
| #include "platform/geometry/IntSize.h" |
| #include "platform/graphics/GraphicsContext.h" |
| #include "platform/graphics/UnacceleratedImageBufferSurface.h" |
| #include "platform/graphics/gpu/AcceleratedImageBufferSurface.h" |
| -#include "platform/graphics/gpu/DrawingBuffer.h" |
| #include "public/platform/Platform.h" |
| -#include "public/platform/WebGraphicsContext3DProvider.h" |
| #include "public/platform/functional/WebFunction.h" |
| #include "wtf/Functional.h" |
| #include "wtf/PassOwnPtr.h" |
| @@ -108,19 +106,24 @@ namespace { |
| const double secondsBetweenRestoreAttempts = 1.0; |
| const int maxGLErrorsAllowedToConsole = 256; |
| const unsigned maxGLActiveContexts = 16; |
| +const unsigned maxGLActiveContextsOnWorker = 4; |
| using WebGLRenderingContextBaseSet = PersistentHeapHashSet<WeakMember<WebGLRenderingContextBase>>; |
| WebGLRenderingContextBaseSet& activeContexts() |
| { |
| - DEFINE_STATIC_LOCAL(WebGLRenderingContextBaseSet, activeContexts, ()); |
| - return activeContexts; |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<WebGLRenderingContextBaseSet>, activeContexts, new ThreadSpecific<WebGLRenderingContextBaseSet>()); |
| + if (!activeContexts.isSet()) |
| + activeContexts->registerAsStaticReference(); |
| + return *activeContexts; |
| } |
| using WebGLRenderingContextBaseMap = PersistentHeapHashMap<WeakMember<WebGLRenderingContextBase>, int>; |
| WebGLRenderingContextBaseMap& forciblyEvictedContexts() |
| { |
| - DEFINE_STATIC_LOCAL(WebGLRenderingContextBaseMap, forciblyEvictedContexts, ()); |
| - return forciblyEvictedContexts; |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<WebGLRenderingContextBaseMap>, forciblyEvictedContexts, new ThreadSpecific<WebGLRenderingContextBaseMap>()); |
| + if (!forciblyEvictedContexts.isSet()) |
| + forciblyEvictedContexts->registerAsStaticReference(); |
| + return *forciblyEvictedContexts; |
| } |
| } // namespace |
| @@ -190,8 +193,13 @@ WebGLRenderingContextBase* WebGLRenderingContextBase::oldestEvictedContext() |
| void WebGLRenderingContextBase::activateContext(WebGLRenderingContextBase* context) |
| { |
| + unsigned maxGLContexts; |
|
sof
2016/05/07 07:21:42
Could you create a local method for this next to w
|
| + if (isMainThread()) |
| + maxGLContexts = maxGLActiveContexts; |
| + else |
| + maxGLContexts = maxGLActiveContextsOnWorker; |
| unsigned removedContexts = 0; |
| - while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) { |
| + while (activeContexts().size() >= maxGLContexts && removedContexts < maxGLContexts) { |
| forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost."); |
| removedContexts++; |
| } |
| @@ -223,8 +231,13 @@ void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* co |
| ASSERT(!forciblyEvictedContexts().contains(context)); |
| ASSERT(!activeContexts().contains(context)); |
| + unsigned maxGLContexts; |
| + if (isMainThread()) |
| + maxGLContexts = maxGLActiveContexts; |
| + else |
| + maxGLContexts = maxGLActiveContextsOnWorker; |
| // Try to re-enable the oldest inactive contexts. |
| - while (activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) { |
| + while (activeContexts().size() < maxGLContexts && forciblyEvictedContexts().size()) { |
| WebGLRenderingContextBase* evictedContext = oldestEvictedContext(); |
| if (!evictedContext->m_restoreAllowed) { |
| forciblyEvictedContexts().remove(evictedContext); |
| @@ -520,17 +533,38 @@ static String extractWebGLContextCreationError(const Platform::GraphicsInfo& inf |
| return statusMessage; |
| } |
| -static PassOwnPtr<WebGraphicsContext3DProvider> createWebGraphicsContext3DProviderInternal(HTMLCanvasElement* canvas, ScriptState* scriptState, WebGLContextAttributes attributes, unsigned webGLVersion) |
| +void WebGLRenderingContextBase::createContextProviderOnMainThread(WebGLRenderingContextBase::ContextProviderCreationInfo* creationInfo, WaitableEvent* waitableEvent) |
| +{ |
| + ASSERT(isMainThread()); |
| + Platform::GraphicsInfo glInfo = creationInfo->glInfo(); |
| + OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| + creationInfo->contextAttributes(), creationInfo->scriptState()->getExecutionContext()->url(), 0, &glInfo, Platform::DoNotBindToCurrentThread)); |
| + creationInfo->setContextProvider(provider.release()); |
| + waitableEvent->signal(); |
| +} |
| + |
| +PassOwnPtr<WebGraphicsContext3DProvider> WebGLRenderingContextBase::createContextProviderInternal(HTMLCanvasElement* canvas, ScriptState* scriptState, WebGLContextAttributes attributes, unsigned webGLVersion) |
| { |
| Platform::ContextAttributes contextAttributes = toPlatformContextAttributes(attributes, webGLVersion); |
| Platform::GraphicsInfo glInfo; |
| OwnPtr<WebGraphicsContext3DProvider> contextProvider; |
| if (canvas) { |
| contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| - contextAttributes, canvas->document().topDocument().url(), 0, &glInfo)); |
| + contextAttributes, canvas->document().topDocument().url(), 0, &glInfo, Platform::BindToCurrentThread)); |
| } else { |
| - contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| - contextAttributes, scriptState->getExecutionContext()->url(), 0, &glInfo)); |
| + if (isMainThread()) { |
| + contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| + contextAttributes, scriptState->getExecutionContext()->url(), 0, &glInfo, Platform::BindToCurrentThread)); |
| + } else { |
| + WaitableEvent waitableEvent; |
|
sof
2016/05/07 07:21:42
Could you abstract this out as createContextProvid
xidachen
2016/05/07 17:07:48
Yes, it is definitely a future work to make this a
|
| + WebTaskRunner* taskRunner = Platform::current()->mainThread()->getWebTaskRunner(); |
| + OwnPtr<WebGLRenderingContextBase::ContextProviderCreationInfo> creationInfo = adoptPtr(new WebGLRenderingContextBase::ContextProviderCreationInfo(contextAttributes, glInfo, scriptState)); |
| + taskRunner->postTask(BLINK_FROM_HERE, threadSafeBind(&createContextProviderOnMainThread, AllowCrossThreadAccess(creationInfo.get()), AllowCrossThreadAccess(&waitableEvent))); |
| + waitableEvent.wait(); |
| + contextProvider = creationInfo->releaseContextProvider(); |
| + if (!contextProvider->BindToCurrentThread()) |
| + return nullptr; |
| + } |
| } |
| if (!contextProvider || shouldFailContextCreationForTesting) { |
| shouldFailContextCreationForTesting = false; |
| @@ -544,7 +578,6 @@ static PassOwnPtr<WebGraphicsContext3DProvider> createWebGraphicsContext3DProvid |
| canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "OES_packed_depth_stencil support is required.")); |
| return nullptr; |
| } |
| - |
| return contextProvider.release(); |
| } |
| @@ -565,12 +598,12 @@ PassOwnPtr<WebGraphicsContext3DProvider> WebGLRenderingContextBase::createWebGra |
| return nullptr; |
| } |
| - return createWebGraphicsContext3DProviderInternal(canvas, nullptr, attributes, webGLVersion); |
| + return createContextProviderInternal(canvas, nullptr, attributes, webGLVersion); |
| } |
| PassOwnPtr<WebGraphicsContext3DProvider> WebGLRenderingContextBase::createWebGraphicsContext3DProvider(ScriptState* scriptState, WebGLContextAttributes attributes, unsigned webGLVersion) |
| { |
| - return createWebGraphicsContext3DProviderInternal(nullptr, scriptState, attributes, webGLVersion); |
| + return createContextProviderInternal(nullptr, scriptState, attributes, webGLVersion); |
| } |
| void WebGLRenderingContextBase::forceNextWebGLContextCreationToFail() |
| @@ -1084,6 +1117,11 @@ WebGLRenderingContextBase::~WebGLRenderingContextBase() |
| destroyContext(); |
| + if (activeContexts().contains(this)) |
| + activeContexts().remove(this); |
| + if (forciblyEvictedContexts().contains(this)) |
| + forciblyEvictedContexts().remove(this); |
| + |
| willDestroyContext(this); |
| } |
| @@ -5968,7 +6006,7 @@ void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB |
| Platform::ContextAttributes attributes = toPlatformContextAttributes(m_requestedAttributes, version()); |
| Platform::GraphicsInfo glInfo; |
| OwnPtr<WebGraphicsContext3DProvider> contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| - attributes, canvas()->document().topDocument().url(), 0, &glInfo)); |
| + attributes, canvas()->document().topDocument().url(), 0, &glInfo, Platform::BindToCurrentThread)); |
| RefPtr<DrawingBuffer> buffer; |
| if (contextProvider) { |
| // Construct a new drawing buffer with the new GL context. |