From 21939df44de1705786c545cd1bf519d47250322d Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Tue, 11 May 2010 18:35:50 +0100 Subject: Merge Webkit at r58956: Initial merge by Git. Change-Id: I1d9fb60ea2c3f2ddc04c17a871acdb39353be228 --- WebCore/rendering/RenderLayerCompositor.cpp | 150 ++++++++++++++++++++++------ 1 file changed, 119 insertions(+), 31 deletions(-) (limited to 'WebCore/rendering/RenderLayerCompositor.cpp') diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index 25d8eda..e96e375 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -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" @@ -124,7 +125,12 @@ void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) else destroyRootPlatformLayer(); - m_renderView->compositingStateChanged(m_compositing); + if (shouldPropagateCompositingToIFrameParent()) { + if (Element* ownerElement = m_renderView->document()->ownerElement()) { + // Trigger a recalcStyle in the parent document, to update compositing in that document. + ownerElement->setNeedsStyleRecalc(SyntheticStyleChange); + } + } } } @@ -592,6 +598,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O childState.m_compositingAncestor = layer; if (overlapMap) addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); + willBeComposited = true; } } } @@ -622,6 +629,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O } } + ASSERT(willBeComposited == needsToBeComposited(layer)); + // If we have a software transform, and we have layers under us, we need to also // be composited. Also, if we have opacity < 1, then we need to be a layer so that // the child layers are opaque, then rendered with opacity on this layer. @@ -699,19 +708,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 { @@ -799,11 +795,30 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons } if (layerBacking) { - layerBacking->parentForSublayers()->setChildren(layerChildren); + if (shouldPropagateCompositingToIFrameParent() && 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) { @@ -957,7 +972,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() @@ -965,13 +980,28 @@ 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; + if (shouldPropagateCompositingToIFrameParent()) { + if (Element* ownerElement = m_renderView->document()->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; + } + } + } + + 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; + page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer.get()); + } + m_rootLayerAttached = true; } void RenderLayerCompositor::willMoveOffscreen() @@ -979,19 +1009,45 @@ 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; + if (shouldPropagateCompositingToIFrameParent()) { + if (Element* ownerElement = m_renderView->document()->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() @@ -1007,6 +1063,18 @@ bool RenderLayerCompositor::has3DContent() const return layerHas3DContent(rootRenderLayer()); } +bool RenderLayerCompositor::shouldPropagateCompositingToIFrameParent() +{ + // 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. +#if !PLATFORM(MAC) + return true; +#else + return false; +#endif +} + bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const { if (!canBeComposited(layer)) @@ -1194,7 +1262,9 @@ bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) bool RenderLayerCompositor::requiresCompositingForIFrame(RenderObject* renderer) const { - return renderer->isRenderIFrame() && toRenderIFrame(renderer)->requiresAcceleratedCompositing(); + return shouldPropagateCompositingToIFrameParent() + && renderer->isRenderIFrame() + && toRenderIFrame(renderer)->requiresAcceleratedCompositing(); } bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const @@ -1226,13 +1296,31 @@ 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); + if (shouldPropagateCompositingToIFrameParent()) { + // Create a clipping layer if this is an iframe + if (Element* ownerElement = m_renderView->document()->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(); } -- cgit v1.1