2010-05-10 Simon Fraser <simon.fraser@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 May 2010 05:44:06 +0000 (05:44 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 May 2010 05:44:06 +0000 (05:44 +0000)
        Reviewed by Anders Carlsson

        Allow compositing layers to be connected across iframe boundaries on Mac
        https://bugs.webkit.org/show_bug.cgi?id=38856

        Changes to allow compositing layers for iframes to switch between being hosted
        by the iframe's layer-backed NSView, and parented in the GraphicsLayer tree of the
        enclosing document.

        Tests: compositing/iframes/connect-compositing-iframe.html
               compositing/iframes/connect-compositing-iframe2.html
               compositing/iframes/connect-compositing-iframe3.html

        * page/FrameView.h:
        * page/FrameView.cpp:
        (WebCore::FrameView::hasCompositedContent): New convenience method.
        (WebCore::FrameView::setIsOverlapped): If we're composited, poke the owner document in case it
            wants to re-evaluate compositing decisions.
        (WebCore::FrameView::isOverlapped): Just expose the existing flag.

        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::shouldBeNormalFlowOnly):
        (WebCore::RenderLayer::isSelfPaintingLayer):

        * rendering/RenderLayerBacking.cpp:
        (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): If this is an iframe, we need
            to ensure that the layers for the iframe content are hooked up.
        (WebCore::RenderLayerBacking::updateDrawsContent): When an iframe toggles between different
            attachments, the 'drawsContent' behavior of its root layer changes, so needs to be updated.

        * rendering/RenderLayerCompositor.h:
        (WebCore::RenderLayerCompositor::updateCompositingLayers): Call destroyRootPlatformLayer()
            instead of detachRootPlatformLayer() and manually zeroing out the OwnPtrs.
        (WebCore::RenderLayerCompositor::updateBacking): If a RenderIFrame changes compositing mode,
            we need to ensure that its content compositor attachment is updated.
        (WebCore::RenderLayerCompositor::repaintOnCompositingChange): The existing code had a bug
            that caused repaints for RenderViews (which have no parent) to bail. We only want to bail
            for non-RenderViews that are not attached.
        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Factored the iframe-connecting
            code into a new method, parentIFrameContentLayers().
        (WebCore::RenderLayerCompositor::parentIFrameContentLayers): New method to share the code that hooks
            up the iframe's compositing layers to the parent.
        (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame): Add logic to propagate
            compositing out of iframes on Mac in two situations: 1) when the FrameView is overlapped, and 2)
            if the parent document is already composited.
        (WebCore::RenderLayerCompositor::ensureRootPlatformLayer): Clean up the logic here to better deal
            with dynamic changes of the attachment type.
        (WebCore::RenderLayerCompositor::destroyRootPlatformLayer): Clean up and null out the clipping layer here.
        (WebCore::RenderLayerCompositor::attachRootPlatformLayer): Call rootLayerAttachmentChanged().
        (WebCore::RenderLayerCompositor::detachRootPlatformLayer): Ditto. Also unparent the clipping and platform layers.
        (WebCore::RenderLayerCompositor::updateRootLayerAttachment): Call ensureRootPlatformLayer() to re-evaluate
            the layer attachment.
        (WebCore::RenderLayerCompositor::rootLayerAttachmentChanged): We need to update the drawsContent() status
            of the RenderView's layer's backing, because it changes depending on the attachment.

        * rendering/RenderWidget.cpp:
        (WebCore::RenderWidget::paint): Do overlap testing if the frameView can do fast repaints (as before),
            but also now when the frameView has composited content.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@59136 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/iframes/composited-parent-iframe-expected.txt [new file with mode: 0644]
LayoutTests/compositing/iframes/composited-parent-iframe.html
LayoutTests/compositing/iframes/connect-compositing-iframe-expected.txt [new file with mode: 0644]
LayoutTests/compositing/iframes/connect-compositing-iframe.html [new file with mode: 0644]
LayoutTests/compositing/iframes/connect-compositing-iframe2-expected.txt [new file with mode: 0644]
LayoutTests/compositing/iframes/connect-compositing-iframe2.html [new file with mode: 0644]
LayoutTests/compositing/iframes/connect-compositing-iframe3-expected.txt [new file with mode: 0644]
LayoutTests/compositing/iframes/connect-compositing-iframe3.html [new file with mode: 0644]
LayoutTests/compositing/iframes/enter-compositing-iframe-expected.txt
LayoutTests/compositing/iframes/enter-compositing-iframe.html
LayoutTests/compositing/iframes/iframe-resize-expected.txt
LayoutTests/compositing/iframes/leave-compositing-iframe.html
LayoutTests/compositing/iframes/overlapped-iframe-expected.txt
LayoutTests/platform/mac/compositing/iframes/composited-parent-iframe-expected.txt [deleted file]
WebCore/ChangeLog
WebCore/page/FrameView.cpp
WebCore/page/FrameView.h
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderLayerBacking.cpp
WebCore/rendering/RenderLayerBacking.h
WebCore/rendering/RenderLayerCompositor.cpp
WebCore/rendering/RenderLayerCompositor.h
WebCore/rendering/RenderWidget.cpp

index bc97842..f7dcf23 100644 (file)
 
 2010-05-10  Simon Fraser  <simon.fraser@apple.com>
 
+        Reviewed by Anders Carlsson.
+
+        https://bugs.webkit.org/show_bug.cgi?id=38856
+        Allow compositing layers to be connected across iframe boundaries on Mac
+        
+        New expected results now that Mac propagates compositing out of iframes, if overlapped.
+        
+        Also add new tests to exercise the code that connects the compositing layers of
+        the iframe content with the parent document, for different compositing configurations.
+
+        * compositing/iframes/composited-parent-iframe-expected.txt: Added.
+        * compositing/iframes/composited-parent-iframe.html:
+        * compositing/iframes/connect-compositing-iframe-expected.txt: Added.
+        * compositing/iframes/connect-compositing-iframe.html: Added.
+        * compositing/iframes/connect-compositing-iframe2-expected.txt: Added.
+        * compositing/iframes/connect-compositing-iframe2.html: Added.
+        * compositing/iframes/connect-compositing-iframe3-expected.txt: Added.
+        * compositing/iframes/connect-compositing-iframe3.html: Added.
+        * compositing/iframes/enter-compositing-iframe-expected.txt:
+        * compositing/iframes/enter-compositing-iframe.html:
+        * compositing/iframes/iframe-resize-expected.txt:
+        * compositing/iframes/leave-compositing-iframe.html:
+        * compositing/iframes/overlapped-iframe-expected.txt:
+        * platform/mac/compositing/iframes/composited-parent-iframe-expected.txt: Removed.
+
+2010-05-10  Simon Fraser  <simon.fraser@apple.com>
+
         Fix up test results from last commit, which were generated with a build from before r59129.
 
         * platform/win/compositing/iframes/composited-parent-iframe-expected.txt:
diff --git a/LayoutTests/compositing/iframes/composited-parent-iframe-expected.txt b/LayoutTests/compositing/iframes/composited-parent-iframe-expected.txt
new file mode 100644 (file)
index 0000000..499bb24
--- /dev/null
@@ -0,0 +1,105 @@
+
+(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 1
+    (GraphicsLayer
+      (position -12.00 0.00)
+      (anchor 0.50 0.50)
+      (bounds 812.00 600.00)
+      (opacity 1.00)
+      (usingTiledLayer 0)
+      (preserves3D 0)
+      (drawsContent 0)
+      (backfaceVisibility visible)
+      (backgroundColor none)
+      (transform identity)
+      (childrenTransform identity)
+      (children 1
+        (GraphicsLayer
+          (position 0.00 -12.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
index d6dbe6c..d063c89 100644 (file)
@@ -9,7 +9,7 @@
         height: 150px;
         width: 300px;
         -webkit-box-shadow: 0 0 20px black;
-        -webkit-transform: translateX(0);
+        -webkit-transform: translateZ(0);
     }
   </style>
   <script type="text/javascript" charset="utf-8">
diff --git a/LayoutTests/compositing/iframes/connect-compositing-iframe-expected.txt b/LayoutTests/compositing/iframes/connect-compositing-iframe-expected.txt
new file mode 100644 (file)
index 0000000..b691f0e
--- /dev/null
@@ -0,0 +1,118 @@
+
+(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 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 8.00 8.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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 50.00 50.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/iframes/connect-compositing-iframe.html b/LayoutTests/compositing/iframes/connect-compositing-iframe.html
new file mode 100644 (file)
index 0000000..03fc05d
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    iframe {
+        border: 10px solid black;
+        padding: 5px;
+        margin: 20px;
+        height: 150px;
+        width: 300px;
+        -webkit-box-shadow: 0 0 20px black;
+        -webkit-transform: translateZ(0);
+    }
+    
+    .overlay {
+      position: absolute;
+      width: 50px;
+      height: 50px;
+      top: 5px;
+      left: 5px;
+      background-color: rgba(0, 0, 0, 0.2);
+    }
+    
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    // Called from subframe.
+    function testDone()
+    {
+      // Wait for a layer update.
+      window.setTimeout(function() {
+        if (window.layoutTestController) {
+          document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
+          layoutTestController.notifyDone();
+        }
+      }, 0);
+    }
+  </script>
+</head>
+<body>
+
+    <!-- Test with already-composited iframe, and iframe contents becoming composited. -->
+    <iframe id="parent-iframe" src="resources/enter-compositing-subframe.html"></iframe>
+    
+    <div class="overlay">
+    </div>
+
+    <pre id="layers">Layer tree appears here in DRT.</pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/iframes/connect-compositing-iframe2-expected.txt b/LayoutTests/compositing/iframes/connect-compositing-iframe2-expected.txt
new file mode 100644 (file)
index 0000000..b691f0e
--- /dev/null
@@ -0,0 +1,118 @@
+
+(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 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 8.00 8.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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 50.00 50.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/iframes/connect-compositing-iframe2.html b/LayoutTests/compositing/iframes/connect-compositing-iframe2.html
new file mode 100644 (file)
index 0000000..f033016
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    iframe {
+        border: 10px solid black;
+        padding: 5px;
+        margin: 20px;
+        height: 150px;
+        width: 300px;
+        -webkit-box-shadow: 0 0 20px black;
+        -webkit-transform: translateZ(0);
+    }
+    
+    .overlay {
+      position: absolute;
+      width: 50px;
+      height: 50px;
+      top: 5px;
+      left: 5px;
+      background-color: rgba(0, 0, 0, 0.2);
+    }
+    
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    function doTest()
+    {
+      document.getElementById('iframe').className = 'composited';
+
+      // Wait for a layer update.
+      window.setTimeout(function() {
+        if (window.layoutTestController) {
+          document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
+          layoutTestController.notifyDone();
+        }
+      }, 0);
+    }
+    
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+    <!-- Test with already-composited iframe, and iframe contents becoming composited. -->
+    <iframe id="iframe" src="resources/composited-subframe.html"></iframe>
+    
+    <div class="overlay">
+    </div>
+
+    <pre id="layers">Layer tree appears here in DRT.</pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/iframes/connect-compositing-iframe3-expected.txt b/LayoutTests/compositing/iframes/connect-compositing-iframe3-expected.txt
new file mode 100644 (file)
index 0000000..8487469
--- /dev/null
@@ -0,0 +1,105 @@
+
+(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 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 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/iframes/connect-compositing-iframe3.html b/LayoutTests/compositing/iframes/connect-compositing-iframe3.html
new file mode 100644 (file)
index 0000000..935a98e
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    iframe {
+        border: 10px solid black;
+        padding: 5px;
+        margin: 20px;
+        height: 150px;
+        width: 300px;
+        -webkit-box-shadow: 0 0 20px black;
+    }
+    
+    .composited {
+      -webkit-transform: translateZ(0);
+    }
+    
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    function doTest()
+    {
+      document.getElementById('iframe').className = 'composited';
+
+      // Wait for a layer update.
+      window.setTimeout(function() {
+        if (window.layoutTestController) {
+          document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
+          layoutTestController.notifyDone();
+        }
+      }, 0);
+    }
+    
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+    <!-- Test with already-composited iframe contents, and iframe itself composited. -->
+    <iframe id="iframe" src="resources/composited-subframe.html"></iframe>
+    
+    <pre id="layers">Layer tree appears here in DRT.</pre>
+</body>
+</html>
index 139597f..b691f0e 100644 (file)
@@ -1,2 +1,118 @@
 
+(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 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 8.00 8.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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 50.00 50.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+        )
+      )
+    )
+  )
+)
 
index f263e04..d5c9cb2 100644 (file)
     // Called from subframe.
     function testDone()
     {
-      if (window.layoutTestController) {
-        document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
-        layoutTestController.notifyDone();
-      }
+      // Wait for a layer update.
+      window.setTimeout(function() {
+        if (window.layoutTestController) {
+          document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
+          layoutTestController.notifyDone();
+        }
+      }, 0);
     }
   </script>
 </head>
index 139597f..b691f0e 100644 (file)
@@ -1,2 +1,118 @@
 
+(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 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 8.00 8.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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 50.00 50.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+        )
+      )
+    )
+  )
+)
 
index 07c7662..781b7ce 100644 (file)
     // Called from subframe.
     function testDone()
     {
-      if (window.layoutTestController) {
-        document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
-        layoutTestController.notifyDone();
-      }
+      // Wait for a layer update.
+      window.setTimeout(function() {
+        if (window.layoutTestController) {
+          document.getElementById('layers').innerText = layoutTestController.layerTreeAsText();
+          layoutTestController.notifyDone();
+        }
+      }, 0);
     }
   </script>
 </head>
index 139597f..b691f0e 100644 (file)
@@ -1,2 +1,118 @@
 
+(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 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 8.00 8.00)
+          (anchor 0.50 0.50)
+          (bounds 370.00 220.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+          (children 1
+            (GraphicsLayer
+              (position 35.00 35.00)
+              (anchor 0.50 0.50)
+              (bounds 300.00 150.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 285.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 285.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 50.00 50.00)
+          (opacity 1.00)
+          (usingTiledLayer 0)
+          (preserves3D 0)
+          (drawsContent 1)
+          (backfaceVisibility visible)
+          (backgroundColor none)
+          (transform identity)
+          (childrenTransform identity)
+        )
+      )
+    )
+  )
+)
 
diff --git a/LayoutTests/platform/mac/compositing/iframes/composited-parent-iframe-expected.txt b/LayoutTests/platform/mac/compositing/iframes/composited-parent-iframe-expected.txt
deleted file mode 100644 (file)
index 139597f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
index 5ded087..6a4e7bc 100644 (file)
@@ -5,6 +5,67 @@
         Allow compositing layers to be connected across iframe boundaries on Mac
         https://bugs.webkit.org/show_bug.cgi?id=38856
 
+        Changes to allow compositing layers for iframes to switch between being hosted
+        by the iframe's layer-backed NSView, and parented in the GraphicsLayer tree of the
+        enclosing document.
+
+        Tests: compositing/iframes/connect-compositing-iframe.html
+               compositing/iframes/connect-compositing-iframe2.html
+               compositing/iframes/connect-compositing-iframe3.html
+
+        * page/FrameView.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::hasCompositedContent): New convenience method.
+        (WebCore::FrameView::setIsOverlapped): If we're composited, poke the owner document in case it
+            wants to re-evaluate compositing decisions.
+        (WebCore::FrameView::isOverlapped): Just expose the existing flag.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::shouldBeNormalFlowOnly):
+        (WebCore::RenderLayer::isSelfPaintingLayer):
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): If this is an iframe, we need
+            to ensure that the layers for the iframe content are hooked up.
+        (WebCore::RenderLayerBacking::updateDrawsContent): When an iframe toggles between different
+            attachments, the 'drawsContent' behavior of its root layer changes, so needs to be updated.
+
+        * rendering/RenderLayerCompositor.h:
+        (WebCore::RenderLayerCompositor::updateCompositingLayers): Call destroyRootPlatformLayer()
+            instead of detachRootPlatformLayer() and manually zeroing out the OwnPtrs.
+        (WebCore::RenderLayerCompositor::updateBacking): If a RenderIFrame changes compositing mode,
+            we need to ensure that its content compositor attachment is updated.
+        (WebCore::RenderLayerCompositor::repaintOnCompositingChange): The existing code had a bug
+            that caused repaints for RenderViews (which have no parent) to bail. We only want to bail
+            for non-RenderViews that are not attached.
+        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Factored the iframe-connecting
+            code into a new method, parentIFrameContentLayers().
+        (WebCore::RenderLayerCompositor::parentIFrameContentLayers): New method to share the code that hooks
+            up the iframe's compositing layers to the parent.
+        (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame): Add logic to propagate
+            compositing out of iframes on Mac in two situations: 1) when the FrameView is overlapped, and 2)
+            if the parent document is already composited.
+        (WebCore::RenderLayerCompositor::ensureRootPlatformLayer): Clean up the logic here to better deal
+            with dynamic changes of the attachment type.
+        (WebCore::RenderLayerCompositor::destroyRootPlatformLayer): Clean up and null out the clipping layer here.
+        (WebCore::RenderLayerCompositor::attachRootPlatformLayer): Call rootLayerAttachmentChanged().
+        (WebCore::RenderLayerCompositor::detachRootPlatformLayer): Ditto. Also unparent the clipping and platform layers.
+        (WebCore::RenderLayerCompositor::updateRootLayerAttachment): Call ensureRootPlatformLayer() to re-evaluate
+            the layer attachment.
+        (WebCore::RenderLayerCompositor::rootLayerAttachmentChanged): We need to update the drawsContent() status
+            of the RenderView's layer's backing, because it changes depending on the attachment.
+
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paint): Do overlap testing if the frameView can do fast repaints (as before),
+            but also now when the frameView has composited content.
+
+2010-05-10  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Anders Carlsson
+
+        Allow compositing layers to be connected across iframe boundaries on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=38856
+
         Rename the static shouldPropagateCompositingToIFrameParent() to shouldPropagateCompositingToEnclosingIFrame(),
         to pave the way for runtime switches in the propagation behavior. We have to make sure we call it on
         the correct RenderLayerCompositor (that belonging to the iframe's content document).
index 9b93beb..3f34261 100644 (file)
@@ -478,6 +478,15 @@ void FrameView::setNeedsOneShotDrawingSynchronization()
 
 #endif // USE(ACCELERATED_COMPOSITING)
 
+bool FrameView::hasCompositedContent() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+    if (RenderView* view = m_frame->contentRenderer())
+        return view->compositor()->inCompositingMode();
+#endif
+    return false;
+}
+
 bool FrameView::isEnclosedInCompositingLayer() const
 {
 #if USE(ACCELERATED_COMPOSITING)
@@ -897,6 +906,15 @@ void FrameView::setIsOverlapped(bool isOverlapped)
 
     m_isOverlapped = isOverlapped;
     setCanBlitOnScroll(!useSlowRepaints());
+    
+#if USE(ACCELERATED_COMPOSITING)
+    // Overlap can affect compositing tests, so if it changes, we need to trigger
+    // a recalcStyle in the parent document.
+    if (hasCompositedContent()) {
+        if (Element* ownerElement = m_frame->document()->ownerElement())
+            ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
+    }
+#endif    
 }
 
 void FrameView::setContentIsOpaque(bool contentIsOpaque)
index efceebe..f6dfb1d 100644 (file)
@@ -105,6 +105,7 @@ public:
     void setNeedsOneShotDrawingSynchronization();
 #endif
 
+    bool hasCompositedContent() const;
     bool isEnclosedInCompositingLayer() const;
 
     // Only used with accelerated compositing, but outside the #ifdef to make linkage easier.
@@ -149,6 +150,7 @@ public:
 
     void setUseSlowRepaints();
     void setIsOverlapped(bool);
+    bool isOverlapped() const { return m_isOverlapped; }
     void setContentIsOpaque(bool);
 
     void addSlowRepaintObject();
index d11254d..f047837 100644 (file)
@@ -3429,16 +3429,16 @@ void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject
 
 bool RenderLayer::shouldBeNormalFlowOnly() const
 {
-    return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo() || renderer()->isEmbeddedObject()) &&
-           !renderer()->isPositioned() &&
-           !renderer()->isRelPositioned() &&
-           !renderer()->hasTransform() &&
-           !isTransparent();
+    return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo() || renderer()->isEmbeddedObject() || renderer()->isRenderIFrame())
+            && !renderer()->isPositioned()
+            && !renderer()->isRelPositioned()
+            && !renderer()->hasTransform()
+            && !isTransparent();
 }
 
 bool RenderLayer::isSelfPaintingLayer() const
 {
-    return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject();
+    return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject() || renderer()->isRenderIFrame();
 }
 
 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
index ff7f6ba..310a9c2 100644 (file)
@@ -233,6 +233,9 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
     }
 #endif
 
+    if (renderer()->isRenderIFrame())
+        layerConfigChanged = RenderLayerCompositor::parentIFrameContentLayers(toRenderIFrame(renderer()));
+
     return layerConfigChanged;
 }
 
@@ -385,7 +388,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
     }
 
     m_graphicsLayer->setContentsRect(contentsBox());
-    m_graphicsLayer->setDrawsContent(containsPaintedContent());
+    updateDrawsContent();
 
     // If this is an iframe parent, update the iframe content's box
     if (renderer()->isRenderIFrame()) {
@@ -410,6 +413,11 @@ void RenderLayerBacking::updateInternalHierarchy()
     }
 }
 
+void RenderLayerBacking::updateDrawsContent()
+{
+    m_graphicsLayer->setDrawsContent(containsPaintedContent());
+}
+
 // Return true if the layers changed.
 bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
 {
index a6907e7..ff8c76c 100644 (file)
@@ -62,6 +62,7 @@ public:
     void updateGraphicsLayerGeometry(); // make private
     // Update contents and clipping structure.
     void updateInternalHierarchy(); // make private
+    void updateDrawsContent();
     
     GraphicsLayer* graphicsLayer() const { return m_graphicsLayer.get(); }
 
index 0223a25..b20a50a 100644 (file)
@@ -224,14 +224,9 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
 
         // Host the document layer in the RenderView's root layer.
         if (updateRoot == rootRenderLayer()) {
-            if (childList.isEmpty()) {
-                detachRootPlatformLayer();
-                if (m_clippingLayer) {
-                    m_clippingLayer->removeAllChildren();
-                    m_clippingLayer = 0;
-                }
-                m_rootPlatformLayer = 0;
-            } else
+            if (childList.isEmpty())
+                destroyRootPlatformLayer();
+            else
                 m_rootPlatformLayer->setChildren(childList);
         }
     } else if (needGeometryUpdate) {
@@ -305,6 +300,13 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR
         video->acceleratedRenderingStateChanged();
     }
 #endif
+
+    if (layerChanged && layer->renderer()->isRenderIFrame()) {
+        RenderLayerCompositor* innerCompositor = iframeContentsCompositor(toRenderIFrame(layer->renderer()));
+        if (innerCompositor && innerCompositor->inCompositingMode())
+            innerCompositor->updateRootLayerAttachment();
+    }
+
     return layerChanged;
 }
 
@@ -323,7 +325,7 @@ bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, Comp
 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
 {
     // If the renderer is not attached yet, no need to repaint.
-    if (!layer->renderer()->parent())
+    if (layer->renderer() != m_renderView && !layer->renderer()->parent())
         return;
 
     RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint();
@@ -750,18 +752,8 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons
     
     if (layerBacking) {
         bool parented = false;
-        if (layer->renderer()->isRenderIFrame()) {
-            RenderLayerCompositor* innerCompositor = iframeContentsCompositor(toRenderIFrame(layer->renderer()));
-            if (innerCompositor->inCompositingMode() && innerCompositor->rootLayerAttachment() == RootLayerAttachedViaEnclosingIframe) {
-                // This is an iframe parent. Make it the parent of the iframe document's root
-                layerBacking->parentForSublayers()->removeAllChildren();
-                GraphicsLayer* innerRootLayer = innerCompositor->rootPlatformLayer();
-                if (innerRootLayer) {
-                    layerBacking->parentForSublayers()->addChild(innerRootLayer);
-                    parented = true;
-                }
-            }
-        }
+        if (layer->renderer()->isRenderIFrame())
+            parented = parentIFrameContentLayers(toRenderIFrame(layer->renderer()));
         
         if (!parented)
             layerBacking->parentForSublayers()->setChildren(layerChildren);
@@ -788,6 +780,26 @@ RenderLayerCompositor* RenderLayerCompositor::iframeContentsCompositor(RenderIFr
     return 0;
 }
 
+bool RenderLayerCompositor::parentIFrameContentLayers(RenderIFrame* renderer)
+{
+    RenderLayerCompositor* innerCompositor = iframeContentsCompositor(renderer);
+    if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingIframe)
+        return false;
+    
+    RenderLayer* layer = renderer->layer();
+    if (!layer->isComposited())
+        return false;
+
+    RenderLayerBacking* backing = layer->backing();
+    GraphicsLayer* hostingLayer = backing->parentForSublayers();
+    GraphicsLayer* rootLayer = innerCompositor->rootPlatformLayer();
+    if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
+        hostingLayer->removeAllChildren();
+        hostingLayer->addChild(rootLayer);
+    }
+    return true;
+}
+
 // This just updates layer geometry without changing the hierarchy.
 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
 {
@@ -981,12 +993,31 @@ bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame() const
     // Parent document content needs to be able to render on top of a composited iframe, so correct behavior
     // is to have the parent document become composited too. However, this can cause problems on platforms that
     // use native views for frames (like Mac), so disable that behavior on those platforms for now.
+    Element* ownerElement = enclosingIFrameElement();
+    RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
+    if (!renderer || !renderer->isRenderIFrame())
+        return false;
+
 #if !PLATFORM(MAC)
-    if (Element* ownerElement = enclosingIFrameElement()) {
-        if (RenderObject* renderer = ownerElement->renderer())
-            return renderer->isRenderIFrame();
-    }
+    // On non-Mac platforms, let compositing propagate for all iframes.
+    return true;
 #endif
+
+    // On Mac, only propagate compositing if the iframe is overlapped in the parent
+    // document, or the parent is already compositing.
+    RenderIFrame* iframeRenderer = toRenderIFrame(renderer);
+    if (iframeRenderer->widget()) {
+        ASSERT(iframeRenderer->widget()->isFrameView());
+        FrameView* view = static_cast<FrameView*>(iframeRenderer->widget());
+        if (view->isOverlapped())
+            return true;
+        
+        if (RenderView* view = iframeRenderer->view()) {
+            if (view->compositor()->inCompositingMode())
+                return true;
+        }
+    }
+
     return false;
 }
 
@@ -1187,16 +1218,26 @@ void RenderLayerCompositor::ensureRootPlatformLayer()
     // The root layer does flipping if we need it on this platform.
     m_rootPlatformLayer->setGeometryOrientation(expectedAttachment == RootLayerAttachedViaEnclosingIframe ? GraphicsLayer::CompositingCoordinatesTopDown : GraphicsLayer::compositingCoordinatesOrientation());
     
-    if (expectedAttachment == RootLayerAttachedViaEnclosingIframe && !m_clippingLayer) {
-        // Create a clipping layer if this is an iframe
-        m_clippingLayer = GraphicsLayer::create(0);
+    if (expectedAttachment == RootLayerAttachedViaEnclosingIframe) {
+        if (!m_clippingLayer) {
+            // Create a clipping layer if this is an iframe
+            m_clippingLayer = GraphicsLayer::create(0);
 #ifndef NDEBUG
-        m_clippingLayer->setName("iframe Clipping");
+            m_clippingLayer->setName("iframe Clipping");
 #endif
-        m_clippingLayer->setMasksToBounds(true);
-        m_clippingLayer->addChild(m_rootPlatformLayer.get());
+            m_clippingLayer->setMasksToBounds(true);
+            m_clippingLayer->addChild(m_rootPlatformLayer.get());
+        }
+    } else if (m_clippingLayer) {
+        m_clippingLayer->removeAllChildren();
+        m_clippingLayer->removeFromParent();
+        m_clippingLayer = 0;
     }
 
+    // Check to see if we have to change the attachment
+    if (m_rootLayerAttachment != RootLayerUnattached)
+        detachRootPlatformLayer();
+
     attachRootPlatformLayer(expectedAttachment);
 }
 
@@ -1206,6 +1247,10 @@ void RenderLayerCompositor::destroyRootPlatformLayer()
         return;
 
     detachRootPlatformLayer();
+    if (m_clippingLayer) {
+        m_clippingLayer->removeAllChildren();
+        m_clippingLayer = 0;
+    }
     m_rootPlatformLayer = 0;
 }
 
@@ -1236,6 +1281,7 @@ void RenderLayerCompositor::attachRootPlatformLayer(RootLayerAttachment attachme
     }
     
     m_rootLayerAttachment = attachment;
+    rootLayerAttachmentChanged();
 }
 
 void RenderLayerCompositor::detachRootPlatformLayer()
@@ -1247,6 +1293,10 @@ void RenderLayerCompositor::detachRootPlatformLayer()
         case RootLayerAttachedViaEnclosingIframe: {
             // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
             // for the iframe's renderer in the parent document.
+            if (m_clippingLayer)
+                m_clippingLayer->removeFromParent();
+            else
+                m_rootPlatformLayer->removeFromParent();
             m_renderView->document()->ownerElement()->setNeedsStyleRecalc(SyntheticStyleChange);
             break;
         }
@@ -1264,6 +1314,21 @@ void RenderLayerCompositor::detachRootPlatformLayer()
     }
 
     m_rootLayerAttachment = RootLayerUnattached;
+    rootLayerAttachmentChanged();
+}
+
+void RenderLayerCompositor::updateRootLayerAttachment()
+{
+    ensureRootPlatformLayer();
+}
+
+void RenderLayerCompositor::rootLayerAttachmentChanged()
+{
+    // The attachment can affect whether the RenderView layer's paintingGoesToWindow() behavior,
+    // so call updateGraphicsLayerGeometry() to udpate that.
+    RenderLayer* layer = m_renderView->layer();
+    if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
+        backing->updateDrawsContent();
 }
 
 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
index d47cb2c..ffe584e 100644 (file)
@@ -129,11 +129,11 @@ public:
     };
 
     RootLayerAttachment rootLayerAttachment() const { return m_rootLayerAttachment; }
-
+    void updateRootLayerAttachment();
+    void updateRootLayerPosition();
+    
     void didMoveOnscreen();
     void willMoveOffscreen();
-
-    void updateRootLayerPosition();
     
     void didStartAcceleratedAnimation();
     
@@ -151,7 +151,10 @@ public:
     bool shouldPropagateCompositingToEnclosingIFrame() const;
 
     Element* enclosingIFrameElement() const;
+
     static RenderLayerCompositor* iframeContentsCompositor(RenderIFrame*);
+    // Return true if the layers changed.
+    static bool parentIFrameContentLayers(RenderIFrame*);
 
     void setRootPlatformLayerClippingBox(const IntRect& contentsBox);
 
@@ -194,6 +197,8 @@ private:
     void attachRootPlatformLayer(RootLayerAttachment);
     void detachRootPlatformLayer();
     
+    void rootLayerAttachmentChanged();
+
     // Whether a running transition or animation enforces the need for a compositing layer.
     bool requiresCompositingForAnimation(RenderObject*) const;
     bool requiresCompositingForTransform(RenderObject*) const;
index 7f5fabc..925b7d9 100644 (file)
@@ -282,10 +282,15 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
             if (!paintOffset.isZero())
                 paintInfo.context->translate(-paintOffset);
         }
-        if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaintsIfNotOverlapped()) {
-            ASSERT(!paintInfo.overlapTestRequests->contains(this));
-            paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
-        }
+
+        if (m_widget->isFrameView()) {
+            FrameView* frameView = static_cast<FrameView*>(m_widget.get());
+            bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContent();
+            if (paintInfo.overlapTestRequests && runOverlapTests) {
+                ASSERT(!paintInfo.overlapTestRequests->contains(this));
+                paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
+            }
+         }
     }
 
     if (style()->hasBorderRadius())