Title: [91112] trunk
Revision
91112
Author
[email protected]
Date
2011-07-15 14:22:45 -0700 (Fri, 15 Jul 2011)

Log Message

Don't restore WebGL context if it was guilty of a graphics reset
https://bugs.webkit.org/show_bug.cgi?id=64497

Reviewed by Stephen White.

Source/WebCore: 

Use getGraphicsResetStatusARB already defined in Extensions3D to
determine why the context was lost, and respond to guilty context
notifications by forbidding restoration of the context.

It isn't currently possible to write an automated test for this.
We might consider extending the WEBKIT_lose_context extension to
allow a reason to be provided why the context was lost. It was
tested manually in Chromium on Windows and Linux with some test
cases that provoke actual graphics card resets.

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired):
(WebCore::WebGLRenderingContext::forceLostContext):
(WebCore::WebGLRenderingContext::maybeRestoreContext):
* html/canvas/WebGLRenderingContext.h:

Source/WebKit/chromium: 

Actually implement getGraphicsResetStatusARB rather than inferring
the status based on whether the context has been lost.

* public/WebGraphicsContext3D.h:
(WebKit::WebGraphicsContext3D::getGraphicsResetStatusARB):
* src/Extensions3DChromium.cpp:
(WebCore::Extensions3DChromium::getGraphicsResetStatusARB):
* src/GraphicsContext3DChromium.cpp:
* src/GraphicsContext3DInternal.h:

LayoutTests: 

Updated expectations for context-lost test and added comment about
the order of event delivery. Per the specification of the
WEBKIT_lose_context extension, the previous expectations were wrong.

* fast/canvas/webgl/context-lost-expected.txt:
* fast/canvas/webgl/context-lost.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (91111 => 91112)


--- trunk/LayoutTests/ChangeLog	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/LayoutTests/ChangeLog	2011-07-15 21:22:45 UTC (rev 91112)
@@ -1,3 +1,17 @@
+2011-07-15  Kenneth Russell  <[email protected]>
+
+        Don't restore WebGL context if it was guilty of a graphics reset
+        https://bugs.webkit.org/show_bug.cgi?id=64497
+
+        Reviewed by Stephen White.
+
+        Updated expectations for context-lost test and added comment about
+        the order of event delivery. Per the specification of the
+        WEBKIT_lose_context extension, the previous expectations were wrong.
+
+        * fast/canvas/webgl/context-lost-expected.txt:
+        * fast/canvas/webgl/context-lost.html:
+
 2011-07-15  Adrienne Walker  <[email protected]>
 
         [chromium] Re-mark tests as failing as a result of r91069

Modified: trunk/LayoutTests/fast/canvas/webgl/context-lost-expected.txt (91111 => 91112)


--- trunk/LayoutTests/fast/canvas/webgl/context-lost-expected.txt	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost-expected.txt	2011-07-15 21:22:45 UTC (rev 91112)
@@ -15,8 +15,6 @@
 PASS gl.isTexture(texture) is true
 
 Lose context
-PASS extension.loseContext() was expected value: NO_ERROR.
-
 Test lost context
 PASS gl.isContextLost() is true
 PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
@@ -179,6 +177,9 @@
 PASS gl.isShader(shader) is false
 PASS gl.isTexture(texture) is false
 PASS gl.getError() is gl.NO_ERROR
+
+PASS extension.loseContext() was expected value: NO_ERROR.
+
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/canvas/webgl/context-lost.html (91111 => 91112)


--- trunk/LayoutTests/fast/canvas/webgl/context-lost.html	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost.html	2011-07-15 21:22:45 UTC (rev 91112)
@@ -59,6 +59,9 @@
 {
     debug("");
     debug("Lose context");
+
+    // Note: this will cause the context to be lost, and the
+    // webglcontextlost event listener to be called, immediately.
     shouldGenerateGLError(gl, gl.NO_ERROR, "extension.loseContext()");
     debug("");
 }
@@ -292,6 +295,8 @@
 
     shouldBe("gl.getError()", "gl.NO_ERROR");
 
+    debug("");
+
     finish();
 }
 

Modified: trunk/Source/WebCore/ChangeLog (91111 => 91112)


--- trunk/Source/WebCore/ChangeLog	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebCore/ChangeLog	2011-07-15 21:22:45 UTC (rev 91112)
@@ -1,3 +1,26 @@
+2011-07-15  Kenneth Russell  <[email protected]>
+
+        Don't restore WebGL context if it was guilty of a graphics reset
+        https://bugs.webkit.org/show_bug.cgi?id=64497
+
+        Reviewed by Stephen White.
+
+        Use getGraphicsResetStatusARB already defined in Extensions3D to
+        determine why the context was lost, and respond to guilty context
+        notifications by forbidding restoration of the context.
+
+        It isn't currently possible to write an automated test for this.
+        We might consider extending the WEBKIT_lose_context extension to
+        allow a reason to be provided why the context was lost. It was
+        tested manually in Chromium on Windows and Linux with some test
+        cases that provoke actual graphics card resets.
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired):
+        (WebCore::WebGLRenderingContext::forceLostContext):
+        (WebCore::WebGLRenderingContext::maybeRestoreContext):
+        * html/canvas/WebGLRenderingContext.h:
+
 2011-07-15  Chris Marrin  <[email protected]>
 
         Move TransformState to platform/graphics and give it the option to transform just a FloatQuad

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (91111 => 91112)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2011-07-15 21:22:45 UTC (rev 91112)
@@ -339,23 +339,7 @@
 
 void WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired()
 {
-    // Timer is started when m_contextLost is false.  It will first call
-    // onLostContext, which will set m_contextLost to true.  Then it will keep
-    // calling restoreContext and reschedule itself until m_contextLost is back
-    // to false.
-    if (!m_context->m_contextLost) {
-        m_context->onLostContext();
-        startOneShot(secondsBetweenRestoreAttempts);
-    } else {
-        // The rendering context is not restored if there is no handler for
-        // the context restored event.
-        if (!m_context->canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent))
-            return;
-
-        m_context->restoreContext();
-        if (m_context->m_contextLost)
-            startOneShot(secondsBetweenRestoreAttempts);
-    }
+    m_context->maybeRestoreContext();
 }
 
 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
@@ -3940,7 +3924,7 @@
         return;
     }
 
-    m_restoreTimer.startOneShot(0);
+    maybeRestoreContext();
 }
 
 void WebGLRenderingContext::onLostContext()
@@ -4794,6 +4778,63 @@
     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
 }
 
+void WebGLRenderingContext::maybeRestoreContext()
+{
+    // Timer is started when m_contextLost is false. It will first call
+    // onLostContext, which will set m_contextLost to true. Then it will keep
+    // calling restoreContext and reschedule itself until m_contextLost is back
+    // to false.
+    bool shouldStartTimer = false;
+    bool shouldAttemptRestoreNow = true;
+
+    if (!m_contextLost) {
+        onLostContext();
+        shouldStartTimer = true;
+        shouldAttemptRestoreNow = false;
+    }
+
+    // The rendering context is not restored if there is no handler for
+    // the context restored event.
+    if (!canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent))
+        return;
+
+    int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
+
+    switch (contextLostReason) {
+    case GraphicsContext3D::NO_ERROR:
+        // The GraphicsContext3D implementation might not fully
+        // support GL_ARB_robustness semantics yet. Alternatively, the
+        // WebGL WEBKIT_lose_context extension might have been used to
+        // force a lost context.
+        break;
+    case Extensions3D::GUILTY_CONTEXT_RESET_ARB:
+        // The rendering context is not restored if this context was
+        // guilty of causing the graphics reset.
+        printWarningToConsole("WARNING: WebGL content on the page caused the graphics card to reset; not restoring the context");
+        return;
+    case Extensions3D::INNOCENT_CONTEXT_RESET_ARB:
+        // Always allow the context to be restored.
+        break;
+    case Extensions3D::UNKNOWN_CONTEXT_RESET_ARB:
+        // Warn. Ideally, prompt the user telling them that WebGL
+        // content on the page might have caused the graphics card to
+        // reset and ask them whether they want to continue running
+        // the content. Only if they say "yes" should we start
+        // attempting to restore the context.
+        printWarningToConsole("WARNING: WebGL content on the page might have caused the graphics card to reset");
+        break;
+    }
+
+    if (shouldAttemptRestoreNow) {
+        restoreContext();
+        if (m_contextLost)
+            shouldStartTimer = true;
+    }
+
+    if (shouldStartTimer)
+        m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+}
+
 WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
     : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity]))
     , m_capacity(capacity)

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (91111 => 91112)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2011-07-15 21:22:45 UTC (rev 91112)
@@ -610,6 +610,9 @@
     bool simulateVertexAttrib0(GC3Dsizei numVertex);
     void restoreStatesAfterVertexAttrib0Simulation();
 
+    // Helper for restoration after context lost.
+    void maybeRestoreContext();
+
     friend class WebGLStateRestorer;
 };
 

Modified: trunk/Source/WebKit/chromium/ChangeLog (91111 => 91112)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-07-15 21:22:45 UTC (rev 91112)
@@ -1,3 +1,20 @@
+2011-07-15  Kenneth Russell  <[email protected]>
+
+        Don't restore WebGL context if it was guilty of a graphics reset
+        https://bugs.webkit.org/show_bug.cgi?id=64497
+
+        Reviewed by Stephen White.
+
+        Actually implement getGraphicsResetStatusARB rather than inferring
+        the status based on whether the context has been lost.
+
+        * public/WebGraphicsContext3D.h:
+        (WebKit::WebGraphicsContext3D::getGraphicsResetStatusARB):
+        * src/Extensions3DChromium.cpp:
+        (WebCore::Extensions3DChromium::getGraphicsResetStatusARB):
+        * src/GraphicsContext3DChromium.cpp:
+        * src/GraphicsContext3DInternal.h:
+
 2011-07-15  Dan Bernstein  <[email protected]>
 
         Chromium build fix.

Modified: trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h (91111 => 91112)


--- trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h	2011-07-15 21:22:45 UTC (rev 91112)
@@ -356,6 +356,12 @@
     virtual void deleteTexture(WebGLId) = 0;
 
     virtual void setContextLostCallback(WebGraphicsContextLostCallback* callback) {}
+    // GL_ARB_robustness
+    //
+    // This entry point must provide slightly different semantics than
+    // the GL_ARB_robustness extension; specifically, the lost context
+    // state is sticky, rather than reported only once.
+    virtual WGC3Denum getGraphicsResetStatusARB() { return 0; /* GL_NO_ERROR */ }
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/chromium/src/Extensions3DChromium.cpp (91111 => 91112)


--- trunk/Source/WebKit/chromium/src/Extensions3DChromium.cpp	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebKit/chromium/src/Extensions3DChromium.cpp	2011-07-15 21:22:45 UTC (rev 91112)
@@ -64,7 +64,7 @@
 
 int Extensions3DChromium::getGraphicsResetStatusARB()
 {
-    return m_internal->isContextLost() ? static_cast<int>(Extensions3D::UNKNOWN_CONTEXT_RESET_ARB) : static_cast<int>(GraphicsContext3D::NO_ERROR);
+    return static_cast<int>(m_internal->getGraphicsResetStatusARB());
 }
 
 void Extensions3DChromium::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter)

Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp (91111 => 91112)


--- trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp	2011-07-15 21:22:45 UTC (rev 91112)
@@ -840,6 +840,7 @@
 DELEGATE_TO_IMPL_1(setLatchCHROMIUM, GC3Duint)
 
 DELEGATE_TO_IMPL(rateLimitOffscreenContextCHROMIUM)
+DELEGATE_TO_IMPL_R(getGraphicsResetStatusARB, GC3Denum)
 
 //----------------------------------------------------------------------
 // GraphicsContext3D

Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DInternal.h (91111 => 91112)


--- trunk/Source/WebKit/chromium/src/GraphicsContext3DInternal.h	2011-07-15 21:17:23 UTC (rev 91111)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DInternal.h	2011-07-15 21:22:45 UTC (rev 91112)
@@ -292,6 +292,9 @@
     // GL_CHROMIUM_rate_limit_offscreen_context
     void rateLimitOffscreenContextCHROMIUM();
 
+    // GL_ARB_robustness
+    GC3Denum getGraphicsResetStatusARB();
+
 private:
     OwnPtr<WebKit::WebGraphicsContext3D> m_impl;
     OwnPtr<Extensions3DChromium> m_extensions;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to