summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderLayerCompositor.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-05-11 18:35:50 +0100
committerBen Murdoch <benm@google.com>2010-05-14 10:23:05 +0100
commit21939df44de1705786c545cd1bf519d47250322d (patch)
treeef56c310f5c0cdc379c2abb2e212308a3281ce20 /WebCore/rendering/RenderLayerCompositor.cpp
parent4ff1d8891d520763f17675827154340c7c740f90 (diff)
downloadexternal_webkit-21939df44de1705786c545cd1bf519d47250322d.zip
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.gz
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.bz2
Merge Webkit at r58956: Initial merge by Git.
Change-Id: I1d9fb60ea2c3f2ddc04c17a871acdb39353be228
Diffstat (limited to 'WebCore/rendering/RenderLayerCompositor.cpp')
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp150
1 files changed, 119 insertions, 31 deletions
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();
}