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

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

Issue 1914233006: Implement offscreenCanvas.getContext('webgl') on a worker thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address kbr@'s comments, and limit maxGLActiveContexts=4 per worker thread Created 4 years, 7 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 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.

Powered by Google App Engine
This is Rietveld 408576698