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/dom/ScriptForbiddenScope.h"
33 #include "core/frame/FrameView.h"
34 #include "core/frame/LocalFrame.h"
35 #include "core/frame/Settings.h"
36 #include "core/html/HTMLIFrameElement.h"
37 #include "core/inspector/InspectorInstrumentation.h"
38 #include "core/inspector/InspectorNodeIds.h"
39 #include "core/page/Chrome.h"
40 #include "core/page/Page.h"
41 #include "core/page/scrolling/ScrollingCoordinator.h"
42 #include "core/rendering/RenderLayerStackingNode.h"
43 #include "core/rendering/RenderLayerStackingNodeIterator.h"
44 #include "core/rendering/RenderVideo.h"
45 #include "core/rendering/RenderView.h"
46 #include "core/rendering/compositing/CompositedLayerMapping.h"
47 #include "core/rendering/compositing/CompositingInputsUpdater.h"
48 #include "core/rendering/compositing/CompositingLayerAssigner.h"
49 #include "core/rendering/compositing/CompositingRequirementsUpdater.h"
50 #include "core/rendering/compositing/GraphicsLayerTreeBuilder.h"
51 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
52 #include "platform/OverscrollTheme.h"
53 #include "platform/RuntimeEnabledFeatures.h"
54 #include "platform/TraceEvent.h"
55 #include "platform/graphics/GraphicsLayer.h"
56 #include "public/platform/Platform.h"
60 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
61 : m_renderView(renderView)
62 , m_compositingReasonFinder(renderView)
63 , m_pendingUpdateType(CompositingUpdateNone)
64 , m_hasAcceleratedCompositing(true)
65 , m_compositing(false)
66 , m_rootShouldAlwaysCompositeDirty(true)
67 , m_needsUpdateFixedBackground(false)
68 , m_isTrackingRepaints(false)
69 , m_rootLayerAttachment(RootLayerUnattached)
70 , m_inOverlayFullscreenVideo(false)
72 updateAcceleratedCompositingSettings();
75 RenderLayerCompositor::~RenderLayerCompositor()
77 ASSERT(m_rootLayerAttachment == RootLayerUnattached);
80 bool RenderLayerCompositor::inCompositingMode() const
82 // FIXME: This should assert that lificycle is >= CompositingClean since
83 // the last step of updateIfNeeded can set this bit to false.
84 ASSERT(!m_rootShouldAlwaysCompositeDirty);
88 bool RenderLayerCompositor::staleInCompositingMode() const
93 void RenderLayerCompositor::setCompositingModeEnabled(bool enable)
95 if (enable == m_compositing)
98 m_compositing = enable;
100 // RenderPart::requiresAcceleratedCompositing is used to determine self-paintingness
101 // and bases it's return value for frames on the m_compositing bit here.
102 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
103 if (RenderPart* renderer = ownerElement->renderPart())
104 renderer->layer()->updateSelfPaintingLayer();
112 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
113 // we need to schedule a style recalc in our parent document.
114 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
115 ownerElement->setNeedsCompositingUpdate();
118 void RenderLayerCompositor::enableCompositingModeIfNeeded()
120 if (!m_rootShouldAlwaysCompositeDirty)
123 m_rootShouldAlwaysCompositeDirty = false;
127 if (rootShouldAlwaysComposite()) {
128 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_bug.cgi?id=26651.
129 // No tests fail if it's deleted.
130 setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
131 setCompositingModeEnabled(true);
135 bool RenderLayerCompositor::rootShouldAlwaysComposite() const
137 if (!m_hasAcceleratedCompositing)
139 return m_renderView.frame()->isMainFrame() || m_compositingReasonFinder.requiresCompositingForScrollableFrame();
142 void RenderLayerCompositor::updateAcceleratedCompositingSettings()
144 m_compositingReasonFinder.updateTriggers();
145 m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled();
146 m_rootShouldAlwaysCompositeDirty = true;
149 bool RenderLayerCompositor::layerSquashingEnabled() const
151 if (!RuntimeEnabledFeatures::layerSquashingEnabled())
153 if (Settings* settings = m_renderView.document().settings())
154 return settings->layerSquashingEnabled();
158 bool RenderLayerCompositor::acceleratedCompositingForOverflowScrollEnabled() const
160 return m_compositingReasonFinder.hasOverflowScrollTrigger();
163 static RenderVideo* findFullscreenVideoRenderer(Document& document)
165 Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document);
166 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
167 Document* contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
168 if (!contentDocument)
170 fullscreenElement = FullscreenElementStack::fullscreenElementFrom(*contentDocument);
172 if (!isHTMLVideoElement(fullscreenElement))
174 RenderObject* renderer = fullscreenElement->renderer();
177 return toRenderVideo(renderer);
180 void RenderLayerCompositor::updateIfNeededRecursive()
182 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
183 if (child->isLocalFrame())
184 toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeededRecursive();
187 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateIfNeededRecursive");
189 ASSERT(!m_renderView.needsLayout());
191 ScriptForbiddenScope forbidScript;
193 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree,
194 // which asserts that it's not InCompositingUpdate.
195 enableCompositingModeIfNeeded();
197 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
199 lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
201 DocumentAnimations::startPendingAnimations(m_renderView.document());
202 // TODO: Figure out why this fails on Chrome OS login page. crbug.com/365507
203 // ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
206 assertNoUnresolvedDirtyBits();
207 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
208 if (child->isLocalFrame())
209 toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnresolvedDirtyBits();
214 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType)
216 ASSERT(updateType != CompositingUpdateNone);
218 // FIXME: This function should only set dirty bits. We shouldn't
219 // enable compositing mode here.
220 // We check needsLayout here because we don't know if we need to enable
221 // compositing mode until layout is up-to-date because we need to know
222 // if this frame scrolls.
224 // NOTE: CastStreamingApiTestWithPixelOutput.RtpStreamError triggers
225 // an ASSERT when this code is removed.
226 if (!m_renderView.needsLayout())
227 enableCompositingModeIfNeeded();
229 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType);
230 page()->animator().scheduleVisualUpdate();
231 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
234 void RenderLayerCompositor::didLayout()
236 // FIXME: Technically we only need to do this when the FrameView's
237 // isScrollable method would return a different value.
238 m_rootShouldAlwaysCompositeDirty = true;
239 enableCompositingModeIfNeeded();
241 // FIXME: Rather than marking the entire RenderView as dirty, we should
242 // track which RenderLayers moved during layout and only dirty those
243 // specific RenderLayers.
244 rootRenderLayer()->setNeedsCompositingInputsUpdate();
245 setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
250 void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
252 ASSERT(m_pendingUpdateType == CompositingUpdateNone);
253 ASSERT(!m_rootShouldAlwaysCompositeDirty);
258 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment()
260 m_inOverlayFullscreenVideo = false;
261 if (!m_rootContentLayer)
264 bool isMainFrame = m_renderView.frame()->isMainFrame();
265 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
266 if (!video || !video->hasCompositedLayerMapping()) {
268 GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer();
269 if (backgroundLayer && !backgroundLayer->parent())
270 rootFixedBackgroundsChanged();
275 GraphicsLayer* videoLayer = video->compositedLayerMapping()->mainGraphicsLayer();
277 // The fullscreen video has layer position equal to its enclosing frame's scroll position because fullscreen container is fixed-positioned.
278 // We should reset layer position here since we are going to reattach the layer at the very top level.
279 videoLayer->setPosition(IntPoint());
281 // Only steal fullscreen video layer and clear all other layers if we are the main frame.
285 m_rootContentLayer->removeAllChildren();
286 m_overflowControlsHostLayer->addChild(videoLayer);
287 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
288 backgroundLayer->removeFromParent();
289 m_inOverlayFullscreenVideo = true;
292 void RenderLayerCompositor::updateIfNeeded()
294 CompositingUpdateType updateType = m_pendingUpdateType;
295 m_pendingUpdateType = CompositingUpdateNone;
297 if (!hasAcceleratedCompositing() || updateType == CompositingUpdateNone)
300 RenderLayer* updateRoot = rootRenderLayer();
302 Vector<RenderLayer*> layersNeedingRepaint;
304 if (updateType >= CompositingUpdateAfterCompositingInputChange) {
305 bool layersChanged = false;
307 TRACE_EVENT0("blink_rendering", "CompositingInputsUpdater::update");
308 CompositingInputsUpdater(updateRoot).update(updateRoot);
310 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(updateRoot);
314 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).update(updateRoot);
317 TRACE_EVENT0("blink_rendering", "CompositingLayerAssigner::assign");
318 CompositingLayerAssigner(this).assign(updateRoot, layersChanged, layersNeedingRepaint);
322 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateAfterCompositingChange");
323 if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas()) {
324 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
325 (*it)->updateAfterCompositingChange();
330 updateType = std::max(updateType, CompositingUpdateRebuildTree);
333 if (updateType != CompositingUpdateNone) {
334 TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
335 GraphicsLayerUpdater updater;
336 updater.update(layersNeedingRepaint, *updateRoot);
338 if (updater.needsRebuildTree())
339 updateType = std::max(updateType, CompositingUpdateRebuildTree);
342 // FIXME: Move this check to the end of the compositing update.
343 GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updateRoot);
347 if (updateType >= CompositingUpdateRebuildTree) {
348 GraphicsLayerVector childList;
350 TRACE_EVENT0("blink_rendering", "GraphicsLayerTreeBuilder::rebuild");
351 GraphicsLayerTreeBuilder().rebuild(*updateRoot, childList);
354 if (childList.isEmpty())
357 m_rootContentLayer->setChildren(childList);
359 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
360 applyOverlayFullscreenVideoAdjustment();
363 if (m_needsUpdateFixedBackground) {
364 rootFixedBackgroundsChanged();
365 m_needsUpdateFixedBackground = false;
368 for (unsigned i = 0; i < layersNeedingRepaint.size(); i++) {
369 RenderLayer* layer = layersNeedingRepaint[i];
370 layer->repainter().computeRepaintRectsIncludingNonCompositingDescendants();
372 repaintOnCompositingChange(layer);
375 // Inform the inspector that the layer tree has changed.
376 if (m_renderView.frame()->isMainFrame())
377 InspectorInstrumentation::layerTreeDidChange(m_renderView.frame());
380 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
382 bool compositedLayerMappingChanged = false;
383 bool nonCompositedReasonChanged = updateLayerIfViewportConstrained(layer);
385 // FIXME: It would be nice to directly use the layer's compositing reason,
386 // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
387 // requirements fully.
388 switch (compositedLayerUpdate) {
389 case AllocateOwnCompositedLayerMapping:
390 ASSERT(!layer->hasCompositedLayerMapping());
391 setCompositingModeEnabled(true);
393 // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
394 // that computing repaint rects will know the layer's correct compositingState.
395 // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
396 // Need to create a test where a squashed layer pops into compositing. And also to cover all other
397 // sorts of compositingState transitions.
398 layer->setLostGroupedMapping(false);
399 layer->setGroupedMapping(0);
401 // If we need to repaint, do so before allocating the compositedLayerMapping
402 repaintOnCompositingChange(layer);
403 layer->ensureCompositedLayerMapping();
404 compositedLayerMappingChanged = true;
406 // At this time, the ScrollingCooridnator only supports the top-level frame.
407 if (layer->isRootLayer() && m_renderView.frame()->isMainFrame()) {
408 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
409 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
412 case RemoveOwnCompositedLayerMapping:
413 // PutInSquashingLayer means you might have to remove the composited layer mapping first.
414 case PutInSquashingLayer:
415 if (layer->hasCompositedLayerMapping()) {
416 // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
417 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
418 // are both either composited, or not composited.
419 if (layer->isReflection()) {
420 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
421 if (sourceLayer->hasCompositedLayerMapping()) {
422 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
423 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
427 layer->clearCompositedLayerMapping();
428 compositedLayerMappingChanged = true;
432 case RemoveFromSquashingLayer:
433 case NoCompositingStateChange:
438 if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons())
439 compositedLayerMappingChanged = true;
441 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
442 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
443 if (innerCompositor && innerCompositor->staleInCompositingMode())
444 innerCompositor->updateRootLayerAttachment();
447 if (compositedLayerMappingChanged)
448 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
450 // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
451 // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
452 if (compositedLayerMappingChanged || nonCompositedReasonChanged) {
453 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
454 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
457 return compositedLayerMappingChanged || nonCompositedReasonChanged;
460 bool RenderLayerCompositor::updateLayerIfViewportConstrained(RenderLayer* layer)
462 RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
463 m_compositingReasonFinder.requiresCompositingForPositionFixed(layer->renderer(), layer, &viewportConstrainedNotCompositedReason);
465 if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
466 ASSERT(viewportConstrainedNotCompositedReason == RenderLayer::NoNotCompositedReason || layer->renderer()->style()->position() == FixedPosition);
467 layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
473 // These are temporary hacks to work around chicken-egg issues while we continue to refactor the compositing code.
474 // See crbug.com/383191 for a list of tests that fail if this method is removed.
475 void RenderLayerCompositor::applyUpdateLayerCompositingStateChickenEggHacks(RenderLayer* layer, CompositingStateTransitionType compositedLayerUpdate)
477 if (compositedLayerUpdate != NoCompositingStateChange) {
478 bool compositedLayerMappingChanged = allocateOrClearCompositedLayerMapping(layer, compositedLayerUpdate);
479 if (compositedLayerMappingChanged) {
480 // Repaint rects can only be computed for layers that have already been attached to the
481 // render tree, but a chicken-egg compositing update can happen before |layer| gets
482 // attached. Since newly-created renderers don't get parented until they are attached
483 // (see RenderTreeBuilder::createRendererForElementIfNeeded), we can check for attachment
484 // by checking for a parent.
486 layer->repainter().computeRepaintRectsIncludingNonCompositingDescendants();
487 repaintOnCompositingChange(layer);
492 void RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, UpdateLayerCompositingStateOptions options)
494 layer->setCompositingReasons(layer->styleDeterminedCompositingReasons(), CompositingReasonComboAllStyleDeterminedReasons);
495 CompositingStateTransitionType compositedLayerUpdate = CompositingLayerAssigner(this).computeCompositedLayerUpdate(layer);
497 if (compositedLayerUpdate != NoCompositingStateChange)
498 setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
500 if (options == UseChickenEggHacks)
501 applyUpdateLayerCompositingStateChickenEggHacks(layer, compositedLayerUpdate);
504 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
506 // If the renderer is not attached yet, no need to repaint.
507 if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
510 layer->repainter().repaintIncludingNonCompositingDescendants();
513 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
514 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
516 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(ExcludeSelf);
517 if (!compositedAncestor)
519 ASSERT(compositedAncestor->compositingState() == PaintsIntoOwnBacking || compositedAncestor->compositingState() == PaintsIntoGroupedBacking);
522 layer->convertToLayerCoords(compositedAncestor, offset);
523 LayoutRect repaintRect = rect;
524 repaintRect.moveBy(offset);
525 compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
528 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
530 if (m_overflowControlsHostLayer)
531 m_overflowControlsHostLayer->setPosition(contentsOffset);
534 void RenderLayerCompositor::frameViewDidChangeSize()
536 if (m_containerLayer) {
537 FrameView* frameView = m_renderView.frameView();
538 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
540 frameViewDidScroll();
541 updateOverflowControlsLayers();
545 enum AcceleratedFixedRootBackgroundHistogramBuckets {
546 ScrolledMainFrameBucket = 0,
547 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
548 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
549 AcceleratedFixedRootBackgroundHistogramMax = 3
552 void RenderLayerCompositor::frameViewDidScroll()
554 FrameView* frameView = m_renderView.frameView();
555 IntPoint scrollPosition = frameView->scrollPosition();
560 bool scrollingCoordinatorHandlesOffset = false;
561 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
562 if (Settings* settings = m_renderView.document().settings()) {
563 if (m_renderView.frame()->isMainFrame() || settings->compositedScrollingForFramesEnabled())
564 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
568 // Scroll position = scroll minimum + scroll offset. Adjust the layer's
569 // position to handle whatever the scroll coordinator isn't handling.
570 // The minimum scroll position is non-zero for RTL pages with overflow.
571 if (scrollingCoordinatorHandlesOffset)
572 m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
574 m_scrollLayer->setPosition(-scrollPosition);
577 blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
578 ScrolledMainFrameBucket,
579 AcceleratedFixedRootBackgroundHistogramMax);
582 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
584 if (m_containerLayer)
585 updateOverflowControlsLayers();
588 void RenderLayerCompositor::rootFixedBackgroundsChanged()
590 if (!supportsFixedRootBackgroundCompositing())
593 // To avoid having to make the fixed root background layer fixed positioned to
594 // stay put, we position it in the layer tree as follows:
596 // + Overflow controls host
598 // + (Fixed root background) <-- Here.
599 // + LocalFrame scroll
600 // + Root content layer
603 // That is, it needs to be the first child of the frame clip, the sibling of
604 // the frame scroll layer. The compositor does not own the background layer, it
605 // just positions it (like the foreground layer).
606 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
607 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
610 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
612 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
613 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
617 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
619 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean);
621 if (!m_rootContentLayer)
624 // We skip dumping the scroll and clip layers to keep layerTreeAsText output
625 // similar between platforms (unless we explicitly request dumping from the
627 GraphicsLayer* rootLayer = m_rootContentLayer.get();
628 if (flags & LayerTreeIncludesRootLayer)
629 rootLayer = rootGraphicsLayer();
631 String layerTreeText = rootLayer->layerTreeAsText(flags);
633 // The true root layer is not included in the dump, so if we want to report
634 // its repaint rects, they must be included here.
635 if (flags & LayerTreeIncludesRepaintRects)
636 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() + layerTreeText;
638 return layerTreeText;
641 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
643 if (!renderer->node()->isFrameOwnerElement())
646 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
647 if (Document* contentDocument = element->contentDocument()) {
648 if (RenderView* view = contentDocument->renderView())
649 return view->compositor();
654 // FIXME: What does this function do? It needs a clearer name.
655 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
657 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
658 if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
661 RenderLayer* layer = renderer->layer();
662 if (!layer->hasCompositedLayerMapping())
665 CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
666 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
667 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
668 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
669 hostingLayer->removeAllChildren();
670 hostingLayer->addChild(rootLayer);
675 void RenderLayerCompositor::repaintCompositedLayers()
677 recursiveRepaintLayer(rootRenderLayer());
680 void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer)
682 // FIXME: This method does not work correctly with transforms.
683 if (layer->compositingState() == PaintsIntoOwnBacking) {
684 layer->compositedLayerMapping()->setContentsNeedDisplay();
685 // This function is called only when it is desired to repaint the entire compositing graphics layer tree.
686 // This includes squashing.
687 layer->compositedLayerMapping()->setSquashingContentsNeedDisplay();
690 layer->stackingNode()->updateLayerListsIfNeeded();
693 LayerListMutationDetector mutationChecker(layer->stackingNode());
696 unsigned childrenToVisit = NormalFlowChildren;
697 if (layer->hasCompositingDescendant())
698 childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren;
699 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit);
700 while (RenderLayerStackingNode* curNode = iterator.next())
701 recursiveRepaintLayer(curNode->layer());
704 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
706 return m_renderView.layer();
709 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
711 if (m_overflowControlsHostLayer)
712 return m_overflowControlsHostLayer.get();
713 return m_rootContentLayer.get();
716 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
718 return m_scrollLayer.get();
721 GraphicsLayer* RenderLayerCompositor::containerLayer() const
723 return m_containerLayer.get();
726 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
728 ASSERT(rootGraphicsLayer());
730 if (!m_rootTransformLayer.get()) {
731 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
732 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
733 m_rootTransformLayer->addChild(m_containerLayer.get());
734 updateOverflowControlsLayers();
737 return m_rootTransformLayer.get();
740 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
742 if (!staleInCompositingMode())
746 if (m_rootLayerAttachment != RootLayerUnattached)
749 RootLayerAttachment attachment = m_renderView.frame()->isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
750 attachRootLayer(attachment);
752 if (m_rootLayerAttachment == RootLayerUnattached)
759 void RenderLayerCompositor::updateRootLayerPosition()
761 if (m_rootContentLayer) {
762 const IntRect& documentRect = m_renderView.documentRect();
763 m_rootContentLayer->setSize(documentRect.size());
764 m_rootContentLayer->setPosition(documentRect.location());
765 #if USE(RUBBER_BANDING)
766 if (m_layerForOverhangShadow)
767 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
770 if (m_containerLayer) {
771 FrameView* frameView = m_renderView.frameView();
772 m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
776 void RenderLayerCompositor::updateStyleDeterminedCompositingReasons(RenderLayer* layer)
778 CompositingReasons reasons = m_compositingReasonFinder.styleDeterminedReasons(layer->renderer());
779 layer->setStyleDeterminedCompositingReasons(reasons);
782 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
784 CompositingReasons reasons = m_compositingReasonFinder.directReasons(layer);
785 layer->setCompositingReasons(reasons, CompositingReasonComboAllDirectReasons);
788 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer)
790 ASSERT(rootGraphicsLayer());
792 if (layer->parent() != m_overflowControlsHostLayer.get())
793 m_overflowControlsHostLayer->addChild(layer);
796 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
798 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
799 // See http://webkit.org/b/84900 to re-enable it.
800 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->subtreeIsInvisible() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
803 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
804 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
805 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
806 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
807 // but a sibling in the z-order hierarchy.
808 bool RenderLayerCompositor::clippedByNonAncestorInStackingTree(const RenderLayer* layer) const
810 if (!layer->hasCompositedLayerMapping() || !layer->parent())
813 const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
814 if (!compositingAncestor)
817 RenderObject* clippingContainer = layer->renderer()->clippingContainer();
818 if (!clippingContainer)
821 if (compositingAncestor->renderer()->isDescendantOf(clippingContainer))
827 // Return true if the given layer is a stacking context and has compositing child
828 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
829 // into the hierarchy between this layer and its children in the z-order hierarchy.
830 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
832 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
835 // If an element has negative z-index children, those children render in front of the
836 // layer background, so we need an extra 'contents' layer for the foreground of the layer
838 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
840 return layer->stackingNode()->hasNegativeZOrderList();
843 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
849 const IntRect& scrollbarRect = scrollbar->frameRect();
850 context.translate(-scrollbarRect.x(), -scrollbarRect.y());
851 IntRect transformedClip = clip;
852 transformedClip.moveBy(scrollbarRect.location());
853 scrollbar->paint(&context, transformedClip);
857 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
859 if (graphicsLayer == layerForHorizontalScrollbar())
860 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
861 else if (graphicsLayer == layerForVerticalScrollbar())
862 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
863 else if (graphicsLayer == layerForScrollCorner()) {
864 const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
866 context.translate(-scrollCorner.x(), -scrollCorner.y());
867 IntRect transformedClip = clip;
868 transformedClip.moveBy(scrollCorner.location());
869 m_renderView.frameView()->paintScrollCorner(&context, transformedClip);
874 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
876 if (Settings* settings = m_renderView.document().settings()) {
877 if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
883 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
885 if (layer != m_renderView.layer())
888 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
891 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
893 // Get the fixed root background from the RenderView layer's compositedLayerMapping.
894 RenderLayer* viewLayer = m_renderView.layer();
898 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
899 return viewLayer->compositedLayerMapping()->backgroundLayer();
904 static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
909 graphicsLayer->resetTrackedRepaints();
911 for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
912 resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
914 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
915 resetTrackedRepaintRectsRecursive(replicaLayer);
917 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
918 resetTrackedRepaintRectsRecursive(maskLayer);
920 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
921 resetTrackedRepaintRectsRecursive(clippingMaskLayer);
924 void RenderLayerCompositor::resetTrackedRepaintRects()
926 if (GraphicsLayer* rootLayer = rootGraphicsLayer())
927 resetTrackedRepaintRectsRecursive(rootLayer);
930 void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
932 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
933 m_isTrackingRepaints = tracksRepaints;
936 bool RenderLayerCompositor::isTrackingRepaints() const
938 return m_isTrackingRepaints;
941 static bool shouldCompositeOverflowControls(FrameView* view)
943 if (Page* page = view->frame().page()) {
944 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
945 if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
952 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
954 FrameView* view = m_renderView.frameView();
955 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
958 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
960 FrameView* view = m_renderView.frameView();
961 return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
964 bool RenderLayerCompositor::requiresScrollCornerLayer() const
966 FrameView* view = m_renderView.frameView();
967 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
970 void RenderLayerCompositor::updateOverflowControlsLayers()
972 #if USE(RUBBER_BANDING)
973 if (m_renderView.frame()->isMainFrame()) {
974 if (!m_layerForOverhangShadow) {
975 m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
976 OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
977 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
978 m_scrollLayer->addChild(m_layerForOverhangShadow.get());
981 ASSERT(!m_layerForOverhangShadow);
984 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
986 if (requiresHorizontalScrollbarLayer()) {
987 if (!m_layerForHorizontalScrollbar) {
988 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
991 if (m_layerForHorizontalScrollbar->parent() != controlsParent) {
992 controlsParent->addChild(m_layerForHorizontalScrollbar.get());
994 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
995 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
997 } else if (m_layerForHorizontalScrollbar) {
998 m_layerForHorizontalScrollbar->removeFromParent();
999 m_layerForHorizontalScrollbar = nullptr;
1001 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1002 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1005 if (requiresVerticalScrollbarLayer()) {
1006 if (!m_layerForVerticalScrollbar) {
1007 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
1010 if (m_layerForVerticalScrollbar->parent() != controlsParent) {
1011 controlsParent->addChild(m_layerForVerticalScrollbar.get());
1013 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1014 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1016 } else if (m_layerForVerticalScrollbar) {
1017 m_layerForVerticalScrollbar->removeFromParent();
1018 m_layerForVerticalScrollbar = nullptr;
1020 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1021 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1024 if (requiresScrollCornerLayer()) {
1025 if (!m_layerForScrollCorner) {
1026 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
1027 controlsParent->addChild(m_layerForScrollCorner.get());
1029 } else if (m_layerForScrollCorner) {
1030 m_layerForScrollCorner->removeFromParent();
1031 m_layerForScrollCorner = nullptr;
1034 m_renderView.frameView()->positionScrollbarLayers();
1037 void RenderLayerCompositor::ensureRootLayer()
1039 RootLayerAttachment expectedAttachment = m_renderView.frame()->isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
1040 if (expectedAttachment == m_rootLayerAttachment)
1043 if (!m_rootContentLayer) {
1044 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1045 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
1046 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
1047 m_rootContentLayer->setPosition(FloatPoint());
1048 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderView.generatingNode()));
1050 // Need to clip to prevent transformed content showing outside this frame
1051 m_rootContentLayer->setMasksToBounds(true);
1054 if (!m_overflowControlsHostLayer) {
1055 ASSERT(!m_scrollLayer);
1056 ASSERT(!m_containerLayer);
1058 // Create a layer to host the clipping layer and the overflow controls layers.
1059 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1061 // Create a clipping layer if this is an iframe or settings require to clip.
1062 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1063 bool containerMasksToBounds = !m_renderView.frame()->isMainFrame();
1064 if (Settings* settings = m_renderView.document().settings()) {
1065 if (settings->mainFrameClipsContent())
1066 containerMasksToBounds = true;
1068 m_containerLayer->setMasksToBounds(containerMasksToBounds);
1070 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1071 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1072 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
1075 m_overflowControlsHostLayer->addChild(m_containerLayer.get());
1076 m_containerLayer->addChild(m_scrollLayer.get());
1077 m_scrollLayer->addChild(m_rootContentLayer.get());
1079 frameViewDidChangeSize();
1082 // Check to see if we have to change the attachment
1083 if (m_rootLayerAttachment != RootLayerUnattached)
1086 attachRootLayer(expectedAttachment);
1089 void RenderLayerCompositor::destroyRootLayer()
1091 if (!m_rootContentLayer)
1096 #if USE(RUBBER_BANDING)
1097 if (m_layerForOverhangShadow) {
1098 m_layerForOverhangShadow->removeFromParent();
1099 m_layerForOverhangShadow = nullptr;
1103 if (m_layerForHorizontalScrollbar) {
1104 m_layerForHorizontalScrollbar->removeFromParent();
1105 m_layerForHorizontalScrollbar = nullptr;
1106 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1107 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1108 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
1109 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1112 if (m_layerForVerticalScrollbar) {
1113 m_layerForVerticalScrollbar->removeFromParent();
1114 m_layerForVerticalScrollbar = nullptr;
1115 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1116 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1117 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
1118 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1121 if (m_layerForScrollCorner) {
1122 m_layerForScrollCorner = nullptr;
1123 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
1126 if (m_overflowControlsHostLayer) {
1127 m_overflowControlsHostLayer = nullptr;
1128 m_containerLayer = nullptr;
1129 m_scrollLayer = nullptr;
1131 ASSERT(!m_scrollLayer);
1132 m_rootContentLayer = nullptr;
1133 m_rootTransformLayer = nullptr;
1136 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
1138 if (!m_rootContentLayer)
1141 switch (attachment) {
1142 case RootLayerUnattached:
1143 ASSERT_NOT_REACHED();
1145 case RootLayerAttachedViaChromeClient: {
1146 LocalFrame& frame = m_renderView.frameView()->frame();
1147 Page* page = frame.page();
1150 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
1153 case RootLayerAttachedViaEnclosingFrame: {
1154 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
1155 ASSERT(ownerElement);
1156 // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1157 // for the frame's renderer in the parent document.
1158 ownerElement->setNeedsCompositingUpdate();
1163 m_rootLayerAttachment = attachment;
1166 void RenderLayerCompositor::detachRootLayer()
1168 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
1171 switch (m_rootLayerAttachment) {
1172 case RootLayerAttachedViaEnclosingFrame: {
1173 // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1174 // for the frame's renderer in the parent document.
1175 if (m_overflowControlsHostLayer)
1176 m_overflowControlsHostLayer->removeFromParent();
1178 m_rootContentLayer->removeFromParent();
1180 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
1181 ownerElement->setNeedsCompositingUpdate();
1184 case RootLayerAttachedViaChromeClient: {
1185 LocalFrame& frame = m_renderView.frameView()->frame();
1186 Page* page = frame.page();
1189 page->chrome().client().attachRootGraphicsLayer(0);
1192 case RootLayerUnattached:
1196 m_rootLayerAttachment = RootLayerUnattached;
1199 void RenderLayerCompositor::updateRootLayerAttachment()
1204 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
1206 if (Page* page = this->page())
1207 return page->scrollingCoordinator();
1212 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
1214 if (Page* page = this->page())
1215 return page->chrome().client().graphicsLayerFactory();
1219 Page* RenderLayerCompositor::page() const
1221 return m_renderView.frameView()->frame().page();
1224 DocumentLifecycle& RenderLayerCompositor::lifecycle() const
1226 return m_renderView.document().lifecycle();
1229 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
1232 if (graphicsLayer == m_rootContentLayer.get()) {
1233 name = "Content Root Layer";
1234 } else if (graphicsLayer == m_rootTransformLayer.get()) {
1235 name = "Root Transform Layer";
1236 #if USE(RUBBER_BANDING)
1237 } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
1238 name = "Overhang Areas Shadow";
1240 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
1241 name = "Overflow Controls Host Layer";
1242 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
1243 name = "Horizontal Scrollbar Layer";
1244 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
1245 name = "Vertical Scrollbar Layer";
1246 } else if (graphicsLayer == m_layerForScrollCorner.get()) {
1247 name = "Scroll Corner Layer";
1248 } else if (graphicsLayer == m_containerLayer.get()) {
1249 name = "LocalFrame Clipping Layer";
1250 } else if (graphicsLayer == m_scrollLayer.get()) {
1251 name = "LocalFrame Scrolling Layer";
1253 ASSERT_NOT_REACHED();
1259 } // namespace WebCore