Title: [112178] trunk/Source/WebCore
Revision
112178
Author
fsam...@chromium.org
Date
2012-03-26 17:09:12 -0700 (Mon, 26 Mar 2012)

Log Message

[Chromium] Using WebViewPlugins with --force-compositing-mode causes an ASSERT to fail
https://bugs.webkit.org/show_bug.cgi?id=81954

Reviewed by James Robinson.

A static variable s_inPaintContents is set when painting, and it ensures
that we don't delete GraphicsLayers or create GraphicsLayers while painting.

However, because this variable is static, it does not permit the existence
of multiple WebViews in different stages (one laying out and one painting).

This manifests itself if one attempts to use the --force-compositing-mode
in Chromium and attempts to navigate to a page with a missing or old plugin
or a browser plugin (which uses a WebViewPlugin as a placeholder until it's
done loading).

The solution to simplify debugging is to make this flag per-Page.
We can access Page from RenderLayerBacking which is a GraphicsLayerClient.
We add a new method GraphicsLayerClient::verifyNotPainting with a default
(do nothing) implementation and override it in RenderLayerBacking to
test the flag set in Page.

* page/Page.cpp:
(WebCore::Page::Page):
* page/Page.h:
(Page):
(WebCore::Page::setIsPainting):
(WebCore::Page::isPainting):
* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::GraphicsLayer):
(WebCore::GraphicsLayer::~GraphicsLayer):
(WebCore::GraphicsLayer::paintGraphicsLayerContents):
* platform/graphics/GraphicsLayerClient.h:
(GraphicsLayerClient):
(WebCore::GraphicsLayerClient::verifyNotPainting):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::paintContents):
(WebCore):
(WebCore::RenderLayerBacking::verifyNotPainting):
* rendering/RenderLayerBacking.h:
(RenderLayerBacking):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (112177 => 112178)


--- trunk/Source/WebCore/ChangeLog	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/ChangeLog	2012-03-27 00:09:12 UTC (rev 112178)
@@ -1,3 +1,47 @@
+2012-03-26  Fady Samuel  <fsam...@chromium.org>
+
+        [Chromium] Using WebViewPlugins with --force-compositing-mode causes an ASSERT to fail
+        https://bugs.webkit.org/show_bug.cgi?id=81954
+
+        Reviewed by James Robinson.
+
+        A static variable s_inPaintContents is set when painting, and it ensures
+        that we don't delete GraphicsLayers or create GraphicsLayers while painting.
+
+        However, because this variable is static, it does not permit the existence
+        of multiple WebViews in different stages (one laying out and one painting).
+
+        This manifests itself if one attempts to use the --force-compositing-mode
+        in Chromium and attempts to navigate to a page with a missing or old plugin
+        or a browser plugin (which uses a WebViewPlugin as a placeholder until it's
+        done loading).
+
+        The solution to simplify debugging is to make this flag per-Page.
+        We can access Page from RenderLayerBacking which is a GraphicsLayerClient.
+        We add a new method GraphicsLayerClient::verifyNotPainting with a default
+        (do nothing) implementation and override it in RenderLayerBacking to
+        test the flag set in Page.
+
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+        * page/Page.h:
+        (Page):
+        (WebCore::Page::setIsPainting):
+        (WebCore::Page::isPainting):
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::GraphicsLayer):
+        (WebCore::GraphicsLayer::~GraphicsLayer):
+        (WebCore::GraphicsLayer::paintGraphicsLayerContents):
+        * platform/graphics/GraphicsLayerClient.h:
+        (GraphicsLayerClient):
+        (WebCore::GraphicsLayerClient::verifyNotPainting):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::paintContents):
+        (WebCore):
+        (WebCore::RenderLayerBacking::verifyNotPainting):
+        * rendering/RenderLayerBacking.h:
+        (RenderLayerBacking):
+
 2012-03-23  Ryosuke Niwa  <rn...@webkit.org>
 
         cssText should use shorthand notations

Modified: trunk/Source/WebCore/page/Page.cpp (112177 => 112178)


--- trunk/Source/WebCore/page/Page.cpp	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/page/Page.cpp	2012-03-27 00:09:12 UTC (rev 112178)
@@ -160,6 +160,9 @@
 #endif
     , m_displayID(0)
     , m_isCountingRelevantRepaintedObjects(false)
+#ifndef NDEBUG
+    , m_isPainting(false)
+#endif
 {
     if (!allPages) {
         allPages = new HashSet<Page*>;

Modified: trunk/Source/WebCore/page/Page.h (112177 => 112178)


--- trunk/Source/WebCore/page/Page.h	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/page/Page.h	2012-03-27 00:09:12 UTC (rev 112178)
@@ -331,7 +331,10 @@
 
         void suspendActiveDOMObjectsAndAnimations();
         void resumeActiveDOMObjectsAndAnimations();
-
+#ifndef NDEBUG
+        void setIsPainting(bool painting) { m_isPainting = painting; }
+        bool isPainting() const { return m_isPainting; }
+#endif
     private:
         void initGroup();
 
@@ -431,6 +434,9 @@
         Region m_relevantPaintedRegion;
         Region m_relevantUnpaintedRegion;
         bool m_isCountingRelevantRepaintedObjects;
+#ifndef NDEBUG
+        bool m_isPainting;
+#endif
     };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (112177 => 112178)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp	2012-03-27 00:09:12 UTC (rev 112178)
@@ -63,10 +63,6 @@
     m_values.append(value);
 }
 
-#ifndef NDEBUG
-static bool s_inPaintContents = false;
-#endif
-
 GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
     : m_client(client)
     , m_anchorPoint(0.5f, 0.5f, 0)
@@ -91,12 +87,18 @@
     , m_replicatedLayer(0)
     , m_repaintCount(0)
 {
-    ASSERT(!s_inPaintContents);
+#ifndef NDEBUG
+    if (m_client)
+        m_client->verifyNotPainting();
+#endif
 }
 
 GraphicsLayer::~GraphicsLayer()
 {
-    ASSERT(!s_inPaintContents);
+#ifndef NDEBUG
+    if (m_client)
+        m_client->verifyNotPainting();
+#endif
     removeAllChildren();
     removeFromParent();
 }
@@ -288,9 +290,6 @@
 
 void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const IntRect& clip)
 {
-#ifndef NDEBUG
-    s_inPaintContents = true;
-#endif
     if (m_client) {
         LayoutSize offset = offsetFromRenderer();
         context.translate(-offset);
@@ -300,9 +299,6 @@
 
         m_client->paintContents(this, context, m_paintingPhase, pixelSnappedIntRect(clipRect));
     }
-#ifndef NDEBUG
-    s_inPaintContents = false;
-#endif
 }
 
 String GraphicsLayer::animationNameForTransition(AnimatedPropertyID property)

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h (112177 => 112178)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h	2012-03-27 00:09:12 UTC (rev 112178)
@@ -74,6 +74,15 @@
 
     virtual bool showDebugBorders(const GraphicsLayer*) const = 0;
     virtual bool showRepaintCounter(const GraphicsLayer*) const = 0;
+
+#ifndef NDEBUG
+    // RenderLayerBacking overrides this to verify that it is not
+    // currently painting contents. An ASSERT fails, if it is.
+    // This is executed in GraphicsLayer construction and destruction
+    // to verify that we don't create or destroy GraphicsLayers
+    // while painting.
+    virtual void verifyNotPainting() { }
+#endif
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (112177 => 112178)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2012-03-27 00:09:12 UTC (rev 112178)
@@ -1160,6 +1160,10 @@
 // Up-call from compositing layer drawing callback.
 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
 {
+#ifndef NDEBUG
+    if (Page* page = renderer()->frame()->page())
+        page->setIsPainting(true);
+#endif
     if (graphicsLayer == m_graphicsLayer.get() || graphicsLayer == m_foregroundLayer.get() || graphicsLayer == m_maskLayer.get()) {
         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), &context, clip);
 
@@ -1185,6 +1189,10 @@
         m_owningLayer->paintResizer(&context, IntPoint(), transformedClip);
         context.restore();
     }
+#ifndef NDEBUG
+    if (Page* page = renderer()->frame()->page())
+        page->setIsPainting(false);
+#endif
 }
 
 float RenderLayerBacking::pageScaleFactor() const
@@ -1212,6 +1220,13 @@
     return compositor() ? compositor()->compositorShowRepaintCounter() : false;
 }
 
+#ifndef NDEBUG
+void RenderLayerBacking::verifyNotPainting()
+{
+    ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
+}
+#endif
+
 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
 {
     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (112177 => 112178)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2012-03-26 23:59:27 UTC (rev 112177)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2012-03-27 00:09:12 UTC (rev 112178)
@@ -136,6 +136,10 @@
     virtual bool showDebugBorders(const GraphicsLayer*) const;
     virtual bool showRepaintCounter(const GraphicsLayer*) const;
 
+#ifndef NDEBUG
+    virtual void verifyNotPainting();
+#endif
+
     IntRect contentsBox() const;
     
     // For informative purposes only.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to