Title: [91414] trunk
Revision
91414
Author
k...@google.com
Date
2011-07-20 16:13:32 -0700 (Wed, 20 Jul 2011)

Log Message

Add restoreContext() to WEBKIT_lose_context
https://bugs.webkit.org/show_bug.cgi?id=58626

Reviewed by James Robinson.

Source/WebCore: 

Added the restoreContext() entry point to the WEBKIT_lose_context
extension. Refactored and simplified the logic associated with context
loss and restoration.

A subsequent patch will make the delivery of the webglcontextrestored
event spec compliant.

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired):
(WebCore::WebGLRenderingContextLostCallback::WebGLRenderingContextLostCallback):
(WebCore::WebGLRenderingContextLostCallback::onContextLost):
(WebCore::WebGLRenderingContext::isContextLost):
(WebCore::WebGLRenderingContext::forceLostContext):
(WebCore::WebGLRenderingContext::forceRestoreContext):
(WebCore::WebGLRenderingContext::loseContext):
(WebCore::WebGLRenderingContext::maybeRestoreContext):
* html/canvas/WebGLRenderingContext.h:
(WebCore::WebGLRenderingContext::WebGLRenderingContextRestoreTimer::WebGLRenderingContextRestoreTimer):
* html/canvas/WebKitLoseContext.cpp:
(WebCore::WebKitLoseContext::loseContext):
(WebCore::WebKitLoseContext::restoreContext):
* html/canvas/WebKitLoseContext.h:
* html/canvas/WebKitLoseContext.idl:

LayoutTests: 

Used the new WEBKIT_lose_context restoreContext() entry point in
the associated layout test.

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

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (91413 => 91414)


--- trunk/LayoutTests/ChangeLog	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/LayoutTests/ChangeLog	2011-07-20 23:13:32 UTC (rev 91414)
@@ -1,3 +1,16 @@
+2011-07-20  Kenneth Russell  <k...@google.com>
+
+        Add restoreContext() to WEBKIT_lose_context
+        https://bugs.webkit.org/show_bug.cgi?id=58626
+
+        Reviewed by James Robinson.
+
+        Used the new WEBKIT_lose_context restoreContext() entry point in
+        the associated layout test.
+
+        * fast/canvas/webgl/context-lost-restored-expected.txt:
+        * fast/canvas/webgl/context-lost-restored.html:
+
 2011-07-19  Vsevolod Vlasov  <vse...@chromium.org>
 
         Web Inspector: Add support for disabling cache in web inspector.

Modified: trunk/LayoutTests/fast/canvas/webgl/context-lost-restored-expected.txt (91413 => 91414)


--- trunk/LayoutTests/fast/canvas/webgl/context-lost-restored-expected.txt	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost-restored-expected.txt	2011-07-20 23:13:32 UTC (rev 91414)
@@ -1,7 +1,8 @@
-Tests behavior under a restored context
+Tests behavior under a restored context.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
+Test losing a context and inability to restore it.
 Test valid context
 PASS gl.isContextLost() is false
 PASS gl.getError() is gl.NO_ERROR
@@ -13,6 +14,20 @@
 PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
 PASS gl.getError() is gl.NO_ERROR
 
+PASS extension.restoreContext() was expected value: INVALID_OPERATION.
+
+Test losing and restoring a context.
+Test valid context
+PASS gl.isContextLost() is false
+PASS gl.getError() is gl.NO_ERROR
+PASS shouldBe 255,10,20
+PASS gl.getError() is gl.NO_ERROR
+
+Test lost context
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
+PASS gl.getError() is gl.NO_ERROR
+
 Test restored context
 PASS gl.isContextLost() is false
 PASS gl.getError() is gl.NO_ERROR
@@ -25,6 +40,7 @@
 PASS gl.useProgram(program) was expected value: NO_ERROR.
 PASS gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0]) was expected value: NO_ERROR.
 
+
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/canvas/webgl/context-lost-restored.html (91413 => 91414)


--- trunk/LayoutTests/fast/canvas/webgl/context-lost-restored.html	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost-restored.html	2011-07-20 23:13:32 UTC (rev 91414)
@@ -22,26 +22,66 @@
         window.initNonKhronosFramework(true);
     }
 
-    description("Tests behavior under a restored context");
+    description("Tests behavior under a restored context.");
 
-    canvas = document.getElementById("canvas");
-    canvas.addEventListener("webglcontextlost", testLostContext);
-    canvas.addEventListener("webglcontextrestored", testRestoredContext);
+    shouldGenerateGLError = wtu.shouldGenerateGLError;
+    runTests();
+}
 
+function runTests()
+{
+    testLosingContext();
+    testLosingAndRestoringContext();
+
+    finish();
+}
+
+function setupTest()
+{
+    canvas = document.createElement("canvas");
+    canvas.width = 1;
+    canvas.height = 1;
     gl = wtu.create3DContext(canvas);
-    shouldGenerateGLError = wtu.shouldGenerateGLError;
-
     extension = gl.getExtension(extension_name);
     if (!extension) {
         debug(extension_name + " extension not found.");
-        finish();
-        return;
+        return false;
     }
+    return true;
+}
 
+function testLosingContext()
+{
+    if (!setupTest())
+        return;
+
+    debug("Test losing a context and inability to restore it.");
+
+    canvas.addEventListener("webglcontextlost", testLostContext);
+
     testOriginalContext();
     extension.loseContext();
+    // FIXME: this isn't yet spec compliant.
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()");
+    debug("");
 }
 
+function testLosingAndRestoringContext()
+{
+    if (!setupTest())
+        return;
+
+    debug("Test losing and restoring a context.");
+
+    canvas.addEventListener("webglcontextlost", testLostContext);
+    canvas.addEventListener("webglcontextrestored", testRestoredContext);
+
+    testOriginalContext();
+    extension.loseContext();
+    extension.restoreContext();
+    debug("");
+}
+
 function testRendering()
 {
     gl.clearColor(0, 0, 0, 255);
@@ -105,8 +145,6 @@
     // Validate new resources created in testRendering().
     testResources(gl.NO_ERROR);
     debug("");
-
-    finish();
 }
 
 function finish() {
@@ -125,6 +163,5 @@
 <body _onload_="init()">
 <div id="description"></div>
 <div id="console"></div>
-<canvas id="canvas" width="1px" height="1px"></canvas>
 </body>
 </html>

Modified: trunk/Source/WebCore/ChangeLog (91413 => 91414)


--- trunk/Source/WebCore/ChangeLog	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/Source/WebCore/ChangeLog	2011-07-20 23:13:32 UTC (rev 91414)
@@ -1,3 +1,34 @@
+2011-07-20  Kenneth Russell  <k...@google.com>
+
+        Add restoreContext() to WEBKIT_lose_context
+        https://bugs.webkit.org/show_bug.cgi?id=58626
+
+        Reviewed by James Robinson.
+
+        Added the restoreContext() entry point to the WEBKIT_lose_context
+        extension. Refactored and simplified the logic associated with context
+        loss and restoration.
+
+        A subsequent patch will make the delivery of the webglcontextrestored
+        event spec compliant.
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired):
+        (WebCore::WebGLRenderingContextLostCallback::WebGLRenderingContextLostCallback):
+        (WebCore::WebGLRenderingContextLostCallback::onContextLost):
+        (WebCore::WebGLRenderingContext::isContextLost):
+        (WebCore::WebGLRenderingContext::forceLostContext):
+        (WebCore::WebGLRenderingContext::forceRestoreContext):
+        (WebCore::WebGLRenderingContext::loseContext):
+        (WebCore::WebGLRenderingContext::maybeRestoreContext):
+        * html/canvas/WebGLRenderingContext.h:
+        (WebCore::WebGLRenderingContext::WebGLRenderingContextRestoreTimer::WebGLRenderingContextRestoreTimer):
+        * html/canvas/WebKitLoseContext.cpp:
+        (WebCore::WebKitLoseContext::loseContext):
+        (WebCore::WebKitLoseContext::restoreContext):
+        * html/canvas/WebKitLoseContext.h:
+        * html/canvas/WebKitLoseContext.idl:
+
 2011-07-20  Tony Chang  <t...@chromium.org>
 
         Pass -webkit-flex() values on to RenderStyle

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (91413 => 91414)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2011-07-20 23:13:32 UTC (rev 91414)
@@ -339,16 +339,16 @@
 
 void WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired()
 {
-    m_context->maybeRestoreContext();
+    m_context->maybeRestoreContext(RealLostContext);
 }
 
 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
 public:
-    WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_contextLostCallback(cb) {}
-    virtual void onContextLost() { m_contextLostCallback->forceLostContext(); }
+    explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
+    virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
     virtual ~WebGLRenderingContextLostCallback() {}
 private:
-    WebGLRenderingContext* m_contextLostCallback;
+    WebGLRenderingContext* m_context;
 };
 
 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
@@ -2677,14 +2677,6 @@
 
 bool WebGLRenderingContext::isContextLost()
 {
-    if (m_restoreTimer.isActive())
-        return true;
-
-    bool newContextLost = m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR;
-
-    if (newContextLost != m_contextLost)
-        m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
-
     return m_contextLost;
 }
 
@@ -3917,45 +3909,27 @@
     cleanupAfterGraphicsCall(false);
 }
 
-void WebGLRenderingContext::forceLostContext()
+void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
 {
     if (isContextLost()) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
 
-    maybeRestoreContext();
-}
+    loseContext();
 
-void WebGLRenderingContext::onLostContext()
-{
-    m_contextLost = true;
-
-    detachAndRemoveAllObjects();
-
-    // There is no direct way to clear errors from a GL implementation and
-    // looping until getError() becomes NO_ERROR might cause an infinite loop if
-    // the driver or context implementation had a bug.  So, loop a reasonably
-    // large number of times to clear any existing errors.
-    for (int i = 0; i < 100; ++i) {
-        if (m_context->getError() == GraphicsContext3D::NO_ERROR)
-            break;
-    }
-    m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
-
-    canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, ""));
+    if (mode == RealLostContext)
+        m_restoreTimer.startOneShot(0);
 }
 
-void WebGLRenderingContext::restoreContext()
+void WebGLRenderingContext::forceRestoreContext()
 {
-    RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, canvas()->document()->view()->root()->hostWindow()));
-    if (!context)
+    if (!isContextLost()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
+    }
 
-    m_context = context;
-    m_contextLost = false;
-    initializeNewContext();
-    canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
+    maybeRestoreContext(SyntheticLostContext);
 }
 
 void WebGLRenderingContext::removeObject(WebGLObject* object)
@@ -4778,25 +4752,41 @@
     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
 }
 
-void WebGLRenderingContext::maybeRestoreContext()
+void WebGLRenderingContext::loseContext()
 {
-    // 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;
+    m_contextLost = true;
 
+    detachAndRemoveAllObjects();
+
+    // There is no direct way to clear errors from a GL implementation and
+    // looping until getError() becomes NO_ERROR might cause an infinite loop if
+    // the driver or context implementation had a bug. So, loop a reasonably
+    // large number of times to clear any existing errors.
+    for (int i = 0; i < 100; ++i) {
+        if (m_context->getError() == GraphicsContext3D::NO_ERROR)
+            break;
+    }
+    m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
+
+    canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, ""));
+}
+
+void WebGLRenderingContext::maybeRestoreContext(WebGLRenderingContext::LostContextMode mode)
+{
     if (!m_contextLost) {
-        onLostContext();
-        shouldStartTimer = true;
-        shouldAttemptRestoreNow = false;
+        ASSERT(mode == SyntheticLostContext);
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return;
     }
 
-    // The rendering context is not restored if there is no handler for
-    // the context restored event.
-    if (!canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent))
+    // The rendering context is not restored if there is no handler for the
+    // context restored event. (FIXME: this is not spec compliant. A follow-on
+    // patch will bring this to spec compliance.)
+    if (!canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent)) {
+        if (mode == SyntheticLostContext)
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
+    }
 
     int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
 
@@ -4825,14 +4815,20 @@
         break;
     }
 
-    if (shouldAttemptRestoreNow) {
-        restoreContext();
-        if (m_contextLost)
-            shouldStartTimer = true;
+    RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, canvas()->document()->view()->root()->hostWindow()));
+    if (!context) {
+        if (mode == RealLostContext)
+            m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+        else
+            // This likely shouldn't happen but is the best way to report it to the WebGL app.
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return;
     }
 
-    if (shouldStartTimer)
-        m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+    m_context = context;
+    m_contextLost = false;
+    initializeNewContext();
+    canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
 }
 
 WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (91413 => 91414)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2011-07-20 23:13:32 UTC (rev 91414)
@@ -277,10 +277,17 @@
 
     void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
 
-    void forceLostContext();
-    void onLostContext();
-    void restoreContext();
+    // WEBKIT_lose_context support
+    enum LostContextMode {
+        // Lost context occurred at the graphics system level.
+        RealLostContext,
 
+        // Lost context provoked by WEBKIT_lose_context.
+        SyntheticLostContext
+    };
+    void forceLostContext(LostContextMode);
+    void forceRestoreContext();
+
     GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
 #if USE(ACCELERATED_COMPOSITING)
     virtual PlatformLayer* platformLayer() const { return m_context->platformLayer(); }
@@ -350,7 +357,7 @@
 
     class WebGLRenderingContextRestoreTimer : public TimerBase {
     public:
-        WebGLRenderingContextRestoreTimer(WebGLRenderingContext* context) : m_context(context) { }
+        explicit WebGLRenderingContextRestoreTimer(WebGLRenderingContext* context) : m_context(context) { }
     private:
         virtual void fired();
         WebGLRenderingContext* m_context;
@@ -610,8 +617,9 @@
     bool simulateVertexAttrib0(GC3Dsizei numVertex);
     void restoreStatesAfterVertexAttrib0Simulation();
 
+    void loseContext();
     // Helper for restoration after context lost.
-    void maybeRestoreContext();
+    void maybeRestoreContext(LostContextMode);
 
     friend class WebGLStateRestorer;
 };

Modified: trunk/Source/WebCore/html/canvas/WebKitLoseContext.cpp (91413 => 91414)


--- trunk/Source/WebCore/html/canvas/WebKitLoseContext.cpp	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/Source/WebCore/html/canvas/WebKitLoseContext.cpp	2011-07-20 23:13:32 UTC (rev 91414)
@@ -54,9 +54,14 @@
 
 void WebKitLoseContext::loseContext()
 {
-    m_context->forceLostContext();
+    m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
 }
 
+void WebKitLoseContext::restoreContext()
+{
+    m_context->forceRestoreContext();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBGL)

Modified: trunk/Source/WebCore/html/canvas/WebKitLoseContext.h (91413 => 91414)


--- trunk/Source/WebCore/html/canvas/WebKitLoseContext.h	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/Source/WebCore/html/canvas/WebKitLoseContext.h	2011-07-20 23:13:32 UTC (rev 91414)
@@ -41,6 +41,7 @@
     virtual ExtensionName getName() const;
 
     void loseContext();
+    void restoreContext();
 
 private:
     WebKitLoseContext(WebGLRenderingContext*);

Modified: trunk/Source/WebCore/html/canvas/WebKitLoseContext.idl (91413 => 91414)


--- trunk/Source/WebCore/html/canvas/WebKitLoseContext.idl	2011-07-20 23:03:08 UTC (rev 91413)
+++ trunk/Source/WebCore/html/canvas/WebKitLoseContext.idl	2011-07-20 23:13:32 UTC (rev 91414)
@@ -30,5 +30,6 @@
         OmitConstructor
     ] WebKitLoseContext {
         [StrictTypeChecking] void loseContext();
+        [StrictTypeChecking] void restoreContext();
     };
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to