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

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

Issue 14217005: Limit the number of WebGL contexts that are active at any given time (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 8 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: Source/WebCore/html/canvas/WebGLRenderingContext.cpp
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 08fc484f861952d2f2de26a3bb5e576dc732186e..c95ef680bcac29cf367c24ed10d145526e30cc71 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -84,6 +84,69 @@ namespace WebCore {
const double secondsBetweenRestoreAttempts = 1.0;
const int maxGLErrorsAllowedToConsole = 256;
+const int maxGLActiveContexts = 16;
+
+Vector<WebGLRenderingContext*>& WebGLRenderingContext::activeContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, activeContexts, ());
+ return activeContexts;
+}
+
+Vector<WebGLRenderingContext*>& WebGLRenderingContext::inactiveContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, inactiveContexts, ());
+ return inactiveContexts;
+}
+
+void WebGLRenderingContext::forceLostOldestContext()
+{
+ if(activeContexts().size()) {
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 Add space between if and ( everywhere please.
+ WebGLRenderingContext* oldestActiveContext = activeContexts().first();
+ activeContexts().remove(0);
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 The implicit assumption here is that contexts' age
+
+ // This will call deactivateContext once the context has actually been lost
+ oldestActiveContext->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+ }
+}
+
+void WebGLRenderingContext::activateContext(WebGLRenderingContext* context)
+{
+ if(!activeContexts().contains(context))
+ activeContexts().append(context);
+
+ if(activeContexts().size() > maxGLActiveContexts)
+ forceLostOldestContext();
+}
+
+void WebGLRenderingContext::deactivateContext(WebGLRenderingContext* context, bool addToInactiveList)
+{
+ size_t position = activeContexts().find(context);
+ if(position != WTF::notFound)
+ activeContexts().remove(position);
+
+ if(addToInactiveList && !inactiveContexts().contains(context))
+ inactiveContexts().append(context);
+}
+
+void WebGLRenderingContext::removeContext(WebGLRenderingContext* context)
+{
+ size_t position = inactiveContexts().find(context);
+ if(position != WTF::notFound)
+ inactiveContexts().remove(position);
+
+ deactivateContext(context, false);
+
+ // Try to re-enable the oldest inactive contexts
+ while(activeContexts().size() < maxGLActiveContexts && inactiveContexts().size() > 0) {
+ WebGLRenderingContext* oldestInactiveContext = inactiveContexts().first();
+ inactiveContexts().remove(0);
+
+ if(oldestInactiveContext->m_restoreAllowed) {
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 If restoration isn't allowed, we lose track of old
+ oldestInactiveContext->forceRestoreContext();
+ activeContexts().append(oldestInactiveContext);
+ }
+ }
+}
namespace {
@@ -407,7 +470,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
return nullptr;
Settings* settings = frame->settings();
- // The FrameLoaderClient might creation of a new WebGL context despite the page settings; in
+ // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
// particular, if WebGL contexts were lost one or more times via the GL_ARB_robustness extension.
if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnabled())) {
canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL context."));
@@ -565,6 +628,8 @@ void WebGLRenderingContext::initializeNewContext()
m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this)));
+
+ activateContext(this);
}
void WebGLRenderingContext::setupFlags()
@@ -625,6 +690,8 @@ WebGLRenderingContext::~WebGLRenderingContext()
detachAndRemoveAllObjects();
destroyGraphicsContext3D();
m_contextGroup->removeContext(this);
+
+ removeContext(this);
}
void WebGLRenderingContext::destroyGraphicsContext3D()
@@ -4631,6 +4698,7 @@ void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMo
// Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
m_drawingBuffer->setTexture2DBinding(0);
m_drawingBuffer->setFramebufferBinding(0);
+ m_drawingBuffer->clear();
}
// There is no direct way to clear errors from a GL implementation and
@@ -5794,6 +5862,7 @@ void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext
RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "");
canvas()->dispatchEvent(event);
m_restoreAllowed = event->defaultPrevented();
+ deactivateContext(this, m_restoreAllowed);
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 This doesn't seem right. If a context receives a R
if (m_contextLostMode == RealLostContext && m_restoreAllowed)
m_restoreTimer.startOneShot(0);
}
@@ -5962,7 +6031,6 @@ void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functi
m_context->synthesizeGLError(error);
}
-
void WebGLRenderingContext::printGLWarningToConsole(const char* functionName, const char* description)
{
if (m_synthesizedErrorsToConsole) {

Powered by Google App Engine
This is Rietveld 408576698