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 "core/animation/DocumentAnimations.h"
31 #include "core/dom/Fullscreen.h"
32 #include "core/frame/FrameView.h"
33 #include "core/frame/LocalFrame.h"
34 #include "core/frame/Settings.h"
35 #include "core/html/HTMLIFrameElement.h"
36 #include "core/inspector/InspectorInstrumentation.h"
37 #include "core/inspector/InspectorNodeIds.h"
38 #include "core/page/Chrome.h"
39 #include "core/page/ChromeClient.h"
40 #include "core/page/Page.h"
41 #include "core/page/scrolling/ScrollingCoordinator.h"
42 #include "core/paint/FramePainter.h"
43 #include "core/rendering/RenderEmbeddedObject.h"
44 #include "core/rendering/RenderLayerStackingNode.h"
45 #include "core/rendering/RenderLayerStackingNodeIterator.h"
46 #include "core/rendering/RenderPart.h"
47 #include "core/rendering/RenderVideo.h"
48 #include "core/rendering/RenderView.h"
49 #include "core/rendering/compositing/CompositedLayerMapping.h"
50 #include "core/rendering/compositing/CompositingInputsUpdater.h"
51 #include "core/rendering/compositing/CompositingLayerAssigner.h"
52 #include "core/rendering/compositing/CompositingRequirementsUpdater.h"
53 #include "core/rendering/compositing/GraphicsLayerTreeBuilder.h"
54 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
55 #include "platform/OverscrollTheme.h"
56 #include "platform/RuntimeEnabledFeatures.h"
57 #include "platform/ScriptForbiddenScope.h"
58 #include "platform/TraceEvent.h"
59 #include "platform/graphics/GraphicsLayer.h"
60 #include "public/platform/Platform.h"
64 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
65 : m_renderView(renderView)
66 , m_compositingReasonFinder(renderView)
67 , m_pendingUpdateType(CompositingUpdateNone)
68 , m_hasAcceleratedCompositing(true)
69 , m_compositing(false)
70 , m_rootShouldAlwaysCompositeDirty(true)
71 , m_needsUpdateFixedBackground(false)
72 , m_isTrackingPaintInvalidations(false)
73 , m_rootLayerAttachment(RootLayerUnattached)
74 , m_inOverlayFullscreenVideo(false)
76 updateAcceleratedCompositingSettings();
79 RenderLayerCompositor::~RenderLayerCompositor()
81 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
84 bool RenderLayerCompositor::inCompositingMode() const
86 // FIXME: This should assert that lificycle is >= CompositingClean since
87 // the last step of updateIfNeeded can set this bit to false.
88 ASSERT(!m_rootShouldAlwaysCompositeDirty);
92 bool RenderLayerCompositor::staleInCompositingMode() const
97 void RenderLayerCompositor::setCompositingModeEnabled(bool enable)
99 if (enable == m_compositing)
102 m_compositing = enable;
104 // RenderPart::requiresAcceleratedCompositing is used to determine self-paintingness
105 // and bases it's return value for frames on the m_compositing bit here.
106 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
107 if (RenderPart* renderer = ownerElement->renderPart())
108 renderer->layer()->updateSelfPaintingLayer();
116 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
117 // we need to schedule a style recalc in our parent document.
118 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
119 ownerElement->setNeedsCompositingUpdate();
122 void RenderLayerCompositor::enableCompositingModeIfNeeded()
124 if (!m_rootShouldAlwaysCompositeDirty)
127 m_rootShouldAlwaysCompositeDirty = false;
131 if (rootShouldAlwaysComposite()) {
132 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_bug.cgi?id=26651.
133 // No tests fail if it's deleted.
134 setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
135 setCompositingModeEnabled(true);
139 bool RenderLayerCompositor::rootShouldAlwaysComposite() const
141 if (!m_hasAcceleratedCompositing)
143 return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requiresCompositingForScrollableFrame();
146 void RenderLayerCompositor::updateAcceleratedCompositingSettings()
148 m_compositingReasonFinder.updateTriggers();
149 m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled();
150 m_rootShouldAlwaysCompositeDirty = true;
153 bool RenderLayerCompositor::layerSquashingEnabled() const
155 if (!RuntimeEnabledFeatures::layerSquashingEnabled())
157 if (Settings* settings = m_renderView.document().settings())
158 return settings->layerSquashingEnabled();
162 bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const
164 return m_compositingReasonFinder.hasOverflowScrollTrigger();
167 static RenderVideo* findFullscreenVideoRenderer(Document& document)
169 // Recursively find the document that is in fullscreen.
170 Element* fullscreenElement = Fullscreen::fullscreenElementFrom(document);
171 Document* contentDocument = &document;
172 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
173 contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
174 if (!contentDocument)
176 fullscreenElement = Fullscreen::fullscreenElementFrom(*contentDocument);
178 // Get the current fullscreen element from the document.
179 fullscreenElement = Fullscreen::currentFullScreenElementFrom(*contentDocument);
180 if (!isHTMLVideoElement(fullscreenElement))
182 RenderObject* renderer = fullscreenElement->renderer();
185 return toRenderVideo(renderer);
188 void RenderLayerCompositor::updateIfNeededRecursive()
190 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
191 if (child->isLocalFrame())
192 toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeededRecursive();
195 TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive");
197 ASSERT(!m_renderView.needsLayout());
199 ScriptForbiddenScope forbidScript;
201 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree,
202 // which asserts that it's not InCompositingUpdate.
203 enableCompositingModeIfNeeded();
205 rootRenderLayer()->updateDescendantDependentFlagsForEntireSubtree();
207 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
209 lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
211 DocumentAnimations::startPendingAnimations(m_renderView.document());
214 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
215 assertNoUnresolvedDirtyBits();
216 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
217 if (child->isLocalFrame())
218 toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnresolvedDirtyBits();
223 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType)
225 ASSERT(updateType != CompositingUpdateNone);
226 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType);
227 page()->animator().scheduleVisualUpdate();
228 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
231 void RenderLayerCompositor::didLayout()
233 // FIXME: Technically we only need to do this when the FrameView's
234 // isScrollable method would return a different value.
235 m_rootShouldAlwaysCompositeDirty = true;
236 enableCompositingModeIfNeeded();
238 // FIXME: Rather than marking the entire RenderView as dirty, we should
239 // track which RenderLayers moved during layout and only dirty those
240 // specific RenderLayers.
241 rootRenderLayer()->setNeedsCompositingInputsUpdate();
246 void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
248 ASSERT(m_pendingUpdateType == CompositingUpdateNone);
249 ASSERT(!m_rootShouldAlwaysCompositeDirty);
254 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment()
256 m_inOverlayFullscreenVideo = false;
257 if (!m_rootContentLayer)
260 bool isLocalRoot = m_renderView.frame()->isLocalRoot();
261 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
262 if (!video || !video->layer()->hasCompositedLayerMapping()) {
264 GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer();
265 if (backgroundLayer && !backgroundLayer->parent())
266 rootFixedBackgroundsChanged();
271 GraphicsLayer* videoLayer = video->layer()->compositedLayerMapping()->mainGraphicsLayer();
273 // The fullscreen video has layer position equal to its enclosing frame's scroll position because fullscreen container is fixed-positioned.
274 // We should reset layer position here since we are going to reattach the layer at the very top level.
275 videoLayer->setPosition(IntPoint());
277 // Only steal fullscreen video layer and clear all other layers if we are the main frame.
281 m_rootContentLayer->removeAllChildren();
282 m_overflowControlsHostLayer->addChild(videoLayer);
283 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
284 backgroundLayer->removeFromParent();
285 m_inOverlayFullscreenVideo = true;
288 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdateType updateType)
290 ASSERT(!hasAcceleratedCompositing());
292 if (updateType >= CompositingUpdateAfterCompositingInputChange)
293 CompositingInputsUpdater(rootRenderLayer()).update();
296 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(rootRenderLayer());
300 static void forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(RenderObject* renderer)
302 // We clear the previous paint invalidation rect as it's wrong (paint invaliation container
303 // changed, ...). Forcing a full invalidation will make us recompute it. Also we are not
304 // changing the previous position from our paint invalidation container, which is fine as
305 // we want a full paint invalidation anyway.
306 renderer->setPreviousPaintInvalidationRect(LayoutRect());
307 renderer->setShouldDoFullPaintInvalidation();
309 for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling()) {
310 if (!child->isPaintInvalidationContainer())
311 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(child);
316 void RenderLayerCompositor::updateIfNeeded()
318 CompositingUpdateType updateType = m_pendingUpdateType;
319 m_pendingUpdateType = CompositingUpdateNone;
321 if (!hasAcceleratedCompositing()) {
322 updateWithoutAcceleratedCompositing(updateType);
326 if (updateType == CompositingUpdateNone)
329 RenderLayer* updateRoot = rootRenderLayer();
331 Vector<RenderLayer*> layersNeedingPaintInvalidation;
333 if (updateType >= CompositingUpdateAfterCompositingInputChange) {
334 CompositingInputsUpdater(updateRoot).update();
337 // FIXME: Move this check to the end of the compositing update.
338 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(updateRoot);
341 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).update(updateRoot);
343 CompositingLayerAssigner layerAssigner(this);
344 layerAssigner.assign(updateRoot, layersNeedingPaintInvalidation);
346 bool layersChanged = layerAssigner.layersChanged();
349 TRACE_EVENT0("blink", "RenderLayerCompositor::updateAfterCompositingChange");
350 if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas()) {
351 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
352 layersChanged |= (*it)->updateAfterCompositingChange();
357 updateType = std::max(updateType, CompositingUpdateRebuildTree);
360 if (updateType != CompositingUpdateNone) {
361 GraphicsLayerUpdater updater;
362 updater.update(*updateRoot, layersNeedingPaintInvalidation);
364 if (updater.needsRebuildTree())
365 updateType = std::max(updateType, CompositingUpdateRebuildTree);
368 // FIXME: Move this check to the end of the compositing update.
369 GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updateRoot);
373 if (updateType >= CompositingUpdateRebuildTree) {
374 GraphicsLayerTreeBuilder::AncestorInfo ancestorInfo;
375 GraphicsLayerVector childList;
376 ancestorInfo.childLayersOfEnclosingCompositedLayer = &childList;
378 TRACE_EVENT0("blink", "GraphicsLayerTreeBuilder::rebuild");
379 GraphicsLayerTreeBuilder().rebuild(*updateRoot, ancestorInfo);
382 if (childList.isEmpty())
385 m_rootContentLayer->setChildren(childList);
387 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
388 applyOverlayFullscreenVideoAdjustment();
391 if (m_needsUpdateFixedBackground) {
392 rootFixedBackgroundsChanged();
393 m_needsUpdateFixedBackground = false;
396 for (unsigned i = 0; i < layersNeedingPaintInvalidation.size(); i++)
397 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(layersNeedingPaintInvalidation[i]->renderer());
399 // Inform the inspector that the layer tree has changed.
400 if (m_renderView.frame()->isMainFrame())
401 InspectorInstrumentation::layerTreeDidChange(m_renderView.frame());
404 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
406 bool compositedLayerMappingChanged = false;
408 // FIXME: It would be nice to directly use the layer's compositing reason,
409 // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
410 // requirements fully.
411 switch (compositedLayerUpdate) {
412 case AllocateOwnCompositedLayerMapping:
413 ASSERT(!layer->hasCompositedLayerMapping());
414 setCompositingModeEnabled(true);
416 // If we need to issue paint invalidations, do so before allocating the compositedLayerMapping and clearing out the groupedMapping.
417 paintInvalidationOnCompositingChange(layer);
419 // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
420 // that computing paint invalidation rects will know the layer's correct compositingState.
421 // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
422 // Need to create a test where a squashed layer pops into compositing. And also to cover all other
423 // sorts of compositingState transitions.
424 layer->setLostGroupedMapping(false);
425 layer->setGroupedMapping(0);
427 layer->ensureCompositedLayerMapping();
428 compositedLayerMappingChanged = true;
430 // At this time, the ScrollingCooridnator only supports the top-level frame.
431 if (layer->isRootLayer() && m_renderView.frame()->isLocalRoot()) {
432 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
433 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
436 case RemoveOwnCompositedLayerMapping:
437 // PutInSquashingLayer means you might have to remove the composited layer mapping first.
438 case PutInSquashingLayer:
439 if (layer->hasCompositedLayerMapping()) {
440 // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
441 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
442 // are both either composited, or not composited.
443 if (layer->isReflection()) {
444 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
445 if (sourceLayer->hasCompositedLayerMapping()) {
446 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
447 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
451 layer->clearCompositedLayerMapping();
452 compositedLayerMappingChanged = true;
456 case RemoveFromSquashingLayer:
457 case NoCompositingStateChange:
462 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
463 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
464 if (innerCompositor && innerCompositor->staleInCompositingMode())
465 innerCompositor->updateRootLayerAttachment();
468 if (compositedLayerMappingChanged)
469 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
471 // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
472 // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
473 if (compositedLayerMappingChanged) {
474 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
475 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
478 return compositedLayerMappingChanged;
481 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* layer)
483 // If the renderer is not attached yet, no need to issue paint invalidations.
484 if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
487 // For querying RenderLayer::compositingState()
488 // Eager invalidation here is correct, since we are invalidating with respect to the previous frame's
489 // compositing state when changing the compositing backing of the layer.
490 DisableCompositingQueryAsserts disabler;
492 layer->renderer()->invalidatePaintIncludingNonCompositingDescendants();
495 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
497 if (m_overflowControlsHostLayer)
498 m_overflowControlsHostLayer->setPosition(contentsOffset);
501 void RenderLayerCompositor::frameViewDidChangeSize()
503 if (m_containerLayer) {
504 FrameView* frameView = m_renderView.frameView();
505 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
506 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars));
508 frameViewDidScroll();
509 updateOverflowControlsLayers();
513 enum AcceleratedFixedRootBackgroundHistogramBuckets {
514 ScrolledMainFrameBucket = 0,
515 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
516 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
517 AcceleratedFixedRootBackgroundHistogramMax = 3
520 void RenderLayerCompositor::frameViewDidScroll()
522 FrameView* frameView = m_renderView.frameView();
523 IntPoint scrollPosition = frameView->scrollPosition();
528 bool scrollingCoordinatorHandlesOffset = false;
529 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
530 if (Settings* settings = m_renderView.document().settings()) {
531 if (m_renderView.frame()->isLocalRoot() || settings->preferCompositingToLCDTextEnabled())
532 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
536 // Scroll position = scroll minimum + scroll offset. Adjust the layer's
537 // position to handle whatever the scroll coordinator isn't handling.
538 // The minimum scroll position is non-zero for RTL pages with overflow.
539 if (scrollingCoordinatorHandlesOffset)
540 m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
542 m_scrollLayer->setPosition(-scrollPosition);
545 Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
546 ScrolledMainFrameBucket,
547 AcceleratedFixedRootBackgroundHistogramMax);
550 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
552 if (m_containerLayer)
553 updateOverflowControlsLayers();
556 void RenderLayerCompositor::rootFixedBackgroundsChanged()
558 if (!supportsFixedRootBackgroundCompositing())
561 // To avoid having to make the fixed root background layer fixed positioned to
562 // stay put, we position it in the layer tree as follows:
564 // + Overflow controls host
566 // + (Fixed root background) <-- Here.
567 // + LocalFrame scroll
568 // + Root content layer
571 // That is, it needs to be the first child of the frame clip, the sibling of
572 // the frame scroll layer. The compositor does not own the background layer, it
573 // just positions it (like the foreground layer).
574 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
575 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
578 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
580 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
581 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
585 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
587 ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean);
589 if (!m_rootContentLayer)
592 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
593 // similar between platforms (unless we explicitly request dumping from the
595 GraphicsLayer* rootLayer = m_rootContentLayer.get();
596 if (flags & LayerTreeIncludesRootLayer)
597 rootLayer = rootGraphicsLayer();
599 String layerTreeText = rootLayer->layerTreeAsText(flags);
601 // The true root layer is not included in the dump, so if we want to report
602 // its paint invalidation rects, they must be included here.
603 if (flags & LayerTreeIncludesPaintInvalidationRects)
604 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() + layerTreeText;
606 return layerTreeText;
609 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
611 if (!renderer->node()->isFrameOwnerElement())
614 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
615 if (Document* contentDocument = element->contentDocument()) {
616 if (RenderView* view = contentDocument->renderView())
617 return view->compositor();
622 // FIXME: What does this function do? It needs a clearer name.
623 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
625 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
626 if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
629 RenderLayer* layer = renderer->layer();
630 if (!layer->hasCompositedLayerMapping())
633 CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
634 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
635 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
636 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
637 hostingLayer->removeAllChildren();
638 hostingLayer->addChild(rootLayer);
643 static void fullyInvalidatePaintRecursive(RenderLayer* layer)
645 if (layer->compositingState() == PaintsIntoOwnBacking) {
646 layer->compositedLayerMapping()->setContentsNeedDisplay();
647 layer->compositedLayerMapping()->setSquashingContentsNeedDisplay();
650 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
651 fullyInvalidatePaintRecursive(child);
654 void RenderLayerCompositor::fullyInvalidatePaint()
656 // We're walking all compositing layers and invalidating them, so there's
657 // no need to have up-to-date compositing state.
658 DisableCompositingQueryAsserts disabler;
659 fullyInvalidatePaintRecursive(rootRenderLayer());
662 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
664 return m_renderView.layer();
667 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
669 if (m_overflowControlsHostLayer)
670 return m_overflowControlsHostLayer.get();
671 return m_rootContentLayer.get();
674 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
676 return m_scrollLayer.get();
679 GraphicsLayer* RenderLayerCompositor::containerLayer() const
681 return m_containerLayer.get();
684 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
686 ASSERT(rootGraphicsLayer());
688 if (!m_rootTransformLayer.get()) {
689 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
690 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
691 m_rootTransformLayer->addChild(m_containerLayer.get());
692 updateOverflowControlsLayers();
695 return m_rootTransformLayer.get();
698 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
700 if (!staleInCompositingMode())
704 if (m_rootLayerAttachment != RootLayerUnattached)
707 RootLayerAttachment attachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
708 attachRootLayer(attachment);
710 if (m_rootLayerAttachment == RootLayerUnattached)
717 void RenderLayerCompositor::updateRootLayerPosition()
719 if (m_rootContentLayer) {
720 const IntRect& documentRect = m_renderView.documentRect();
721 m_rootContentLayer->setSize(documentRect.size());
722 m_rootContentLayer->setPosition(documentRect.location());
723 #if USE(RUBBER_BANDING)
724 if (m_layerForOverhangShadow)
725 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
728 if (m_containerLayer) {
729 FrameView* frameView = m_renderView.frameView();
730 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
731 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars));
735 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLayer* layer)
737 layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.potentialCompositingReasonsFromStyle(layer->renderer()));
740 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
742 layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer), CompositingReasonComboAllDirectReasons);
745 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer)
747 ASSERT(rootGraphicsLayer());
749 if (layer->parent() != m_overflowControlsHostLayer.get())
750 m_overflowControlsHostLayer->addChild(layer);
753 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
755 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->subtreeIsInvisible();
758 // Return true if the given layer is a stacking context and has compositing child
759 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
760 // into the hierarchy between this layer and its children in the z-order hierarchy.
761 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
763 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
766 // If an element has composited negative z-index children, those children render in front of the
767 // layer background, so we need an extra 'contents' layer for the foreground of the layer
769 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
771 if (!layer->hasCompositingDescendant())
773 return layer->stackingNode()->hasNegativeZOrderList();
776 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
782 const IntRect& scrollbarRect = scrollbar->frameRect();
783 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
784 IntRect transformedClip = clip;
785 transformedClip.moveBy(scrollbarRect.location());
786 scrollbar->paint(&context, transformedClip);
790 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
792 if (graphicsLayer == layerForHorizontalScrollbar())
793 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
794 else if (graphicsLayer == layerForVerticalScrollbar())
795 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
796 else if (graphicsLayer == layerForScrollCorner()) {
797 const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
799 context.translate(-scrollCorner.x(), -scrollCorner.y());
800 IntRect transformedClip = clip;
801 transformedClip.moveBy(scrollCorner.location());
802 FramePainter(*m_renderView.frameView()).paintScrollCorner(&context, transformedClip);
807 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
809 if (Settings* settings = m_renderView.document().settings())
810 return settings->preferCompositingToLCDTextEnabled();
814 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
816 if (layer != m_renderView.layer())
819 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
822 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
824 // Get the fixed root background from the RenderView layer's compositedLayerMapping.
825 RenderLayer* viewLayer = m_renderView.layer();
829 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
830 return viewLayer->compositedLayerMapping()->backgroundLayer();
835 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsLayer)
840 graphicsLayer->resetTrackedPaintInvalidations();
842 for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
843 resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]);
845 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
846 resetTrackedPaintInvalidationRectsRecursive(replicaLayer);
848 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
849 resetTrackedPaintInvalidationRectsRecursive(maskLayer);
851 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
852 resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer);
855 void RenderLayerCompositor::resetTrackedPaintInvalidationRects()
857 if (GraphicsLayer* rootLayer = rootGraphicsLayer())
858 resetTrackedPaintInvalidationRectsRecursive(rootLayer);
861 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalidations)
863 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean);
864 m_isTrackingPaintInvalidations = tracksPaintInvalidations;
867 bool RenderLayerCompositor::isTrackingPaintInvalidations() const
869 return m_isTrackingPaintInvalidations;
872 static bool shouldCompositeOverflowControls(FrameView* view)
874 if (Page* page = view->frame().page()) {
875 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
876 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
883 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
885 FrameView* view = m_renderView.frameView();
886 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
889 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
891 FrameView* view = m_renderView.frameView();
892 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
895 bool RenderLayerCompositor::requiresScrollCornerLayer() const
897 FrameView* view = m_renderView.frameView();
898 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
901 void RenderLayerCompositor::updateOverflowControlsLayers()
903 #if USE(RUBBER_BANDING)
904 if (m_renderView.frame()->isLocalRoot()) {
905 if (!m_layerForOverhangShadow) {
906 m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
907 OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
908 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
909 m_scrollLayer->addChild(m_layerForOverhangShadow.get());
912 ASSERT(!m_layerForOverhangShadow);
915 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
917 if (requiresHorizontalScrollbarLayer()) {
918 if (!m_layerForHorizontalScrollbar) {
919 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
922 if (m_layerForHorizontalScrollbar->parent() != controlsParent) {
923 controlsParent->addChild(m_layerForHorizontalScrollbar.get());
925 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
926 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
928 } else if (m_layerForHorizontalScrollbar) {
929 m_layerForHorizontalScrollbar->removeFromParent();
930 m_layerForHorizontalScrollbar = nullptr;
932 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
933 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
936 if (requiresVerticalScrollbarLayer()) {
937 if (!m_layerForVerticalScrollbar) {
938 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
941 if (m_layerForVerticalScrollbar->parent() != controlsParent) {
942 controlsParent->addChild(m_layerForVerticalScrollbar.get());
944 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
945 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
947 } else if (m_layerForVerticalScrollbar) {
948 m_layerForVerticalScrollbar->removeFromParent();
949 m_layerForVerticalScrollbar = nullptr;
951 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
952 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
955 if (requiresScrollCornerLayer()) {
956 if (!m_layerForScrollCorner) {
957 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
958 controlsParent->addChild(m_layerForScrollCorner.get());
960 } else if (m_layerForScrollCorner) {
961 m_layerForScrollCorner->removeFromParent();
962 m_layerForScrollCorner = nullptr;
965 m_renderView.frameView()->positionScrollbarLayers();
968 void RenderLayerCompositor::ensureRootLayer()
970 RootLayerAttachment expectedAttachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
971 if (expectedAttachment == m_rootLayerAttachment)
974 Settings* settings = m_renderView.document().settings();
975 if (!m_rootContentLayer) {
976 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
977 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
978 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
979 m_rootContentLayer->setPosition(FloatPoint());
980 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderView.generatingNode()));
982 // FIXME: with rootLayerScrolls, we probably don't even need m_rootContentLayer?
983 if (!(settings && settings->rootLayerScrolls())) {
984 // Need to clip to prevent transformed content showing outside this frame
985 m_rootContentLayer->setMasksToBounds(true);
989 if (!m_overflowControlsHostLayer) {
990 ASSERT(!m_scrollLayer);
991 ASSERT(!m_containerLayer);
993 // Create a layer to host the clipping layer and the overflow controls layers.
994 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
996 // Clip iframe's overflow controls layer.
997 bool containerMasksToBounds = !m_renderView.frame()->isLocalRoot();
998 m_overflowControlsHostLayer->setMasksToBounds(containerMasksToBounds);
1000 // Create a clipping layer if this is an iframe or settings require to clip.
1001 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1002 if (Settings* settings = m_renderView.document().settings()) {
1003 if (settings->mainFrameClipsContent())
1004 containerMasksToBounds = true;
1006 m_containerLayer->setMasksToBounds(containerMasksToBounds);
1008 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1009 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1010 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
1013 m_overflowControlsHostLayer->addChild(m_containerLayer.get());
1014 m_containerLayer->addChild(m_scrollLayer.get());
1015 m_scrollLayer->addChild(m_rootContentLayer.get());
1017 frameViewDidChangeSize();
1020 // Check to see if we have to change the attachment
1021 if (m_rootLayerAttachment != RootLayerUnattached)
1024 attachRootLayer(expectedAttachment);
1027 void RenderLayerCompositor::destroyRootLayer()
1029 if (!m_rootContentLayer)
1034 #if USE(RUBBER_BANDING)
1035 if (m_layerForOverhangShadow) {
1036 m_layerForOverhangShadow->removeFromParent();
1037 m_layerForOverhangShadow = nullptr;
1041 if (m_layerForHorizontalScrollbar) {
1042 m_layerForHorizontalScrollbar->removeFromParent();
1043 m_layerForHorizontalScrollbar = nullptr;
1044 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1045 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1046 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
1047 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1050 if (m_layerForVerticalScrollbar) {
1051 m_layerForVerticalScrollbar->removeFromParent();
1052 m_layerForVerticalScrollbar = nullptr;
1053 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1054 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1055 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
1056 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1059 if (m_layerForScrollCorner) {
1060 m_layerForScrollCorner = nullptr;
1061 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
1064 if (m_overflowControlsHostLayer) {
1065 m_overflowControlsHostLayer = nullptr;
1066 m_containerLayer = nullptr;
1067 m_scrollLayer = nullptr;
1069 ASSERT(!m_scrollLayer);
1070 m_rootContentLayer = nullptr;
1071 m_rootTransformLayer = nullptr;
1074 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
1076 if (!m_rootContentLayer)
1079 switch (attachment) {
1080 case RootLayerUnattached:
1081 ASSERT_NOT_REACHED();
1083 case RootLayerAttachedViaChromeClient: {
1084 LocalFrame& frame = m_renderView.frameView()->frame();
1085 Page* page = frame.page();
1088 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
1091 case RootLayerAttachedViaEnclosingFrame: {
1092 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
1093 ASSERT(ownerElement);
1094 // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1095 // for the frame's renderer in the parent document.
1096 ownerElement->setNeedsCompositingUpdate();
1101 m_rootLayerAttachment = attachment;
1104 void RenderLayerCompositor::detachRootLayer()
1106 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
1109 switch (m_rootLayerAttachment) {
1110 case RootLayerAttachedViaEnclosingFrame: {
1111 // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1112 // for the frame's renderer in the parent document.
1113 if (m_overflowControlsHostLayer)
1114 m_overflowControlsHostLayer->removeFromParent();
1116 m_rootContentLayer->removeFromParent();
1118 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
1119 ownerElement->setNeedsCompositingUpdate();
1122 case RootLayerAttachedViaChromeClient: {
1123 LocalFrame& frame = m_renderView.frameView()->frame();
1124 Page* page = frame.page();
1127 page->chrome().client().attachRootGraphicsLayer(0);
1130 case RootLayerUnattached:
1134 m_rootLayerAttachment = RootLayerUnattached;
1137 void RenderLayerCompositor::updateRootLayerAttachment()
1142 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
1144 if (Page* page = this->page())
1145 return page->scrollingCoordinator();
1150 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
1152 if (Page* page = this->page())
1153 return page->chrome().client().graphicsLayerFactory();
1157 Page* RenderLayerCompositor::page() const
1159 return m_renderView.frameView()->frame().page();
1162 DocumentLifecycle& RenderLayerCompositor::lifecycle() const
1164 return m_renderView.document().lifecycle();
1167 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
1170 if (graphicsLayer == m_rootContentLayer.get()) {
1171 name = "Content Root Layer";
1172 } else if (graphicsLayer == m_rootTransformLayer.get()) {
1173 name = "Root Transform Layer";
1174 #if USE(RUBBER_BANDING)
1175 } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
1176 name = "Overhang Areas Shadow";
1178 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
1179 name = "Overflow Controls Host Layer";
1180 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
1181 name = "Horizontal Scrollbar Layer";
1182 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
1183 name = "Vertical Scrollbar Layer";
1184 } else if (graphicsLayer == m_layerForScrollCorner.get()) {
1185 name = "Scroll Corner Layer";
1186 } else if (graphicsLayer == m_containerLayer.get()) {
1187 name = "LocalFrame Clipping Layer";
1188 } else if (graphicsLayer == m_scrollLayer.get()) {
1189 name = "LocalFrame Scrolling Layer";
1191 ASSERT_NOT_REACHED();
1197 } // namespace blink