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/FullscreenElementStack.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/rendering/RenderEmbeddedObject.h"
43 #include "core/rendering/RenderLayerStackingNode.h"
44 #include "core/rendering/RenderLayerStackingNodeIterator.h"
45 #include "core/rendering/RenderPart.h"
46 #include "core/rendering/RenderVideo.h"
47 #include "core/rendering/RenderView.h"
48 #include "core/rendering/compositing/CompositedLayerMapping.h"
49 #include "core/rendering/compositing/CompositingInputsUpdater.h"
50 #include "core/rendering/compositing/CompositingLayerAssigner.h"
51 #include "core/rendering/compositing/CompositingRequirementsUpdater.h"
52 #include "core/rendering/compositing/GraphicsLayerTreeBuilder.h"
53 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
54 #include "platform/OverscrollTheme.h"
55 #include "platform/RuntimeEnabledFeatures.h"
56 #include "platform/ScriptForbiddenScope.h"
57 #include "platform/TraceEvent.h"
58 #include "platform/graphics/GraphicsLayer.h"
59 #include "public/platform/Platform.h"
63 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
64 : m_renderView(renderView)
65 , m_compositingReasonFinder(renderView)
66 , m_pendingUpdateType(CompositingUpdateNone)
67 , m_hasAcceleratedCompositing(true)
68 , m_compositing(false)
69 , m_rootShouldAlwaysCompositeDirty(true)
70 , m_needsUpdateFixedBackground(false)
71 , m_isTrackingPaintInvalidations(false)
72 , m_rootLayerAttachment(RootLayerUnattached)
73 , m_inOverlayFullscreenVideo(false)
75 updateAcceleratedCompositingSettings();
78 RenderLayerCompositor::~RenderLayerCompositor()
80 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
83 bool RenderLayerCompositor::inCompositingMode() const
85 // FIXME: This should assert that lificycle is >= CompositingClean since
86 // the last step of updateIfNeeded can set this bit to false.
87 ASSERT(!m_rootShouldAlwaysCompositeDirty);
91 bool RenderLayerCompositor::staleInCompositingMode() const
96 void RenderLayerCompositor::setCompositingModeEnabled(bool enable)
98 if (enable == m_compositing)
101 m_compositing = enable;
103 // RenderPart::requiresAcceleratedCompositing is used to determine self-paintingness
104 // and bases it's return value for frames on the m_compositing bit here.
105 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
106 if (RenderPart* renderer = ownerElement->renderPart())
107 renderer->layer()->updateSelfPaintingLayer();
115 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
116 // we need to schedule a style recalc in our parent document.
117 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
118 ownerElement->setNeedsCompositingUpdate();
121 void RenderLayerCompositor::enableCompositingModeIfNeeded()
123 if (!m_rootShouldAlwaysCompositeDirty)
126 m_rootShouldAlwaysCompositeDirty = false;
130 if (rootShouldAlwaysComposite()) {
131 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_bug.cgi?id=26651.
132 // No tests fail if it's deleted.
133 setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
134 setCompositingModeEnabled(true);
138 bool RenderLayerCompositor::rootShouldAlwaysComposite() const
140 if (!m_hasAcceleratedCompositing)
142 return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requiresCompositingForScrollableFrame();
145 void RenderLayerCompositor::updateAcceleratedCompositingSettings()
147 m_compositingReasonFinder.updateTriggers();
148 m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled();
149 m_rootShouldAlwaysCompositeDirty = true;
152 bool RenderLayerCompositor::layerSquashingEnabled() const
154 if (!RuntimeEnabledFeatures::layerSquashingEnabled())
156 if (Settings* settings = m_renderView.document().settings())
157 return settings->layerSquashingEnabled();
161 bool RenderLayerCompositor::acceleratedCompositingForOverflowScrollEnabled() const
163 return m_compositingReasonFinder.hasOverflowScrollTrigger();
166 static RenderVideo* findFullscreenVideoRenderer(Document& document)
168 // Recursively find the document that is in fullscreen.
169 Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document);
170 Document* contentDocument = &document;
171 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
172 contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
173 if (!contentDocument)
175 fullscreenElement = FullscreenElementStack::fullscreenElementFrom(*contentDocument);
177 // Get the current fullscreen element from the document.
178 fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(*contentDocument);
179 if (!isHTMLVideoElement(fullscreenElement))
181 RenderObject* renderer = fullscreenElement->renderer();
184 return toRenderVideo(renderer);
187 void RenderLayerCompositor::updateIfNeededRecursive()
189 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
190 if (child->isLocalFrame())
191 toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeededRecursive();
194 TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive");
196 ASSERT(!m_renderView.needsLayout());
198 ScriptForbiddenScope forbidScript;
200 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree,
201 // which asserts that it's not InCompositingUpdate.
202 enableCompositingModeIfNeeded();
204 rootRenderLayer()->updateDescendantDependentFlagsForEntireSubtree();
206 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
208 lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
210 DocumentAnimations::startPendingAnimations(m_renderView.document());
213 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
214 assertNoUnresolvedDirtyBits();
215 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
216 if (child->isLocalFrame())
217 toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnresolvedDirtyBits();
222 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType)
224 ASSERT(updateType != CompositingUpdateNone);
225 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType);
226 page()->animator().scheduleVisualUpdate();
227 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
230 void RenderLayerCompositor::didLayout()
232 // FIXME: Technically we only need to do this when the FrameView's
233 // isScrollable method would return a different value.
234 m_rootShouldAlwaysCompositeDirty = true;
235 enableCompositingModeIfNeeded();
237 // FIXME: Rather than marking the entire RenderView as dirty, we should
238 // track which RenderLayers moved during layout and only dirty those
239 // specific RenderLayers.
240 rootRenderLayer()->setNeedsCompositingInputsUpdate();
245 void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
247 ASSERT(m_pendingUpdateType == CompositingUpdateNone);
248 ASSERT(!m_rootShouldAlwaysCompositeDirty);
253 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment()
255 m_inOverlayFullscreenVideo = false;
256 if (!m_rootContentLayer)
259 bool isLocalRoot = m_renderView.frame()->isLocalRoot();
260 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
261 if (!video || !video->layer()->hasCompositedLayerMapping()) {
263 GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer();
264 if (backgroundLayer && !backgroundLayer->parent())
265 rootFixedBackgroundsChanged();
270 GraphicsLayer* videoLayer = video->layer()->compositedLayerMapping()->mainGraphicsLayer();
272 // The fullscreen video has layer position equal to its enclosing frame's scroll position because fullscreen container is fixed-positioned.
273 // We should reset layer position here since we are going to reattach the layer at the very top level.
274 videoLayer->setPosition(IntPoint());
276 // Only steal fullscreen video layer and clear all other layers if we are the main frame.
280 m_rootContentLayer->removeAllChildren();
281 m_overflowControlsHostLayer->addChild(videoLayer);
282 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
283 backgroundLayer->removeFromParent();
284 m_inOverlayFullscreenVideo = true;
287 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdateType updateType)
289 ASSERT(!hasAcceleratedCompositing());
291 if (updateType >= CompositingUpdateAfterCompositingInputChange)
292 CompositingInputsUpdater(rootRenderLayer()).update();
295 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(rootRenderLayer());
299 void RenderLayerCompositor::updateIfNeeded()
301 CompositingUpdateType updateType = m_pendingUpdateType;
302 m_pendingUpdateType = CompositingUpdateNone;
304 if (!hasAcceleratedCompositing()) {
305 updateWithoutAcceleratedCompositing(updateType);
309 if (updateType == CompositingUpdateNone)
312 RenderLayer* updateRoot = rootRenderLayer();
314 Vector<RenderLayer*> layersNeedingPaintInvalidation;
316 if (updateType >= CompositingUpdateAfterCompositingInputChange) {
317 CompositingInputsUpdater(updateRoot).update();
320 // FIXME: Move this check to the end of the compositing update.
321 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(updateRoot);
324 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).update(updateRoot);
326 CompositingLayerAssigner layerAssigner(this);
327 layerAssigner.assign(updateRoot, layersNeedingPaintInvalidation);
329 bool layersChanged = layerAssigner.layersChanged();
332 TRACE_EVENT0("blink", "RenderLayerCompositor::updateAfterCompositingChange");
333 if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas()) {
334 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
335 layersChanged |= (*it)->updateAfterCompositingChange();
340 updateType = std::max(updateType, CompositingUpdateRebuildTree);
343 if (updateType != CompositingUpdateNone) {
344 GraphicsLayerUpdater updater;
345 updater.update(*updateRoot, layersNeedingPaintInvalidation);
347 if (updater.needsRebuildTree())
348 updateType = std::max(updateType, CompositingUpdateRebuildTree);
351 // FIXME: Move this check to the end of the compositing update.
352 GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updateRoot);
356 if (updateType >= CompositingUpdateRebuildTree) {
357 GraphicsLayerTreeBuilder::AncestorInfo ancestorInfo;
358 GraphicsLayerVector childList;
359 ancestorInfo.childLayersOfEnclosingCompositedLayer = &childList;
361 TRACE_EVENT0("blink", "GraphicsLayerTreeBuilder::rebuild");
362 GraphicsLayerTreeBuilder().rebuild(*updateRoot, ancestorInfo);
365 if (childList.isEmpty())
368 m_rootContentLayer->setChildren(childList);
370 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
371 applyOverlayFullscreenVideoAdjustment();
374 if (m_needsUpdateFixedBackground) {
375 rootFixedBackgroundsChanged();
376 m_needsUpdateFixedBackground = false;
379 for (unsigned i = 0; i < layersNeedingPaintInvalidation.size(); i++) {
380 RenderLayer* layer = layersNeedingPaintInvalidation[i];
381 layer->paintInvalidator().computePaintInvalidationRectsIncludingNonCompositingDescendants();
383 paintInvalidationOnCompositingChange(layer);
386 // Inform the inspector that the layer tree has changed.
387 if (m_renderView.frame()->isMainFrame())
388 InspectorInstrumentation::layerTreeDidChange(m_renderView.frame());
391 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
393 bool compositedLayerMappingChanged = false;
395 // FIXME: It would be nice to directly use the layer's compositing reason,
396 // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
397 // requirements fully.
398 switch (compositedLayerUpdate) {
399 case AllocateOwnCompositedLayerMapping:
400 ASSERT(!layer->hasCompositedLayerMapping());
401 setCompositingModeEnabled(true);
403 // If we need to issue paint invalidations, do so before allocating the compositedLayerMapping and clearing out the groupedMapping.
404 paintInvalidationOnCompositingChange(layer);
406 // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
407 // that computing paint invalidation rects will know the layer's correct compositingState.
408 // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
409 // Need to create a test where a squashed layer pops into compositing. And also to cover all other
410 // sorts of compositingState transitions.
411 layer->setLostGroupedMapping(false);
412 layer->setGroupedMapping(0);
414 layer->ensureCompositedLayerMapping();
415 compositedLayerMappingChanged = true;
417 // At this time, the ScrollingCooridnator only supports the top-level frame.
418 if (layer->isRootLayer() && m_renderView.frame()->isLocalRoot()) {
419 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
420 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
423 case RemoveOwnCompositedLayerMapping:
424 // PutInSquashingLayer means you might have to remove the composited layer mapping first.
425 case PutInSquashingLayer:
426 if (layer->hasCompositedLayerMapping()) {
427 // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
428 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
429 // are both either composited, or not composited.
430 if (layer->isReflection()) {
431 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
432 if (sourceLayer->hasCompositedLayerMapping()) {
433 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
434 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
438 layer->clearCompositedLayerMapping();
439 compositedLayerMappingChanged = true;
443 case RemoveFromSquashingLayer:
444 case NoCompositingStateChange:
449 if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons()) {
450 compositedLayerMappingChanged = true;
451 layer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
454 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
455 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
456 if (innerCompositor && innerCompositor->staleInCompositingMode())
457 innerCompositor->updateRootLayerAttachment();
460 if (compositedLayerMappingChanged)
461 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
463 // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
464 // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
465 if (compositedLayerMappingChanged) {
466 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
467 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
470 return compositedLayerMappingChanged;
473 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* layer)
475 // If the renderer is not attached yet, no need to issue paint invalidations.
476 if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
479 layer->paintInvalidator().paintInvalidationIncludingNonCompositingDescendants();
482 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
484 if (m_overflowControlsHostLayer)
485 m_overflowControlsHostLayer->setPosition(contentsOffset);
488 void RenderLayerCompositor::frameViewDidChangeSize()
490 if (m_containerLayer) {
491 FrameView* frameView = m_renderView.frameView();
492 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
493 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars));
495 frameViewDidScroll();
496 updateOverflowControlsLayers();
500 enum AcceleratedFixedRootBackgroundHistogramBuckets {
501 ScrolledMainFrameBucket = 0,
502 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
503 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
504 AcceleratedFixedRootBackgroundHistogramMax = 3
507 void RenderLayerCompositor::frameViewDidScroll()
509 FrameView* frameView = m_renderView.frameView();
510 IntPoint scrollPosition = frameView->scrollPosition();
515 bool scrollingCoordinatorHandlesOffset = false;
516 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
517 if (Settings* settings = m_renderView.document().settings()) {
518 if (m_renderView.frame()->isLocalRoot() || settings->compositedScrollingForFramesEnabled())
519 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
523 // Scroll position = scroll minimum + scroll offset. Adjust the layer's
524 // position to handle whatever the scroll coordinator isn't handling.
525 // The minimum scroll position is non-zero for RTL pages with overflow.
526 if (scrollingCoordinatorHandlesOffset)
527 m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
529 m_scrollLayer->setPosition(-scrollPosition);
532 Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
533 ScrolledMainFrameBucket,
534 AcceleratedFixedRootBackgroundHistogramMax);
537 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
539 if (m_containerLayer)
540 updateOverflowControlsLayers();
543 void RenderLayerCompositor::rootFixedBackgroundsChanged()
545 if (!supportsFixedRootBackgroundCompositing())
548 // To avoid having to make the fixed root background layer fixed positioned to
549 // stay put, we position it in the layer tree as follows:
551 // + Overflow controls host
553 // + (Fixed root background) <-- Here.
554 // + LocalFrame scroll
555 // + Root content layer
558 // That is, it needs to be the first child of the frame clip, the sibling of
559 // the frame scroll layer. The compositor does not own the background layer, it
560 // just positions it (like the foreground layer).
561 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
562 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
565 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
567 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
568 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
572 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
574 ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean);
576 if (!m_rootContentLayer)
579 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
580 // similar between platforms (unless we explicitly request dumping from the
582 GraphicsLayer* rootLayer = m_rootContentLayer.get();
583 if (flags & LayerTreeIncludesRootLayer)
584 rootLayer = rootGraphicsLayer();
586 String layerTreeText = rootLayer->layerTreeAsText(flags);
588 // The true root layer is not included in the dump, so if we want to report
589 // its paint invalidation rects, they must be included here.
590 if (flags & LayerTreeIncludesPaintInvalidationRects)
591 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() + layerTreeText;
593 return layerTreeText;
596 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
598 if (!renderer->node()->isFrameOwnerElement())
601 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
602 if (Document* contentDocument = element->contentDocument()) {
603 if (RenderView* view = contentDocument->renderView())
604 return view->compositor();
609 // FIXME: What does this function do? It needs a clearer name.
610 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
612 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
613 if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
616 RenderLayer* layer = renderer->layer();
617 if (!layer->hasCompositedLayerMapping())
620 CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
621 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
622 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
623 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
624 hostingLayer->removeAllChildren();
625 hostingLayer->addChild(rootLayer);
630 static void fullyInvalidatePaintRecursive(RenderLayer* layer)
632 if (layer->compositingState() == PaintsIntoOwnBacking) {
633 layer->compositedLayerMapping()->setContentsNeedDisplay();
634 layer->compositedLayerMapping()->setSquashingContentsNeedDisplay();
637 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
638 fullyInvalidatePaintRecursive(child);
641 void RenderLayerCompositor::fullyInvalidatePaint()
643 // We're walking all compositing layers and invalidating them, so there's
644 // no need to have up-to-date compositing state.
645 DisableCompositingQueryAsserts disabler;
646 fullyInvalidatePaintRecursive(rootRenderLayer());
649 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
651 return m_renderView.layer();
654 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
656 if (m_overflowControlsHostLayer)
657 return m_overflowControlsHostLayer.get();
658 return m_rootContentLayer.get();
661 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
663 return m_scrollLayer.get();
666 GraphicsLayer* RenderLayerCompositor::containerLayer() const
668 return m_containerLayer.get();
671 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
673 ASSERT(rootGraphicsLayer());
675 if (!m_rootTransformLayer.get()) {
676 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
677 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
678 m_rootTransformLayer->addChild(m_containerLayer.get());
679 updateOverflowControlsLayers();
682 return m_rootTransformLayer.get();
685 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
687 if (!staleInCompositingMode())
691 if (m_rootLayerAttachment != RootLayerUnattached)
694 RootLayerAttachment attachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
695 attachRootLayer(attachment);
697 if (m_rootLayerAttachment == RootLayerUnattached)
704 void RenderLayerCompositor::updateRootLayerPosition()
706 if (m_rootContentLayer) {
707 const IntRect& documentRect = m_renderView.documentRect();
708 m_rootContentLayer->setSize(documentRect.size());
709 m_rootContentLayer->setPosition(documentRect.location());
710 #if USE(RUBBER_BANDING)
711 if (m_layerForOverhangShadow)
712 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
715 if (m_containerLayer) {
716 FrameView* frameView = m_renderView.frameView();
717 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
718 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars));
722 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLayer* layer)
724 layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.potentialCompositingReasonsFromStyle(layer->renderer()));
727 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
729 layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer), CompositingReasonComboAllDirectReasons);
732 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer)
734 ASSERT(rootGraphicsLayer());
736 if (layer->parent() != m_overflowControlsHostLayer.get())
737 m_overflowControlsHostLayer->addChild(layer);
740 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
742 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
743 // See http://webkit.org/b/84900 to re-enable it.
744 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->subtreeIsInvisible() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
747 // Return true if the given layer is a stacking context and has compositing child
748 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
749 // into the hierarchy between this layer and its children in the z-order hierarchy.
750 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
752 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
755 // If an element has negative z-index children, those children render in front of the
756 // layer background, so we need an extra 'contents' layer for the foreground of the layer
758 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
760 return layer->stackingNode()->hasNegativeZOrderList();
763 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
769 const IntRect& scrollbarRect = scrollbar->frameRect();
770 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
771 IntRect transformedClip = clip;
772 transformedClip.moveBy(scrollbarRect.location());
773 scrollbar->paint(&context, transformedClip);
777 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
779 if (graphicsLayer == layerForHorizontalScrollbar())
780 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
781 else if (graphicsLayer == layerForVerticalScrollbar())
782 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
783 else if (graphicsLayer == layerForScrollCorner()) {
784 const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
786 context.translate(-scrollCorner.x(), -scrollCorner.y());
787 IntRect transformedClip = clip;
788 transformedClip.moveBy(scrollCorner.location());
789 m_renderView.frameView()->paintScrollCorner(&context, transformedClip);
794 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
796 if (Settings* settings = m_renderView.document().settings()) {
797 if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
803 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
805 if (layer != m_renderView.layer())
808 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
811 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
813 // Get the fixed root background from the RenderView layer's compositedLayerMapping.
814 RenderLayer* viewLayer = m_renderView.layer();
818 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
819 return viewLayer->compositedLayerMapping()->backgroundLayer();
824 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsLayer)
829 graphicsLayer->resetTrackedPaintInvalidations();
831 for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
832 resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]);
834 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
835 resetTrackedPaintInvalidationRectsRecursive(replicaLayer);
837 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
838 resetTrackedPaintInvalidationRectsRecursive(maskLayer);
840 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
841 resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer);
844 void RenderLayerCompositor::resetTrackedPaintInvalidationRects()
846 if (GraphicsLayer* rootLayer = rootGraphicsLayer())
847 resetTrackedPaintInvalidationRectsRecursive(rootLayer);
850 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalidations)
852 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean);
853 m_isTrackingPaintInvalidations = tracksPaintInvalidations;
856 bool RenderLayerCompositor::isTrackingPaintInvalidations() const
858 return m_isTrackingPaintInvalidations;
861 static bool shouldCompositeOverflowControls(FrameView* view)
863 if (Page* page = view->frame().page()) {
864 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
865 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
872 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
874 FrameView* view = m_renderView.frameView();
875 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
878 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
880 FrameView* view = m_renderView.frameView();
881 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
884 bool RenderLayerCompositor::requiresScrollCornerLayer() const
886 FrameView* view = m_renderView.frameView();
887 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
890 void RenderLayerCompositor::updateOverflowControlsLayers()
892 #if USE(RUBBER_BANDING)
893 if (m_renderView.frame()->isLocalRoot()) {
894 if (!m_layerForOverhangShadow) {
895 m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
896 OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
897 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
898 m_scrollLayer->addChild(m_layerForOverhangShadow.get());
901 ASSERT(!m_layerForOverhangShadow);
904 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
906 if (requiresHorizontalScrollbarLayer()) {
907 if (!m_layerForHorizontalScrollbar) {
908 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
911 if (m_layerForHorizontalScrollbar->parent() != controlsParent) {
912 controlsParent->addChild(m_layerForHorizontalScrollbar.get());
914 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
915 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
917 } else if (m_layerForHorizontalScrollbar) {
918 m_layerForHorizontalScrollbar->removeFromParent();
919 m_layerForHorizontalScrollbar = nullptr;
921 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
922 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
925 if (requiresVerticalScrollbarLayer()) {
926 if (!m_layerForVerticalScrollbar) {
927 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
930 if (m_layerForVerticalScrollbar->parent() != controlsParent) {
931 controlsParent->addChild(m_layerForVerticalScrollbar.get());
933 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
934 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
936 } else if (m_layerForVerticalScrollbar) {
937 m_layerForVerticalScrollbar->removeFromParent();
938 m_layerForVerticalScrollbar = nullptr;
940 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
941 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
944 if (requiresScrollCornerLayer()) {
945 if (!m_layerForScrollCorner) {
946 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
947 controlsParent->addChild(m_layerForScrollCorner.get());
949 } else if (m_layerForScrollCorner) {
950 m_layerForScrollCorner->removeFromParent();
951 m_layerForScrollCorner = nullptr;
954 m_renderView.frameView()->positionScrollbarLayers();
957 void RenderLayerCompositor::ensureRootLayer()
959 RootLayerAttachment expectedAttachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
960 if (expectedAttachment == m_rootLayerAttachment)
963 if (!m_rootContentLayer) {
964 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
965 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
966 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
967 m_rootContentLayer->setPosition(FloatPoint());
968 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderView.generatingNode()));
970 // Need to clip to prevent transformed content showing outside this frame
971 m_rootContentLayer->setMasksToBounds(true);
974 if (!m_overflowControlsHostLayer) {
975 ASSERT(!m_scrollLayer);
976 ASSERT(!m_containerLayer);
978 // Create a layer to host the clipping layer and the overflow controls layers.
979 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
981 // Create a clipping layer if this is an iframe or settings require to clip.
982 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
983 bool containerMasksToBounds = !m_renderView.frame()->isLocalRoot();
984 if (Settings* settings = m_renderView.document().settings()) {
985 if (settings->mainFrameClipsContent())
986 containerMasksToBounds = true;
988 m_containerLayer->setMasksToBounds(containerMasksToBounds);
989 m_overflowControlsHostLayer->setMasksToBounds(containerMasksToBounds);
991 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
992 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
993 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
996 m_overflowControlsHostLayer->addChild(m_containerLayer.get());
997 m_containerLayer->addChild(m_scrollLayer.get());
998 m_scrollLayer->addChild(m_rootContentLayer.get());
1000 frameViewDidChangeSize();
1003 // Check to see if we have to change the attachment
1004 if (m_rootLayerAttachment != RootLayerUnattached)
1007 attachRootLayer(expectedAttachment);
1010 void RenderLayerCompositor::destroyRootLayer()
1012 if (!m_rootContentLayer)
1017 #if USE(RUBBER_BANDING)
1018 if (m_layerForOverhangShadow) {
1019 m_layerForOverhangShadow->removeFromParent();
1020 m_layerForOverhangShadow = nullptr;
1024 if (m_layerForHorizontalScrollbar) {
1025 m_layerForHorizontalScrollbar->removeFromParent();
1026 m_layerForHorizontalScrollbar = nullptr;
1027 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1028 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1029 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
1030 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1033 if (m_layerForVerticalScrollbar) {
1034 m_layerForVerticalScrollbar->removeFromParent();
1035 m_layerForVerticalScrollbar = nullptr;
1036 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1037 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1038 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
1039 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1042 if (m_layerForScrollCorner) {
1043 m_layerForScrollCorner = nullptr;
1044 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
1047 if (m_overflowControlsHostLayer) {
1048 m_overflowControlsHostLayer = nullptr;
1049 m_containerLayer = nullptr;
1050 m_scrollLayer = nullptr;
1052 ASSERT(!m_scrollLayer);
1053 m_rootContentLayer = nullptr;
1054 m_rootTransformLayer = nullptr;
1057 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
1059 if (!m_rootContentLayer)
1062 switch (attachment) {
1063 case RootLayerUnattached:
1064 ASSERT_NOT_REACHED();
1066 case RootLayerAttachedViaChromeClient: {
1067 LocalFrame& frame = m_renderView.frameView()->frame();
1068 Page* page = frame.page();
1071 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
1074 case RootLayerAttachedViaEnclosingFrame: {
1075 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
1076 ASSERT(ownerElement);
1077 // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1078 // for the frame's renderer in the parent document.
1079 ownerElement->setNeedsCompositingUpdate();
1084 m_rootLayerAttachment = attachment;
1087 void RenderLayerCompositor::detachRootLayer()
1089 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
1092 switch (m_rootLayerAttachment) {
1093 case RootLayerAttachedViaEnclosingFrame: {
1094 // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1095 // for the frame's renderer in the parent document.
1096 if (m_overflowControlsHostLayer)
1097 m_overflowControlsHostLayer->removeFromParent();
1099 m_rootContentLayer->removeFromParent();
1101 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
1102 ownerElement->setNeedsCompositingUpdate();
1105 case RootLayerAttachedViaChromeClient: {
1106 LocalFrame& frame = m_renderView.frameView()->frame();
1107 Page* page = frame.page();
1110 page->chrome().client().attachRootGraphicsLayer(0);
1113 case RootLayerUnattached:
1117 m_rootLayerAttachment = RootLayerUnattached;
1120 void RenderLayerCompositor::updateRootLayerAttachment()
1125 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
1127 if (Page* page = this->page())
1128 return page->scrollingCoordinator();
1133 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
1135 if (Page* page = this->page())
1136 return page->chrome().client().graphicsLayerFactory();
1140 Page* RenderLayerCompositor::page() const
1142 return m_renderView.frameView()->frame().page();
1145 DocumentLifecycle& RenderLayerCompositor::lifecycle() const
1147 return m_renderView.document().lifecycle();
1150 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
1153 if (graphicsLayer == m_rootContentLayer.get()) {
1154 name = "Content Root Layer";
1155 } else if (graphicsLayer == m_rootTransformLayer.get()) {
1156 name = "Root Transform Layer";
1157 #if USE(RUBBER_BANDING)
1158 } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
1159 name = "Overhang Areas Shadow";
1161 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
1162 name = "Overflow Controls Host Layer";
1163 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
1164 name = "Horizontal Scrollbar Layer";
1165 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
1166 name = "Vertical Scrollbar Layer";
1167 } else if (graphicsLayer == m_layerForScrollCorner.get()) {
1168 name = "Scroll Corner Layer";
1169 } else if (graphicsLayer == m_containerLayer.get()) {
1170 name = "LocalFrame Clipping Layer";
1171 } else if (graphicsLayer == m_scrollLayer.get()) {
1172 name = "LocalFrame Scrolling Layer";
1174 ASSERT_NOT_REACHED();
1180 } // namespace blink