diff options
Diffstat (limited to 'WebCore/rendering/RenderLayerCompositor.cpp')
-rw-r--r-- | WebCore/rendering/RenderLayerCompositor.cpp | 119 |
1 files changed, 95 insertions, 24 deletions
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index 8ce59cb..2730114 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -29,6 +29,7 @@ #include "RenderLayerCompositor.h" #include "AnimationController.h" +#include "Chrome.h" #include "ChromeClient.h" #include "CSSPropertyNames.h" #include "Frame.h" @@ -37,7 +38,9 @@ #include "HitTestResult.h" #include "HTMLCanvasElement.h" #include "Page.h" +#include "RenderEmbeddedObject.h" #include "RenderLayerBacking.h" +#include "RenderReplica.h" #include "RenderVideo.h" #include "RenderView.h" #include "Settings.h" @@ -58,6 +61,8 @@ bool WebCoreHas3DRendering = true; namespace WebCore { +using namespace HTMLNames; + struct CompositingState { CompositingState(RenderLayer* compAncestor) : m_compositingAncestor(compAncestor) @@ -147,16 +152,30 @@ void RenderLayerCompositor::scheduleSync() page->chrome()->client()->scheduleCompositingLayerSync(); } -void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot) +void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot) { - // When m_compositingConsultsOverlap is true, then layer positions affect compositing, - // so we can only bail here when we're not looking at overlap. - if (!m_compositingLayersNeedRebuild && !m_compositingConsultsOverlap) + bool checkForHierarchyUpdate = false; + bool needGeometryUpdate = false; + + switch (updateType) { + case CompositingUpdateAfterLayoutOrStyleChange: + case CompositingUpdateOnPaitingOrHitTest: + checkForHierarchyUpdate = true; + break; + case CompositingUpdateOnScroll: + if (m_compositingConsultsOverlap) + checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates. + + needGeometryUpdate = true; + break; + } + + if (!checkForHierarchyUpdate && !needGeometryUpdate) return; ASSERT(inCompositingMode()); - bool needLayerRebuild = m_compositingLayersNeedRebuild; + bool needHierarchyUpdate = m_compositingLayersNeedRebuild; if (!updateRoot) { // Only clear the flag if we're updating the entire hierarchy. m_compositingLayersNeedRebuild = false; @@ -169,24 +188,22 @@ void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot) double startTime = WTF::currentTime(); #endif - // Go through the layers in presentation order, so that we can compute which - // RLs need compositing layers. - // FIXME: we could maybe do this in one pass, but the parenting logic would be more - // complex. - { + if (checkForHierarchyUpdate) { + // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. + // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. CompositingState compState(updateRoot); - bool layersChanged; + bool layersChanged = false; if (m_compositingConsultsOverlap) { OverlapMap overlapTestRequestMap; computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged); } else computeCompositingRequirements(updateRoot, 0, compState, layersChanged); - needLayerRebuild |= layersChanged; + needHierarchyUpdate |= layersChanged; } - if (needLayerRebuild) { - // Now updated and parent the compositing layers. + if (needHierarchyUpdate) { + // Update the hierarchy of the compositing layers. CompositingState compState(updateRoot); Vector<GraphicsLayer*> childList; rebuildCompositingLayerTree(updateRoot, compState, childList); @@ -194,8 +211,9 @@ void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot) // Host the document layer in the RenderView's root layer. if (updateRoot == rootRenderLayer() && !childList.isEmpty()) m_rootPlatformLayer->setChildren(childList); - } else { - // We just need to do a geometry update. + } else if (needGeometryUpdate) { + // We just need to do a geometry update. This is only used for position:fixed scrolling; + // most of the time, geometry is updated via RenderLayer::styleChanged(). updateLayerTreeGeometry(updateRoot); } @@ -233,6 +251,17 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR } } else { if (layer->backing()) { + // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to + // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection + // are both either composited, or not composited. + if (layer->isReflection()) { + RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer(); + if (RenderLayerBacking* backing = sourceLayer->backing()) { + ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer()); + backing->graphicsLayer()->setReplicatedByLayer(0); + } + } + layer->clearBacking(); layerChanged = true; @@ -533,6 +562,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); } + if (layer->reflectionLayer()) + layer->reflectionLayer()->setMustOverlapCompositedLayers(needsToBeComposited(layer)); + // Subsequent layers in the parent stacking context also need to composite. if (childState.m_subtreeIsCompositing) compositingState.m_subtreeIsCompositing = true; @@ -549,6 +581,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). if (updateBacking(layer, CompositingChangeRepaintNow)) layersChanged = true; + + if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow)) + layersChanged = true; } void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) @@ -595,9 +630,7 @@ void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer) #if ENABLE(VIDEO) bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const { - // FIXME: ideally we need to look at all ancestors for mask or video. But for now, - // just bail on the obvious cases. - if (o->hasReflection() || !m_hasAcceleratedCompositing) + if (!m_hasAcceleratedCompositing) return false; return o->supportsAcceleratedRendering(); @@ -615,6 +648,12 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons // The compositing state of all our children has been updated already, so now // we can compute and cache the composited bounds for this layer. layerBacking->updateCompositedBounds(); + + if (RenderLayer* reflection = layer->reflectionLayer()) { + if (reflection->backing()) + reflection->backing()->updateCompositedBounds(); + } + layerBacking->updateGraphicsLayerConfiguration(); layerBacking->updateGraphicsLayerGeometry(); @@ -688,8 +727,10 @@ void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer) // we can compute and cache the composited bounds for this layer. layerBacking->updateCompositedBounds(); - if (layer->reflectionLayer()) - layer->reflectionLayer()->backing()->updateCompositedBounds(); + if (RenderLayer* reflection = layer->reflectionLayer()) { + if (reflection->backing()) + reflection->backing()->updateCompositedBounds(); + } layerBacking->updateGraphicsLayerConfiguration(); layerBacking->updateGraphicsLayerGeometry(); @@ -730,12 +771,21 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com if (layer != compositingAncestor) { if (RenderLayerBacking* layerBacking = layer->backing()) { layerBacking->updateCompositedBounds(); + + if (RenderLayer* reflection = layer->reflectionLayer()) { + if (reflection->backing()) + reflection->backing()->updateCompositedBounds(); + } + layerBacking->updateGraphicsLayerGeometry(); if (updateDepth == RenderLayerBacking::CompositingChildren) return; } } + if (layer->reflectionLayer()) + updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth); + if (!layer->hasCompositingDescendant()) return; @@ -884,9 +934,16 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. // static bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const -{ +{ + RenderObject* renderer = layer->renderer(); + // The compositing state of a reflection should match that of its reflected layer. + if (layer->isReflection()) { + renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. + layer = toRenderBoxModelObject(renderer)->layer(); + } // The root layer always has a compositing layer, but it may not have backing. return (inCompositingMode() && layer->isRootLayer()) || +<<<<<<< HEAD requiresCompositingForTransform(layer->renderer()) || requiresCompositingForVideo(layer->renderer()) || requiresCompositingForCanvas(layer->renderer()) || @@ -895,8 +952,15 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c (layer->renderer()->isPositioned() && layer->renderer()->style()->position() == FixedPosition) || #endif +======= + requiresCompositingForTransform(renderer) || + requiresCompositingForVideo(renderer) || + requiresCompositingForCanvas(renderer) || + requiresCompositingForPlugin(renderer) || + renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden || +>>>>>>> webkit.org at r54127 clipsCompositingDescendants(layer) || - requiresCompositingForAnimation(layer->renderer()); + requiresCompositingForAnimation(renderer); } // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, @@ -959,6 +1023,8 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) RenderVideo* video = toRenderVideo(renderer); return canAccelerateVideoRendering(video); } +#else + UNUSED_PARAM(renderer); #endif return false; } @@ -976,6 +1042,11 @@ bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) return false; } +bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const +{ + return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing(); +} + bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const { if (AnimationController* animController = renderer->animation()) { @@ -987,7 +1058,7 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const { - return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask(); + return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection(); } // If an element has negative z-index children, those children render in front of the |