• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25 
26 #include "config.h"
27 
28 #include "core/rendering/compositing/RenderLayerCompositor.h"
29 
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/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"
60 
61 namespace blink {
62 
RenderLayerCompositor(RenderView & renderView)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)
74 {
75     updateAcceleratedCompositingSettings();
76 }
77 
~RenderLayerCompositor()78 RenderLayerCompositor::~RenderLayerCompositor()
79 {
80     ASSERT(m_rootLayerAttachment == RootLayerUnattached);
81 }
82 
inCompositingMode() const83 bool RenderLayerCompositor::inCompositingMode() const
84 {
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);
88     return m_compositing;
89 }
90 
staleInCompositingMode() const91 bool RenderLayerCompositor::staleInCompositingMode() const
92 {
93     return m_compositing;
94 }
95 
setCompositingModeEnabled(bool enable)96 void RenderLayerCompositor::setCompositingModeEnabled(bool enable)
97 {
98     if (enable == m_compositing)
99         return;
100 
101     m_compositing = enable;
102 
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();
108     }
109 
110     if (m_compositing)
111         ensureRootLayer();
112     else
113         destroyRootLayer();
114 
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();
119 }
120 
enableCompositingModeIfNeeded()121 void RenderLayerCompositor::enableCompositingModeIfNeeded()
122 {
123     if (!m_rootShouldAlwaysCompositeDirty)
124         return;
125 
126     m_rootShouldAlwaysCompositeDirty = false;
127     if (m_compositing)
128         return;
129 
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);
135     }
136 }
137 
rootShouldAlwaysComposite() const138 bool RenderLayerCompositor::rootShouldAlwaysComposite() const
139 {
140     if (!m_hasAcceleratedCompositing)
141         return false;
142     return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requiresCompositingForScrollableFrame();
143 }
144 
updateAcceleratedCompositingSettings()145 void RenderLayerCompositor::updateAcceleratedCompositingSettings()
146 {
147     m_compositingReasonFinder.updateTriggers();
148     m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled();
149     m_rootShouldAlwaysCompositeDirty = true;
150 }
151 
layerSquashingEnabled() const152 bool RenderLayerCompositor::layerSquashingEnabled() const
153 {
154     if (!RuntimeEnabledFeatures::layerSquashingEnabled())
155         return false;
156     if (Settings* settings = m_renderView.document().settings())
157         return settings->layerSquashingEnabled();
158     return true;
159 }
160 
preferCompositingToLCDTextEnabled() const161 bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const
162 {
163     return m_compositingReasonFinder.hasOverflowScrollTrigger();
164 }
165 
findFullscreenVideoRenderer(Document & document)166 static RenderVideo* findFullscreenVideoRenderer(Document& document)
167 {
168     // Recursively find the document that is in fullscreen.
169     Element* fullscreenElement = Fullscreen::fullscreenElementFrom(document);
170     Document* contentDocument = &document;
171     while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
172         contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
173         if (!contentDocument)
174             return 0;
175         fullscreenElement = Fullscreen::fullscreenElementFrom(*contentDocument);
176     }
177     // Get the current fullscreen element from the document.
178     fullscreenElement = Fullscreen::currentFullScreenElementFrom(*contentDocument);
179     if (!isHTMLVideoElement(fullscreenElement))
180         return 0;
181     RenderObject* renderer = fullscreenElement->renderer();
182     if (!renderer)
183         return 0;
184     return toRenderVideo(renderer);
185 }
186 
updateIfNeededRecursive()187 void RenderLayerCompositor::updateIfNeededRecursive()
188 {
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();
192     }
193 
194     TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive");
195 
196     ASSERT(!m_renderView.needsLayout());
197 
198     ScriptForbiddenScope forbidScript;
199 
200     // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree,
201     // which asserts that it's not InCompositingUpdate.
202     enableCompositingModeIfNeeded();
203 
204     rootRenderLayer()->updateDescendantDependentFlagsForEntireSubtree();
205 
206     lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
207     updateIfNeeded();
208     lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
209 
210     DocumentAnimations::startPendingAnimations(m_renderView.document());
211 
212 #if ENABLE(ASSERT)
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();
218     }
219 #endif
220 }
221 
setNeedsCompositingUpdate(CompositingUpdateType updateType)222 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType)
223 {
224     ASSERT(updateType != CompositingUpdateNone);
225     m_pendingUpdateType = std::max(m_pendingUpdateType, updateType);
226     page()->animator().scheduleVisualUpdate();
227     lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
228 }
229 
didLayout()230 void RenderLayerCompositor::didLayout()
231 {
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();
236 
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();
241 }
242 
243 #if ENABLE(ASSERT)
244 
assertNoUnresolvedDirtyBits()245 void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
246 {
247     ASSERT(m_pendingUpdateType == CompositingUpdateNone);
248     ASSERT(!m_rootShouldAlwaysCompositeDirty);
249 }
250 
251 #endif
252 
applyOverlayFullscreenVideoAdjustment()253 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment()
254 {
255     m_inOverlayFullscreenVideo = false;
256     if (!m_rootContentLayer)
257         return;
258 
259     bool isLocalRoot = m_renderView.frame()->isLocalRoot();
260     RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
261     if (!video || !video->layer()->hasCompositedLayerMapping()) {
262         if (isLocalRoot) {
263             GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer();
264             if (backgroundLayer && !backgroundLayer->parent())
265                 rootFixedBackgroundsChanged();
266         }
267         return;
268     }
269 
270     GraphicsLayer* videoLayer = video->layer()->compositedLayerMapping()->mainGraphicsLayer();
271 
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());
275 
276     // Only steal fullscreen video layer and clear all other layers if we are the main frame.
277     if (!isLocalRoot)
278         return;
279 
280     m_rootContentLayer->removeAllChildren();
281     m_overflowControlsHostLayer->addChild(videoLayer);
282     if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
283         backgroundLayer->removeFromParent();
284     m_inOverlayFullscreenVideo = true;
285 }
286 
updateWithoutAcceleratedCompositing(CompositingUpdateType updateType)287 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdateType updateType)
288 {
289     ASSERT(!hasAcceleratedCompositing());
290 
291     if (updateType >= CompositingUpdateAfterCompositingInputChange)
292         CompositingInputsUpdater(rootRenderLayer()).update();
293 
294 #if ENABLE(ASSERT)
295     CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(rootRenderLayer());
296 #endif
297 }
298 
forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(RenderObject * renderer)299 static void forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(RenderObject* renderer)
300 {
301     // We clear the previous paint invalidation rect as it's wrong (paint invaliation container
302     // changed, ...). Forcing a full invalidation will make us recompute it. Also we are not
303     // changing the previous position from our paint invalidation container, which is fine as
304     // we want a full paint invalidation anyway.
305     renderer->setPreviousPaintInvalidationRect(LayoutRect());
306     renderer->setShouldDoFullPaintInvalidation(true);
307 
308     for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling()) {
309         if (!child->isPaintInvalidationContainer())
310             forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(child);
311     }
312 }
313 
314 
updateIfNeeded()315 void RenderLayerCompositor::updateIfNeeded()
316 {
317     CompositingUpdateType updateType = m_pendingUpdateType;
318     m_pendingUpdateType = CompositingUpdateNone;
319 
320     if (!hasAcceleratedCompositing()) {
321         updateWithoutAcceleratedCompositing(updateType);
322         return;
323     }
324 
325     if (updateType == CompositingUpdateNone)
326         return;
327 
328     RenderLayer* updateRoot = rootRenderLayer();
329 
330     Vector<RenderLayer*> layersNeedingPaintInvalidation;
331 
332     if (updateType >= CompositingUpdateAfterCompositingInputChange) {
333         CompositingInputsUpdater(updateRoot).update();
334 
335 #if ENABLE(ASSERT)
336         // FIXME: Move this check to the end of the compositing update.
337         CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(updateRoot);
338 #endif
339 
340         CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).update(updateRoot);
341 
342         CompositingLayerAssigner layerAssigner(this);
343         layerAssigner.assign(updateRoot, layersNeedingPaintInvalidation);
344 
345         bool layersChanged = layerAssigner.layersChanged();
346 
347         {
348             TRACE_EVENT0("blink", "RenderLayerCompositor::updateAfterCompositingChange");
349             if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas()) {
350                 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
351                     layersChanged |= (*it)->updateAfterCompositingChange();
352             }
353         }
354 
355         if (layersChanged)
356             updateType = std::max(updateType, CompositingUpdateRebuildTree);
357     }
358 
359     if (updateType != CompositingUpdateNone) {
360         GraphicsLayerUpdater updater;
361         updater.update(*updateRoot, layersNeedingPaintInvalidation);
362 
363         if (updater.needsRebuildTree())
364             updateType = std::max(updateType, CompositingUpdateRebuildTree);
365 
366 #if ENABLE(ASSERT)
367         // FIXME: Move this check to the end of the compositing update.
368         GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updateRoot);
369 #endif
370     }
371 
372     if (updateType >= CompositingUpdateRebuildTree) {
373         GraphicsLayerTreeBuilder::AncestorInfo ancestorInfo;
374         GraphicsLayerVector childList;
375         ancestorInfo.childLayersOfEnclosingCompositedLayer = &childList;
376         {
377             TRACE_EVENT0("blink", "GraphicsLayerTreeBuilder::rebuild");
378             GraphicsLayerTreeBuilder().rebuild(*updateRoot, ancestorInfo);
379         }
380 
381         if (childList.isEmpty())
382             destroyRootLayer();
383         else
384             m_rootContentLayer->setChildren(childList);
385 
386         if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
387             applyOverlayFullscreenVideoAdjustment();
388     }
389 
390     if (m_needsUpdateFixedBackground) {
391         rootFixedBackgroundsChanged();
392         m_needsUpdateFixedBackground = false;
393     }
394 
395     for (unsigned i = 0; i < layersNeedingPaintInvalidation.size(); i++)
396         forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(layersNeedingPaintInvalidation[i]->renderer());
397 
398     // Inform the inspector that the layer tree has changed.
399     if (m_renderView.frame()->isMainFrame())
400         InspectorInstrumentation::layerTreeDidChange(m_renderView.frame());
401 }
402 
allocateOrClearCompositedLayerMapping(RenderLayer * layer,const CompositingStateTransitionType compositedLayerUpdate)403 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
404 {
405     bool compositedLayerMappingChanged = false;
406 
407     // FIXME: It would be nice to directly use the layer's compositing reason,
408     // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
409     // requirements fully.
410     switch (compositedLayerUpdate) {
411     case AllocateOwnCompositedLayerMapping:
412         ASSERT(!layer->hasCompositedLayerMapping());
413         setCompositingModeEnabled(true);
414 
415         // If we need to issue paint invalidations, do so before allocating the compositedLayerMapping and clearing out the groupedMapping.
416         paintInvalidationOnCompositingChange(layer);
417 
418         // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
419         // that computing paint invalidation rects will know the layer's correct compositingState.
420         // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
421         // Need to create a test where a squashed layer pops into compositing. And also to cover all other
422         // sorts of compositingState transitions.
423         layer->setLostGroupedMapping(false);
424         layer->setGroupedMapping(0);
425 
426         layer->ensureCompositedLayerMapping();
427         compositedLayerMappingChanged = true;
428 
429         // At this time, the ScrollingCooridnator only supports the top-level frame.
430         if (layer->isRootLayer() && m_renderView.frame()->isLocalRoot()) {
431             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
432                 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
433         }
434         break;
435     case RemoveOwnCompositedLayerMapping:
436     // PutInSquashingLayer means you might have to remove the composited layer mapping first.
437     case PutInSquashingLayer:
438         if (layer->hasCompositedLayerMapping()) {
439             // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
440             // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
441             // are both either composited, or not composited.
442             if (layer->isReflection()) {
443                 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
444                 if (sourceLayer->hasCompositedLayerMapping()) {
445                     ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
446                     sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
447                 }
448             }
449 
450             layer->clearCompositedLayerMapping();
451             compositedLayerMappingChanged = true;
452         }
453 
454         break;
455     case RemoveFromSquashingLayer:
456     case NoCompositingStateChange:
457         // Do nothing.
458         break;
459     }
460 
461     if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons()) {
462         compositedLayerMappingChanged = true;
463         layer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
464     }
465 
466     if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
467         RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
468         if (innerCompositor && innerCompositor->staleInCompositingMode())
469             innerCompositor->updateRootLayerAttachment();
470     }
471 
472     if (compositedLayerMappingChanged)
473         layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
474 
475     // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
476     // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
477     if (compositedLayerMappingChanged) {
478         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
479             scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
480     }
481 
482     return compositedLayerMappingChanged;
483 }
484 
paintInvalidationOnCompositingChange(RenderLayer * layer)485 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* layer)
486 {
487     // If the renderer is not attached yet, no need to issue paint invalidations.
488     if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
489         return;
490 
491     // For querying RenderLayer::compositingState()
492     // Eager invalidation here is correct, since we are invalidating with respect to the previous frame's
493     // compositing state when changing the compositing backing of the layer.
494     DisableCompositingQueryAsserts disabler;
495 
496     layer->renderer()->invalidatePaintIncludingNonCompositingDescendants();
497 }
498 
frameViewDidChangeLocation(const IntPoint & contentsOffset)499 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
500 {
501     if (m_overflowControlsHostLayer)
502         m_overflowControlsHostLayer->setPosition(contentsOffset);
503 }
504 
frameViewDidChangeSize()505 void RenderLayerCompositor::frameViewDidChangeSize()
506 {
507     if (m_containerLayer) {
508         FrameView* frameView = m_renderView.frameView();
509         m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
510         m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars));
511 
512         frameViewDidScroll();
513         updateOverflowControlsLayers();
514     }
515 }
516 
517 enum AcceleratedFixedRootBackgroundHistogramBuckets {
518     ScrolledMainFrameBucket = 0,
519     ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
520     ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
521     AcceleratedFixedRootBackgroundHistogramMax = 3
522 };
523 
frameViewDidScroll()524 void RenderLayerCompositor::frameViewDidScroll()
525 {
526     FrameView* frameView = m_renderView.frameView();
527     IntPoint scrollPosition = frameView->scrollPosition();
528 
529     if (!m_scrollLayer)
530         return;
531 
532     bool scrollingCoordinatorHandlesOffset = false;
533     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
534         if (Settings* settings = m_renderView.document().settings()) {
535             if (m_renderView.frame()->isLocalRoot() || settings->preferCompositingToLCDTextEnabled())
536                 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
537         }
538     }
539 
540     // Scroll position = scroll minimum + scroll offset. Adjust the layer's
541     // position to handle whatever the scroll coordinator isn't handling.
542     // The minimum scroll position is non-zero for RTL pages with overflow.
543     if (scrollingCoordinatorHandlesOffset)
544         m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
545     else
546         m_scrollLayer->setPosition(-scrollPosition);
547 
548 
549     Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
550         ScrolledMainFrameBucket,
551         AcceleratedFixedRootBackgroundHistogramMax);
552 }
553 
frameViewScrollbarsExistenceDidChange()554 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
555 {
556     if (m_containerLayer)
557         updateOverflowControlsLayers();
558 }
559 
rootFixedBackgroundsChanged()560 void RenderLayerCompositor::rootFixedBackgroundsChanged()
561 {
562     if (!supportsFixedRootBackgroundCompositing())
563         return;
564 
565     // To avoid having to make the fixed root background layer fixed positioned to
566     // stay put, we position it in the layer tree as follows:
567     //
568     // + Overflow controls host
569     //   + LocalFrame clip
570     //     + (Fixed root background) <-- Here.
571     //     + LocalFrame scroll
572     //       + Root content layer
573     //   + Scrollbars
574     //
575     // That is, it needs to be the first child of the frame clip, the sibling of
576     // the frame scroll layer. The compositor does not own the background layer, it
577     // just positions it (like the foreground layer).
578     if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
579         m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
580 }
581 
scrollingLayerDidChange(RenderLayer * layer)582 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
583 {
584     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
585         return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
586     return false;
587 }
588 
layerTreeAsText(LayerTreeFlags flags)589 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
590 {
591     ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean);
592 
593     if (!m_rootContentLayer)
594         return String();
595 
596     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
597     // similar between platforms (unless we explicitly request dumping from the
598     // root.
599     GraphicsLayer* rootLayer = m_rootContentLayer.get();
600     if (flags & LayerTreeIncludesRootLayer)
601         rootLayer = rootGraphicsLayer();
602 
603     String layerTreeText = rootLayer->layerTreeAsText(flags);
604 
605     // The true root layer is not included in the dump, so if we want to report
606     // its paint invalidation rects, they must be included here.
607     if (flags & LayerTreeIncludesPaintInvalidationRects)
608         return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() + layerTreeText;
609 
610     return layerTreeText;
611 }
612 
frameContentsCompositor(RenderPart * renderer)613 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
614 {
615     if (!renderer->node()->isFrameOwnerElement())
616         return 0;
617 
618     HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
619     if (Document* contentDocument = element->contentDocument()) {
620         if (RenderView* view = contentDocument->renderView())
621             return view->compositor();
622     }
623     return 0;
624 }
625 
626 // FIXME: What does this function do? It needs a clearer name.
parentFrameContentLayers(RenderPart * renderer)627 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
628 {
629     RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
630     if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
631         return false;
632 
633     RenderLayer* layer = renderer->layer();
634     if (!layer->hasCompositedLayerMapping())
635         return false;
636 
637     CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
638     GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
639     GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
640     if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
641         hostingLayer->removeAllChildren();
642         hostingLayer->addChild(rootLayer);
643     }
644     return true;
645 }
646 
fullyInvalidatePaintRecursive(RenderLayer * layer)647 static void fullyInvalidatePaintRecursive(RenderLayer* layer)
648 {
649     if (layer->compositingState() == PaintsIntoOwnBacking) {
650         layer->compositedLayerMapping()->setContentsNeedDisplay();
651         layer->compositedLayerMapping()->setSquashingContentsNeedDisplay();
652     }
653 
654     for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
655         fullyInvalidatePaintRecursive(child);
656 }
657 
fullyInvalidatePaint()658 void RenderLayerCompositor::fullyInvalidatePaint()
659 {
660     // We're walking all compositing layers and invalidating them, so there's
661     // no need to have up-to-date compositing state.
662     DisableCompositingQueryAsserts disabler;
663     fullyInvalidatePaintRecursive(rootRenderLayer());
664 }
665 
rootRenderLayer() const666 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
667 {
668     return m_renderView.layer();
669 }
670 
rootGraphicsLayer() const671 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
672 {
673     if (m_overflowControlsHostLayer)
674         return m_overflowControlsHostLayer.get();
675     return m_rootContentLayer.get();
676 }
677 
scrollLayer() const678 GraphicsLayer* RenderLayerCompositor::scrollLayer() const
679 {
680     return m_scrollLayer.get();
681 }
682 
containerLayer() const683 GraphicsLayer* RenderLayerCompositor::containerLayer() const
684 {
685     return m_containerLayer.get();
686 }
687 
ensureRootTransformLayer()688 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
689 {
690     ASSERT(rootGraphicsLayer());
691 
692     if (!m_rootTransformLayer.get()) {
693         m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
694         m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
695         m_rootTransformLayer->addChild(m_containerLayer.get());
696         updateOverflowControlsLayers();
697     }
698 
699     return m_rootTransformLayer.get();
700 }
701 
setIsInWindow(bool isInWindow)702 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
703 {
704     if (!staleInCompositingMode())
705         return;
706 
707     if (isInWindow) {
708         if (m_rootLayerAttachment != RootLayerUnattached)
709             return;
710 
711         RootLayerAttachment attachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
712         attachRootLayer(attachment);
713     } else {
714         if (m_rootLayerAttachment == RootLayerUnattached)
715             return;
716 
717         detachRootLayer();
718     }
719 }
720 
updateRootLayerPosition()721 void RenderLayerCompositor::updateRootLayerPosition()
722 {
723     if (m_rootContentLayer) {
724         const IntRect& documentRect = m_renderView.documentRect();
725         m_rootContentLayer->setSize(documentRect.size());
726         m_rootContentLayer->setPosition(documentRect.location());
727 #if USE(RUBBER_BANDING)
728         if (m_layerForOverhangShadow)
729             OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
730 #endif
731     }
732     if (m_containerLayer) {
733         FrameView* frameView = m_renderView.frameView();
734         m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
735         m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars));
736     }
737 }
738 
updatePotentialCompositingReasonsFromStyle(RenderLayer * layer)739 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLayer* layer)
740 {
741     layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.potentialCompositingReasonsFromStyle(layer->renderer()));
742 }
743 
updateDirectCompositingReasons(RenderLayer * layer)744 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
745 {
746     layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer), CompositingReasonComboAllDirectReasons);
747 }
748 
setOverlayLayer(GraphicsLayer * layer)749 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer)
750 {
751     ASSERT(rootGraphicsLayer());
752 
753     if (layer->parent() != m_overflowControlsHostLayer.get())
754         m_overflowControlsHostLayer->addChild(layer);
755 }
756 
canBeComposited(const RenderLayer * layer) const757 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
758 {
759     // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
760     // See http://webkit.org/b/84900 to re-enable it.
761     return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->subtreeIsInvisible() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
762 }
763 
764 // Return true if the given layer is a stacking context and has compositing child
765 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
766 // into the hierarchy between this layer and its children in the z-order hierarchy.
clipsCompositingDescendants(const RenderLayer * layer) const767 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
768 {
769     return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
770 }
771 
772 // If an element has composited negative z-index children, those children render in front of the
773 // layer background, so we need an extra 'contents' layer for the foreground of the layer
774 // object.
needsContentsCompositingLayer(const RenderLayer * layer) const775 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
776 {
777     if (!layer->hasCompositingDescendant())
778         return false;
779     return layer->stackingNode()->hasNegativeZOrderList();
780 }
781 
paintScrollbar(Scrollbar * scrollbar,GraphicsContext & context,const IntRect & clip)782 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
783 {
784     if (!scrollbar)
785         return;
786 
787     context.save();
788     const IntRect& scrollbarRect = scrollbar->frameRect();
789     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
790     IntRect transformedClip = clip;
791     transformedClip.moveBy(scrollbarRect.location());
792     scrollbar->paint(&context, transformedClip);
793     context.restore();
794 }
795 
paintContents(const GraphicsLayer * graphicsLayer,GraphicsContext & context,GraphicsLayerPaintingPhase,const IntRect & clip)796 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
797 {
798     if (graphicsLayer == layerForHorizontalScrollbar())
799         paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
800     else if (graphicsLayer == layerForVerticalScrollbar())
801         paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
802     else if (graphicsLayer == layerForScrollCorner()) {
803         const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
804         context.save();
805         context.translate(-scrollCorner.x(), -scrollCorner.y());
806         IntRect transformedClip = clip;
807         transformedClip.moveBy(scrollCorner.location());
808         m_renderView.frameView()->paintScrollCorner(&context, transformedClip);
809         context.restore();
810     }
811 }
812 
supportsFixedRootBackgroundCompositing() const813 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
814 {
815     if (Settings* settings = m_renderView.document().settings())
816         return settings->preferCompositingToLCDTextEnabled();
817     return false;
818 }
819 
needsFixedRootBackgroundLayer(const RenderLayer * layer) const820 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
821 {
822     if (layer != m_renderView.layer())
823         return false;
824 
825     return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
826 }
827 
fixedRootBackgroundLayer() const828 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
829 {
830     // Get the fixed root background from the RenderView layer's compositedLayerMapping.
831     RenderLayer* viewLayer = m_renderView.layer();
832     if (!viewLayer)
833         return 0;
834 
835     if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
836         return viewLayer->compositedLayerMapping()->backgroundLayer();
837 
838     return 0;
839 }
840 
resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer * graphicsLayer)841 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsLayer)
842 {
843     if (!graphicsLayer)
844         return;
845 
846     graphicsLayer->resetTrackedPaintInvalidations();
847 
848     for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
849         resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]);
850 
851     if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
852         resetTrackedPaintInvalidationRectsRecursive(replicaLayer);
853 
854     if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
855         resetTrackedPaintInvalidationRectsRecursive(maskLayer);
856 
857     if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
858         resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer);
859 }
860 
resetTrackedPaintInvalidationRects()861 void RenderLayerCompositor::resetTrackedPaintInvalidationRects()
862 {
863     if (GraphicsLayer* rootLayer = rootGraphicsLayer())
864         resetTrackedPaintInvalidationRectsRecursive(rootLayer);
865 }
866 
setTracksPaintInvalidations(bool tracksPaintInvalidations)867 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalidations)
868 {
869     ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean);
870     m_isTrackingPaintInvalidations = tracksPaintInvalidations;
871 }
872 
isTrackingPaintInvalidations() const873 bool RenderLayerCompositor::isTrackingPaintInvalidations() const
874 {
875     return m_isTrackingPaintInvalidations;
876 }
877 
shouldCompositeOverflowControls(FrameView * view)878 static bool shouldCompositeOverflowControls(FrameView* view)
879 {
880     if (Page* page = view->frame().page()) {
881         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
882             if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
883                 return true;
884     }
885 
886     return true;
887 }
888 
requiresHorizontalScrollbarLayer() const889 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
890 {
891     FrameView* view = m_renderView.frameView();
892     return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
893 }
894 
requiresVerticalScrollbarLayer() const895 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
896 {
897     FrameView* view = m_renderView.frameView();
898     return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
899 }
900 
requiresScrollCornerLayer() const901 bool RenderLayerCompositor::requiresScrollCornerLayer() const
902 {
903     FrameView* view = m_renderView.frameView();
904     return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
905 }
906 
updateOverflowControlsLayers()907 void RenderLayerCompositor::updateOverflowControlsLayers()
908 {
909 #if USE(RUBBER_BANDING)
910     if (m_renderView.frame()->isLocalRoot()) {
911         if (!m_layerForOverhangShadow) {
912             m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
913             OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
914             OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
915             m_scrollLayer->addChild(m_layerForOverhangShadow.get());
916         }
917     } else {
918         ASSERT(!m_layerForOverhangShadow);
919     }
920 #endif
921     GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
922 
923     if (requiresHorizontalScrollbarLayer()) {
924         if (!m_layerForHorizontalScrollbar) {
925             m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
926         }
927 
928         if (m_layerForHorizontalScrollbar->parent() != controlsParent) {
929             controlsParent->addChild(m_layerForHorizontalScrollbar.get());
930 
931             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
932                 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
933         }
934     } else if (m_layerForHorizontalScrollbar) {
935         m_layerForHorizontalScrollbar->removeFromParent();
936         m_layerForHorizontalScrollbar = nullptr;
937 
938         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
939             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
940     }
941 
942     if (requiresVerticalScrollbarLayer()) {
943         if (!m_layerForVerticalScrollbar) {
944             m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
945         }
946 
947         if (m_layerForVerticalScrollbar->parent() != controlsParent) {
948             controlsParent->addChild(m_layerForVerticalScrollbar.get());
949 
950             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
951                 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
952         }
953     } else if (m_layerForVerticalScrollbar) {
954         m_layerForVerticalScrollbar->removeFromParent();
955         m_layerForVerticalScrollbar = nullptr;
956 
957         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
958             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
959     }
960 
961     if (requiresScrollCornerLayer()) {
962         if (!m_layerForScrollCorner) {
963             m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
964             controlsParent->addChild(m_layerForScrollCorner.get());
965         }
966     } else if (m_layerForScrollCorner) {
967         m_layerForScrollCorner->removeFromParent();
968         m_layerForScrollCorner = nullptr;
969     }
970 
971     m_renderView.frameView()->positionScrollbarLayers();
972 }
973 
ensureRootLayer()974 void RenderLayerCompositor::ensureRootLayer()
975 {
976     RootLayerAttachment expectedAttachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
977     if (expectedAttachment == m_rootLayerAttachment)
978          return;
979 
980     if (!m_rootContentLayer) {
981         m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
982         IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
983         m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
984         m_rootContentLayer->setPosition(FloatPoint());
985         m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderView.generatingNode()));
986 
987         // Need to clip to prevent transformed content showing outside this frame
988         m_rootContentLayer->setMasksToBounds(true);
989     }
990 
991     if (!m_overflowControlsHostLayer) {
992         ASSERT(!m_scrollLayer);
993         ASSERT(!m_containerLayer);
994 
995         // Create a layer to host the clipping layer and the overflow controls layers.
996         m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
997 
998         // Clip iframe's overflow controls layer.
999         bool containerMasksToBounds = !m_renderView.frame()->isLocalRoot();
1000         m_overflowControlsHostLayer->setMasksToBounds(containerMasksToBounds);
1001 
1002         // Create a clipping layer if this is an iframe or settings require to clip.
1003         m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1004         if (Settings* settings = m_renderView.document().settings()) {
1005             if (settings->mainFrameClipsContent())
1006                 containerMasksToBounds = true;
1007         }
1008         m_containerLayer->setMasksToBounds(containerMasksToBounds);
1009 
1010         m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
1011         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1012             scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
1013 
1014         // Hook them up
1015         m_overflowControlsHostLayer->addChild(m_containerLayer.get());
1016         m_containerLayer->addChild(m_scrollLayer.get());
1017         m_scrollLayer->addChild(m_rootContentLayer.get());
1018 
1019         frameViewDidChangeSize();
1020     }
1021 
1022     // Check to see if we have to change the attachment
1023     if (m_rootLayerAttachment != RootLayerUnattached)
1024         detachRootLayer();
1025 
1026     attachRootLayer(expectedAttachment);
1027 }
1028 
destroyRootLayer()1029 void RenderLayerCompositor::destroyRootLayer()
1030 {
1031     if (!m_rootContentLayer)
1032         return;
1033 
1034     detachRootLayer();
1035 
1036 #if USE(RUBBER_BANDING)
1037     if (m_layerForOverhangShadow) {
1038         m_layerForOverhangShadow->removeFromParent();
1039         m_layerForOverhangShadow = nullptr;
1040     }
1041 #endif
1042 
1043     if (m_layerForHorizontalScrollbar) {
1044         m_layerForHorizontalScrollbar->removeFromParent();
1045         m_layerForHorizontalScrollbar = nullptr;
1046         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1047             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
1048         if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
1049             m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
1050     }
1051 
1052     if (m_layerForVerticalScrollbar) {
1053         m_layerForVerticalScrollbar->removeFromParent();
1054         m_layerForVerticalScrollbar = nullptr;
1055         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1056             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
1057         if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
1058             m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
1059     }
1060 
1061     if (m_layerForScrollCorner) {
1062         m_layerForScrollCorner = nullptr;
1063         m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
1064     }
1065 
1066     if (m_overflowControlsHostLayer) {
1067         m_overflowControlsHostLayer = nullptr;
1068         m_containerLayer = nullptr;
1069         m_scrollLayer = nullptr;
1070     }
1071     ASSERT(!m_scrollLayer);
1072     m_rootContentLayer = nullptr;
1073     m_rootTransformLayer = nullptr;
1074 }
1075 
attachRootLayer(RootLayerAttachment attachment)1076 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
1077 {
1078     if (!m_rootContentLayer)
1079         return;
1080 
1081     switch (attachment) {
1082         case RootLayerUnattached:
1083             ASSERT_NOT_REACHED();
1084             break;
1085         case RootLayerAttachedViaChromeClient: {
1086             LocalFrame& frame = m_renderView.frameView()->frame();
1087             Page* page = frame.page();
1088             if (!page)
1089                 return;
1090             page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
1091             break;
1092         }
1093         case RootLayerAttachedViaEnclosingFrame: {
1094             HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
1095             ASSERT(ownerElement);
1096             // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1097             // for the frame's renderer in the parent document.
1098             ownerElement->setNeedsCompositingUpdate();
1099             break;
1100         }
1101     }
1102 
1103     m_rootLayerAttachment = attachment;
1104 }
1105 
detachRootLayer()1106 void RenderLayerCompositor::detachRootLayer()
1107 {
1108     if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
1109         return;
1110 
1111     switch (m_rootLayerAttachment) {
1112     case RootLayerAttachedViaEnclosingFrame: {
1113         // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
1114         // for the frame's renderer in the parent document.
1115         if (m_overflowControlsHostLayer)
1116             m_overflowControlsHostLayer->removeFromParent();
1117         else
1118             m_rootContentLayer->removeFromParent();
1119 
1120         if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
1121             ownerElement->setNeedsCompositingUpdate();
1122         break;
1123     }
1124     case RootLayerAttachedViaChromeClient: {
1125         LocalFrame& frame = m_renderView.frameView()->frame();
1126         Page* page = frame.page();
1127         if (!page)
1128             return;
1129         page->chrome().client().attachRootGraphicsLayer(0);
1130     }
1131     break;
1132     case RootLayerUnattached:
1133         break;
1134     }
1135 
1136     m_rootLayerAttachment = RootLayerUnattached;
1137 }
1138 
updateRootLayerAttachment()1139 void RenderLayerCompositor::updateRootLayerAttachment()
1140 {
1141     ensureRootLayer();
1142 }
1143 
scrollingCoordinator() const1144 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
1145 {
1146     if (Page* page = this->page())
1147         return page->scrollingCoordinator();
1148 
1149     return 0;
1150 }
1151 
graphicsLayerFactory() const1152 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
1153 {
1154     if (Page* page = this->page())
1155         return page->chrome().client().graphicsLayerFactory();
1156     return 0;
1157 }
1158 
page() const1159 Page* RenderLayerCompositor::page() const
1160 {
1161     return m_renderView.frameView()->frame().page();
1162 }
1163 
lifecycle() const1164 DocumentLifecycle& RenderLayerCompositor::lifecycle() const
1165 {
1166     return m_renderView.document().lifecycle();
1167 }
1168 
debugName(const GraphicsLayer * graphicsLayer)1169 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
1170 {
1171     String name;
1172     if (graphicsLayer == m_rootContentLayer.get()) {
1173         name = "Content Root Layer";
1174     } else if (graphicsLayer == m_rootTransformLayer.get()) {
1175         name = "Root Transform Layer";
1176 #if USE(RUBBER_BANDING)
1177     } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
1178         name = "Overhang Areas Shadow";
1179 #endif
1180     } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
1181         name = "Overflow Controls Host Layer";
1182     } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
1183         name = "Horizontal Scrollbar Layer";
1184     } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
1185         name = "Vertical Scrollbar Layer";
1186     } else if (graphicsLayer == m_layerForScrollCorner.get()) {
1187         name = "Scroll Corner Layer";
1188     } else if (graphicsLayer == m_containerLayer.get()) {
1189         name = "LocalFrame Clipping Layer";
1190     } else if (graphicsLayer == m_scrollLayer.get()) {
1191         name = "LocalFrame Scrolling Layer";
1192     } else {
1193         ASSERT_NOT_REACHED();
1194     }
1195 
1196     return name;
1197 }
1198 
1199 } // namespace blink
1200