[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

simon.fraser at apple.com simon.fraser at apple.com
Wed Dec 22 12:35:07 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit bd17434cefe6c3021ad6f3ca1a5f4bc5bc930228
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Aug 25 18:24:17 2010 +0000

    2010-08-25  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            Flash content draws in front of site's drop down menu at http://www.monster.com/
            https://bugs.webkit.org/show_bug.cgi?id=41330
    
            If an iframe with composited content became overlapped, we failed to
            consider that iframe for compositing if it had no RenderLayer, so the layering
            would be incorrect.
    
            Overlap is detected at painting time, but it's bad for FrameView::setIsOverlapped()
            to call setNeedsStyleRecalc(), because this would cause subsequent calls to
            FrameView::paintContents() in the same painting batch to bail with needsLayout().
    
            Instead, we do the setNeedsStyleRecalc() from RenderLayerCompositor::notifyIFramesOfCompositingChange(),
            so that the parent document has a chance to update style, and give the iframe a RenderLayer.
            Then setIsOverlapped() simply needs to schedule a layer update, which we do on a timer.
    
            When dumping layers via Frame::layerTreeAsText(), if a layer update is pending, then
            update the layers.
    
            Test: compositing/iframes/become-overlapped-iframe.html
    
            * page/Frame.cpp:
            (WebCore::Frame::layerTreeAsText):
            * page/FrameView.cpp:
            (WebCore::FrameView::setIsOverlapped):
            * rendering/RenderLayerCompositor.cpp:
            (WebCore::RenderLayerCompositor::RenderLayerCompositor):
            (WebCore::RenderLayerCompositor::scheduleCompositingLayerUpdate):
            (WebCore::RenderLayerCompositor::compositingLayerUpdatePending):
            (WebCore::RenderLayerCompositor::updateCompositingLayersTimerFired):
            (WebCore::RenderLayerCompositor::updateCompositingLayers):
            (WebCore::RenderLayerCompositor::notifyIFramesOfCompositingChange):
            * rendering/RenderLayerCompositor.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66028 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 59d7da6..7b7681a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-08-25  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Flash content draws in front of site's drop down menu at http://www.monster.com/
+        https://bugs.webkit.org/show_bug.cgi?id=41330
+        
+        Testcase with a non-layered iframe that gets overlapped dynamically.
+
+        * compositing/iframes/become-overlapped-iframe-expected.txt: Added.
+        * compositing/iframes/become-overlapped-iframe.html: Added.
+
 2010-08-24  Eric Carlson  <eric.carlson at apple.com>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/LayoutTests/compositing/iframes/become-overlapped-iframe-expected.txt b/LayoutTests/compositing/iframes/become-overlapped-iframe-expected.txt
new file mode 100644
index 0000000..084ae45
--- /dev/null
+++ b/LayoutTests/compositing/iframes/become-overlapped-iframe-expected.txt
@@ -0,0 +1,132 @@
+
+(GraphicsLayer
+  (position 0.00 0.00)
+  (anchor 0.50 0.50)
+  (bounds 800.00 600.00)
+  (opacity 1.00)
+  (usingTiledLayer 0)
+  (preserves3D 0)
+  (drawsContent 0)
+  (backfaceVisibility visible)
+  (backgroundColor none)
+  (transform identity)
+  (children 1
+    (GraphicsLayer
+      (position 0.00 0.00)
+      (anchor 0.50 0.50)
+      (bounds 800.00 600.00)
+      (opacity 1.00)
+      (usingTiledLayer 0)
+      (preserves3D 0)
+      (drawsContent 0)
+      (backfaceVisibility visible)
+      (backgroundColor none)
+      (transform identity)
+      (childrenTransform identity)
+      (children 2
+        (GraphicsLayer
+          (position 58.00 58.00)
+          (anchor 0.50 0.50)
+          (bounds 350.00 200.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 15.00 15.00)
+              (anchor 0.50 0.50)
+              (bounds 305.00 170.00)
+              (opacity 1.00)
+              (usingTiledLayer 0)
+              (preserves3D 0)
+              (drawsContent 0)
+              (backfaceVisibility visible)
+              (backgroundColor none)
+              (transform identity)
+              (childrenTransform identity)
+              (children 1
+                (GraphicsLayer
+                  (position 0.00 0.00)
+                  (anchor 0.50 0.50)
+                  (bounds 0.00 0.00)
+                  (opacity 1.00)
+                  (usingTiledLayer 0)
+                  (preserves3D 0)
+                  (drawsContent 0)
+                  (backfaceVisibility visible)
+                  (backgroundColor none)
+                  (transform identity)
+                  (childrenTransform identity)
+                  (children 1
+                    (GraphicsLayer
+                      (position 0.00 0.00)
+                      (anchor 0.50 0.50)
+                      (bounds 305.00 230.00)
+                      (opacity 1.00)
+                      (usingTiledLayer 0)
+                      (preserves3D 0)
+                      (drawsContent 0)
+                      (backfaceVisibility visible)
+                      (backgroundColor none)
+                      (transform identity)
+                      (childrenTransform identity)
+                      (children 1
+                        (GraphicsLayer
+                          (position 0.00 0.00)
+                          (anchor 0.50 0.50)
+                          (bounds 305.00 230.00)
+                          (opacity 1.00)
+                          (usingTiledLayer 0)
+                          (preserves3D 0)
+                          (drawsContent 1)
+                          (backfaceVisibility visible)
+                          (backgroundColor none)
+                          (transform identity)
+                          (childrenTransform identity)
+                          (children 1
+                            (GraphicsLayer
+                              (position 18.00 10.00)
+                              (anchor 0.50 0.50)
+                              (bounds 210.00 210.00)
+                              (opacity 1.00)
+                              (usingTiledLayer 0)
+                              (preserves3D 0)
+                              (drawsContent 1)
+                              (backfaceVisibility visible)
+                              (backgroundColor none)
+                              (transform identity)
+                              (childrenTransform identity)
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 5.00 5.00)
+          (anchor 0.50 0.50)
+          (bounds 150.00 150.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/iframes/become-overlapped-iframe.html b/LayoutTests/compositing/iframes/become-overlapped-iframe.html
new file mode 100644
index 0000000..2efdebe
--- /dev/null
+++ b/LayoutTests/compositing/iframes/become-overlapped-iframe.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    iframe {
+        border: 10px solid black;
+        padding: 5px;
+        margin: 50px;
+        height: 170px;
+        width: 320px;
+        float: left;
+    }
+    
+    #overlay {
+        position: absolute;
+        width: 150px;
+        height: 50px;
+        top: 5px;
+        left: 5px;
+        background-color: rgba(0, 0, 0, 0.6);
+    }
+    
+    pre {
+        clear: both;
+    }
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    function doTest()
+    {
+        // Need to wait for compositing layers to be updated.
+        window.setTimeout(function() {
+          document.getElementById('overlay').style.height = '150px';
+            if (window.layoutTestController) {
+                layoutTestController.display(); // Painting has to happen to detect overlap.
+                document.getElementById('layers').innerHTML = layoutTestController.layerTreeAsText();
+                layoutTestController.notifyDone();
+            }
+        }, 0);
+    }
+
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+    <!-- Test that the parent document becomes composited when the iframe becomes overlapped. -->
+    <!-- The iframe does not start with a RenderLayer. -->
+    <iframe id="iframe" src="resources/composited-subframe.html"></iframe>
+
+    <div id="overlay">
+    </div>
+    
+    <pre id="layers">Layer tree appears here in DRT.</pre>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 7c06c27..8f662e7 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,40 @@
+2010-08-25  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Flash content draws in front of site's drop down menu at http://www.monster.com/
+        https://bugs.webkit.org/show_bug.cgi?id=41330
+        
+        If an iframe with composited content became overlapped, we failed to
+        consider that iframe for compositing if it had no RenderLayer, so the layering
+        would be incorrect.
+        
+        Overlap is detected at painting time, but it's bad for FrameView::setIsOverlapped()
+        to call setNeedsStyleRecalc(), because this would cause subsequent calls to
+        FrameView::paintContents() in the same painting batch to bail with needsLayout().
+        
+        Instead, we do the setNeedsStyleRecalc() from RenderLayerCompositor::notifyIFramesOfCompositingChange(),
+        so that the parent document has a chance to update style, and give the iframe a RenderLayer.
+        Then setIsOverlapped() simply needs to schedule a layer update, which we do on a timer.
+        
+        When dumping layers via Frame::layerTreeAsText(), if a layer update is pending, then
+        update the layers.
+        
+        Test: compositing/iframes/become-overlapped-iframe.html
+
+        * page/Frame.cpp:
+        (WebCore::Frame::layerTreeAsText):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setIsOverlapped):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::RenderLayerCompositor):
+        (WebCore::RenderLayerCompositor::scheduleCompositingLayerUpdate):
+        (WebCore::RenderLayerCompositor::compositingLayerUpdatePending):
+        (WebCore::RenderLayerCompositor::updateCompositingLayersTimerFired):
+        (WebCore::RenderLayerCompositor::updateCompositingLayers):
+        (WebCore::RenderLayerCompositor::notifyIFramesOfCompositingChange):
+        * rendering/RenderLayerCompositor.h:
+
 2010-08-25  Martin Robinson  <mrobinson at igalia.com>
 
         Reviewed by Gustavo Noronha Silva.
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index a013f39..3c07106 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -1612,7 +1612,11 @@ String Frame::layerTreeAsText() const
     if (!contentRenderer())
         return String();
 
-    GraphicsLayer* rootLayer = contentRenderer()->compositor()->rootPlatformLayer();
+    RenderLayerCompositor* compositor = contentRenderer()->compositor();
+    if (compositor->compositingLayerUpdatePending())
+        compositor->updateCompositingLayers();
+
+    GraphicsLayer* rootLayer = compositor->rootPlatformLayer();
     if (!rootLayer)
         return String();
 
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index f53b47f..1f87984 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -991,6 +991,7 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
     return false;
 }
 
+// Note that this gets called at painting time.
 void FrameView::setIsOverlapped(bool isOverlapped)
 {
     if (isOverlapped == m_isOverlapped)
@@ -1001,10 +1002,15 @@ void FrameView::setIsOverlapped(bool isOverlapped)
     
 #if USE(ACCELERATED_COMPOSITING)
     // Overlap can affect compositing tests, so if it changes, we need to trigger
-    // a recalcStyle in the parent document.
+    // a layer update in the parent document.
     if (hasCompositedContent()) {
-        if (Element* ownerElement = m_frame->document()->ownerElement())
-            ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
+        if (Frame* parentFrame = m_frame->tree()->parent()) {
+            if (RenderView* parentView = parentFrame->contentRenderer()) {
+                RenderLayerCompositor* compositor = parentView->compositor();
+                compositor->setCompositingLayersNeedRebuild();
+                compositor->scheduleCompositingLayerUpdate();
+            }
+        }
     }
 #endif    
 }
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index b112daf..d37bac3 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -91,6 +91,7 @@ struct CompositingState {
 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
     : m_renderView(renderView)
     , m_rootPlatformLayer(0)
+    , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
     , m_hasAcceleratedCompositing(true)
     , m_showDebugBorders(false)
     , m_showRepaintCounter(false)
@@ -168,8 +169,26 @@ void RenderLayerCompositor::scheduleSync()
     page->chrome()->client()->scheduleCompositingLayerSync();
 }
 
+void RenderLayerCompositor::scheduleCompositingLayerUpdate()
+{
+    if (!m_updateCompositingLayersTimer.isActive())
+        m_updateCompositingLayersTimer.startOneShot(0);
+}
+
+bool RenderLayerCompositor::compositingLayerUpdatePending() const
+{
+    return m_updateCompositingLayersTimer.isActive();
+}
+
+void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*)
+{
+    updateCompositingLayers();
+}
+
 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
 {
+    m_updateCompositingLayersTimer.stop();
+
     if (!m_compositingDependsOnGeometry && !m_compositing)
         return;
 
@@ -1396,7 +1415,7 @@ void RenderLayerCompositor::detachRootPlatformLayer()
             else
                 m_rootPlatformLayer->removeFromParent();
 
-            if (Element* ownerElement = m_renderView->document()->ownerElement())
+            if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
                 scheduleNeedsStyleRecalc(ownerElement);
             break;
         }
@@ -1457,6 +1476,11 @@ void RenderLayerCompositor::notifyIFramesOfCompositingChange()
         if (child->document() && child->document()->ownerElement())
             scheduleNeedsStyleRecalc(child->document()->ownerElement());
     }
+    
+    // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 
+    // we need to schedule a style recalc in our parent document.
+    if (HTMLFrameOwnerElement* ownerElement = m_renderView->document()->ownerElement())
+        scheduleNeedsStyleRecalc(ownerElement);
 }
 
 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
index 0ce80a9..c2db3e2 100644
--- a/WebCore/rendering/RenderLayerCompositor.h
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -88,7 +88,11 @@ public:
     
     // Rebuild the tree of compositing layers
     void updateCompositingLayers(CompositingUpdateType = CompositingUpdateAfterLayoutOrStyleChange, RenderLayer* updateRoot = 0);
-
+    // This is only used when state changes and we do not exepect a style update or layout to happen soon (e.g. when
+    // we discover that an iframe is overlapped during painting).
+    void scheduleCompositingLayerUpdate();
+    bool compositingLayerUpdatePending() const;
+    
     // Update the compositing state of the given layer. Returns true if that state changed.
     enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater };
     bool updateLayerCompositingState(RenderLayer*, CompositingChangeRepaint = CompositingChangeRepaintNow);
@@ -179,6 +183,8 @@ private:
     static void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed);
     static bool overlapsCompositedLayers(OverlapMap&, const IntRect& layerBounds);
 
+    void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
+
     // Returns true if any layer's compositing changed
     void computeCompositingRequirements(RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);
     
@@ -219,6 +225,8 @@ private:
 private:
     RenderView* m_renderView;
     OwnPtr<GraphicsLayer> m_rootPlatformLayer;
+    Timer<RenderLayerCompositor> m_updateCompositingLayersTimer;
+
     bool m_hasAcceleratedCompositing;
     bool m_showDebugBorders;
     bool m_showRepaintCounter;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list