summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderLayerCompositor.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-02 14:57:50 +0000
committerSteve Block <steveblock@google.com>2010-02-04 15:06:55 +0000
commitd0825bca7fe65beaee391d30da42e937db621564 (patch)
tree7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/rendering/RenderLayerCompositor.cpp
parent3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff)
downloadexternal_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/rendering/RenderLayerCompositor.cpp')
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp119
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