Commit 10c77cf0 authored by cmarrin@apple.com's avatar cmarrin@apple.com

Reviewed by Simon Fraser.

        Made composited iframes work on Windows
        https://bugs.webkit.org/show_bug.cgi?id=32446
        
        This completes the work in http://trac.webkit.org/changeset/57919
        to create compositing layers in the parent document when an iframe has 
        a compositing layer. The parent document has a layer for the iframe 
        element and builds a layer tree to the page root. The layer tree for the
        iframe document is then parented to the iframe element's GraphicsLayer.
        
        The RenderLayerCompositor for the iframe document (which owns the
        root of the layer tree) now has a clippingLayer which is the 
        parent of the layer tree root so it can be clipped to the parent
        iframe's bounds, taking into account borders, padding, etc. in
        the parent iframe element.
        
        I also got rid of a no longer used function: RenderLayerCompositor::parentInRootLayer

        Test: compositing/iframes/composited-parent-iframe.html

        * rendering/RenderLayerBacking.cpp:Make calls to RenderLayerCompositor to set the clipping bounds for iframe content
        * rendering/RenderLayerCompositor.cpp:Hook the iframe content to the parent iframe element
        * rendering/RenderLayerCompositor.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@58797 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 7f75bba5
2010-05-04 Chris Marrin <cmarrin@apple.com>
Reviewed by Simon Fraser.
Made composited iframes work on Windows
https://bugs.webkit.org/show_bug.cgi?id=32446
I've added one new test (composited-parent-iframe.html) which
shows both the parent iframe and the iframe contents document
with compositing. It also shows correct behavior with clipping,
borders, margins, padding and shadows. It also sets the iframe
size as a percent of the page to show correct resizing behavior.
The existing composited-iframe.html has been changed similarly
but without the page resizing. The existing preserve-3d-switching.html
test needed new results because of changes to the layer dumper.
* compositing/geometry/preserve-3d-switching-expected.txt:
* compositing/iframes/composited-iframe.html:
* compositing/iframes/composited-parent-iframe.html: Added.
* compositing/iframes/resources/composited-subframe.html:
* platform/win/compositing/iframes/composited-iframe-expected.txt:
* platform/win/compositing/iframes/composited-parent-iframe-expected.txt: Added.
2010-05-04 Alexey Proskuryakov <ap@apple.com>
Not reviewed.
......
......@@ -4,9 +4,11 @@
<head>
<style type="text/css" media="screen">
iframe {
border: 2px solid black;
height: 150px;
width: 300px;
border: 10px solid black;
padding: 10px;
height: 60%;
width: 80%;
-webkit-box-shadow: 0 0 20px black;
}
</style>
<script type="text/javascript" charset="utf-8">
......@@ -32,7 +34,7 @@
<body>
<!-- The parent document should be thrown into compositing mode by the iframe. -->
<iframe src="resources/composited-subframe.html"></iframe>
<iframe id="parent-iframe" src="resources/composited-subframe.html"></iframe>
<pre id="layers">Layer tree appears here in DRT.</pre>
</body>
......
<!DOCTYPE html>
<html>
<head>
<style type="text/css" media="screen">
iframe {
border: 10px solid black;
padding: 5px;
height: 150px;
width: 300px;
-webkit-box-shadow: 0 0 20px black;
-webkit-transform: translateX(0);
}
</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() {
if (window.layoutTestController) {
document.getElementById('layers').innerHTML = layoutTestController.layerTreeAsText();
layoutTestController.notifyDone();
}
}, 0);
}
window.addEventListener('load', doTest, false);
</script>
</head>
<body>
<!-- The parent document should be thrown into compositing mode by the iframe. -->
<iframe id="parent-iframe" src="resources/composited-subframe.html"></iframe>
<pre id="layers">Layer tree appears here in DRT.</pre>
</body>
</html>
......@@ -3,18 +3,25 @@
<html>
<head>
<style type="text/css" media="screen">
body { background-color:silver }
.box {
height: 100px;
width: 100px;
height: 200px;
width: 200px;
margin: 10px;
padding: 5px;
background-color: blue;
-webkit-transform: translateZ(0);
overflow:hidden;
}
.box:hover {
-webkit-transform: none;
}
</style>
</head>
<body>
<div class="box">
<div id="iframe-content" class="box">
</div>
</body>
......
......@@ -13,9 +13,9 @@
(childrenTransform identity)
(children 1
(GraphicsLayer
(position 0.00 0.00)
(position -12.00 0.00)
(anchor 0.50 0.50)
(bounds 800.00 600.00)
(bounds 812.00 600.00)
(opacity 1.00)
(usingTiledLayer 0)
(preserves3D 0)
......@@ -26,9 +26,9 @@
(childrenTransform identity)
(children 1
(GraphicsLayer
(position 8.00 8.00)
(position 0.00 -12.00)
(anchor 0.50 0.50)
(bounds 304.00 154.00)
(bounds 707.00 440.00)
(opacity 1.00)
(usingTiledLayer 0)
(preserves3D 0)
......@@ -37,6 +37,66 @@
(backgroundColor none)
(transform identity)
(childrenTransform identity)
(children 1
(GraphicsLayer
(position 40.00 40.00)
(anchor 0.00 0.00)
(bounds 627.00 360.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 627.00 360.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 627.00 360.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 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.00 0.00)
(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 -80.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)
)
)
)
)
)
)
)
)
)
)
)
)
)
2010-05-04 Chris Marrin <cmarrin@apple.com>
Reviewed by Simon Fraser.
Made composited iframes work on Windows
https://bugs.webkit.org/show_bug.cgi?id=32446
This completes the work in http://trac.webkit.org/changeset/57919
to create compositing layers in the parent document when an iframe has
a compositing layer. The parent document has a layer for the iframe
element and builds a layer tree to the page root. The layer tree for the
iframe document is then parented to the iframe element's GraphicsLayer.
The RenderLayerCompositor for the iframe document (which owns the
root of the layer tree) now has a clippingLayer which is the
parent of the layer tree root so it can be clipped to the parent
iframe's bounds, taking into account borders, padding, etc. in
the parent iframe element.
I also got rid of a no longer used function: RenderLayerCompositor::parentInRootLayer
Test: compositing/iframes/composited-parent-iframe.html
* rendering/RenderLayerBacking.cpp:Make calls to RenderLayerCompositor to set the clipping bounds for iframe content
* rendering/RenderLayerCompositor.cpp:Hook the iframe content to the parent iframe element
* rendering/RenderLayerCompositor.h:
2010-05-03 Alexey Proskuryakov <ap@apple.com>
Reviewed by Adam Barth.
......@@ -38,6 +38,7 @@
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
#include "HTMLIFrameElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "InspectorTimelineAgent.h"
......@@ -384,6 +385,24 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_graphicsLayer->setContentsRect(contentsBox());
m_graphicsLayer->setDrawsContent(containsPaintedContent());
// If this is an iframe parent, update the iframe content's box
RenderLayerCompositor* innerCompositor = innerRenderLayerCompositor();
if (innerCompositor)
innerCompositor->setRootPlatformLayerClippingBox(contentsBox());
}
RenderLayerCompositor* RenderLayerBacking::innerRenderLayerCompositor() const
{
if (renderer()->isRenderIFrame()) {
HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(renderer()->node());
if (Document* contentDocument = element->contentDocument()) {
if (RenderView* view = contentDocument->renderView())
return view->compositor();
}
}
return 0;
}
void RenderLayerBacking::updateInternalHierarchy()
......@@ -823,7 +842,11 @@ FloatPoint RenderLayerBacking::contentsToGraphicsLayerCoordinates(const Graphics
bool RenderLayerBacking::paintingGoesToWindow() const
{
return m_owningLayer->isRootLayer();
if (!m_owningLayer->isRootLayer())
return false;
// Iframe root layers paint into backing store.
return !toRenderView(renderer())->document()->ownerElement();
}
void RenderLayerBacking::setContentsNeedDisplay()
......
......@@ -124,6 +124,8 @@ public:
IntRect contentsBox() const;
RenderLayerCompositor* innerRenderLayerCompositor() const;
private:
void createGraphicsLayer();
void destroyGraphicsLayer();
......
......@@ -37,6 +37,7 @@
#include "GraphicsLayer.h"
#include "HitTestResult.h"
#include "HTMLCanvasElement.h"
#include "HTMLIFrameElement.h"
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
......@@ -664,19 +665,6 @@ void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
hostingLayer->removeAllChildren();
}
void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer)
{
ASSERT(layer->isComposited());
GraphicsLayer* layerAnchor = layer->backing()->childForSuperlayers();
if (layerAnchor->parent() != m_rootPlatformLayer) {
layerAnchor->removeFromParent();
if (m_rootPlatformLayer)
m_rootPlatformLayer->addChild(layerAnchor);
}
}
#if ENABLE(VIDEO)
bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
{
......@@ -764,11 +752,30 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons
}
if (layerBacking) {
layerBacking->parentForSublayers()->setChildren(layerChildren);
if (layer->renderer()->isRenderIFrame()) {
// This is an iframe parent. Make it the parent of the iframe document's root
layerBacking->parentForSublayers()->removeAllChildren();
RenderLayerCompositor* innerCompositor = layerBacking->innerRenderLayerCompositor();
if (innerCompositor) {
GraphicsLayer* innerRootLayer = innerCompositor->rootPlatformLayer();
if (innerRootLayer)
layerBacking->parentForSublayers()->addChild(innerRootLayer);
}
} else
layerBacking->parentForSublayers()->setChildren(layerChildren);
childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
}
}
void RenderLayerCompositor::setRootPlatformLayerClippingBox(const IntRect& contentsBox)
{
if (m_clippingLayer) {
m_clippingLayer->setPosition(FloatPoint(contentsBox.x(), contentsBox.y()));
m_clippingLayer->setSize(FloatSize(contentsBox.width(), contentsBox.height()));
}
}
// This just updates layer geometry without changing the hierarchy.
void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
{
......@@ -922,7 +929,7 @@ RenderLayer* RenderLayerCompositor::rootRenderLayer() const
GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
{
return m_rootPlatformLayer.get();
return m_clippingLayer ? m_clippingLayer.get() : m_rootPlatformLayer.get();
}
void RenderLayerCompositor::didMoveOnscreen()
......@@ -930,13 +937,27 @@ void RenderLayerCompositor::didMoveOnscreen()
if (!m_rootPlatformLayer)
return;
Frame* frame = m_renderView->frameView()->frame();
Page* page = frame ? frame->page() : 0;
if (!page)
return;
bool attached = false;
Element* ownerElement = m_renderView->document()->ownerElement();
if (ownerElement) {
RenderObject* renderer = ownerElement->renderer();
if (renderer && renderer->isRenderIFrame()) {
// The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
// for the iframe's renderer in the parent document.
ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
attached = true;
}
}
page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get());
m_rootLayerAttached = true;
if (!attached) {
Frame* frame = m_renderView->frameView()->frame();
Page* page = frame ? frame->page() : 0;
if (!page)
return;
page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get());
}
m_rootLayerAttached = true;
}
void RenderLayerCompositor::willMoveOffscreen()
......@@ -944,19 +965,44 @@ void RenderLayerCompositor::willMoveOffscreen()
if (!m_rootPlatformLayer || !m_rootLayerAttached)
return;
Frame* frame = m_renderView->frameView()->frame();
Page* page = frame ? frame->page() : 0;
if (!page)
return;
bool detached = false;
Element* ownerElement = m_renderView->document()->ownerElement();
if (ownerElement) {
RenderObject* renderer = ownerElement->renderer();
if (renderer->isRenderIFrame()) {
// The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
// for the iframe's renderer in the parent document.
ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
detached = true;
}
}
if (!detached) {
Frame* frame = m_renderView->frameView()->frame();
Page* page = frame ? frame->page() : 0;
if (!page)
return;
page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
}
m_rootLayerAttached = false;
}
void RenderLayerCompositor::updateRootLayerPosition()
{
if (m_rootPlatformLayer)
m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
if (m_rootPlatformLayer) {
// FIXME: Adjust the y position of the m_rootPlatformLayer if we are clipping by its top edge
// Eventually this will be taken care of by scrolling logic
// https://bugs.webkit.org/show_bug.cgi?id=38518
float height = m_renderView->bottomLayoutOverflow();
float yOffset = 0;
if (m_clippingLayer && height > m_clippingLayer->size().height())
yOffset = m_clippingLayer->size().height() - height;
m_rootPlatformLayer->setPosition(FloatPoint(0, yOffset));
m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), height));
}
}
void RenderLayerCompositor::didStartAcceleratedAnimation()
......@@ -1152,13 +1198,30 @@ void RenderLayerCompositor::ensureRootPlatformLayer()
m_rootPlatformLayer = GraphicsLayer::create(0);
m_rootPlatformLayer->setSize(FloatSize(m_renderView->rightLayoutOverflow(), m_renderView->bottomLayoutOverflow()));
m_rootPlatformLayer->setPosition(FloatPoint(0, 0));
m_rootPlatformLayer->setPosition(FloatPoint());
// The root layer does flipping if we need it on this platform.
m_rootPlatformLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation());
// Need to clip to prevent transformed content showing outside this frame
m_rootPlatformLayer->setMasksToBounds(true);
// Create a clipping layer if this is an iframe
Element* ownerElement = m_renderView->document()->ownerElement();
if (ownerElement) {
RenderObject* renderer = ownerElement->renderer();
if (renderer && renderer->isRenderIFrame()) {
m_clippingLayer = GraphicsLayer::create(0);
m_clippingLayer->setGeometryOrientation(GraphicsLayer::compositingCoordinatesOrientation());
#ifndef NDEBUG
m_clippingLayer->setName("iframe Clipping");
#endif
m_clippingLayer->setMasksToBounds(true);
m_clippingLayer->setAnchorPoint(FloatPoint());
m_clippingLayer->addChild(m_rootPlatformLayer.get());
}
}
didMoveOnscreen();
}
......
......@@ -141,6 +141,8 @@ public:
// their parent document.
static bool shouldPropagateCompositingToIFrameParent();
void setRootPlatformLayerClippingBox(const IntRect& contentsBox);
private:
// Whether the given RL needs a compositing layer.
bool needsToBeComposited(const RenderLayer*) const;
......@@ -172,8 +174,6 @@ private:
void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
void removeCompositedChildren(RenderLayer*);
void parentInRootLayer(RenderLayer*);
bool layerHas3DContent(const RenderLayer*) const;
void ensureRootPlatformLayer();
......@@ -198,6 +198,9 @@ private:
bool m_compositing;
bool m_rootLayerAttached;
bool m_compositingLayersNeedRebuild;
// Enclosing clipping layer for iframe content
OwnPtr<GraphicsLayer> m_clippingLayer;
#if PROFILE_LAYER_REBUILD
int m_rootLayerUpdateCount;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment