2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "core/rendering/compositing/RenderLayerCompositor.h"
30 #include "CSSPropertyNames.h"
31 #include "HTMLNames.h"
32 #include "RuntimeEnabledFeatures.h"
33 #include "core/animation/ActiveAnimations.h"
34 #include "core/animation/DocumentAnimations.h"
35 #include "core/dom/FullscreenElementStack.h"
36 #include "core/dom/NodeList.h"
37 #include "core/frame/DeprecatedScheduleStyleRecalcDuringCompositingUpdate.h"
38 #include "core/frame/FrameView.h"
39 #include "core/frame/LocalFrame.h"
40 #include "core/frame/Settings.h"
41 #include "core/html/HTMLCanvasElement.h"
42 #include "core/html/HTMLIFrameElement.h"
43 #include "core/html/HTMLMediaElement.h"
44 #include "core/html/canvas/CanvasRenderingContext.h"
45 #include "core/inspector/InspectorInstrumentation.h"
46 #include "core/page/Chrome.h"
47 #include "core/page/Page.h"
48 #include "core/page/scrolling/ScrollingConstraints.h"
49 #include "core/page/scrolling/ScrollingCoordinator.h"
50 #include "core/rendering/HitTestResult.h"
51 #include "core/rendering/RenderApplet.h"
52 #include "core/rendering/RenderEmbeddedObject.h"
53 #include "core/rendering/RenderFullScreen.h"
54 #include "core/rendering/RenderIFrame.h"
55 #include "core/rendering/RenderLayerStackingNode.h"
56 #include "core/rendering/RenderLayerStackingNodeIterator.h"
57 #include "core/rendering/RenderReplica.h"
58 #include "core/rendering/RenderVideo.h"
59 #include "core/rendering/RenderView.h"
60 #include "core/rendering/compositing/CompositedLayerMapping.h"
61 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
62 #include "platform/OverscrollTheme.h"
63 #include "platform/TraceEvent.h"
64 #include "platform/geometry/TransformState.h"
65 #include "platform/graphics/GraphicsLayer.h"
66 #include "platform/scroll/ScrollbarTheme.h"
67 #include "public/platform/Platform.h"
68 #include "wtf/TemporaryChange.h"
71 #include "core/rendering/RenderTreeAsText.h"
76 using namespace HTMLNames;
78 class OverlapMapContainer {
80 void add(const IntRect& bounds)
82 m_layerRects.append(bounds);
83 m_boundingBox.unite(bounds);
86 bool overlapsLayers(const IntRect& bounds) const
88 // Checking with the bounding box will quickly reject cases when
89 // layers are created for lists of items going in one direction and
90 // never overlap with each other.
91 if (!bounds.intersects(m_boundingBox))
93 for (unsigned i = 0; i < m_layerRects.size(); i++) {
94 if (m_layerRects[i].intersects(bounds))
100 void unite(const OverlapMapContainer& otherContainer)
102 m_layerRects.appendVector(otherContainer.m_layerRects);
103 m_boundingBox.unite(otherContainer.m_boundingBox);
106 Vector<IntRect, 64> m_layerRects;
107 IntRect m_boundingBox;
110 class RenderLayerCompositor::OverlapMap {
111 WTF_MAKE_NONCOPYABLE(OverlapMap);
115 // Begin by assuming the root layer will be composited so that there
116 // is something on the stack. The root layer should also never get a
117 // finishCurrentOverlapTestingContext() call.
118 beginNewOverlapTestingContext();
121 void add(const IntRect& bounds)
123 // Layers do not contribute to overlap immediately--instead, they will
124 // contribute to overlap as soon as they have been recursively processed
125 // and popped off the stack.
126 ASSERT(m_overlapStack.size() >= 2);
127 m_overlapStack[m_overlapStack.size() - 2].add(bounds);
130 bool overlapsLayers(const IntRect& bounds) const
132 return m_overlapStack.last().overlapsLayers(bounds);
135 void beginNewOverlapTestingContext()
137 // This effectively creates a new "clean slate" for overlap state.
138 // This is used when we know that a subtree or remaining set of
139 // siblings does not need to check overlap with things behind it.
140 m_overlapStack.append(OverlapMapContainer());
143 void finishCurrentOverlapTestingContext()
145 // The overlap information on the top of the stack is still necessary
146 // for checking overlap of any layers outside this context that may
147 // overlap things from inside this context. Therefore, we must merge
148 // the information from the top of the stack before popping the stack.
150 // FIXME: we may be able to avoid this deep copy by rearranging how
151 // overlapMap state is managed.
152 m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
153 m_overlapStack.removeLast();
157 Vector<OverlapMapContainer> m_overlapStack;
160 struct CompositingRecursionData {
161 CompositingRecursionData(RenderLayer* compAncestor, RenderLayer* mostRecentCompositedLayer, bool testOverlap)
162 : m_compositingAncestor(compAncestor)
163 , m_mostRecentCompositedLayer(mostRecentCompositedLayer)
164 , m_subtreeIsCompositing(false)
165 , m_hasUnisolatedCompositedBlendingDescendant(false)
166 , m_testingOverlap(testOverlap)
173 CompositingRecursionData(const CompositingRecursionData& other)
174 : m_compositingAncestor(other.m_compositingAncestor)
175 , m_mostRecentCompositedLayer(other.m_mostRecentCompositedLayer)
176 , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
177 , m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompositedBlendingDescendant)
178 , m_testingOverlap(other.m_testingOverlap)
180 , m_depth(other.m_depth + 1)
185 RenderLayer* m_compositingAncestor;
186 RenderLayer* m_mostRecentCompositedLayer; // in paint order regardless of hierarchy.
187 bool m_subtreeIsCompositing;
188 bool m_hasUnisolatedCompositedBlendingDescendant;
189 bool m_testingOverlap;
195 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
196 : m_renderView(renderView)
197 , m_compositingReasonFinder(renderView)
198 , m_hasAcceleratedCompositing(true)
199 , m_showRepaintCounter(false)
200 , m_needsToRecomputeCompositingRequirements(false)
201 , m_needsToUpdateLayerTreeGeometry(false)
202 , m_pendingUpdateType(GraphicsLayerUpdater::DoNotForceUpdate)
203 , m_pendingPropertyUpdateType(CompositingPropertyUpdater::DoNotForceUpdate)
204 , m_compositing(false)
205 , m_compositingLayersNeedRebuild(false)
206 , m_forceCompositingMode(false)
207 , m_needsUpdateCompositingRequirementsState(false)
208 , m_isTrackingRepaints(false)
209 , m_rootLayerAttachment(RootLayerUnattached)
213 RenderLayerCompositor::~RenderLayerCompositor()
215 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
218 void RenderLayerCompositor::enableCompositingMode(bool enable)
220 if (enable == m_compositing)
223 m_compositing = enable;
230 notifyIFramesOfCompositingChange();
233 void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
235 bool hasAcceleratedCompositing = false;
236 bool showRepaintCounter = false;
237 bool forceCompositingMode = false;
239 if (Settings* settings = m_renderView.document().settings()) {
240 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
242 // We allow the chrome to override the settings, in case the page is rendered
243 // on a chrome that doesn't allow accelerated compositing.
244 if (hasAcceleratedCompositing) {
246 m_compositingReasonFinder.updateTriggers();
247 hasAcceleratedCompositing = m_compositingReasonFinder.hasTriggers();
251 showRepaintCounter = settings->showRepaintCounter();
252 forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
254 if (forceCompositingMode && !isMainFrame())
255 forceCompositingMode = m_compositingReasonFinder.requiresCompositingForScrollableFrame();
258 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
259 setCompositingLayersNeedRebuild();
261 m_hasAcceleratedCompositing = hasAcceleratedCompositing;
262 m_showRepaintCounter = showRepaintCounter;
263 m_forceCompositingMode = forceCompositingMode;
266 bool RenderLayerCompositor::layerSquashingEnabled() const
268 if (RuntimeEnabledFeatures::bleedingEdgeFastPathsEnabled())
270 if (Settings* settings = m_renderView.document().settings())
271 return settings->layerSquashingEnabled();
276 bool RenderLayerCompositor::canRender3DTransforms() const
278 return hasAcceleratedCompositing() && m_compositingReasonFinder.has3DTransformTrigger();
281 void RenderLayerCompositor::setCompositingLayersNeedRebuild()
283 // FIXME: crbug,com/332248 ideally this could be merged with setNeedsCompositingUpdate().
284 if (inCompositingMode())
285 m_compositingLayersNeedRebuild = true;
286 page()->animator().scheduleVisualUpdate();
289 void RenderLayerCompositor::updateCompositingRequirementsState()
291 if (!m_needsUpdateCompositingRequirementsState)
294 TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerCompositor::updateCompositingRequirementsState");
296 m_needsUpdateCompositingRequirementsState = false;
298 if (!rootRenderLayer() || !m_renderView.acceleratedCompositingForOverflowScrollEnabled())
301 for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it)
302 (*it)->updateHasUnclippedDescendant();
304 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas();
305 if (!scrollableAreas)
308 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
309 (*it)->updateNeedsCompositedScrolling();
312 static RenderVideo* findFullscreenVideoRenderer(Document& document)
314 Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document);
315 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
316 Document* contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
317 if (!contentDocument)
319 fullscreenElement = FullscreenElementStack::fullscreenElementFrom(*contentDocument);
321 if (!isHTMLVideoElement(fullscreenElement))
323 RenderObject* renderer = fullscreenElement->renderer();
326 return toRenderVideo(renderer);
329 void RenderLayerCompositor::finishCompositingUpdateForFrameTree(LocalFrame* frame)
331 for (LocalFrame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
332 finishCompositingUpdateForFrameTree(child);
334 // Update compositing for current frame after all descendant frames are updated.
335 if (frame && frame->contentRenderer()) {
336 RenderLayerCompositor* frameCompositor = frame->contentRenderer()->compositor();
337 if (frameCompositor && !frameCompositor->isMainFrame())
338 frame->contentRenderer()->compositor()->updateCompositingLayers();
342 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType)
344 // FIXME: this code was historically part of updateCompositingLayers, and
345 // for now is kept totally equivalent to the previous implementation. We
346 // should carefully clean up the awkward early-exit semantics, balancing between
347 // skipping unnecessary compositing updates and not incorrectly skipping
348 // necessary updates.
350 // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
351 if (m_renderView.needsLayout())
354 if (m_forceCompositingMode && !m_compositing)
355 enableCompositingMode(true);
357 if (!m_needsToRecomputeCompositingRequirements && !m_compositing)
360 switch (updateType) {
361 case CompositingUpdateAfterStyleChange:
362 m_needsToRecomputeCompositingRequirements = true;
364 case CompositingUpdateAfterLayout:
365 m_needsToRecomputeCompositingRequirements = true;
366 // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
367 m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate;
368 // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
369 m_pendingPropertyUpdateType = CompositingPropertyUpdater::ForceUpdate;
371 case CompositingUpdateOnScroll:
372 m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
373 m_needsToUpdateLayerTreeGeometry = true;
374 // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
375 m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate;
376 // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
377 m_pendingPropertyUpdateType = CompositingPropertyUpdater::ForceUpdate;
379 case CompositingUpdateOnCompositedScroll:
380 m_needsToUpdateLayerTreeGeometry = true;
381 // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
382 m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate;
383 // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
384 m_pendingPropertyUpdateType = CompositingPropertyUpdater::ForceUpdate;
386 case CompositingUpdateAfterCanvasContextChange:
387 m_needsToUpdateLayerTreeGeometry = true;
391 page()->animator().scheduleVisualUpdate();
394 static void clearAncestorDependentPropertyCacheRecursive(RenderLayer* layer)
396 layer->clearAncestorDependentPropertyCache();
397 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
398 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
399 clearAncestorDependentPropertyCacheRecursive(child);
402 void RenderLayerCompositor::updateCompositingLayers()
404 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateCompositingLayers");
406 // FIXME: We should carefully clean up the awkward early-exit semantics, balancing
407 // between skipping unnecessary compositing updates and not incorrectly skipping
408 // necessary updates.
410 // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
411 // FIXME: Can we assert that we never return here?
412 if (m_renderView.needsLayout())
415 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
417 updateCompositingLayersInternal();
419 // Clear data only valid during compositing updates.
420 clearAncestorDependentPropertyCacheRecursive(rootRenderLayer());
422 lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
424 DocumentAnimations::startPendingAnimations(m_renderView.document());
425 ASSERT(m_renderView.document().lifecycle().state() == DocumentLifecycle::CompositingClean);
428 void RenderLayerCompositor::scheduleAnimationIfNeeded()
430 LocalFrame* localFrame = &m_renderView.frameView()->frame();
431 for (LocalFrame* currentFrame = localFrame; currentFrame; currentFrame = currentFrame->tree().traverseNext(localFrame)) {
432 if (currentFrame->contentRenderer()) {
433 RenderLayerCompositor* childCompositor = currentFrame->contentRenderer()->compositor();
434 if (childCompositor && childCompositor->hasUnresolvedDirtyBits()) {
435 m_renderView.frameView()->scheduleAnimation();
442 bool RenderLayerCompositor::hasUnresolvedDirtyBits()
444 return m_needsToRecomputeCompositingRequirements || m_compositingLayersNeedRebuild || m_needsToUpdateLayerTreeGeometry || m_needsUpdateCompositingRequirementsState || m_pendingUpdateType != GraphicsLayerUpdater::DoNotForceUpdate;
447 void RenderLayerCompositor::updateCompositingLayersInternal()
449 if (isMainFrame() && m_renderView.frameView())
450 finishCompositingUpdateForFrameTree(&m_renderView.frameView()->frame());
452 if (m_forceCompositingMode && !m_compositing)
453 enableCompositingMode(true);
455 if (!m_needsToRecomputeCompositingRequirements && !m_compositing)
458 bool needCompositingRequirementsUpdate = m_needsToRecomputeCompositingRequirements;
459 bool needHierarchyAndGeometryUpdate = m_compositingLayersNeedRebuild;
460 bool needGeometryUpdate = m_needsToUpdateLayerTreeGeometry;
461 bool needsToUpdateScrollingCoordinator = scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false;
463 if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate && !needsToUpdateScrollingCoordinator)
466 GraphicsLayerUpdater::UpdateType updateType = m_pendingUpdateType;
468 // Only clear the flags if we're updating the entire hierarchy.
469 m_compositingLayersNeedRebuild = false;
470 m_needsToUpdateLayerTreeGeometry = false;
471 m_needsToRecomputeCompositingRequirements = false;
472 m_pendingUpdateType = GraphicsLayerUpdater::DoNotForceUpdate;
474 RenderLayer* updateRoot = rootRenderLayer();
476 if (needCompositingRequirementsUpdate) {
477 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
478 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
479 CompositingRecursionData recursionData(updateRoot, 0, true);
480 bool layersChanged = false;
481 bool saw3DTransform = false;
484 TRACE_EVENT0("blink_rendering", "CompositingPropertyUpdater::updateAncestorDependentProperties");
485 CompositingPropertyUpdater().updateAncestorDependentProperties(updateRoot, m_pendingPropertyUpdateType);
486 m_pendingPropertyUpdateType = CompositingPropertyUpdater::DoNotForceUpdate;
488 CompositingPropertyUpdater::assertNeedsToUpdateAncestorDependantPropertiesBitsCleared(updateRoot);
493 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::computeCompositingRequirements");
494 OverlapMap overlapTestRequestMap;
496 // FIXME: Passing these unclippedDescendants down and keeping track
497 // of them dynamically, we are requiring a full tree walk. This
498 // should be removed as soon as proper overlap testing based on
499 // scrolling and animation bounds is implemented (crbug.com/252472).
500 Vector<RenderLayer*> unclippedDescendants;
501 IntRect absoluteDecendantBoundingBox;
502 computeCompositingRequirements(0, updateRoot, overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants, absoluteDecendantBoundingBox);
506 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayersToBackings");
507 assignLayersToBackings(updateRoot, layersChanged);
511 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateHasVisibleNonLayerContentLoop");
512 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas();
513 if (scrollableAreas) {
514 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
515 (*it)->updateHasVisibleNonLayerContent();
520 needHierarchyAndGeometryUpdate = true;
523 if (needGeometryUpdate || needHierarchyAndGeometryUpdate) {
524 TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
525 GraphicsLayerUpdater().update(*updateRoot, updateType);
528 if (needHierarchyAndGeometryUpdate) {
529 // Update the hierarchy of the compositing layers.
530 GraphicsLayerVector childList;
532 TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::rebuildTree");
533 GraphicsLayerUpdater().rebuildTree(*updateRoot, childList);
536 // Host the document layer in the RenderView's root layer.
537 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isMainFrame()) {
538 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
539 if (video && video->hasCompositedLayerMapping()) {
541 childList.append(video->compositedLayerMapping()->mainGraphicsLayer());
545 if (childList.isEmpty())
548 m_rootContentLayer->setChildren(childList);
551 ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
553 if (!hasAcceleratedCompositing())
554 enableCompositingMode(false);
556 // The scrolling coordinator may realize that it needs updating while compositing was being updated in this function.
557 needsToUpdateScrollingCoordinator |= scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false;
558 if (needsToUpdateScrollingCoordinator && isMainFrame() && scrollingCoordinator() && inCompositingMode())
559 scrollingCoordinator()->updateAfterCompositingChange();
561 // Inform the inspector that the layer tree has changed.
563 InspectorInstrumentation::layerTreeDidChange(page());
566 static bool requiresCompositing(CompositingReasons reasons)
568 // Any reasons other than overlap or assumed overlap will require the layer to be separately compositing.
569 return reasons & ~CompositingReasonComboSquashableReasons;
572 static bool requiresSquashing(CompositingReasons reasons)
574 // If the layer has overlap or assumed overlap, but no other reasons, then it should be squashed.
575 return !requiresCompositing(reasons) && (reasons & CompositingReasonComboSquashableReasons);
578 static bool requiresCompositingOrSquashing(CompositingReasons reasons)
581 bool fastAnswer = reasons != CompositingReasonNone;
582 bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons);
583 ASSERT(fastAnswer == slowAnswer);
585 return reasons != CompositingReasonNone;
588 void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer)
590 m_outOfFlowPositionedLayers.add(layer);
593 void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer)
595 m_outOfFlowPositionedLayers.remove(layer);
598 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
600 bool compositedLayerMappingChanged = false;
601 bool nonCompositedReasonChanged = updateLayerIfViewportConstrained(layer);
603 // FIXME: It would be nice to directly use the layer's compositing reason,
604 // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
605 // requirements fully.
606 switch (compositedLayerUpdate) {
607 case AllocateOwnCompositedLayerMapping:
608 ASSERT(!layer->hasCompositedLayerMapping());
609 enableCompositingMode();
611 // If we need to repaint, do so before allocating the compositedLayerMapping
612 repaintOnCompositingChange(layer);
613 layer->ensureCompositedLayerMapping();
614 compositedLayerMappingChanged = true;
616 // At this time, the ScrollingCooridnator only supports the top-level frame.
617 if (layer->isRootLayer() && isMainFrame()) {
618 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
619 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
622 // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
623 // that computing repaint rects will know the layer's correct compositingState.
624 // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
625 // Need to create a test where a squashed layer pops into compositing. And also to cover all other
626 // sorts of compositingState transitions.
627 layer->setLostGroupedMapping(false);
628 layer->setGroupedMapping(0);
630 // FIXME: it seems premature to compute this before all compositing state has been updated?
631 // This layer and all of its descendants have cached repaints rects that are relative to
632 // the repaint container, so change when compositing changes; we need to update them here.
634 layer->repainter().computeRepaintRectsIncludingDescendants();
637 case RemoveOwnCompositedLayerMapping:
638 // PutInSquashingLayer means you might have to remove the composited layer mapping first.
639 case PutInSquashingLayer:
640 if (layer->hasCompositedLayerMapping()) {
641 // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
642 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
643 // are both either composited, or not composited.
644 if (layer->isReflection()) {
645 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
646 if (sourceLayer->hasCompositedLayerMapping()) {
647 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
648 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
652 removeViewportConstrainedLayer(layer);
654 layer->clearCompositedLayerMapping();
655 compositedLayerMappingChanged = true;
657 // This layer and all of its descendants have cached repaints rects that are relative to
658 // the repaint container, so change when compositing changes; we need to update them here.
659 layer->repainter().computeRepaintRectsIncludingDescendants();
661 // If we need to repaint, do so now that we've removed the compositedLayerMapping
662 repaintOnCompositingChange(layer);
666 case RemoveFromSquashingLayer:
667 case NoCompositingStateChange:
672 if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons())
673 compositedLayerMappingChanged = true;
675 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
676 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
677 if (innerCompositor && innerCompositor->inCompositingMode())
678 innerCompositor->updateRootLayerAttachment();
681 if (compositedLayerMappingChanged)
682 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
684 // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
685 // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
686 if (compositedLayerMappingChanged || nonCompositedReasonChanged) {
687 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
688 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
691 return compositedLayerMappingChanged || nonCompositedReasonChanged;
694 static LayoutPoint computeOffsetFromAbsolute(RenderLayer* layer)
696 TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
697 layer->renderer()->mapLocalToContainer(0, transformState, ApplyContainerFlip);
698 transformState.flatten();
699 return LayoutPoint(transformState.lastPlanarPoint());
702 bool RenderLayerCompositor::updateSquashingAssignment(RenderLayer* layer, SquashingState& squashingState, const CompositingStateTransitionType compositedLayerUpdate)
705 // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than
706 // the squashed RenderLayer's own primary contents. This would happen when we have a composited negative z-index element that needs
707 // to paint on top of the background, but below the layer's main contents. For now, because we always composite layers
708 // when they have a composited negative z-index child, such layers will never need squashing so it is not yet an issue.
709 if (compositedLayerUpdate == PutInSquashingLayer) {
710 // A layer that is squashed with other layers cannot have its own CompositedLayerMapping.
711 ASSERT(!layer->hasCompositedLayerMapping());
712 ASSERT(squashingState.hasMostRecentMapping);
714 LayoutPoint offsetFromAbsoluteForSquashedLayer = computeOffsetFromAbsolute(layer);
716 LayoutSize offsetFromSquashingCLM(offsetFromAbsoluteForSquashedLayer.x() - squashingState.offsetFromAbsoluteForSquashingCLM.x(),
717 offsetFromAbsoluteForSquashedLayer.y() - squashingState.offsetFromAbsoluteForSquashingCLM.y());
719 bool changedSquashingLayer =
720 squashingState.mostRecentMapping->updateSquashingLayerAssignment(layer, offsetFromSquashingCLM, squashingState.nextSquashedLayerIndex);
721 squashingState.nextSquashedLayerIndex++;
723 if (!changedSquashingLayer)
726 layer->clipper().clearClipRectsIncludingDescendants();
728 // If we need to repaint, do so before allocating the layer to the squashing layer.
729 repaintOnCompositingChange(layer);
731 // FIXME: it seems premature to compute this before all compositing state has been updated?
732 // This layer and all of its descendants have cached repaints rects that are relative to
733 // the repaint container, so change when compositing changes; we need to update them here.
735 // FIXME: what's up with parent()?
737 layer->repainter().computeRepaintRectsIncludingDescendants();
740 } else if (compositedLayerUpdate == RemoveFromSquashingLayer) {
741 layer->setGroupedMapping(0);
743 // This layer and all of its descendants have cached repaints rects that are relative to
744 // the repaint container, so change when compositing changes; we need to update them here.
745 layer->repainter().computeRepaintRectsIncludingDescendants();
747 // If we need to repaint, do so now that we've removed it from a squashed layer
748 repaintOnCompositingChange(layer);
750 layer->setLostGroupedMapping(false);
756 bool RenderLayerCompositor::updateLayerIfViewportConstrained(RenderLayer* layer)
758 RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
759 m_compositingReasonFinder.requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason, &m_needsToRecomputeCompositingRequirements);
761 if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
762 ASSERT(layer->renderer()->style()->position() == FixedPosition);
764 layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
770 bool RenderLayerCompositor::canSquashIntoCurrentSquashingOwner(const RenderLayer* layer, const RenderLayerCompositor::SquashingState& squashingState, const RenderLayer* clippingAncestor)
772 ASSERT(clippingAncestor);
773 if (clippingAncestor != squashingState.clippingAncestorForMostRecentMapping)
776 ASSERT(squashingState.hasMostRecentMapping);
777 if (layer->scrollsWithRespectTo(&squashingState.mostRecentMapping->owningLayer()))
783 RenderLayerCompositor::CompositingStateTransitionType RenderLayerCompositor::computeCompositedLayerUpdate(RenderLayer* layer)
785 CompositingStateTransitionType update = NoCompositingStateChange;
786 if (!layer->subtreeIsInvisible() && needsOwnBacking(layer)) {
787 if (!layer->hasCompositedLayerMapping()) {
788 update = AllocateOwnCompositedLayerMapping;
791 if (layer->hasCompositedLayerMapping())
792 update = RemoveOwnCompositedLayerMapping;
794 if (layerSquashingEnabled()) {
795 if (!layer->subtreeIsInvisible() && requiresSquashing(layer->compositingReasons())) {
796 // We can't compute at this time whether the squashing layer update is a no-op,
797 // since that requires walking the render layer tree.
798 update = PutInSquashingLayer;
799 } else if (layer->groupedMapping() || layer->lostGroupedMapping()) {
800 update = RemoveFromSquashingLayer;
807 // These are temporary hacks to work around chicken-egg issues while we continue to refactor the compositing code.
808 // See crbug.com/339892 for a list of tests that fail if this method is removed.
809 void RenderLayerCompositor::applyUpdateLayerCompositingStateChickenEggHacks(RenderLayer* layer, CompositingStateTransitionType compositedLayerUpdate)
811 // See if we need content or clipping layers. Methods called here should assume
812 // that the compositing state of descendant layers has not been updated yet.
813 if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateGraphicsLayerConfiguration()) {
814 setCompositingLayersNeedRebuild();
815 } else if (compositedLayerUpdate == NoCompositingStateChange) {
816 if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor)
817 setCompositingLayersNeedRebuild();
820 if (compositedLayerUpdate != NoCompositingStateChange)
821 allocateOrClearCompositedLayerMapping(layer, computeCompositedLayerUpdate(layer));
824 void RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, UpdateLayerCompositingStateOptions options)
826 updateDirectCompositingReasons(layer);
827 CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
829 if (compositedLayerUpdate != NoCompositingStateChange) {
830 setCompositingLayersNeedRebuild();
831 setNeedsToRecomputeCompositingRequirements();
834 if (options == UseChickenEggHacks)
835 applyUpdateLayerCompositingStateChickenEggHacks(layer, compositedLayerUpdate);
838 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
840 // If the renderer is not attached yet, no need to repaint.
841 if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
844 RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint();
845 if (!repaintContainer)
846 repaintContainer = &m_renderView;
848 layer->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
851 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
852 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
854 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(ExcludeSelf);
855 if (compositedAncestor) {
856 // FIXME: make sure repaintRect is computed correctly for squashed scenario
858 layer->convertToLayerCoords(compositedAncestor, offset);
860 LayoutRect repaintRect = rect;
861 repaintRect.moveBy(offset);
863 if (compositedAncestor->compositingState() == PaintsIntoOwnBacking) {
864 compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
865 } else if (compositedAncestor->compositingState() == PaintsIntoGroupedBacking) {
866 // FIXME: Need to perform the correct coordinate conversion for repaintRect here, including transforms
867 compositedAncestor->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect);
869 ASSERT_NOT_REACHED();
874 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
875 // RenderLayers that are rendered by the composited RenderLayer.
876 LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const
878 if (!canBeComposited(layer))
881 RenderLayer::CalculateLayerBoundsFlags flags = RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask;
882 return layer->calculateLayerBounds(ancestorLayer, 0, flags);
885 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
887 setCompositingLayersNeedRebuild();
890 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
892 if (!child->hasCompositedLayerMapping() || parent->renderer()->documentBeingDestroyed())
895 removeViewportConstrainedLayer(child);
898 // FIXME: This is called from within RenderLayer::removeChild, which is called from RenderObject::RemoveChild.
899 // There's no guarantee that compositor state is up to date.
900 DisableCompositingQueryAsserts disabler;
901 repaintInCompositedAncestor(child, child->compositedLayerMapping()->compositedBounds());
904 setCompositingParent(child, 0);
905 setCompositingLayersNeedRebuild();
908 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, const IntRect& layerBounds)
910 if (layer->isRootLayer())
913 IntRect clipRect = pixelSnappedIntRect(layer->clipper().backgroundClipRect(ClipRectsContext(rootRenderLayer(), AbsoluteClipRects)).rect());
914 clipRect.intersect(layerBounds);
915 overlapMap.add(clipRect);
918 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
919 // For the z-order children of a compositing layer:
920 // If a child layers has a compositing layer, then all subsequent layers must
921 // be compositing in order to render above that layer.
923 // If a child in the negative z-order list is compositing, then the layer itself
924 // must be compositing so that its contents render over that child.
925 // This implies that its positive z-index children must also be compositing.
927 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap& overlapMap, CompositingRecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox)
929 layer->stackingNode()->updateLayerListsIfNeeded();
932 layer->setHasCompositingDescendant(false);
933 layer->setHasNonCompositedChild(false);
935 // Start by assuming this layer will not need to composite.
936 CompositingReasons reasonsToComposite = CompositingReasonNone;
938 // First accumulate the straightforward compositing reasons.
939 CompositingReasons directReasons = m_compositingReasonFinder.directReasons(layer, &m_needsToRecomputeCompositingRequirements);
941 // Video is special. It's the only RenderLayer type that can both have
942 // RenderLayer children and whose children can't use its backing to render
943 // into. These children (the controls) always need to be promoted into their
944 // own layers to draw on top of the accelerated video.
945 if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->renderer()->isVideo())
946 directReasons |= CompositingReasonVideoOverlay;
948 if (canBeComposited(layer))
949 reasonsToComposite |= directReasons;
951 // Next, accumulate reasons related to overlap.
952 // If overlap testing is used, this reason will be overridden. If overlap testing is not
953 // used, we must assume we overlap if there is anything composited behind us in paint-order.
954 CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;
956 if (m_renderView.compositorDrivenAcceleratedScrollingEnabled()) {
957 Vector<size_t> unclippedDescendantsToRemove;
958 for (size_t i = 0; i < unclippedDescendants.size(); i++) {
959 RenderLayer* unclippedDescendant = unclippedDescendants.at(i);
960 // If we've reached the containing block of one of the unclipped
961 // descendants, that element is no longer relevant to whether or not we
962 // should opt in. Unfortunately we can't easily remove from the list
963 // while we're iterating, so we have to store it for later removal.
964 if (unclippedDescendant->renderer()->containingBlock() == layer->renderer()) {
965 unclippedDescendantsToRemove.append(i);
968 if (layer->scrollsWithRespectTo(unclippedDescendant))
969 reasonsToComposite |= CompositingReasonAssumedOverlap;
972 // Remove irrelevant unclipped descendants in reverse order so our stored
973 // indices remain valid.
974 for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++)
975 unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1));
977 if (reasonsToComposite & CompositingReasonOutOfFlowClipping)
978 unclippedDescendants.append(layer);
982 if (!layer->isRootLayer()) {
983 absBounds = layer->ancestorDependentProperties().absoluteBoundingBox;
984 // Setting the absBounds to 1x1 instead of 0x0 makes very little sense,
985 // but removing this code will make JSGameBench sad.
986 // See https://codereview.chromium.org/13912020/
987 if (absBounds.isEmpty())
988 absBounds.setSize(IntSize(1, 1));
991 absoluteDecendantBoundingBox = absBounds;
993 if (currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons))
994 overlapCompositingReason = overlapMap.overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
996 reasonsToComposite |= overlapCompositingReason;
998 // The children of this layer don't need to composite, unless there is
999 // a compositing layer among them, so start by inheriting the compositing
1000 // ancestor with m_subtreeIsCompositing set to false.
1001 CompositingRecursionData childRecursionData(currentRecursionData);
1002 childRecursionData.m_subtreeIsCompositing = false;
1004 bool willBeCompositedOrSquashed = canBeComposited(layer) && requiresCompositingOrSquashing(reasonsToComposite);
1005 if (willBeCompositedOrSquashed) {
1006 // Tell the parent it has compositing descendants.
1007 currentRecursionData.m_subtreeIsCompositing = true;
1008 // This layer now acts as the ancestor for kids.
1009 childRecursionData.m_compositingAncestor = layer;
1011 // Here we know that all children and the layer's own contents can blindly paint into
1012 // this layer's backing, until a descendant is composited. So, we don't need to check
1013 // for overlap with anything behind this layer.
1014 overlapMap.beginNewOverlapTestingContext();
1015 // This layer is going to be composited, so children can safely ignore the fact that there's an
1016 // animation running behind this layer, meaning they can rely on the overlap map testing again.
1017 childRecursionData.m_testingOverlap = true;
1020 #if !ASSERT_DISABLED
1021 LayerListMutationDetector mutationChecker(layer->stackingNode());
1024 bool anyDescendantHas3DTransform = false;
1025 bool willHaveForegroundLayer = false;
1027 if (layer->stackingNode()->isStackingContainer()) {
1028 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
1029 while (RenderLayerStackingNode* curNode = iterator.next()) {
1030 IntRect absoluteChildDecendantBoundingBox;
1031 computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDecendantBoundingBox);
1032 absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox);
1034 // If we have to make a layer for this child, make one now so we can have a contents layer
1035 // (since we need to ensure that the -ve z-order child renders underneath our contents).
1036 if (childRecursionData.m_subtreeIsCompositing) {
1037 reasonsToComposite |= CompositingReasonNegativeZIndexChildren;
1039 if (!willBeCompositedOrSquashed) {
1040 // make layer compositing
1041 childRecursionData.m_compositingAncestor = layer;
1042 overlapMap.beginNewOverlapTestingContext();
1043 willBeCompositedOrSquashed = true;
1044 willHaveForegroundLayer = true;
1046 // FIXME: temporary solution for the first negative z-index composited child:
1047 // re-compute the absBounds for the child so that we can add the
1048 // negative z-index child's bounds to the new overlap context.
1049 overlapMap.beginNewOverlapTestingContext();
1050 addToOverlapMap(overlapMap, curNode->layer(), curNode->layer()->ancestorDependentProperties().absoluteBoundingBox);
1051 overlapMap.finishCurrentOverlapTestingContext();
1057 if (willHaveForegroundLayer) {
1058 ASSERT(willBeCompositedOrSquashed);
1059 // A foreground layer effectively is a new backing for all subsequent children, so
1060 // we don't need to test for overlap with anything behind this. So, we can finish
1061 // the previous context that was accumulating rects for the negative z-index
1062 // children, and start with a fresh new empty context.
1063 overlapMap.finishCurrentOverlapTestingContext();
1064 overlapMap.beginNewOverlapTestingContext();
1065 // This layer is going to be composited, so children can safely ignore the fact that there's an
1066 // animation running behind this layer, meaning they can rely on the overlap map testing again
1067 childRecursionData.m_testingOverlap = true;
1070 if (requiresCompositing(reasonsToComposite)) {
1071 currentRecursionData.m_mostRecentCompositedLayer = layer;
1072 childRecursionData.m_mostRecentCompositedLayer = layer;
1075 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
1076 while (RenderLayerStackingNode* curNode = iterator.next()) {
1077 IntRect absoluteChildDecendantBoundingBox;
1078 computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDecendantBoundingBox);
1079 absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox);
1082 currentRecursionData.m_mostRecentCompositedLayer = childRecursionData.m_mostRecentCompositedLayer;
1084 // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree.
1086 // If we entered compositing mode during the recursion, the root will also need to be composited (as long as accelerated compositing is enabled).
1087 if (layer->isRootLayer()) {
1088 if (inCompositingMode() && m_hasAcceleratedCompositing)
1089 willBeCompositedOrSquashed = true;
1092 // All layers (even ones that aren't being composited) need to get added to
1093 // the overlap map. Layers that are not separately composited will paint into their
1094 // compositing ancestor's backing, and so are still considered for overlap.
1095 if (childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
1096 addToOverlapMap(overlapMap, layer, absBounds);
1098 if (layer->stackingNode()->isStackingContext()) {
1099 layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant);
1101 layer->setShouldIsolateCompositedDescendants(false);
1102 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = childRecursionData.m_hasUnisolatedCompositedBlendingDescendant;
1105 // Now check for reasons to become composited that depend on the state of descendant layers.
1106 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform);
1107 reasonsToComposite |= subtreeCompositingReasons;
1108 if (!willBeCompositedOrSquashed && canBeComposited(layer) && requiresCompositingOrSquashing(subtreeCompositingReasons)) {
1109 childRecursionData.m_compositingAncestor = layer;
1110 // FIXME: this context push is effectively a no-op but needs to exist for
1111 // now, because the code is designed to push overlap information to the
1112 // second-from-top context of the stack.
1113 overlapMap.beginNewOverlapTestingContext();
1114 addToOverlapMap(overlapMap, layer, absoluteDecendantBoundingBox);
1115 willBeCompositedOrSquashed = true;
1118 // If the original layer is composited, the reflection needs to be, too.
1119 if (layer->reflectionInfo()) {
1120 // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
1121 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
1122 CompositingReasons reflectionCompositingReason = willBeCompositedOrSquashed ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone;
1123 reflectionLayer->setCompositingReasons(reflectionLayer->compositingReasons() | reflectionCompositingReason);
1126 // Subsequent layers in the parent's stacking context may also need to composite.
1127 if (childRecursionData.m_subtreeIsCompositing)
1128 currentRecursionData.m_subtreeIsCompositing = true;
1130 if (willBeCompositedOrSquashed && layer->blendInfo().hasBlendMode())
1131 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true;
1133 // Set the flag to say that this SC has compositing children.
1134 layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing);
1136 // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
1137 // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
1138 // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
1139 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposite & CompositingReasonClipsCompositingDescendants);
1140 if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer->renderer()))
1141 currentRecursionData.m_testingOverlap = false;
1143 if (childRecursionData.m_compositingAncestor == layer && !layer->isRootLayer())
1144 overlapMap.finishCurrentOverlapTestingContext();
1146 if (layer->isRootLayer()) {
1147 // The root layer needs to be composited if anything else in the tree is composited.
1148 // Otherwise, we can disable compositing entirely.
1149 if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || m_forceCompositingMode) {
1150 willBeCompositedOrSquashed = true;
1151 reasonsToComposite |= CompositingReasonRoot;
1153 enableCompositingMode(false);
1154 willBeCompositedOrSquashed = false;
1155 reasonsToComposite = CompositingReasonNone;
1159 if (requiresCompositing(reasonsToComposite))
1160 currentRecursionData.m_mostRecentCompositedLayer = layer;
1162 // At this point we have finished collecting all reasons to composite this layer.
1163 layer->setCompositingReasons(reasonsToComposite);
1165 if (!willBeCompositedOrSquashed && layer->parent())
1166 layer->parent()->setHasNonCompositedChild(true);
1168 descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
1171 void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, LayoutPoint newOffsetFromAbsoluteForSquashingCLM, RenderLayer* newClippingAncestorForMostRecentMapping)
1173 // The most recent backing is done accumulating any more squashing layers.
1174 if (hasMostRecentMapping)
1175 mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIndex);
1177 nextSquashedLayerIndex = 0;
1178 mostRecentMapping = newCompositedLayerMapping;
1179 hasMostRecentMapping = hasNewCompositedLayerMapping;
1180 offsetFromAbsoluteForSquashingCLM = newOffsetFromAbsoluteForSquashingCLM;
1181 clippingAncestorForMostRecentMapping = newClippingAncestorForMostRecentMapping;
1184 void RenderLayerCompositor::assignLayersToBackings(RenderLayer* updateRoot, bool& layersChanged)
1186 SquashingState squashingState;
1187 assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged, updateRoot);
1188 if (squashingState.hasMostRecentMapping)
1189 squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex);
1192 void RenderLayerCompositor::assignLayersToBackingsForReflectionLayer(RenderLayer* reflectionLayer, bool& layersChanged)
1194 CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(reflectionLayer);
1195 if (compositedLayerUpdate != NoCompositingStateChange) {
1196 layersChanged = true;
1197 allocateOrClearCompositedLayerMapping(reflectionLayer, compositedLayerUpdate);
1199 updateDirectCompositingReasons(reflectionLayer);
1200 if (reflectionLayer->hasCompositedLayerMapping())
1201 reflectionLayer->compositedLayerMapping()->updateGraphicsLayerConfiguration();
1204 void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged, RenderLayer* clippingAncestor)
1206 if (layer->renderer()->hasClipOrOverflowClip())
1207 clippingAncestor = layer;
1209 if (layerSquashingEnabled() && requiresSquashing(layer->compositingReasons()) && !canSquashIntoCurrentSquashingOwner(layer, squashingState, clippingAncestor))
1210 layer->setCompositingReasons(layer->compositingReasons() | CompositingReasonNoSquashingTargetFound);
1212 CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
1214 if (allocateOrClearCompositedLayerMapping(layer, compositedLayerUpdate))
1215 layersChanged = true;
1217 // FIXME: special-casing reflection layers here is not right.
1218 if (layer->reflectionInfo())
1219 assignLayersToBackingsForReflectionLayer(layer->reflectionInfo()->reflectionLayer(), layersChanged);
1222 // Add this layer to a squashing backing if needed.
1223 if (layerSquashingEnabled()) {
1224 if (updateSquashingAssignment(layer, squashingState, compositedLayerUpdate))
1225 layersChanged = true;
1228 if (layer->stackingNode()->isStackingContainer()) {
1229 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
1230 while (RenderLayerStackingNode* curNode = iterator.next())
1231 assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged, clippingAncestor);
1234 if (layerSquashingEnabled()) {
1235 // At this point, if the layer is to be "separately" composited, then its backing becomes the most recent in paint-order.
1236 if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
1237 ASSERT(!requiresSquashing(layer->compositingReasons()));
1238 LayoutPoint offsetFromAbsoluteForSquashingCLM = computeOffsetFromAbsolute(layer);
1239 squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), offsetFromAbsoluteForSquashingCLM, clippingAncestor);
1243 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
1244 while (RenderLayerStackingNode* curNode = iterator.next())
1245 assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged, clippingAncestor);
1248 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
1250 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
1251 ASSERT(childLayer->hasCompositedLayerMapping());
1253 // It's possible to be called with a parent that isn't yet composited when we're doing
1254 // partial updates as required by painting or hit testing. Just bail in that case;
1255 // we'll do a full layer update soon.
1256 if (!parentLayer || !parentLayer->hasCompositedLayerMapping())
1260 GraphicsLayer* hostingLayer = parentLayer->compositedLayerMapping()->parentForSublayers();
1261 GraphicsLayer* hostedLayer = childLayer->compositedLayerMapping()->childForSuperlayers();
1263 hostingLayer->addChild(hostedLayer);
1265 childLayer->compositedLayerMapping()->childForSuperlayers()->removeFromParent();
1269 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
1271 ASSERT(layer->hasCompositedLayerMapping());
1273 GraphicsLayer* hostingLayer = layer->compositedLayerMapping()->parentForSublayers();
1274 hostingLayer->removeAllChildren();
1277 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1279 if (m_overflowControlsHostLayer)
1280 m_overflowControlsHostLayer->setPosition(contentsOffset);
1283 void RenderLayerCompositor::frameViewDidChangeSize()
1285 if (m_containerLayer) {
1286 FrameView* frameView = m_renderView.frameView();
1287 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
1289 frameViewDidScroll();
1290 updateOverflowControlsLayers();
1294 enum AcceleratedFixedRootBackgroundHistogramBuckets {
1295 ScrolledMainFrameBucket = 0,
1296 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
1297 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
1298 AcceleratedFixedRootBackgroundHistogramMax = 3
1301 void RenderLayerCompositor::frameViewDidScroll()
1303 FrameView* frameView = m_renderView.frameView();
1304 IntPoint scrollPosition = frameView->scrollPosition();
1309 bool scrollingCoordinatorHandlesOffset = false;
1310 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
1311 if (Settings* settings = m_renderView.document().settings()) {
1312 if (isMainFrame() || settings->compositedScrollingForFramesEnabled())
1313 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
1317 // Scroll position = scroll minimum + scroll offset. Adjust the layer's
1318 // position to handle whatever the scroll coordinator isn't handling.
1319 // The minimum scroll position is non-zero for RTL pages with overflow.
1320 if (scrollingCoordinatorHandlesOffset)
1321 m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
1323 m_scrollLayer->setPosition(-scrollPosition);
1326 blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
1327 ScrolledMainFrameBucket,
1328 AcceleratedFixedRootBackgroundHistogramMax);
1331 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
1333 if (m_containerLayer)
1334 updateOverflowControlsLayers();
1337 void RenderLayerCompositor::rootFixedBackgroundsChanged()
1339 if (!supportsFixedRootBackgroundCompositing())
1342 // crbug.com/343132.
1343 DisableCompositingQueryAsserts disabler;
1345 // To avoid having to make the fixed root background layer fixed positioned to
1346 // stay put, we position it in the layer tree as follows:
1348 // + Overflow controls host
1349 // + LocalFrame clip
1350 // + (Fixed root background) <-- Here.
1351 // + LocalFrame scroll
1352 // + Root content layer
1355 // That is, it needs to be the first child of the frame clip, the sibling of
1356 // the frame scroll layer. The compositor does not own the background layer, it
1357 // just positions it (like the foreground layer).
1358 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
1359 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
1362 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
1364 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1365 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
1369 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
1371 ASSERT(m_renderView.document().lifecycle().state() >= DocumentLifecycle::CompositingClean);
1373 if (!m_rootContentLayer)
1376 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1377 // similar between platforms (unless we explicitly request dumping from the
1379 GraphicsLayer* rootLayer = m_rootContentLayer.get();
1380 if (flags & LayerTreeIncludesRootLayer)
1381 rootLayer = rootGraphicsLayer();
1383 String layerTreeText = rootLayer->layerTreeAsText(flags);
1385 // The true root layer is not included in the dump, so if we want to report
1386 // its repaint rects, they must be included here.
1387 if (flags & LayerTreeIncludesRepaintRects)
1388 return m_renderView.frameView()->trackedRepaintRectsAsText() + layerTreeText;
1390 return layerTreeText;
1393 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
1395 if (!renderer->node()->isFrameOwnerElement())
1398 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
1399 if (Document* contentDocument = element->contentDocument()) {
1400 if (RenderView* view = contentDocument->renderView())
1401 return view->compositor();
1406 // FIXME: What does this function do? It needs a clearer name.
1407 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
1409 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1410 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1413 RenderLayer* layer = renderer->layer();
1414 if (!layer->hasCompositedLayerMapping())
1417 CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
1418 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
1419 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
1420 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1421 hostingLayer->removeAllChildren();
1422 hostingLayer->addChild(rootLayer);
1427 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1428 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly)
1430 if (layer->stackingNode() != compositingAncestor) {
1431 if (layer->hasCompositedLayerMapping()) {
1432 CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
1433 compositedLayerMapping->updateCompositedBounds(GraphicsLayerUpdater::ForceUpdate);
1435 if (layer->reflectionInfo()) {
1436 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
1437 if (reflectionLayer->hasCompositedLayerMapping())
1438 reflectionLayer->compositedLayerMapping()->updateCompositedBounds(GraphicsLayerUpdater::ForceUpdate);
1441 compositedLayerMapping->updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
1442 if (compositedChildrenOnly)
1447 if (layer->reflectionInfo())
1448 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionInfo()->reflectionLayer(), compositedChildrenOnly);
1450 if (!layer->hasCompositingDescendant())
1453 #if !ASSERT_DISABLED
1454 LayerListMutationDetector mutationChecker(layer->stackingNode());
1457 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
1458 while (RenderLayerStackingNode* curNode = iterator.next())
1459 updateCompositingDescendantGeometry(compositingAncestor, curNode->layer(), compositedChildrenOnly);
1463 void RenderLayerCompositor::repaintCompositedLayers()
1465 recursiveRepaintLayer(rootRenderLayer());
1468 void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer)
1470 // FIXME: This method does not work correctly with transforms.
1471 if (layer->compositingState() == PaintsIntoOwnBacking)
1472 layer->repainter().setBackingNeedsRepaint();
1474 #if !ASSERT_DISABLED
1475 LayerListMutationDetector mutationChecker(layer->stackingNode());
1478 unsigned childrenToVisit = NormalFlowChildren;
1479 if (layer->hasCompositingDescendant())
1480 childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren;
1481 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit);
1482 while (RenderLayerStackingNode* curNode = iterator.next())
1483 recursiveRepaintLayer(curNode->layer());
1486 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
1488 return m_renderView.layer();
1491 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
1493 if (m_overflowControlsHostLayer)
1494 return m_overflowControlsHostLayer.get();
1495 return m_rootContentLayer.get();
1498 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
1500 return m_scrollLayer.get();
1503 GraphicsLayer* RenderLayerCompositor::containerLayer() const
1505 return m_containerLayer.get();
1508 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
1510 ASSERT(rootGraphicsLayer());
1512 if (!m_rootTransformLayer.get()) {
1513 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1514 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
1515 m_rootTransformLayer->addChild(m_containerLayer.get());
1516 updateOverflowControlsLayers();
1519 return m_rootTransformLayer.get();
1522 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
1524 if (!inCompositingMode())
1528 if (m_rootLayerAttachment != RootLayerUnattached)
1531 RootLayerAttachment attachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
1532 attachRootLayer(attachment);
1534 if (m_rootLayerAttachment == RootLayerUnattached)
1541 void RenderLayerCompositor::updateRootLayerPosition()
1543 if (m_rootContentLayer) {
1544 const IntRect& documentRect = m_renderView.documentRect();
1545 m_rootContentLayer->setSize(documentRect.size());
1546 m_rootContentLayer->setPosition(documentRect.location());
1547 #if USE(RUBBER_BANDING)
1548 if (m_layerForOverhangShadow)
1549 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
1552 if (m_containerLayer) {
1553 FrameView* frameView = m_renderView.frameView();
1554 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
1558 void RenderLayerCompositor::updateStyleDeterminedCompositingReasons(RenderLayer* layer)
1560 CompositingReasons reasons = m_compositingReasonFinder.styleDeterminedReasons(layer->renderer());
1561 layer->setCompositingReasons(reasons, CompositingReasonComboAllStyleDeterminedReasons);
1564 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
1566 CompositingReasons reasons = m_compositingReasonFinder.directReasons(layer, &m_needsToRecomputeCompositingRequirements);
1567 layer->setCompositingReasons(reasons, CompositingReasonComboAllDirectReasons);
1570 bool RenderLayerCompositor::needsOwnBacking(const RenderLayer* layer) const
1572 if (!canBeComposited(layer))
1575 // If squashing is disabled, then layers that would have been squashed should just be separately composited.
1576 bool needsOwnBackingForDisabledSquashing = !layerSquashingEnabled() && requiresSquashing(layer->compositingReasons());
1578 return requiresCompositing(layer->compositingReasons()) || needsOwnBackingForDisabledSquashing || (inCompositingMode() && layer->isRootLayer());
1581 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
1583 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
1584 // See http://webkit.org/b/84900 to re-enable it.
1585 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
1588 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1589 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
1590 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
1591 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
1592 // but a sibling in the z-order hierarchy.
1593 bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const
1595 if (!layer->hasCompositedLayerMapping() || !layer->parent())
1598 const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
1599 if (!compositingAncestor)
1602 RenderObject* clippingContainer = layer->renderer()->clippingContainer();
1603 if (!clippingContainer)
1606 if (compositingAncestor->renderer()->isDescendantOf(clippingContainer))
1612 // Return true if the given layer is a stacking context and has compositing child
1613 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
1614 // into the hierarchy between this layer and its children in the z-order hierarchy.
1615 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
1617 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
1620 CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants) const
1622 CompositingReasons subtreeReasons = CompositingReasonNone;
1624 // FIXME: this seems to be a potentially different layer than the layer for which this was called. May not be an error, but is very confusing.
1625 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1627 // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
1628 // via compositing so that they also apply to those composited descdendants.
1629 if (hasCompositedDescendants) {
1630 if (layer->transform())
1631 subtreeReasons |= CompositingReasonTransformWithCompositedDescendants;
1633 if (layer->shouldIsolateCompositedDescendants()) {
1634 ASSERT(layer->stackingNode()->isStackingContext());
1635 subtreeReasons |= CompositingReasonIsolateCompositedDescendants;
1638 // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
1639 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup());
1640 if (renderer->isTransparent())
1641 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants;
1642 if (renderer->hasMask())
1643 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants;
1644 if (renderer->hasFilter())
1645 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants;
1646 if (renderer->hasBlendMode())
1647 subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants;
1649 if (renderer->hasReflection())
1650 subtreeReasons |= CompositingReasonReflectionWithCompositedDescendants;
1652 if (renderer->hasClipOrOverflowClip())
1653 subtreeReasons |= CompositingReasonClipsCompositingDescendants;
1657 // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
1658 // will be affected by the preserve-3d or perspective.
1659 if (has3DTransformedDescendants) {
1660 if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D)
1661 subtreeReasons |= CompositingReasonPreserve3DWith3DDescendants;
1663 if (renderer->style()->hasPerspective())
1664 subtreeReasons |= CompositingReasonPerspectiveWith3DDescendants;
1667 return subtreeReasons;
1670 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
1672 if (!m_compositingReasonFinder.hasAnimationTrigger())
1674 return hasActiveAnimations(*renderer, CSSPropertyWebkitTransform);
1677 // If an element has negative z-index children, those children render in front of the
1678 // layer background, so we need an extra 'contents' layer for the foreground of the layer
1680 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
1682 return layer->stackingNode()->hasNegativeZOrderList();
1685 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
1691 const IntRect& scrollbarRect = scrollbar->frameRect();
1692 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
1693 IntRect transformedClip = clip;
1694 transformedClip.moveBy(scrollbarRect.location());
1695 scrollbar->paint(&context, transformedClip);
1699 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
1701 if (graphicsLayer == layerForHorizontalScrollbar())
1702 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
1703 else if (graphicsLayer == layerForVerticalScrollbar())
1704 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
1705 else if (graphicsLayer == layerForScrollCorner()) {
1706 const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
1708 context.translate(-scrollCorner.x(), -scrollCorner.y());
1709 IntRect transformedClip = clip;
1710 transformedClip.moveBy(scrollCorner.location());
1711 m_renderView.frameView()->paintScrollCorner(&context, transformedClip);
1716 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
1718 if (Settings* settings = m_renderView.document().settings()) {
1719 if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
1725 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
1727 if (layer != m_renderView.layer())
1730 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
1733 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
1735 // Get the fixed root background from the RenderView layer's compositedLayerMapping.
1736 RenderLayer* viewLayer = m_renderView.layer();
1740 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
1741 return viewLayer->compositedLayerMapping()->backgroundLayer();
1746 static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
1751 graphicsLayer->resetTrackedRepaints();
1753 for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
1754 resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
1756 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
1757 resetTrackedRepaintRectsRecursive(replicaLayer);
1759 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
1760 resetTrackedRepaintRectsRecursive(maskLayer);
1762 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
1763 resetTrackedRepaintRectsRecursive(clippingMaskLayer);
1766 void RenderLayerCompositor::resetTrackedRepaintRects()
1768 if (GraphicsLayer* rootLayer = rootGraphicsLayer())
1769 resetTrackedRepaintRectsRecursive(rootLayer);
1772 void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
1774 updateCompositingLayers();
1775 m_isTrackingRepaints = tracksRepaints;
1778 bool RenderLayerCompositor::isTrackingRepaints() const
1780 return m_isTrackingRepaints;
1783 static bool shouldCompositeOverflowControls(FrameView* view)
1785 if (Page* page = view->frame().page()) {
1786 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1787 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
1794 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
1796 FrameView* view = m_renderView.frameView();
1797 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
1800 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
1802 FrameView* view = m_renderView.frameView();
1803 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
1806 bool RenderLayerCompositor::requiresScrollCornerLayer() const
1808 FrameView* view = m_renderView.frameView();
1809 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
1812 #if USE(RUBBER_BANDING)
1813 bool RenderLayerCompositor::requiresOverhangLayers() const
1815 // We don't want a layer if this is a subframe.
1819 // We do want a layer if we have a scrolling coordinator and can scroll.
1820 if (scrollingCoordinator() && m_renderView.frameView()->hasOpaqueBackground())
1823 // Chromium always wants a layer.
1828 void RenderLayerCompositor::updateOverflowControlsLayers()
1830 #if USE(RUBBER_BANDING)
1831 if (requiresOverhangLayers()) {
1832 if (!m_layerForOverhangShadow) {
1833 m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
1834 OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
1835 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
1836 m_scrollLayer->addChild(m_layerForOverhangShadow.get());
1839 if (m_layerForOverhangShadow) {
1840 m_layerForOverhangShadow->removeFromParent();
1841 m_layerForOverhangShadow = nullptr;
1845 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
1847 if (requiresHorizontalScrollbarLayer()) {
1848 if (!m_layerForHorizontalScrollbar) {
1849 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
1850 controlsParent->addChild(m_layerForHorizontalScrollbar.get());
1852 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1853 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1855 } else if (m_layerForHorizontalScrollbar) {
1856 m_layerForHorizontalScrollbar->removeFromParent();
1857 m_layerForHorizontalScrollbar = nullptr;
1859 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1860 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1863 if (requiresVerticalScrollbarLayer()) {
1864 if (!m_layerForVerticalScrollbar) {
1865 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
1866 controlsParent->addChild(m_layerForVerticalScrollbar.get());
1868 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1869 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1871 } else if (m_layerForVerticalScrollbar) {
1872 m_layerForVerticalScrollbar->removeFromParent();
1873 m_layerForVerticalScrollbar = nullptr;
1875 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1876 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1879 if (requiresScrollCornerLayer()) {
1880 if (!m_layerForScrollCorner) {
1881 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
1882 controlsParent->addChild(m_layerForScrollCorner.get());
1884 } else if (m_layerForScrollCorner) {
1885 m_layerForScrollCorner->removeFromParent();
1886 m_layerForScrollCorner = nullptr;
1889 m_renderView.frameView()->positionScrollbarLayers();
1892 void RenderLayerCompositor::ensureRootLayer()
1894 RootLayerAttachment expectedAttachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
1895 if (expectedAttachment == m_rootLayerAttachment)
1898 if (!m_rootContentLayer) {
1899 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1900 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
1901 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
1902 m_rootContentLayer->setPosition(FloatPoint());
1904 // Need to clip to prevent transformed content showing outside this frame
1905 m_rootContentLayer->setMasksToBounds(true);
1908 if (!m_overflowControlsHostLayer) {
1909 ASSERT(!m_scrollLayer);
1910 ASSERT(!m_containerLayer);
1912 // Create a layer to host the clipping layer and the overflow controls layers.
1913 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1915 // Create a clipping layer if this is an iframe or settings require to clip.
1916 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1917 bool containerMasksToBounds = !isMainFrame();
1918 if (Settings* settings = m_renderView.document().settings()) {
1919 if (settings->mainFrameClipsContent())
1920 containerMasksToBounds = true;
1922 m_containerLayer->setMasksToBounds(containerMasksToBounds);
1924 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1925 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1926 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
1929 m_overflowControlsHostLayer->addChild(m_containerLayer.get());
1930 m_containerLayer->addChild(m_scrollLayer.get());
1931 m_scrollLayer->addChild(m_rootContentLayer.get());
1933 frameViewDidChangeSize();
1934 frameViewDidScroll();
1937 // Check to see if we have to change the attachment
1938 if (m_rootLayerAttachment != RootLayerUnattached)
1941 attachRootLayer(expectedAttachment);
1944 void RenderLayerCompositor::destroyRootLayer()
1946 if (!m_rootContentLayer)
1951 #if USE(RUBBER_BANDING)
1952 if (m_layerForOverhangShadow) {
1953 m_layerForOverhangShadow->removeFromParent();
1954 m_layerForOverhangShadow = nullptr;
1958 if (m_layerForHorizontalScrollbar) {
1959 m_layerForHorizontalScrollbar->removeFromParent();
1960 m_layerForHorizontalScrollbar = nullptr;
1961 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1962 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1963 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
1964 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1967 if (m_layerForVerticalScrollbar) {
1968 m_layerForVerticalScrollbar->removeFromParent();
1969 m_layerForVerticalScrollbar = nullptr;
1970 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1971 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1972 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
1973 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1976 if (m_layerForScrollCorner) {
1977 m_layerForScrollCorner = nullptr;
1978 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
1981 if (m_overflowControlsHostLayer) {
1982 m_overflowControlsHostLayer = nullptr;
1983 m_containerLayer = nullptr;
1984 m_scrollLayer = nullptr;
1986 ASSERT(!m_scrollLayer);
1987 m_rootContentLayer = nullptr;
1988 m_rootTransformLayer = nullptr;
1991 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
1993 if (!m_rootContentLayer)
1996 switch (attachment) {
1997 case RootLayerUnattached:
1998 ASSERT_NOT_REACHED();
2000 case RootLayerAttachedViaChromeClient: {
2001 LocalFrame& frame = m_renderView.frameView()->frame();
2002 Page* page = frame.page();
2005 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
2008 case RootLayerAttachedViaEnclosingFrame: {
2009 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
2010 ASSERT(ownerElement);
2011 DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
2012 // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
2013 // for the frame's renderer in the parent document.
2014 ownerElement->scheduleLayerUpdate();
2019 m_rootLayerAttachment = attachment;
2022 void RenderLayerCompositor::detachRootLayer()
2024 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
2027 switch (m_rootLayerAttachment) {
2028 case RootLayerAttachedViaEnclosingFrame: {
2029 // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
2030 // for the frame's renderer in the parent document.
2031 if (m_overflowControlsHostLayer)
2032 m_overflowControlsHostLayer->removeFromParent();
2034 m_rootContentLayer->removeFromParent();
2036 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
2037 DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
2038 ownerElement->scheduleLayerUpdate();
2042 case RootLayerAttachedViaChromeClient: {
2043 LocalFrame& frame = m_renderView.frameView()->frame();
2044 Page* page = frame.page();
2047 page->chrome().client().attachRootGraphicsLayer(0);
2050 case RootLayerUnattached:
2054 m_rootLayerAttachment = RootLayerUnattached;
2057 void RenderLayerCompositor::updateRootLayerAttachment()
2062 bool RenderLayerCompositor::isMainFrame() const
2064 // FIXME: LocalFrame::isMainFrame() is probably better.
2065 return !m_renderView.document().ownerElement();
2068 // IFrames are special, because we hook compositing layers together across iframe boundaries
2069 // when both parent and iframe content are composited. So when this frame becomes composited, we have
2070 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
2071 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
2073 if (!m_renderView.frameView())
2075 LocalFrame& frame = m_renderView.frameView()->frame();
2077 for (LocalFrame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) {
2078 if (!child->document())
2079 continue; // FIXME: Can this happen?
2080 if (HTMLFrameOwnerElement* ownerElement = child->document()->ownerElement()) {
2081 DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
2082 ownerElement->scheduleLayerUpdate();
2086 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
2087 // we need to schedule a style recalc in our parent document.
2088 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
2089 ownerElement->document().renderView()->compositor()->setNeedsToRecomputeCompositingRequirements();
2090 DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
2091 ownerElement->scheduleLayerUpdate();
2095 void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer)
2097 if (CompositingReasonFinder::isViewportConstrainedFixedOrStickyLayer(layer))
2098 addViewportConstrainedLayer(layer);
2100 removeViewportConstrainedLayer(layer);
2103 void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer* layer)
2105 m_viewportConstrainedLayers.add(layer);
2108 void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer* layer)
2110 if (!m_viewportConstrainedLayers.contains(layer))
2113 m_viewportConstrainedLayers.remove(layer);
2116 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
2118 if (Page* page = this->page())
2119 return page->scrollingCoordinator();
2124 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
2126 if (Page* page = this->page())
2127 return page->chrome().client().graphicsLayerFactory();
2131 Page* RenderLayerCompositor::page() const
2133 return m_renderView.frameView()->frame().page();
2136 DocumentLifecycle& RenderLayerCompositor::lifecycle() const
2138 return m_renderView.document().lifecycle();
2141 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
2144 if (graphicsLayer == m_rootContentLayer.get()) {
2145 name = "Content Root Layer";
2146 } else if (graphicsLayer == m_rootTransformLayer.get()) {
2147 name = "Root Transform Layer";
2148 #if USE(RUBBER_BANDING)
2149 } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
2150 name = "Overhang Areas Shadow";
2152 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
2153 name = "Overflow Controls Host Layer";
2154 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
2155 name = "Horizontal Scrollbar Layer";
2156 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
2157 name = "Vertical Scrollbar Layer";
2158 } else if (graphicsLayer == m_layerForScrollCorner.get()) {
2159 name = "Scroll Corner Layer";
2160 } else if (graphicsLayer == m_containerLayer.get()) {
2161 name = "LocalFrame Clipping Layer";
2162 } else if (graphicsLayer == m_scrollLayer.get()) {
2163 name = "LocalFrame Scrolling Layer";
2165 ASSERT_NOT_REACHED();
2171 } // namespace WebCore