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