Title: [89635] trunk/Source
Revision
89635
Author
commit-qu...@webkit.org
Date
2011-06-23 17:11:51 -0700 (Thu, 23 Jun 2011)

Log Message

2011-06-23  John Bates  <jba...@google.com>

        Reviewed by James Robinson.

        Fix latch deadlock when GPU process crashes or context is lost.
        https://bugs.webkit.org/show_bug.cgi?id=63189
        The main bug fix is to only set/wait latches if the child context has no errors.
        Additionally, the LayerChromium classes needed to be modified to not continue drawing when
        their corresponding contexts have errors. Otherwise, they would draw with invalid texture ids.

        Test: open particles WebGL demo in chrome, kill GPU process from Task Manager; observe no deadlock.

        * platform/graphics/chromium/LayerRendererChromium.cpp:
        (WebCore::LayerRendererChromium::LayerRendererChromium):
        (WebCore::LayerRendererChromium::updateAndDrawLayers):
        (WebCore::LayerRendererChromium::updateLayers):
        (WebCore::LayerRendererChromium::isCompositorContextLost):
        * platform/graphics/chromium/LayerRendererChromium.h:
        * platform/graphics/chromium/WebGLLayerChromium.cpp:
        (WebCore::WebGLLayerChromium::drawsContent):
        (WebCore::WebGLLayerChromium::updateCompositorResources):
        (WebCore::WebGLLayerChromium::setContext):
        * platform/graphics/chromium/WebGLLayerChromium.h:
        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
        (WebCore::Canvas2DLayerChromium::drawsContent):
        * platform/graphics/chromium/Canvas2DLayerChromium.h:
2011-06-23  John Bates  <jba...@google.com>

        Reviewed by James Robinson.

        Fix latch deadlock when GPU process crashes or context is lost
        https://bugs.webkit.org/show_bug.cgi?id=63189

        * src/WebViewImpl.cpp:
        (WebKit::WebViewImpl::composite):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (89634 => 89635)


--- trunk/Source/WebCore/ChangeLog	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/ChangeLog	2011-06-24 00:11:51 UTC (rev 89635)
@@ -1,3 +1,30 @@
+2011-06-23  John Bates  <jba...@google.com>
+
+        Reviewed by James Robinson.
+
+        Fix latch deadlock when GPU process crashes or context is lost.
+        https://bugs.webkit.org/show_bug.cgi?id=63189
+        The main bug fix is to only set/wait latches if the child context has no errors.
+        Additionally, the LayerChromium classes needed to be modified to not continue drawing when
+        their corresponding contexts have errors. Otherwise, they would draw with invalid texture ids.
+
+        Test: open particles WebGL demo in chrome, kill GPU process from Task Manager; observe no deadlock.
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::LayerRendererChromium):
+        (WebCore::LayerRendererChromium::updateAndDrawLayers):
+        (WebCore::LayerRendererChromium::updateLayers):
+        (WebCore::LayerRendererChromium::isCompositorContextLost):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        * platform/graphics/chromium/WebGLLayerChromium.cpp:
+        (WebCore::WebGLLayerChromium::drawsContent):
+        (WebCore::WebGLLayerChromium::updateCompositorResources):
+        (WebCore::WebGLLayerChromium::setContext):
+        * platform/graphics/chromium/WebGLLayerChromium.h:
+        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+        (WebCore::Canvas2DLayerChromium::drawsContent):
+        * platform/graphics/chromium/Canvas2DLayerChromium.h:
+
 2011-06-23  Alok Priyadarshi  <al...@chromium.org>
 
         Reviewed by James Robinson.

Modified: trunk/Source/WebCore/platform/graphics/Extensions3D.h (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/Extensions3D.h	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/Extensions3D.h	2011-06-24 00:11:51 UTC (rev 89635)
@@ -106,6 +106,12 @@
     };
 
     // GL_ARB_robustness
+    // Note: This method's behavior differs from the GL_ARB_robustness
+    // specification in the following way:
+    // The implementation must not reset the error state during this call.
+    // If getGraphicsResetStatusARB returns an error, it should continue
+    // returning the same error. Restoring the GraphicsContext3D is handled
+    // externally.
     virtual int getGraphicsResetStatusARB() = 0;
     
     // GL_ANGLE_framebuffer_blit

Modified: trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp	2011-06-24 00:11:51 UTC (rev 89635)
@@ -35,6 +35,7 @@
 #include "Canvas2DLayerChromium.h"
 
 #include "DrawingBuffer.h"
+#include "Extensions3DChromium.h"
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h"
 
@@ -59,9 +60,17 @@
         layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get());
 }
 
+bool Canvas2DLayerChromium::drawsContent() const
+{
+    GraphicsContext3D* context;
+    return (m_drawingBuffer
+            && (context = m_drawingBuffer->graphicsContext3D().get())
+            && (context->getExtensions()->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR));
+}
+
 void Canvas2DLayerChromium::updateCompositorResources()
 {
-    if (!m_contentsDirty || !m_drawingBuffer)
+    if (!m_contentsDirty || !drawsContent())
         return;
     if (m_textureChanged) { // We have to generate a new backing texture.
         GraphicsContext3D* context = layerRendererContext();

Modified: trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h	2011-06-24 00:11:51 UTC (rev 89635)
@@ -45,7 +45,7 @@
 public:
     static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner);
     virtual ~Canvas2DLayerChromium();
-    virtual bool drawsContent() const { return true; }
+    virtual bool drawsContent() const;
     virtual void updateCompositorResources();
 
     void setTextureChanged();

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-06-24 00:11:51 UTC (rev 89635)
@@ -120,7 +120,6 @@
     , m_offscreenFramebufferId(0)
     , m_compositeOffscreen(false)
     , m_context(context)
-    , m_childContextsWereCopied(false)
     , m_contextSupportsLatch(false)
     , m_contextSupportsTextureFormatBGRA(false)
     , m_contextSupportsReadFormatBGRA(false)
@@ -255,22 +254,19 @@
         // thread can execute WebGL calls on the child context at any time,
         // potentially clobbering the parent texture that is being renderered
         // by the compositor thread.
-        if (m_childContextsWereCopied) {
-            Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
-            // For each child context:
-            //   glWaitLatch(Offscreen->Compositor);
-            ChildContextMap::iterator i = m_childContexts.begin();
-            for (; i != m_childContexts.end(); ++i) {
-                Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
-                GC3Duint latchId;
-                childExt->getChildToParentLatchCHROMIUM(&latchId);
-                parentExt->waitLatchCHROMIUM(latchId);
+        Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
+        // For each child context:
+        //   glWaitLatch(Offscreen->Compositor);
+        ChildContextMap::iterator i = m_childContexts.begin();
+        for (; i != m_childContexts.end(); ++i) {
+            Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
+            if (childExt->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR) {
+                GC3Duint childToParentLatchId;
+                childExt->getChildToParentLatchCHROMIUM(&childToParentLatchId);
+                childExt->setLatchCHROMIUM(childToParentLatchId);
+                parentExt->waitLatchCHROMIUM(childToParentLatchId);
             }
         }
-        // Reset to false to indicate that we have consumed the dirty child
-        // contexts' parent textures. (This is only useful when the compositor
-        // is multithreaded.)
-        m_childContextsWereCopied = false;
     }
 
     drawLayers(renderSurfaceLayerList);
@@ -285,9 +281,12 @@
         ChildContextMap::iterator i = m_childContexts.begin();
         for (; i != m_childContexts.end(); ++i) {
             Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
-            GC3Duint latchId;
-            childExt->getParentToChildLatchCHROMIUM(&latchId);
-            parentExt->setLatchCHROMIUM(latchId);
+            if (childExt->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR) {
+                GC3Duint parentToChildLatchId;
+                childExt->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
+                parentExt->setLatchCHROMIUM(parentToChildLatchId);
+                childExt->waitLatchCHROMIUM(parentToChildLatchId);
+            }
         }
     }
 
@@ -340,53 +339,12 @@
     s_inPaintLayerContents = false;
 #endif
 
-    // FIXME: Before updateCompositorResources, when the compositor runs in
-    // its own thread, and when the copyTexImage2D bug is fixed, insert
-    // a glWaitLatch(Compositor->Offscreen) on all child contexts here instead
-    // of after updateCompositorResources.
-    // Also uncomment the glSetLatch(Compositor->Offscreen) code in addChildContext.
-//  if (hardwareCompositing() && m_contextSupportsLatch) {
-//      // For each child context:
-//      //   glWaitLatch(Compositor->Offscreen);
-//      ChildContextMap::iterator i = m_childContexts.begin();
-//      for (; i != m_childContexts.end(); ++i) {
-//          Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions());
-//          GC3Duint childToParentLatchId, parentToChildLatchId;
-//          ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
-//          ext->waitLatchCHROMIUM(parentToChildLatchId);
-//      }
-//  }
-
     updateCompositorResources(renderSurfaceLayerList);
     // Update compositor resources for root layer.
     {
         TRACE_EVENT("LayerRendererChromium::updateLayer::updateRoot", this, 0);
         m_rootLayerContentTiler->updateRect();
     }
-
-    // After updateCompositorResources, set/wait latches for all child
-    // contexts. This will prevent the compositor from using any of the child
-    // parent textures while WebGL commands are executing from _javascript_ *and*
-    // while the final parent texture is being blit'd. copyTexImage2D
-    // uses the parent texture as a temporary resolve buffer, so that's why the
-    // waitLatch is below, to block the compositor from using the parent texture
-    // until the next WebGL SwapBuffers (or copyTextureToParentTexture for
-    // Canvas2D).
-    if (hardwareCompositing() && m_contextSupportsLatch) {
-        m_childContextsWereCopied = true;
-        // For each child context:
-        //   glSetLatch(Offscreen->Compositor);
-        //   glWaitLatch(Compositor->Offscreen);
-        ChildContextMap::iterator i = m_childContexts.begin();
-        for (; i != m_childContexts.end(); ++i) {
-            Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions());
-            GC3Duint childToParentLatchId, parentToChildLatchId;
-            ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
-            ext->getChildToParentLatchCHROMIUM(&childToParentLatchId);
-            ext->setLatchCHROMIUM(childToParentLatchId);
-            ext->waitLatchCHROMIUM(parentToChildLatchId);
-        }
-    }
 }
 
 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
@@ -1295,6 +1253,11 @@
     }
 }
 
+bool LayerRendererChromium::isCompositorContextLost()
+{
+    return (m_context.get()->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR);
+}
+
 void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const
 {
     if (layer->ccLayerImpl()->renderSurface())

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h	2011-06-24 00:11:51 UTC (rev 89635)
@@ -150,6 +150,9 @@
     void addChildContext(GraphicsContext3D*);
     void removeChildContext(GraphicsContext3D*);
 
+    // Return true if the compositor context has an error.
+    bool isCompositorContextLost();
+
 #ifndef NDEBUG
     static bool s_inPaintLayerContents;
 #endif
@@ -241,11 +244,6 @@
 #endif
 
     ChildContextMap m_childContexts;
-    // If true, the child contexts were copied to the compositor texture targets
-    // and the compositor will need to wait on the proper latches before using
-    // the target textures. If false, the compositor is reusing the textures
-    // from last frame.
-    bool m_childContextsWereCopied;
 
     bool m_contextSupportsLatch;
     bool m_contextSupportsMapSub;

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2011-06-24 00:11:51 UTC (rev 89635)
@@ -61,9 +61,14 @@
         layerRenderer()->removeChildContext(m_context);
 }
 
+bool WebGLLayerChromium::drawsContent() const
+{
+    return (m_context && m_context->getExtensions()->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR);
+}
+
 void WebGLLayerChromium::updateCompositorResources()
 {
-    if (!m_context)
+    if (!drawsContent())
         return;
 
     if (!m_contentsDirty)
@@ -103,7 +108,8 @@
 
 void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
 {
-    if (m_context != context && layerRenderer()) {
+    bool contextChanged = (m_context != context);
+    if (contextChanged && layerRenderer()) {
         if (m_context)
             layerRenderer()->removeChildContext(m_context);
         if (context)
@@ -116,7 +122,7 @@
         return;
 
     unsigned int textureId = m_context->platformTexture();
-    if (textureId != m_textureId) {
+    if (textureId != m_textureId || contextChanged) {
         m_textureChanged = true;
         m_textureUpdated = true;
     }

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h (89634 => 89635)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h	2011-06-24 00:11:51 UTC (rev 89635)
@@ -49,7 +49,7 @@
 
     virtual ~WebGLLayerChromium();
 
-    virtual bool drawsContent() const { return m_context; }
+    virtual bool drawsContent() const;
     virtual void updateCompositorResources();
     void setTextureUpdated();
 

Modified: trunk/Source/WebKit/chromium/ChangeLog (89634 => 89635)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-06-24 00:11:51 UTC (rev 89635)
@@ -1,3 +1,13 @@
+2011-06-23  John Bates  <jba...@google.com>
+
+        Reviewed by James Robinson.
+
+        Fix latch deadlock when GPU process crashes or context is lost
+        https://bugs.webkit.org/show_bug.cgi?id=63189
+
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::composite):
+
 2011-06-23  Ryosuke Niwa  <rn...@webkit.org>
 
         Rolled DEPS.

Modified: trunk/Source/WebKit/chromium/src/WebViewImpl.cpp (89634 => 89635)


--- trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2011-06-23 23:47:39 UTC (rev 89634)
+++ trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2011-06-24 00:11:51 UTC (rev 89635)
@@ -1154,8 +1154,7 @@
     // Put result onscreen.
     m_layerRenderer->present();
 
-    GraphicsContext3D* context = m_layerRenderer->context();
-    if (context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR) {
+    if (m_layerRenderer->isCompositorContextLost()) {
         // Trying to recover the context right here will not work if GPU process
         // died. This is because GpuChannelHost::OnErrorMessage will only be
         // called at the next iteration of the message loop, reverting our
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to