Title: [104102] trunk
Revision
104102
Author
[email protected]
Date
2012-01-04 17:12:52 -0800 (Wed, 04 Jan 2012)

Log Message

Fix semantics of WEBKIT_WEBGL_lose_context
https://bugs.webkit.org/show_bug.cgi?id=75053

Reviewed by James Robinson.

Source/WebCore:

Updated WEBGL_lose_context extension to match WebGL spec's
behavior:

  - loseContext() causes the context to be lost immediately, but
    the webglcontextlost event isn't dispatched until _javascript_
    returns.
  - restoreContext() may only be called once dispatch of the
    webglcontextlost event has completed, *and* if that event handler
    prevented the default behavior of the event.
  - restoreContext() performs its work asynchronously. The context
    is not restored until just before the webglcontextrestored event
    is dispatched.

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::WebGLRenderingContext):
(WebCore::WebGLRenderingContext::forceLostContext):
(WebCore::WebGLRenderingContext::forceRestoreContext):
(WebCore::WebGLRenderingContext::dispatchContextLostEvent):
(WebCore::WebGLRenderingContext::maybeRestoreContext):
* html/canvas/WebGLRenderingContext.h:

LayoutTests:

Updated context-lost and context-lost-restored tests to latest
versions in Khronos repository. Updated WebGLContextEvent.html to
match new semantics.

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

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (104101 => 104102)


--- trunk/LayoutTests/ChangeLog	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/ChangeLog	2012-01-05 01:12:52 UTC (rev 104102)
@@ -1,3 +1,21 @@
+2012-01-04  Kenneth Russell  <[email protected]>
+
+        Fix semantics of WEBKIT_WEBGL_lose_context
+        https://bugs.webkit.org/show_bug.cgi?id=75053
+
+        Reviewed by James Robinson.
+
+        Updated context-lost and context-lost-restored tests to latest
+        versions in Khronos repository. Updated WebGLContextEvent.html to
+        match new semantics.
+
+        * fast/canvas/webgl/WebGLContextEvent-expected.txt:
+        * fast/canvas/webgl/WebGLContextEvent.html:
+        * fast/canvas/webgl/context-lost-expected.txt:
+        * fast/canvas/webgl/context-lost-restored-expected.txt:
+        * fast/canvas/webgl/context-lost-restored.html:
+        * fast/canvas/webgl/context-lost.html:
+
 2012-01-04  Ojan Vafai  <[email protected]>
 
         Remove a line for a test that no longer fails on the bots.

Modified: trunk/LayoutTests/fast/canvas/webgl/WebGLContextEvent-expected.txt (104101 => 104102)


--- trunk/LayoutTests/fast/canvas/webgl/WebGLContextEvent-expected.txt	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/fast/canvas/webgl/WebGLContextEvent-expected.txt	2012-01-05 01:12:52 UTC (rev 104102)
@@ -1,8 +1,11 @@
 Test that the event passed to a listener of webglcontextlost is a WebGLContextEvent.
 PASS evt.toString() is '[object WebGLContextEvent]'
 PASS evt.statusMessage is ''
+PASS context.getError() is context.NO_ERROR
 Test that the event passed to a listener of webglcontextrestored is a WebGLContextEvent.
 PASS evt.toString() is '[object WebGLContextEvent]'
 PASS evt.statusMessage is ''
-PASS extension.restoreContext() was expected value: NO_ERROR.
+PASS successfullyParsed is true
 
+TEST COMPLETE
+

Modified: trunk/LayoutTests/fast/canvas/webgl/WebGLContextEvent.html (104101 => 104102)


--- trunk/LayoutTests/fast/canvas/webgl/WebGLContextEvent.html	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/fast/canvas/webgl/WebGLContextEvent.html	2012-01-05 01:12:52 UTC (rev 104102)
@@ -24,32 +24,46 @@
     }
 }
 
-function runTest()
+function runTest1()
 {
+    if (window.initNonKhronosFramework)
+        window.initNonKhronosFramework(true);
     createNewCanvas();
     canvas.addEventListener("webglcontextlost", function(e) {
         evt = e;
         debug("Test that the event passed to a listener of webglcontextlost is a WebGLContextEvent.")
         shouldBe("evt.toString()", "'[object WebGLContextEvent]'");
         shouldBe("evt.statusMessage", "''");
+        // Start the next test when event dispatch has finished.
+        setTimeout(function() {
+          runTest2();
+        }, 0);
     }, false);
     extension.loseContext();
+}
 
-
+function runTest2()
+{
     createNewCanvas();
     canvas.addEventListener("webglcontextlost", function(e) {
         e.preventDefault();
+        // Restore the context after event dispatch has finished.
+        setTimeout(function() {
+          // Because context restoration is specified as being asynchronous, we can not verify
+          // that the GL error state is empty here.
+          extension.restoreContext();
+        }, 0);
     }, false);
     canvas.addEventListener("webglcontextrestored", function(e) {
         evt = e;
+        shouldBe("context.getError()", "context.NO_ERROR");
         debug("Test that the event passed to a listener of webglcontextrestored is a WebGLContextEvent.")
         shouldBe("evt.toString()", "'[object WebGLContextEvent]'");
         shouldBe("evt.statusMessage", "''");
+
+        setTimeout(finish, 0);
     }, false);
     extension.loseContext();
-    WebGLTestUtils.shouldGenerateGLError(context, context.NO_ERROR, "extension.restoreContext()");
-
-    finish();
 }
 
 function finish() {
@@ -65,7 +79,7 @@
 </script>
 
 </head>
-<body _onload_="runTest()">
+<body _onload_="runTest1()">
 <div id="description"></div>
 <div id="console"></div>
 <canvas id="canvas">

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


--- trunk/LayoutTests/fast/canvas/webgl/context-lost-expected.txt	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost-expected.txt	2012-01-05 01:12:52 UTC (rev 104102)
@@ -15,6 +15,7 @@
 PASS gl.isTexture(texture) is true
 
 Lose context
+
 Test lost context
 PASS gl.isContextLost() is true
 PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
@@ -178,8 +179,6 @@
 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-restored-expected.txt (104101 => 104102)


--- trunk/LayoutTests/fast/canvas/webgl/context-lost-restored-expected.txt	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost-restored-expected.txt	2012-01-05 01:12:52 UTC (rev 104102)
@@ -9,10 +9,15 @@
 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
+PASS gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP) was expected value: NO_ERROR.
+PASS contextLostEventFired is false
+Test lost context
+PASS contextLostEventFired is false
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.NO_ERROR
 
 PASS extension.restoreContext() was expected value: INVALID_OPERATION.
 
@@ -23,12 +28,22 @@
 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
+PASS gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP) was expected value: NO_ERROR.
+PASS contextLostEventFired is false
+Test lost context
+PASS contextLostEventFired is false
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.NO_ERROR
 
+PASS extension.restoreContext() was expected value: NO_ERROR.
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP) was expected value: NO_ERROR.
 Test restored context
+PASS contextRestoredEventFired is false
 PASS gl.isContextLost() is false
 PASS gl.getError() is gl.NO_ERROR
 PASS gl.bindTexture(gl.TEXTURE_2D, texture) was expected value: INVALID_OPERATION.
@@ -40,8 +55,6 @@
 PASS gl.useProgram(program) was expected value: NO_ERROR.
 PASS gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0]) was expected value: NO_ERROR.
 
-PASS extension.restoreContext() was expected value: NO_ERROR.
-
 PASS successfullyParsed is true
 
 TEST COMPLETE

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


--- trunk/LayoutTests/fast/canvas/webgl/context-lost-restored.html	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost-restored.html	2012-01-05 01:12:52 UTC (rev 104102)
@@ -1,5 +1,7 @@
+<!DOCTYPE html>
 <html>
 <head>
+<link rel="stylesheet" href=""
 <script src=""
 <script src=""
 <script src=""
@@ -18,6 +20,8 @@
 var texture;
 var texColor = [255, 10, 20, 255];
 var allowRestore;
+var contextLostEventFired;
+var contextRestoredEventFired;
 
 function init()
 {
@@ -28,15 +32,7 @@
     description("Tests behavior under a restored context.");
 
     shouldGenerateGLError = wtu.shouldGenerateGLError;
-    runTests();
-}
-
-function runTests()
-{
     testLosingContext();
-    testLosingAndRestoringContext();
-
-    finish();
 }
 
 function setupTest()
@@ -60,35 +56,75 @@
 function testLosingContext()
 {
     if (!setupTest())
-        return;
+        finishTest();
 
     debug("Test losing a context and inability to restore it.");
 
-    canvas.addEventListener("webglcontextlost", testLostContext);
+    canvas.addEventListener("webglcontextlost", function(e) {
+       testLostContext(e);
+       // restore the context after this event has exited.
+       setTimeout(function() {
+         // we didn't call prevent default so we should not be able to restore the context
+         shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()");
+         testLosingAndRestoringContext();
+       }, 0);
+    });
     canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
     allowRestore = false;
+    contextLostEventFired = false;
+    contextRestoredEventFired = false;
 
     testOriginalContext();
     extension.loseContext();
-    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()");
-    debug("");
+    // The context should be lost immediately.
+    shouldBeTrue("gl.isContextLost()");
+    shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
+    shouldBe("gl.getError()", "gl.NO_ERROR");
+    // gl methods should be no-ops
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
+    // but the event should not have been fired.
+    shouldBeFalse("contextLostEventFired");
 }
 
 function testLosingAndRestoringContext()
 {
     if (!setupTest())
-        return;
+        finishTest();
 
+    debug("");
     debug("Test losing and restoring a context.");
 
-    canvas.addEventListener("webglcontextlost", testLostContext);
-    canvas.addEventListener("webglcontextrestored", testRestoredContext);
+    canvas.addEventListener("webglcontextlost", function(e) {
+      testLostContext(e);
+      // restore the context after this event has exited.
+      setTimeout(function() {
+        shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
+        // The context should still be lost. It will not get restored until the 
+        // webglrestorecontext event is fired.
+        shouldBeTrue("gl.isContextLost()");
+        shouldBe("gl.getError()", "gl.NO_ERROR");
+        // gl methods should still be no-ops
+        shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
+      }, 0);
+    });
+    canvas.addEventListener("webglcontextrestored", function() {
+      testRestoredContext();
+      finishTest();
+    });
     allowRestore = true;
+    contextLostEventFired = false;
+    contextRestoredEventFired = false;
 
     testOriginalContext();
     extension.loseContext();
-    shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
-    debug("");
+    // The context should be lost immediately.
+    shouldBeTrue("gl.isContextLost()");
+    shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
+    shouldBe("gl.getError()", "gl.NO_ERROR");
+    // gl methods should be no-ops
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
+    // but the event should not have been fired.
+    shouldBeFalse("contextLostEventFired");
 }
 
 function testRendering()
@@ -122,12 +158,13 @@
 function testLostContext(e)
 {
     debug("Test lost context");
+    shouldBeFalse("contextLostEventFired");
+    contextLostEventFired = true;
     shouldBeTrue("gl.isContextLost()");
-    shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
     shouldBe("gl.getError()", "gl.NO_ERROR");
     debug("");
     if (allowRestore)
-        e.preventDefault();
+      e.preventDefault();
 }
 
 function testShouldNotRestoreContext(e)
@@ -151,6 +188,8 @@
 function testRestoredContext()
 {
     debug("Test restored context");
+    shouldBeFalse("contextRestoredEventFired");
+    contextRestoredEventFired = true;
     shouldBeFalse("gl.isContextLost()");
     shouldBe("gl.getError()", "gl.NO_ERROR");
 
@@ -164,15 +203,6 @@
     debug("");
 }
 
-function finish() {
-    var epilogue = document.createElement("script");
-    epilogue._onload_ = function() {
-        if (window.nonKhronosFrameworkNotifyDone)
-            window.nonKhronosFrameworkNotifyDone();
-    };
-    epilogue.src = ""
-    document.body.appendChild(epilogue);
-}
 
 </script>
 </head>

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


--- trunk/LayoutTests/fast/canvas/webgl/context-lost.html	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/LayoutTests/fast/canvas/webgl/context-lost.html	2012-01-05 01:12:52 UTC (rev 104102)
@@ -1,5 +1,7 @@
+<!DOCTYPE html>
 <html>
 <head>
+<link rel="stylesheet" href=""
 <script src=""
 <script src=""
 <script src=""
@@ -45,6 +47,10 @@
         window.initNonKhronosFramework(true);
     }
 
+    // call testValidContext() before checking for the extension, because this is where we check
+    // for the isContextLost() method, which we want to do regardless of the extension's presence.
+    testValidContext();
+
     for (var ii = 0; ii < extensionNames.length; ++ii) {
         extension = gl.getExtension(extensionNames[ii]);
         if (extension) {
@@ -54,12 +60,12 @@
     }
     if (!extension) {
         debug("Could not find lose_context extension under the following names: " + extensionNames.join(" "));
+        finishTest();
         return false;
     }
 
-    canvas.addEventListener("webglcontextlost", testLostContext);
+    canvas.addEventListener("webglcontextlost", testLostContext, false);
 
-    testValidContext();
     loseContext();
 }
 
@@ -68,9 +74,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()");
+    // Note: this will cause the context to be lost, but the
+    // webglcontextlost event listener to be queued.
+    extension.loseContext();
     debug("");
 }
 
@@ -305,18 +311,9 @@
 
     debug("");
 
-    finish();
+    finishTest();
 }
 
-function finish() {
-    var epilogue = document.createElement("script");
-    epilogue._onload_ = function() {
-        if (window.nonKhronosFrameworkNotifyDone)
-            window.nonKhronosFrameworkNotifyDone();
-    };
-    epilogue.src = ""
-    document.body.appendChild(epilogue);
-}
 </script>
 </head>
 <body _onload_="init()">

Modified: trunk/Source/WebCore/ChangeLog (104101 => 104102)


--- trunk/Source/WebCore/ChangeLog	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/Source/WebCore/ChangeLog	2012-01-05 01:12:52 UTC (rev 104102)
@@ -1,3 +1,31 @@
+2012-01-04  Kenneth Russell  <[email protected]>
+
+        Fix semantics of WEBKIT_WEBGL_lose_context
+        https://bugs.webkit.org/show_bug.cgi?id=75053
+
+        Reviewed by James Robinson.
+
+        Updated WEBGL_lose_context extension to match WebGL spec's
+        behavior:
+
+          - loseContext() causes the context to be lost immediately, but
+            the webglcontextlost event isn't dispatched until _javascript_
+            returns.
+          - restoreContext() may only be called once dispatch of the
+            webglcontextlost event has completed, *and* if that event handler
+            prevented the default behavior of the event.
+          - restoreContext() performs its work asynchronously. The context
+            is not restored until just before the webglcontextrestored event
+            is dispatched.
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::WebGLRenderingContext):
+        (WebCore::WebGLRenderingContext::forceLostContext):
+        (WebCore::WebGLRenderingContext::forceRestoreContext):
+        (WebCore::WebGLRenderingContext::dispatchContextLostEvent):
+        (WebCore::WebGLRenderingContext::maybeRestoreContext):
+        * html/canvas/WebGLRenderingContext.h:
+
 2011-12-30  Ryosuke Niwa  <[email protected]>
 
         Inserting nodes is slow due to Node::notifyNodeListsAttributeChanged (20%+)

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (104101 => 104102)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2012-01-05 01:12:52 UTC (rev 104102)
@@ -364,11 +364,6 @@
     bool m_changed;
 };
 
-void WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired()
-{
-    m_context->maybeRestoreContext(RealLostContext);
-}
-
 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
 public:
     explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
@@ -412,10 +407,12 @@
     : CanvasRenderingContext(passedCanvas)
     , m_context(context)
     , m_drawingBuffer(0)
+    , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
     , m_restoreAllowed(false)
-    , m_restoreTimer(this)
+    , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
     , m_videoCache(4)
     , m_contextLost(false)
+    , m_contextLostMode(SyntheticLostContext)
     , m_attributes(attributes)
 {
     ASSERT(m_context);
@@ -4093,10 +4090,28 @@
         return;
     }
 
-    loseContext();
+    m_contextLost = true;
+    m_contextLostMode = mode;
 
-    if (mode == RealLostContext)
-        m_restoreTimer.startOneShot(0);
+    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);
+
+    // Don't allow restoration unless the context lost event has both been
+    // dispatched and its default behavior prevented.
+    m_restoreAllowed = false;
+
+    // Always defer the dispatch of the context lost event, to implement
+    // the spec behavior of queueing a task.
+    m_dispatchContextLostEventTimer.startOneShot(0);
 }
 
 void WebGLRenderingContext::forceRestoreContext()
@@ -4106,7 +4121,14 @@
         return;
     }
 
-    maybeRestoreContext(SyntheticLostContext);
+    if (!m_restoreAllowed) {
+        if (m_contextLostMode == SyntheticLostContext)
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return;
+    }
+
+    if (!m_restoreTimer.isActive())
+        m_restoreTimer.startOneShot(0);
 }
 
 #if USE(ACCELERATED_COMPOSITING)
@@ -4951,42 +4973,29 @@
     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
 }
 
-void WebGLRenderingContext::loseContext()
+void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext>*)
 {
-    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);
-
     RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "");
     canvas()->dispatchEvent(event);
     m_restoreAllowed = event->defaultPrevented();
+    if (m_contextLostMode == RealLostContext && m_restoreAllowed)
+        m_restoreTimer.startOneShot(0);
 }
 
-void WebGLRenderingContext::maybeRestoreContext(WebGLRenderingContext::LostContextMode mode)
+void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
 {
-    if (!m_contextLost) {
-        ASSERT(mode == SyntheticLostContext);
-        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+    ASSERT(m_contextLost);
+    if (!m_contextLost)
         return;
-    }
 
-    // The rendering context is not restored unless the default
-    // behavior of the webglcontextlost event was prevented earlier.
-    if (!m_restoreAllowed) {
-        if (mode == SyntheticLostContext)
-            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+    // The rendering context is not restored unless the default behavior of the
+    // webglcontextlost event was prevented earlier.
+    //
+    // Because of the way m_restoreTimer is set up for real vs. synthetic lost
+    // context events, we don't have to worry about this test short-circuiting
+    // the retry loop for real context lost events.
+    if (!m_restoreAllowed)
         return;
-    }
 
     int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
 
@@ -5017,7 +5026,7 @@
 
     RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, canvas()->document()->view()->root()->hostWindow()));
     if (!context) {
-        if (mode == RealLostContext)
+        if (m_contextLostMode == RealLostContext)
             m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
         else
             // This likely shouldn't happen but is the best way to report it to the WebGL app.

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (104101 => 104102)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2012-01-05 01:11:53 UTC (rev 104101)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2012-01-05 01:12:52 UTC (rev 104102)
@@ -367,16 +367,14 @@
     // to the back-buffer of m_context.
     RefPtr<DrawingBuffer> m_drawingBuffer;
 
-    class WebGLRenderingContextRestoreTimer : public TimerBase {
-    public:
-        explicit WebGLRenderingContextRestoreTimer(WebGLRenderingContext* context) : m_context(context) { }
-    private:
-        virtual void fired();
-        WebGLRenderingContext* m_context;
-    };
-
+    // Dispatches a context lost event once it is determined that one is needed.
+    // This is used both for synthetic and real context losses. For real ones, it's
+    // likely that there's no _javascript_ on the stack, but that might be dependent
+    // on how exactly the platform discovers that the context was lost. For better
+    // portability we always defer the dispatch of the event.
+    Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
     bool m_restoreAllowed;
-    WebGLRenderingContextRestoreTimer m_restoreTimer;
+    Timer<WebGLRenderingContext> m_restoreTimer;
 
     bool m_needsUpdate;
     bool m_markedCanvasDirty;
@@ -460,6 +458,7 @@
     bool m_unpackPremultiplyAlpha;
     GC3Denum m_unpackColorspaceConversion;
     bool m_contextLost;
+    LostContextMode m_contextLostMode;
     GraphicsContext3D::Attributes m_attributes;
 
     bool m_layerCleared;
@@ -636,9 +635,9 @@
     bool simulateVertexAttrib0(GC3Dsizei numVertex);
     void restoreStatesAfterVertexAttrib0Simulation();
 
-    void loseContext();
+    void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
     // Helper for restoration after context lost.
-    void maybeRestoreContext(LostContextMode);
+    void maybeRestoreContext(Timer<WebGLRenderingContext>*);
 
     // Determine if we are running privileged code in the browser, for example,
     // a Safari or Chrome extension.
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to