160a53137890ce9a20f155d89005699656495b3f
[WebKit-https.git] / Source / WebCore / rendering / RenderLayerBacking.cpp
1 /*
2  * Copyright (C) 2009, 2010, 2011 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 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 "RenderLayerBacking.h"
29
30 #include "BitmapImage.h"
31 #include "CSSAnimationController.h"
32 #include "CanvasRenderingContext.h"
33 #include "CSSPropertyNames.h"
34 #include "CachedImage.h"
35 #include "Chrome.h"
36 #include "DocumentTimeline.h"
37 #include "FilterEffectRenderer.h"
38 #include "Frame.h"
39 #include "FrameView.h"
40 #include "GraphicsContext.h"
41 #include "GraphicsLayer.h"
42 #include "HTMLBodyElement.h"
43 #include "HTMLCanvasElement.h"
44 #include "HTMLIFrameElement.h"
45 #include "HTMLMediaElement.h"
46 #include "HTMLNames.h"
47 #include "HTMLPlugInElement.h"
48 #include "InspectorInstrumentation.h"
49 #include "KeyframeList.h"
50 #include "Logging.h"
51 #include "Page.h"
52 #include "PerformanceLoggingClient.h"
53 #include "PluginViewBase.h"
54 #include "ProgressTracker.h"
55 #include "RenderFragmentContainer.h"
56 #include "RenderFragmentedFlow.h"
57 #include "RenderHTMLCanvas.h"
58 #include "RenderIFrame.h"
59 #include "RenderImage.h"
60 #include "RenderLayerCompositor.h"
61 #include "RenderEmbeddedObject.h"
62 #include "RenderMedia.h"
63 #include "RenderVideo.h"
64 #include "RenderView.h"
65 #include "RuntimeEnabledFeatures.h"
66 #include "ScrollingCoordinator.h"
67 #include "Settings.h"
68 #include "StyleResolver.h"
69 #include "TiledBacking.h"
70 #include <wtf/text/TextStream.h>
71
72 #if PLATFORM(IOS)
73 #include "RuntimeApplicationChecks.h"
74 #endif
75
76 namespace WebCore {
77
78 using namespace HTMLNames;
79
80 CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer)
81 {
82     ASSERT(renderer.isCanvas());
83     
84     const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer.node());
85     auto* context = canvas->renderingContext();
86     if (!context || !context->isAccelerated())
87         return UnacceleratedCanvas;
88     
89     if (context->isGPUBased())
90         return CanvasAsLayerContents;
91
92 #if ENABLE(ACCELERATED_2D_CANVAS)
93     return CanvasAsLayerContents;
94 #else
95     return CanvasPaintedToLayer; // On Mac and iOS we paint accelerated canvases into their layers.
96 #endif
97 }
98
99 // This acts as a cache of what we know about what is painting into this RenderLayerBacking.
100 class PaintedContentsInfo {
101 public:
102     enum class ContentsTypeDetermination {
103         Unknown,
104         SimpleContainer,
105         DirectlyCompositedImage,
106         Painted
107     };
108
109     PaintedContentsInfo(RenderLayerBacking& inBacking)
110         : m_backing(inBacking)
111     {
112     }
113     
114     void setWantsSubpixelAntialiasedTextState(bool wantsSubpixelAntialiasedTextState)
115     {
116         m_subpixelAntialiasedText = wantsSubpixelAntialiasedTextState ? RequestState::Unknown : RequestState::DontCare;
117     }
118
119     RequestState paintsBoxDecorationsDetermination();
120     bool paintsBoxDecorations()
121     {
122         RequestState state = paintsBoxDecorationsDetermination();
123         return state == RequestState::True || state == RequestState::Undetermined;
124     }
125
126     RequestState paintsContentDetermination();
127     bool paintsContent()
128     {
129         RequestState state = paintsContentDetermination();
130         return state == RequestState::True || state == RequestState::Undetermined;
131     }
132
133     RequestState paintsSubpixelAntialiasedTextDetermination();
134     bool paintsSubpixelAntialiasedText()
135     {
136         RequestState state = paintsSubpixelAntialiasedTextDetermination();
137         return state == RequestState::True || state == RequestState::Undetermined;
138     }
139
140     ContentsTypeDetermination contentsTypeDetermination();
141     bool isSimpleContainer()
142     {
143         return contentsTypeDetermination() == ContentsTypeDetermination::SimpleContainer;
144     }
145
146     bool isDirectlyCompositedImage()
147     {
148         return contentsTypeDetermination() == ContentsTypeDetermination::DirectlyCompositedImage;
149     }
150
151     RenderLayerBacking& m_backing;
152     RequestState m_boxDecorations { RequestState::Unknown };
153     RequestState m_content { RequestState::Unknown };
154     RequestState m_subpixelAntialiasedText { RequestState::DontCare };
155
156     ContentsTypeDetermination m_contentsType { ContentsTypeDetermination::Unknown };
157 };
158
159 RequestState PaintedContentsInfo::paintsBoxDecorationsDetermination()
160 {
161     if (m_boxDecorations != RequestState::Unknown)
162         return m_boxDecorations;
163
164     m_boxDecorations = m_backing.paintsBoxDecorations() ? RequestState::True : RequestState::False;
165     return m_boxDecorations;
166 }
167
168 RequestState PaintedContentsInfo::paintsContentDetermination()
169 {
170     if (m_content != RequestState::Unknown && m_subpixelAntialiasedText != RequestState::Unknown)
171         return m_content;
172
173     RenderLayer::PaintedContentRequest contentRequest;
174     if (m_subpixelAntialiasedText == RequestState::Unknown)
175         contentRequest.hasSubpixelAntialiasedText = RequestState::Unknown;
176
177     m_content = m_backing.paintsContent(contentRequest) ? RequestState::True : RequestState::False;
178
179     if (m_subpixelAntialiasedText == RequestState::Unknown)
180         m_subpixelAntialiasedText = contentRequest.hasSubpixelAntialiasedText;
181
182     return m_content;
183 }
184
185 RequestState PaintedContentsInfo::paintsSubpixelAntialiasedTextDetermination()
186 {
187     if (m_subpixelAntialiasedText != RequestState::Unknown)
188         return m_subpixelAntialiasedText;
189
190     paintsContentDetermination();
191
192     return m_subpixelAntialiasedText;
193 }
194
195 PaintedContentsInfo::ContentsTypeDetermination PaintedContentsInfo::contentsTypeDetermination()
196 {
197     if (m_contentsType != ContentsTypeDetermination::Unknown)
198         return m_contentsType;
199
200     if (m_backing.isSimpleContainerCompositingLayer(*this))
201         m_contentsType = ContentsTypeDetermination::SimpleContainer;
202     else if (m_backing.isDirectlyCompositedImage())
203         m_contentsType = ContentsTypeDetermination::DirectlyCompositedImage;
204     else
205         m_contentsType = ContentsTypeDetermination::Painted;
206
207     return m_contentsType;
208 }
209
210
211 RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
212     : m_owningLayer(layer)
213 {
214     if (layer.isRenderViewLayer()) {
215         m_isMainFrameRenderViewLayer = renderer().frame().isMainFrame();
216         m_isFrameLayerWithTiledBacking = renderer().page().chrome().client().shouldUseTiledBackingForFrameView(renderer().view().frameView());
217     }
218     
219     createPrimaryGraphicsLayer();
220
221     if (auto* tiledBacking = this->tiledBacking()) {
222         tiledBacking->setIsInWindow(renderer().page().isInWindow());
223
224         if (m_isFrameLayerWithTiledBacking) {
225             tiledBacking->setScrollingPerformanceLoggingEnabled(renderer().settings().scrollingPerformanceLoggingEnabled());
226             adjustTiledBackingCoverage();
227         }
228     }
229 }
230
231 RenderLayerBacking::~RenderLayerBacking()
232 {
233     updateAncestorClippingLayer(false);
234     updateChildClippingStrategy(false);
235     updateDescendantClippingLayer(false);
236     updateOverflowControlsLayers(false, false, false);
237     updateForegroundLayer(false);
238     updateBackgroundLayer(false);
239     updateMaskingLayer(false, false);
240     updateScrollingLayers(false);
241     detachFromScrollingCoordinator(Scrolling | ViewportConstrained);
242     destroyGraphicsLayers();
243 }
244
245 void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
246 {
247     if (layer && layer->type() == GraphicsLayer::Type::Normal && layer->tiledBacking())
248         compositor().layerTiledBackingUsageChanged(layer, false);
249 }
250
251 std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name, GraphicsLayer::Type layerType)
252 {
253     auto* graphicsLayerFactory = renderer().page().chrome().client().graphicsLayerFactory();
254
255     std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, *this, layerType);
256
257     graphicsLayer->setName(name);
258
259 #if PLATFORM(COCOA) && USE(CA)
260     graphicsLayer->setAcceleratesDrawing(compositor().acceleratedDrawingEnabled());
261     graphicsLayer->setUsesDisplayListDrawing(compositor().displayListDrawingEnabled());
262 #endif
263     
264     return graphicsLayer;
265 }
266
267 void RenderLayerBacking::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
268 {
269     // Note that this only affects the primary layer.
270     if (usesDisplayListDrawing == m_graphicsLayer->usesDisplayListDrawing())
271         return;
272
273     m_graphicsLayer->setUsesDisplayListDrawing(usesDisplayListDrawing);
274     if (m_graphicsLayer->drawsContent())
275         m_graphicsLayer->setNeedsDisplay();
276 }
277
278 String RenderLayerBacking::displayListAsText(DisplayList::AsTextFlags flags) const
279 {
280     return m_graphicsLayer->displayListAsText(flags);
281 }
282
283 void RenderLayerBacking::setIsTrackingDisplayListReplay(bool isTrackingReplay)
284 {
285     m_graphicsLayer->setIsTrackingDisplayListReplay(isTrackingReplay);
286 }
287
288 String RenderLayerBacking::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
289 {
290     return m_graphicsLayer->replayDisplayListAsText(flags);
291 }
292
293 void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
294 {
295     compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
296 }
297
298 TiledBacking* RenderLayerBacking::tiledBacking() const
299 {
300     return m_graphicsLayer->tiledBacking();
301 }
302
303 static TiledBacking::TileCoverage computePageTiledBackingCoverage(RenderLayerBacking* backing)
304 {
305     // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
306     auto& frameView = backing->owningLayer().renderer().view().frameView();
307
308     // If the page is non-visible, don't incur the cost of keeping extra tiles for scrolling.
309     if (!backing->owningLayer().page().isVisible())
310         return TiledBacking::CoverageForVisibleArea;
311
312     TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
313     bool useMinimalTilesDuringLiveResize = frameView.inLiveResize();
314     if (frameView.speculativeTilingEnabled() && !useMinimalTilesDuringLiveResize) {
315         bool clipsToExposedRect = static_cast<bool>(frameView.viewExposedRect());
316         if (frameView.horizontalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
317             tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
318
319         if (frameView.verticalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
320             tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
321     }
322     return tileCoverage;
323 }
324
325 void RenderLayerBacking::adjustTiledBackingCoverage()
326 {
327     if (!m_isFrameLayerWithTiledBacking)
328         return;
329
330     TiledBacking::TileCoverage tileCoverage = computePageTiledBackingCoverage(this);
331     tiledBacking()->setTileCoverage(tileCoverage);
332 }
333
334 void RenderLayerBacking::setTiledBackingHasMargins(bool hasExtendedBackgroundOnLeftAndRight, bool hasExtendedBackgroundOnTopAndBottom)
335 {
336     if (!m_isFrameLayerWithTiledBacking)
337         return;
338
339     tiledBacking()->setHasMargins(hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnLeftAndRight, hasExtendedBackgroundOnLeftAndRight);
340 }
341
342 void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
343 {
344     m_graphicsLayer->setShowDebugBorder(showBorder);
345     m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
346     
347     if (m_ancestorClippingLayer)
348         m_ancestorClippingLayer->setShowDebugBorder(showBorder);
349
350     if (m_foregroundLayer) {
351         m_foregroundLayer->setShowDebugBorder(showBorder);
352         m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
353     }
354     
355     if (m_contentsContainmentLayer)
356         m_contentsContainmentLayer->setShowDebugBorder(showBorder);
357     
358     if (m_backgroundLayer) {
359         m_backgroundLayer->setShowDebugBorder(showBorder);
360         m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
361     }
362
363     if (m_maskLayer) {
364         m_maskLayer->setShowDebugBorder(showBorder);
365         m_maskLayer->setShowRepaintCounter(showRepaintCounter);
366     }
367
368     if (m_layerForHorizontalScrollbar)
369         m_layerForHorizontalScrollbar->setShowDebugBorder(showBorder);
370
371     if (m_layerForVerticalScrollbar)
372         m_layerForVerticalScrollbar->setShowDebugBorder(showBorder);
373
374     if (m_layerForScrollCorner)
375         m_layerForScrollCorner->setShowDebugBorder(showBorder);
376
377     if (m_scrollingLayer)
378         m_scrollingLayer->setShowDebugBorder(showBorder);
379
380     if (m_scrollingContentsLayer) {
381         m_scrollingContentsLayer->setShowDebugBorder(showBorder);
382         m_scrollingContentsLayer->setShowRepaintCounter(showRepaintCounter);
383     }
384 }
385
386 void RenderLayerBacking::createPrimaryGraphicsLayer()
387 {
388     String layerName = m_owningLayer.name();
389     const unsigned maxLayerNameLength = 100;
390     if (layerName.length() > maxLayerNameLength) {
391         layerName.truncate(maxLayerNameLength);
392         layerName.append("...");
393     }
394     m_graphicsLayer = createGraphicsLayer(layerName, m_isFrameLayerWithTiledBacking ? GraphicsLayer::Type::PageTiledBacking : GraphicsLayer::Type::Normal);
395
396     if (m_isFrameLayerWithTiledBacking) {
397         m_childContainmentLayer = createGraphicsLayer("Page TiledBacking containment");
398         m_graphicsLayer->addChild(m_childContainmentLayer.get());
399     }
400
401 #if !PLATFORM(IOS)
402     if (m_isMainFrameRenderViewLayer) {
403         // Page scale is applied above the RenderView on iOS.
404         m_graphicsLayer->setContentsOpaque(!compositor().viewHasTransparentBackground());
405         m_graphicsLayer->setAppliesPageScale();
406     }
407 #endif
408
409 #if PLATFORM(COCOA) && USE(CA)
410     if (!compositor().acceleratedDrawingEnabled() && renderer().isCanvas()) {
411         const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
412         if (canvas->shouldAccelerate(canvas->size()))
413             m_graphicsLayer->setAcceleratesDrawing(true);
414     }
415 #endif    
416     
417     updateOpacity(renderer().style());
418     updateTransform(renderer().style());
419     updateFilters(renderer().style());
420 #if ENABLE(FILTERS_LEVEL_2)
421     updateBackdropFilters(renderer().style());
422 #endif
423 #if ENABLE(CSS_COMPOSITING)
424     updateBlendMode(renderer().style());
425 #endif
426     updateCustomAppearance(renderer().style());
427 }
428
429 #if PLATFORM(IOS)
430 void RenderLayerBacking::layerWillBeDestroyed()
431 {
432     auto& renderer = this->renderer();
433     if (is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing()) {
434         auto* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer).widget());
435         if (pluginViewBase && m_graphicsLayer->contentsLayerForMedia())
436             pluginViewBase->detachPluginLayer();
437     }
438 }
439
440 bool RenderLayerBacking::needsIOSDumpRenderTreeMainFrameRenderViewLayerIsAlwaysOpaqueHack(const GraphicsLayer& layer) const
441 {
442     if (m_isMainFrameRenderViewLayer && IOSApplication::isDumpRenderTree()) {
443         // In iOS WebKit1 the main frame's RenderView layer is always transparent. We lie that it is opaque so that
444         // internals.layerTreeAsText() tests succeed.
445         ASSERT_UNUSED(layer, !layer.contentsOpaque());
446         return true;
447     }
448     return false;
449 }
450 #endif
451
452 void RenderLayerBacking::destroyGraphicsLayers()
453 {
454     if (m_graphicsLayer) {
455         willDestroyLayer(m_graphicsLayer.get());
456         m_graphicsLayer->removeFromParent();
457     }
458
459     m_ancestorClippingLayer = nullptr;
460     m_contentsContainmentLayer = nullptr;
461     m_graphicsLayer = nullptr;
462     m_foregroundLayer = nullptr;
463     m_backgroundLayer = nullptr;
464     m_childContainmentLayer = nullptr;
465     m_maskLayer = nullptr;
466     m_childClippingMaskLayer = nullptr;
467
468     m_scrollingLayer = nullptr;
469     m_scrollingContentsLayer = nullptr;
470 }
471
472 void RenderLayerBacking::updateOpacity(const RenderStyle& style)
473 {
474     m_graphicsLayer->setOpacity(compositingOpacity(style.opacity()));
475 }
476
477 void RenderLayerBacking::updateTransform(const RenderStyle& style)
478 {
479     // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
480     // baked into it, and we don't want that.
481     TransformationMatrix t;
482     if (m_owningLayer.hasTransform()) {
483         auto& renderBox = downcast<RenderBox>(renderer());
484         style.applyTransform(t, snapRectToDevicePixels(renderBox.borderBoxRect(), deviceScaleFactor()), RenderStyle::ExcludeTransformOrigin);
485         makeMatrixRenderable(t, compositor().canRender3DTransforms());
486     }
487     
488     if (m_contentsContainmentLayer) {
489         m_contentsContainmentLayer->setTransform(t);
490         m_graphicsLayer->setTransform(TransformationMatrix());
491     } else
492         m_graphicsLayer->setTransform(t);
493 }
494
495 void RenderLayerBacking::updateFilters(const RenderStyle& style)
496 {
497     m_canCompositeFilters = m_graphicsLayer->setFilters(style.filter());
498 }
499
500 #if ENABLE(FILTERS_LEVEL_2)
501 void RenderLayerBacking::updateBackdropFilters(const RenderStyle& style)
502 {
503     m_canCompositeBackdropFilters = m_graphicsLayer->setBackdropFilters(style.backdropFilter());
504 }
505
506 void RenderLayerBacking::updateBackdropFiltersGeometry()
507 {
508     if (!m_canCompositeBackdropFilters)
509         return;
510
511     if (!is<RenderBox>(renderer()))
512         return;
513
514     auto& renderer = downcast<RenderBox>(this->renderer());
515     LayoutRect boxRect = renderer.borderBoxRect();
516     if (renderer.hasClip())
517         boxRect.intersect(renderer.clipRect(LayoutPoint(), nullptr));
518     boxRect.move(contentOffsetInCompostingLayer());
519
520     FloatRoundedRect backdropFiltersRect;
521     if (renderer.style().hasBorderRadius() && !renderer.hasClip())
522         backdropFiltersRect = renderer.style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
523     else
524         backdropFiltersRect = FloatRoundedRect(snapRectToDevicePixels(boxRect, deviceScaleFactor()));
525
526     m_graphicsLayer->setBackdropFiltersRect(backdropFiltersRect);
527 }
528 #endif
529
530 #if ENABLE(CSS_COMPOSITING)
531 void RenderLayerBacking::updateBlendMode(const RenderStyle& style)
532 {
533     // FIXME: where is the blend mode updated when m_ancestorClippingLayers come and go?
534     if (m_ancestorClippingLayer) {
535         m_ancestorClippingLayer->setBlendMode(style.blendMode());
536         m_graphicsLayer->setBlendMode(BlendModeNormal);
537     } else
538         m_graphicsLayer->setBlendMode(style.blendMode());
539 }
540 #endif
541
542 void RenderLayerBacking::updateCustomAppearance(const RenderStyle& style)
543 {
544     ControlPart appearance = style.appearance();
545     if (appearance == MediaControlsLightBarBackgroundPart)
546         m_graphicsLayer->setCustomAppearance(GraphicsLayer::LightBackdropAppearance);
547     else if (appearance == MediaControlsDarkBarBackgroundPart)
548         m_graphicsLayer->setCustomAppearance(GraphicsLayer::DarkBackdropAppearance);
549     else
550         m_graphicsLayer->setCustomAppearance(GraphicsLayer::NoCustomAppearance);
551 }
552
553 static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer& layer)
554 {
555     for (auto* curr = &layer; curr; curr = curr->parent()) {
556         if (curr->hasTransform() || curr->usesAcceleratedScrolling())
557             return true;
558     }
559
560     return false;
561 }
562
563 bool RenderLayerBacking::shouldClipCompositedBounds() const
564 {
565 #if !PLATFORM(IOS)
566     // Scrollbar layers use this layer for relative positioning, so don't clip.
567     if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
568         return false;
569 #endif
570
571     if (m_isFrameLayerWithTiledBacking)
572         return false;
573
574     if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
575         return false;
576
577     return true;
578 }
579
580 static bool hasNonZeroTransformOrigin(const RenderObject& renderer)
581 {
582     const RenderStyle& style = renderer.style();
583     return (style.transformOriginX().type() == Fixed && style.transformOriginX().value())
584         || (style.transformOriginY().type() == Fixed && style.transformOriginY().value());
585 }
586
587 void RenderLayerBacking::updateCompositedBounds()
588 {
589     LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, LayoutSize(), RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
590     // Clip to the size of the document or enclosing overflow-scroll layer.
591     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
592     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
593     if (shouldClipCompositedBounds()) {
594         auto& view = renderer().view();
595         auto* rootLayer = view.layer();
596
597         LayoutRect clippingBounds;
598         if (renderer().isFixedPositioned() && renderer().container() == &view)
599             clippingBounds = view.frameView().rectForFixedPositionLayout();
600         else
601             clippingBounds = view.unscaledDocumentRect();
602
603         if (&m_owningLayer != rootLayer)
604             clippingBounds.intersect(m_owningLayer.backgroundClipRect(RenderLayer::ClipRectsContext(rootLayer, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
605
606         LayoutPoint delta = m_owningLayer.convertToLayerCoords(rootLayer, LayoutPoint(), RenderLayer::AdjustForColumns);
607         clippingBounds.move(-delta.x(), -delta.y());
608
609         layerBounds.intersect(clippingBounds);
610     }
611     
612     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
613     // then we need to ensure that the compositing layer has non-zero size so that we can apply
614     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
615     if (layerBounds.isEmpty() && (hasNonZeroTransformOrigin(renderer()) || renderer().style().hasPerspective())) {
616         layerBounds.setWidth(1);
617         layerBounds.setHeight(1);
618         m_artificiallyInflatedBounds = true;
619     } else
620         m_artificiallyInflatedBounds = false;
621
622     setCompositedBounds(layerBounds);
623 }
624
625 void RenderLayerBacking::updateAfterWidgetResize()
626 {
627     if (!is<RenderWidget>(renderer()))
628         return;
629     if (auto* innerCompositor = RenderLayerCompositor::frameContentsCompositor(&downcast<RenderWidget>(renderer()))) {
630         innerCompositor->frameViewDidChangeSize();
631         innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
632     }
633 }
634
635 void RenderLayerBacking::updateAfterLayout(OptionSet<UpdateAfterLayoutFlags> flags)
636 {
637     LOG(Compositing, "RenderLayerBacking %p updateAfterLayout (layer %p)", this, &m_owningLayer);
638
639     if (!compositor().compositingLayersNeedRebuild()) {
640         // Calling updateGeometry() here gives incorrect results, because the
641         // position of this layer's GraphicsLayer depends on the position of our compositing
642         // ancestor's GraphicsLayer. That cannot be determined until all the descendant 
643         // RenderLayers of that ancestor have been processed via updateLayerPositions().
644         //
645         // The solution is to update compositing children of this layer here,
646         // via updateCompositingChildrenGeometry().
647         updateCompositedBounds();
648         compositor().updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer);
649         
650         if (flags.contains(UpdateAfterLayoutFlags::IsUpdateRoot)) {
651             updateGeometry();
652             updateAfterDescendants();
653             compositor().updateRootLayerPosition();
654             auto* stackingContainer = m_owningLayer.enclosingStackingContainer();
655             if (!compositor().compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != &m_owningLayer))
656                 compositor().updateCompositingDescendantGeometry(*stackingContainer, *stackingContainer);
657         }
658     }
659     
660     if (flags.contains(UpdateAfterLayoutFlags::NeedsFullRepaint) && canIssueSetNeedsDisplay())
661         setContentsNeedDisplay();
662 }
663
664 bool RenderLayerBacking::updateConfiguration()
665 {
666     m_owningLayer.updateDescendantDependentFlags();
667     m_owningLayer.updateZOrderLists();
668
669     bool layerConfigChanged = false;
670     setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
671     
672     // The background layer is currently only used for fixed root backgrounds.
673     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
674         layerConfigChanged = true;
675
676     if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
677         layerConfigChanged = true;
678     
679     bool needsDescendantsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
680
681     if (!renderer().view().needsLayout()) {
682         bool usesCompositedScrolling = m_owningLayer.usesAcceleratedScrolling();
683
684         // Our scrolling layer will clip.
685         if (usesCompositedScrolling)
686             needsDescendantsClippingLayer = false;
687
688         if (updateScrollingLayers(usesCompositedScrolling))
689             layerConfigChanged = true;
690
691         if (updateDescendantClippingLayer(needsDescendantsClippingLayer))
692             layerConfigChanged = true;
693     }
694
695     if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
696         layerConfigChanged = true;
697
698     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
699         layerConfigChanged = true;
700
701     if (layerConfigChanged)
702         updateInternalHierarchy();
703
704     if (auto* flatteningLayer = tileCacheFlatteningLayer()) {
705         if (layerConfigChanged || flatteningLayer->parent() != m_graphicsLayer.get())
706             m_graphicsLayer->addChild(flatteningLayer);
707     }
708
709     updateMaskingLayer(renderer().hasMask(), renderer().hasClipPath());
710
711     updateChildClippingStrategy(needsDescendantsClippingLayer);
712
713     if (m_owningLayer.hasReflection()) {
714         if (m_owningLayer.reflectionLayer()->backing()) {
715             auto* reflectionLayer = m_owningLayer.reflectionLayer()->backing()->graphicsLayer();
716             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
717         }
718     } else
719         m_graphicsLayer->setReplicatedByLayer(nullptr);
720
721     PaintedContentsInfo contentsInfo(*this);
722
723     if (!m_owningLayer.isRenderViewLayer()) {
724         bool didUpdateContentsRect = false;
725         updateDirectlyCompositedBoxDecorations(contentsInfo, didUpdateContentsRect);
726     } else
727         updateRootLayerConfiguration();
728     
729     if (contentsInfo.isDirectlyCompositedImage())
730         updateImageContents(contentsInfo);
731
732     if (is<RenderEmbeddedObject>(renderer()) && downcast<RenderEmbeddedObject>(renderer()).allowsAcceleratedCompositing()) {
733         auto* pluginViewBase = downcast<PluginViewBase>(downcast<RenderWidget>(renderer()).widget());
734 #if PLATFORM(IOS)
735         if (pluginViewBase && !m_graphicsLayer->contentsLayerForMedia()) {
736             pluginViewBase->detachPluginLayer();
737             pluginViewBase->attachPluginLayer();
738         }
739 #else
740         if (!pluginViewBase->shouldNotAddLayer())
741             m_graphicsLayer->setContentsToPlatformLayer(pluginViewBase->platformLayer(), GraphicsLayer::ContentsLayerForPlugin);
742 #endif
743     }
744 #if ENABLE(VIDEO)
745     else if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo()) {
746         auto* mediaElement = downcast<HTMLMediaElement>(renderer().element());
747         m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer(), GraphicsLayer::ContentsLayerForMedia);
748     }
749 #endif
750 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
751     else if (renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
752         const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer().element());
753         if (auto* context = canvas->renderingContext())
754             m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer(), GraphicsLayer::ContentsLayerForCanvas);
755         layerConfigChanged = true;
756     }
757 #endif
758     if (is<RenderWidget>(renderer()))
759         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(&downcast<RenderWidget>(renderer()));
760
761     return layerConfigChanged;
762 }
763
764 static LayoutRect clipBox(RenderBox& renderer)
765 {
766     LayoutRect result = LayoutRect::infiniteRect();
767     if (renderer.hasOverflowClip())
768         result = renderer.overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
769
770     if (renderer.hasClip())
771         result.intersect(renderer.clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
772
773     return result;
774 }
775
776 static bool subpixelOffsetFromRendererChanged(const LayoutSize& oldSubpixelOffsetFromRenderer, const LayoutSize& newSubpixelOffsetFromRenderer, float deviceScaleFactor)
777 {
778     FloatSize previous = snapSizeToDevicePixel(oldSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
779     FloatSize current = snapSizeToDevicePixel(newSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
780     return previous != current;
781 }
782     
783 static FloatSize subpixelForLayerPainting(const LayoutPoint& point, float pixelSnappingFactor)
784 {
785     LayoutUnit x = point.x();
786     LayoutUnit y = point.y();
787     x = x >= 0 ? floorToDevicePixel(x, pixelSnappingFactor) : ceilToDevicePixel(x, pixelSnappingFactor);
788     y = y >= 0 ? floorToDevicePixel(y, pixelSnappingFactor) : ceilToDevicePixel(y, pixelSnappingFactor);
789     return point - LayoutPoint(x, y);
790 }
791
792 struct OffsetFromRenderer {
793     // 1.2px - > { m_devicePixelOffset = 1px m_subpixelOffset = 0.2px }
794     LayoutSize m_devicePixelOffset;
795     LayoutSize m_subpixelOffset;
796 };
797
798 static OffsetFromRenderer computeOffsetFromRenderer(const LayoutSize& offset, float deviceScaleFactor)
799 {
800     OffsetFromRenderer offsetFromRenderer;
801     offsetFromRenderer.m_subpixelOffset = LayoutSize(subpixelForLayerPainting(toLayoutPoint(offset), deviceScaleFactor));
802     offsetFromRenderer.m_devicePixelOffset = offset - offsetFromRenderer.m_subpixelOffset;
803     return offsetFromRenderer;
804 }
805     
806 struct SnappedRectInfo {
807     LayoutRect m_snappedRect;
808     LayoutSize m_snapDelta;
809 };
810     
811 static SnappedRectInfo snappedGraphicsLayer(const LayoutSize& offset, const LayoutSize& size, float deviceScaleFactor)
812 {
813     SnappedRectInfo snappedGraphicsLayer;
814     LayoutRect graphicsLayerRect = LayoutRect(toLayoutPoint(offset), size);
815     snappedGraphicsLayer.m_snappedRect = LayoutRect(snapRectToDevicePixels(graphicsLayerRect, deviceScaleFactor));
816     snappedGraphicsLayer.m_snapDelta = snappedGraphicsLayer.m_snappedRect.location() - toLayoutPoint(offset);
817     return snappedGraphicsLayer;
818 }
819
820 static LayoutSize computeOffsetFromAncestorGraphicsLayer(RenderLayer* compositedAncestor, const LayoutPoint& location, float deviceScaleFactor)
821 {
822     if (!compositedAncestor)
823         return toLayoutSize(location);
824
825     // FIXME: This is a workaround until after webkit.org/162634 gets fixed. ancestorSubpixelOffsetFromRenderer
826     // could be stale when a dynamic composited state change triggers a pre-order updateGeometry() traversal.
827     LayoutSize ancestorSubpixelOffsetFromRenderer = compositedAncestor->backing()->subpixelOffsetFromRenderer();
828     LayoutRect ancestorCompositedBounds = compositedAncestor->backing()->compositedBounds();
829     LayoutSize floored = toLayoutSize(LayoutPoint(floorPointToDevicePixels(ancestorCompositedBounds.location() - ancestorSubpixelOffsetFromRenderer, deviceScaleFactor)));
830     LayoutSize ancestorRendererOffsetFromAncestorGraphicsLayer = -(floored + ancestorSubpixelOffsetFromRenderer);
831     return ancestorRendererOffsetFromAncestorGraphicsLayer + toLayoutSize(location);
832 }
833
834 class ComputedOffsets {
835 public:
836     ComputedOffsets(const RenderLayer& renderLayer, const LayoutRect& localRect, const LayoutRect& parentGraphicsLayerRect, const LayoutRect& primaryGraphicsLayerRect)
837         : m_renderLayer(renderLayer)
838         , m_location(localRect.location())
839         , m_parentGraphicsLayerOffset(toLayoutSize(parentGraphicsLayerRect.location()))
840         , m_primaryGraphicsLayerOffset(toLayoutSize(primaryGraphicsLayerRect.location()))
841         , m_deviceScaleFactor(renderLayer.renderer().document().deviceScaleFactor())
842     {
843     }
844
845     LayoutSize fromParentGraphicsLayer()
846     {
847         if (!m_fromParentGraphicsLayer)
848             m_fromParentGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset;
849         return m_fromParentGraphicsLayer.value();
850     }
851     
852     LayoutSize fromPrimaryGraphicsLayer()
853     {
854         if (!m_fromPrimaryGraphicsLayer)
855             m_fromPrimaryGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset - m_primaryGraphicsLayerOffset;
856         return m_fromPrimaryGraphicsLayer.value();
857     }
858     
859 private:
860     LayoutSize fromAncestorGraphicsLayer()
861     {
862         if (!m_fromAncestorGraphicsLayer) {
863             auto* compositedAncestor = m_renderLayer.ancestorCompositingLayer();
864             LayoutPoint localPointInAncestorRenderLayerCoords = m_renderLayer.convertToLayerCoords(compositedAncestor, m_location, RenderLayer::AdjustForColumns);
865             m_fromAncestorGraphicsLayer = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, localPointInAncestorRenderLayerCoords, m_deviceScaleFactor);
866         }
867         return m_fromAncestorGraphicsLayer.value();
868     }
869
870     std::optional<LayoutSize> m_fromAncestorGraphicsLayer;
871     std::optional<LayoutSize> m_fromParentGraphicsLayer;
872     std::optional<LayoutSize> m_fromPrimaryGraphicsLayer;
873     
874     const RenderLayer& m_renderLayer;
875     // Location is relative to the renderer.
876     const LayoutPoint m_location;
877     const LayoutSize m_parentGraphicsLayerOffset;
878     const LayoutSize m_primaryGraphicsLayerOffset;
879     float m_deviceScaleFactor;
880 };
881
882 LayoutRect RenderLayerBacking::computePrimaryGraphicsLayerRect(const LayoutRect& parentGraphicsLayerRect) const
883 {
884     ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, LayoutRect());
885     return LayoutRect(encloseRectToDevicePixels(LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()),
886         deviceScaleFactor()));
887 }
888
889 LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const
890 {
891     if (!compositedAncestor || !compositedAncestor->backing())
892         return renderer().view().documentRect();
893
894     auto* ancestorBackingLayer = compositedAncestor->backing();
895     LayoutRect parentGraphicsLayerRect;
896     if (m_owningLayer.isInsideFragmentedFlow()) {
897         // FIXME: flows/columns need work.
898         LayoutRect ancestorCompositedBounds = ancestorBackingLayer->compositedBounds();
899         ancestorCompositedBounds.setLocation(LayoutPoint());
900         parentGraphicsLayerRect = ancestorCompositedBounds;
901     }
902
903     if (ancestorBackingLayer->hasClippingLayer()) {
904         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore position relative to it.
905         LayoutRect clippingBox = clipBox(downcast<RenderBox>(compositedAncestor->renderer()));
906         LayoutSize clippingBoxOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, clippingBox.location(), deviceScaleFactor());
907         parentGraphicsLayerRect = snappedGraphicsLayer(clippingBoxOffset, clippingBox.size(), deviceScaleFactor()).m_snappedRect;
908     }
909
910 #if PLATFORM(IOS)
911     if (compositedAncestor->hasTouchScrollableOverflow()) {
912         LayoutRect ancestorCompositedBounds = ancestorBackingLayer->compositedBounds();
913         auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
914         LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
915         ScrollOffset scrollOffset = compositedAncestor->scrollOffset();
916         parentGraphicsLayerRect = LayoutRect((paddingBox.location() - toLayoutSize(ancestorCompositedBounds.location()) - toLayoutSize(scrollOffset)), paddingBox.size());
917     }
918 #else
919     if (compositedAncestor->needsCompositedScrolling()) {
920         auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
921         LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
922         parentGraphicsLayerRect = LayoutRect(scrollOrigin - toLayoutSize(compositedAncestor->scrollOffset()), renderBox.borderBoxRect().size());
923     }
924 #endif
925
926     if (m_ancestorClippingLayer) {
927         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
928         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
929         // for a compositing layer, rootLayer is the layer itself.
930         ShouldRespectOverflowClip shouldRespectOverflowClip = compositedAncestor->isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
931         RenderLayer::ClipRectsContext clipRectsContext(compositedAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
932         LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
933         ASSERT(!parentClipRect.isInfinite());
934         LayoutSize clippingOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, parentClipRect.location(), deviceScaleFactor());
935         LayoutRect snappedClippingLayerRect = snappedGraphicsLayer(clippingOffset, parentClipRect.size(), deviceScaleFactor()).m_snappedRect;
936         // The primary layer is then parented in, and positioned relative to this clipping layer.
937         ancestorClippingLayerOffset = snappedClippingLayerRect.location() - parentGraphicsLayerRect.location();
938         parentGraphicsLayerRect = snappedClippingLayerRect;
939     }
940     return parentGraphicsLayerRect;
941 }
942
943 void RenderLayerBacking::updateGeometry()
944 {
945     LOG_WITH_STREAM(Compositing, stream << "updateGeometry " << m_owningLayer);
946
947     // If we haven't built z-order lists yet, wait until later.
948     if (m_owningLayer.isStackingContainer() && m_owningLayer.m_zOrderListsDirty)
949         return;
950
951     const RenderStyle& style = renderer().style();
952
953     bool isRunningAcceleratedTransformAnimation = false;
954     bool isRunningAcceleratedOpacityAnimation = false;
955     if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) {
956         if (auto* timeline = renderer().documentTimeline()) {
957             isRunningAcceleratedTransformAnimation = timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform);
958             isRunningAcceleratedOpacityAnimation = timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity);
959         }
960     } else {
961         isRunningAcceleratedTransformAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused);
962         isRunningAcceleratedOpacityAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused);
963     }
964
965     // Set transform property, if it is not animating. We have to do this here because the transform
966     // is affected by the layer dimensions.
967     if (!isRunningAcceleratedTransformAnimation)
968         updateTransform(style);
969
970     // Set opacity, if it is not animating.
971     if (!isRunningAcceleratedOpacityAnimation)
972         updateOpacity(style);
973
974     updateFilters(style);
975 #if ENABLE(FILTERS_LEVEL_2)
976     updateBackdropFilters(style);
977 #endif
978 #if ENABLE(CSS_COMPOSITING)
979     updateBlendMode(style);
980 #endif
981     m_owningLayer.updateDescendantDependentFlags();
982
983     // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
984     bool preserves3D = style.transformStyle3D() == TransformStyle3DPreserve3D && !renderer().hasReflection();
985     m_graphicsLayer->setPreserves3D(preserves3D);
986     m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
987
988     auto* compositedAncestor = m_owningLayer.ancestorCompositingLayer();
989     LayoutSize ancestorClippingLayerOffset;
990     LayoutRect parentGraphicsLayerRect = computeParentGraphicsLayerRect(compositedAncestor, ancestorClippingLayerOffset);
991     LayoutRect primaryGraphicsLayerRect = computePrimaryGraphicsLayerRect(parentGraphicsLayerRect);
992
993     ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
994     m_compositedBoundsOffsetFromGraphicsLayer = compositedBoundsOffset.fromPrimaryGraphicsLayer();
995     m_graphicsLayer->setPosition(primaryGraphicsLayerRect.location());
996     m_graphicsLayer->setSize(primaryGraphicsLayerRect.size());
997
998     auto computeAnimationExtent = [&] () -> std::optional<FloatRect> {
999         LayoutRect animatedBounds;
1000         if (isRunningAcceleratedTransformAnimation && m_owningLayer.getOverlapBoundsIncludingChildrenAccountingForTransformAnimations(animatedBounds, RenderLayer::IncludeCompositedDescendants))
1001             return FloatRect(animatedBounds);
1002         return { };
1003     };
1004     m_graphicsLayer->setAnimationExtent(computeAnimationExtent());
1005
1006     ComputedOffsets rendererOffset(m_owningLayer, LayoutRect(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
1007     if (m_ancestorClippingLayer) {
1008         // Clipping layer is parented in the ancestor layer.
1009         m_ancestorClippingLayer->setPosition(toLayoutPoint(ancestorClippingLayerOffset));
1010         m_ancestorClippingLayer->setSize(parentGraphicsLayerRect.size());
1011         m_ancestorClippingLayer->setOffsetFromRenderer(-rendererOffset.fromParentGraphicsLayer());
1012     }
1013
1014     if (m_contentsContainmentLayer) {
1015         m_contentsContainmentLayer->setPreserves3D(preserves3D);
1016         m_contentsContainmentLayer->setPosition(primaryGraphicsLayerRect.location());
1017         m_graphicsLayer->setPosition(FloatPoint());
1018         // Use the same size as m_graphicsLayer so transforms behave correctly.
1019         m_contentsContainmentLayer->setSize(primaryGraphicsLayerRect.size());
1020     }
1021
1022     // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordidate system which is not necessarily
1023     // the same as the ancestor graphics layer.
1024     OffsetFromRenderer primaryGraphicsLayerOffsetFromRenderer;
1025     LayoutSize oldSubpixelOffsetFromRenderer = m_subpixelOffsetFromRenderer;
1026     primaryGraphicsLayerOffsetFromRenderer = computeOffsetFromRenderer(-rendererOffset.fromPrimaryGraphicsLayer(), deviceScaleFactor());
1027     m_subpixelOffsetFromRenderer = primaryGraphicsLayerOffsetFromRenderer.m_subpixelOffset;
1028
1029     if (primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset != m_graphicsLayer->offsetFromRenderer()) {
1030         m_graphicsLayer->setOffsetFromRenderer(primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset);
1031         positionOverflowControlsLayers();
1032     }
1033
1034     if (!m_isMainFrameRenderViewLayer && !m_isFrameLayerWithTiledBacking) {
1035         // For non-root layers, background is always painted by the primary graphics layer.
1036         ASSERT(!m_backgroundLayer);
1037         // Subpixel offset from graphics layer or size changed.
1038         bool hadSubpixelRounding = !m_subpixelOffsetFromRenderer.isZero() || compositedBounds().size() != primaryGraphicsLayerRect.size();
1039         m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
1040     }
1041
1042     // If we have a layer that clips children, position it.
1043     LayoutRect clippingBox;
1044     if (auto* clipLayer = clippingLayer()) {
1045         clippingBox = clipBox(downcast<RenderBox>(renderer()));
1046         // Clipping layer is parented in the primary graphics layer.
1047         LayoutSize clipBoxOffsetFromGraphicsLayer = toLayoutSize(clippingBox.location()) + rendererOffset.fromPrimaryGraphicsLayer();
1048         SnappedRectInfo snappedClippingGraphicsLayer = snappedGraphicsLayer(clipBoxOffsetFromGraphicsLayer, clippingBox.size(), deviceScaleFactor());
1049         clipLayer->setPosition(snappedClippingGraphicsLayer.m_snappedRect.location());
1050         clipLayer->setSize(snappedClippingGraphicsLayer.m_snappedRect.size());
1051         clipLayer->setOffsetFromRenderer(toLayoutSize(clippingBox.location() - snappedClippingGraphicsLayer.m_snapDelta));
1052
1053         if (m_childClippingMaskLayer && !m_scrollingLayer) {
1054             m_childClippingMaskLayer->setSize(clipLayer->size());
1055             m_childClippingMaskLayer->setPosition(FloatPoint());
1056             m_childClippingMaskLayer->setOffsetFromRenderer(clipLayer->offsetFromRenderer());
1057         }
1058     }
1059     
1060     if (m_maskLayer)
1061         updateMaskingLayerGeometry();
1062     
1063     if (renderer().hasTransformRelatedProperty()) {
1064         // Update properties that depend on layer dimensions.
1065         FloatPoint3D transformOrigin = computeTransformOriginForPainting(downcast<RenderBox>(renderer()).borderBoxRect());
1066         FloatPoint layerOffset = roundPointToDevicePixels(toLayoutPoint(rendererOffset.fromParentGraphicsLayer()), deviceScaleFactor());
1067         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
1068         FloatPoint3D anchor(
1069             primaryGraphicsLayerRect.width() ? ((layerOffset.x() - primaryGraphicsLayerRect.x()) + transformOrigin.x()) / primaryGraphicsLayerRect.width() : 0.5,
1070             primaryGraphicsLayerRect.height() ? ((layerOffset.y() - primaryGraphicsLayerRect.y())+ transformOrigin.y()) / primaryGraphicsLayerRect.height() : 0.5,
1071             transformOrigin.z());
1072
1073         if (m_contentsContainmentLayer)
1074             m_contentsContainmentLayer->setAnchorPoint(anchor);
1075         else
1076             m_graphicsLayer->setAnchorPoint(anchor);
1077
1078         auto* clipLayer = clippingLayer();
1079         if (style.hasPerspective()) {
1080             TransformationMatrix t = owningLayer().perspectiveTransform();
1081             
1082             if (clipLayer) {
1083                 clipLayer->setChildrenTransform(t);
1084                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
1085             }
1086             else
1087                 m_graphicsLayer->setChildrenTransform(t);
1088         } else {
1089             if (clipLayer)
1090                 clipLayer->setChildrenTransform(TransformationMatrix());
1091             else
1092                 m_graphicsLayer->setChildrenTransform(TransformationMatrix());
1093         }
1094     } else {
1095         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5, 0.5, 0));
1096         if (m_contentsContainmentLayer)
1097             m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5, 0.5, 0));
1098     }
1099
1100     if (m_foregroundLayer) {
1101         FloatPoint foregroundPosition;
1102         FloatSize foregroundSize = primaryGraphicsLayerRect.size();
1103         FloatSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
1104         if (hasClippingLayer()) {
1105             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
1106             // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
1107             foregroundSize = FloatSize(clippingBox.size());
1108             foregroundOffset = toFloatSize(clippingBox.location());
1109         }
1110
1111         m_foregroundLayer->setPosition(foregroundPosition);
1112         m_foregroundLayer->setSize(foregroundSize);
1113         m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
1114     }
1115
1116     if (m_backgroundLayer) {
1117         FloatPoint backgroundPosition;
1118         FloatSize backgroundSize = primaryGraphicsLayerRect.size();
1119         if (backgroundLayerPaintsFixedRootBackground()) {
1120             const FrameView& frameView = renderer().view().frameView();
1121             backgroundPosition = frameView.scrollPositionForFixedPosition();
1122             backgroundSize = frameView.layoutSize();
1123         }
1124         m_backgroundLayer->setPosition(backgroundPosition);
1125         m_backgroundLayer->setSize(backgroundSize);
1126         m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
1127     }
1128
1129     if (m_owningLayer.reflectionLayer() && m_owningLayer.reflectionLayer()->isComposited()) {
1130         auto* reflectionBacking = m_owningLayer.reflectionLayer()->backing();
1131         reflectionBacking->updateGeometry();
1132         
1133         // The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
1134         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
1135         FloatRect layerBounds = this->compositedBounds();
1136         FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
1137         reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
1138     }
1139
1140     if (m_scrollingLayer) {
1141         ASSERT(m_scrollingContentsLayer);
1142         auto& renderBox = downcast<RenderBox>(renderer());
1143         LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
1144         ScrollOffset scrollOffset = m_owningLayer.scrollOffset();
1145
1146         // FIXME: need to do some pixel snapping here.
1147         m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - compositedBounds().location()));
1148
1149         m_scrollingLayer->setSize(roundedIntSize(LayoutSize(renderBox.clientWidth(), renderBox.clientHeight())));
1150 #if PLATFORM(IOS)
1151         FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
1152         m_scrollingLayer->setOffsetFromRenderer(FloatPoint() - paddingBox.location());
1153         bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
1154
1155         if (m_owningLayer.isInUserScroll()) {
1156             // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause jitter.
1157             m_scrollingLayer->syncBoundsOrigin(scrollOffset);
1158             m_owningLayer.setRequiresScrollBoundsOriginUpdate(true);
1159         } else {
1160             // Note that we implement the contents offset via the bounds origin on this layer, rather than a position on the sublayer.
1161             m_scrollingLayer->setBoundsOrigin(scrollOffset);
1162             m_owningLayer.setRequiresScrollBoundsOriginUpdate(false);
1163         }
1164         
1165         IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
1166
1167         m_scrollingContentsLayer->setPosition(FloatPoint());
1168         
1169         if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
1170             m_scrollingContentsLayer->setNeedsDisplay();
1171
1172         m_scrollingContentsLayer->setSize(scrollSize);
1173         // Scrolling the content layer does not need to trigger a repaint. The offset will be compensated away during painting.
1174         // FIXME: The paint offset and the scroll offset should really be separate concepts.
1175         LayoutSize scrollingContentsOffset = toLayoutSize(paddingBox.location() - toLayoutSize(scrollOffset));
1176         m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
1177 #else
1178         m_scrollingContentsLayer->setPosition(-scrollOffset);
1179
1180         FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
1181         m_scrollingLayer->setOffsetFromRenderer(-toFloatSize(paddingBox.location()));
1182
1183         if (m_childClippingMaskLayer) {
1184             m_childClippingMaskLayer->setPosition(m_scrollingLayer->position());
1185             m_childClippingMaskLayer->setSize(m_scrollingLayer->size());
1186             m_childClippingMaskLayer->setOffsetFromRenderer(toFloatSize(paddingBox.location()));
1187         }
1188
1189         bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
1190
1191         IntSize scrollSize(m_owningLayer.scrollWidth(), m_owningLayer.scrollHeight());
1192         if (scrollSize != m_scrollingContentsLayer->size() || paddingBoxOffsetChanged)
1193             m_scrollingContentsLayer->setNeedsDisplay();
1194
1195         LayoutSize scrollingContentsOffset = toLayoutSize(paddingBox.location() - toLayoutSize(scrollOffset));
1196         if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size())
1197             compositor().scrollingLayerDidChange(m_owningLayer);
1198
1199         m_scrollingContentsLayer->setSize(scrollSize);
1200         // FIXME: The paint offset and the scroll offset should really be separate concepts.
1201         m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
1202 #endif
1203
1204         if (m_foregroundLayer) {
1205             m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
1206             m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
1207         }
1208     }
1209
1210     // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
1211     LayoutRect ancestorCompositedBounds = compositedAncestor ? compositedAncestor->backing()->compositedBounds() : LayoutRect();
1212     setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compositedAncestor,
1213         LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()), ancestorCompositedBounds));
1214 #if ENABLE(FILTERS_LEVEL_2)
1215     updateBackdropFiltersGeometry();
1216 #endif
1217     updateAfterWidgetResize();
1218
1219     if (subpixelOffsetFromRendererChanged(oldSubpixelOffsetFromRenderer, m_subpixelOffsetFromRenderer, deviceScaleFactor()) && canIssueSetNeedsDisplay())
1220         setContentsNeedDisplay();
1221
1222     compositor().updateScrollCoordinatedStatus(m_owningLayer, { RenderLayerCompositor::ScrollingNodeChangeFlags::Layer, RenderLayerCompositor::ScrollingNodeChangeFlags::LayerGeometry });
1223 }
1224
1225 void RenderLayerBacking::updateAfterDescendants()
1226 {
1227     // FIXME: this potentially duplicates work we did in updateConfiguration().
1228     PaintedContentsInfo contentsInfo(*this);
1229     contentsInfo.setWantsSubpixelAntialiasedTextState(GraphicsLayer::supportsSubpixelAntialiasedLayerText());
1230
1231     if (!m_owningLayer.isRenderViewLayer()) {
1232         bool didUpdateContentsRect = false;
1233         updateDirectlyCompositedBoxDecorations(contentsInfo, didUpdateContentsRect);
1234         if (!didUpdateContentsRect && m_graphicsLayer->usesContentsLayer())
1235             resetContentsRect();
1236     }
1237
1238     updateDrawsContent(contentsInfo);
1239
1240     m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || hasVisibleNonCompositedDescendants());
1241     if (m_scrollingLayer) {
1242         m_scrollingLayer->setContentsVisible(renderer().style().visibility() == VISIBLE);
1243         m_scrollingLayer->setUserInteractionEnabled(renderer().style().pointerEvents() != PE_NONE);
1244     }
1245 }
1246
1247 // FIXME: Avoid repaints when clip path changes.
1248 void RenderLayerBacking::updateMaskingLayerGeometry()
1249 {
1250     m_maskLayer->setSize(m_graphicsLayer->size());
1251     m_maskLayer->setPosition(FloatPoint());
1252     m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
1253     
1254     if (!m_maskLayer->drawsContent()) {
1255         if (renderer().hasClipPath()) {
1256             ASSERT(renderer().style().clipPath()->type() != ClipPathOperation::Reference);
1257
1258             WindRule windRule;
1259             // FIXME: Use correct reference box for inlines: https://bugs.webkit.org/show_bug.cgi?id=129047
1260             LayoutRect boundingBox = m_owningLayer.boundingBox(&m_owningLayer);
1261             LayoutRect referenceBoxForClippedInline = LayoutRect(snapRectToDevicePixels(boundingBox, deviceScaleFactor()));
1262             LayoutSize offset = LayoutSize(snapSizeToDevicePixel(-m_subpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor()));
1263             Path clipPath = m_owningLayer.computeClipPath(offset, referenceBoxForClippedInline, windRule);
1264
1265             FloatSize pathOffset = m_maskLayer->offsetFromRenderer();
1266             if (!pathOffset.isZero())
1267                 clipPath.translate(-pathOffset);
1268             
1269             m_maskLayer->setShapeLayerPath(clipPath);
1270             m_maskLayer->setShapeLayerWindRule(windRule);
1271         }
1272     }
1273 }
1274
1275 void RenderLayerBacking::updateDirectlyCompositedBoxDecorations(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1276 {
1277     if (!m_owningLayer.hasVisibleContent())
1278         return;
1279
1280     // The order of operations here matters, since the last valid type of contents needs
1281     // to also update the contentsRect.
1282     updateDirectlyCompositedBackgroundColor(contentsInfo, didUpdateContentsRect);
1283     updateDirectlyCompositedBackgroundImage(contentsInfo, didUpdateContentsRect);
1284 }
1285
1286 void RenderLayerBacking::updateInternalHierarchy()
1287 {
1288     // m_foregroundLayer has to be inserted in the correct order with child layers,
1289     // so it's not inserted here.
1290     if (m_ancestorClippingLayer)
1291         m_ancestorClippingLayer->removeAllChildren();
1292     
1293     if (m_contentsContainmentLayer) {
1294         m_contentsContainmentLayer->removeAllChildren();
1295         if (m_ancestorClippingLayer)
1296             m_ancestorClippingLayer->addChild(m_contentsContainmentLayer.get());
1297     }
1298     
1299     if (m_backgroundLayer)
1300         m_contentsContainmentLayer->addChild(m_backgroundLayer.get());
1301
1302     if (m_contentsContainmentLayer)
1303         m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
1304     else if (m_ancestorClippingLayer)
1305         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
1306
1307     if (m_childContainmentLayer) {
1308         m_childContainmentLayer->removeFromParent();
1309         m_graphicsLayer->addChild(m_childContainmentLayer.get());
1310     }
1311
1312     if (m_scrollingLayer) {
1313         auto* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
1314         m_scrollingLayer->removeFromParent();
1315         superlayer->addChild(m_scrollingLayer.get());
1316     }
1317
1318     // The clip for child layers does not include space for overflow controls, so they exist as
1319     // siblings of the clipping layer if we have one. Normal children of this layer are set as
1320     // children of the clipping layer.
1321     if (m_layerForHorizontalScrollbar) {
1322         m_layerForHorizontalScrollbar->removeFromParent();
1323         m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
1324     }
1325     if (m_layerForVerticalScrollbar) {
1326         m_layerForVerticalScrollbar->removeFromParent();
1327         m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
1328     }
1329     if (m_layerForScrollCorner) {
1330         m_layerForScrollCorner->removeFromParent();
1331         m_graphicsLayer->addChild(m_layerForScrollCorner.get());
1332     }
1333 }
1334
1335 void RenderLayerBacking::resetContentsRect()
1336 {
1337     m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
1338     
1339     if (is<RenderBox>(renderer())) {
1340         LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
1341         boxRect.move(contentOffsetInCompostingLayer());
1342         FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
1343         m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
1344     }
1345
1346     m_graphicsLayer->setContentsTileSize(IntSize());
1347     m_graphicsLayer->setContentsTilePhase(IntSize());
1348 }
1349
1350 void RenderLayerBacking::updateDrawsContent()
1351 {
1352     PaintedContentsInfo contentsInfo(*this);
1353     contentsInfo.setWantsSubpixelAntialiasedTextState(GraphicsLayer::supportsSubpixelAntialiasedLayerText());
1354
1355     updateDrawsContent(contentsInfo);
1356 }
1357
1358 void RenderLayerBacking::updateDrawsContent(PaintedContentsInfo& contentsInfo)
1359 {
1360     if (m_scrollingLayer) {
1361         // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
1362         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
1363         // m_scrollingLayer never has backing store.
1364         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
1365         bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasVisibleBoxDecorationsOrBackground();
1366         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
1367
1368         bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || contentsInfo.paintsContent());
1369         m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
1370         return;
1371     }
1372
1373     bool hasPaintedContent = containsPaintedContent(contentsInfo);
1374
1375     m_paintsSubpixelAntialiasedText = renderer().settings().subpixelAntialiasedLayerTextEnabled() && contentsInfo.paintsSubpixelAntialiasedText();
1376
1377     // FIXME: we could refine this to only allocate backing for one of these layers if possible.
1378     m_graphicsLayer->setDrawsContent(hasPaintedContent);
1379     if (m_foregroundLayer) {
1380         m_foregroundLayer->setDrawsContent(hasPaintedContent);
1381         m_foregroundLayer->setSupportsSubpixelAntialiasedText(m_paintsSubpixelAntialiasedText);
1382         // The text content is painted into the foreground layer.
1383         // FIXME: this ignores SVG background images which may contain text.
1384         m_graphicsLayer->setSupportsSubpixelAntialiasedText(false);
1385     } else
1386         m_graphicsLayer->setSupportsSubpixelAntialiasedText(m_paintsSubpixelAntialiasedText);
1387
1388     if (m_backgroundLayer)
1389         m_backgroundLayer->setDrawsContent(hasPaintedContent);
1390 }
1391
1392 // Return true if the layer changed.
1393 bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
1394 {
1395     bool layersChanged = false;
1396
1397     if (needsAncestorClip) {
1398         if (!m_ancestorClippingLayer) {
1399             m_ancestorClippingLayer = createGraphicsLayer("ancestor clipping");
1400             m_ancestorClippingLayer->setMasksToBounds(true);
1401             layersChanged = true;
1402         }
1403     } else if (hasAncestorClippingLayer()) {
1404         willDestroyLayer(m_ancestorClippingLayer.get());
1405         m_ancestorClippingLayer->removeFromParent();
1406         m_ancestorClippingLayer = nullptr;
1407         layersChanged = true;
1408     }
1409     
1410     return layersChanged;
1411 }
1412
1413 // Return true if the layer changed.
1414 bool RenderLayerBacking::updateDescendantClippingLayer(bool needsDescendantClip)
1415 {
1416     bool layersChanged = false;
1417
1418     if (needsDescendantClip) {
1419         if (!m_childContainmentLayer && !m_isFrameLayerWithTiledBacking) {
1420             m_childContainmentLayer = createGraphicsLayer("child clipping");
1421             m_childContainmentLayer->setMasksToBounds(true);
1422             layersChanged = true;
1423         }
1424     } else if (hasClippingLayer()) {
1425         willDestroyLayer(m_childContainmentLayer.get());
1426         m_childContainmentLayer->removeFromParent();
1427         m_childContainmentLayer = nullptr;
1428         layersChanged = true;
1429     }
1430     
1431     return layersChanged;
1432 }
1433
1434 void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
1435 {
1436     if (backgroundLayerPaintsFixedRootBackground == m_backgroundLayerPaintsFixedRootBackground)
1437         return;
1438
1439     m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
1440
1441     if (m_backgroundLayerPaintsFixedRootBackground) {
1442         ASSERT(m_isFrameLayerWithTiledBacking);
1443         renderer().view().frameView().removeSlowRepaintObject(*renderer().view().rendererForRootBackground());
1444     }
1445 }
1446
1447 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
1448 {
1449     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1450         return false;
1451     return m_owningLayer.horizontalScrollbar();
1452 }
1453
1454 bool RenderLayerBacking::requiresVerticalScrollbarLayer() const
1455 {
1456     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1457         return false;
1458     return m_owningLayer.verticalScrollbar();
1459 }
1460
1461 bool RenderLayerBacking::requiresScrollCornerLayer() const
1462 {
1463     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
1464         return false;
1465     return !m_owningLayer.scrollCornerAndResizerRect().isEmpty();
1466 }
1467
1468 bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
1469 {
1470     bool horizontalScrollbarLayerChanged = false;
1471     if (needsHorizontalScrollbarLayer) {
1472         if (!m_layerForHorizontalScrollbar) {
1473             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
1474             m_layerForHorizontalScrollbar->setCanDetachBackingStore(false);
1475             horizontalScrollbarLayerChanged = true;
1476         }
1477     } else if (m_layerForHorizontalScrollbar) {
1478         willDestroyLayer(m_layerForHorizontalScrollbar.get());
1479         m_layerForHorizontalScrollbar = nullptr;
1480         horizontalScrollbarLayerChanged = true;
1481     }
1482
1483     bool verticalScrollbarLayerChanged = false;
1484     if (needsVerticalScrollbarLayer) {
1485         if (!m_layerForVerticalScrollbar) {
1486             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
1487             m_layerForVerticalScrollbar->setCanDetachBackingStore(false);
1488             verticalScrollbarLayerChanged = true;
1489         }
1490     } else if (m_layerForVerticalScrollbar) {
1491         willDestroyLayer(m_layerForVerticalScrollbar.get());
1492         m_layerForVerticalScrollbar = nullptr;
1493         verticalScrollbarLayerChanged = true;
1494     }
1495
1496     bool scrollCornerLayerChanged = false;
1497     if (needsScrollCornerLayer) {
1498         if (!m_layerForScrollCorner) {
1499             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
1500             m_layerForScrollCorner->setCanDetachBackingStore(false);
1501             scrollCornerLayerChanged = true;
1502         }
1503     } else if (m_layerForScrollCorner) {
1504         willDestroyLayer(m_layerForScrollCorner.get());
1505         m_layerForScrollCorner = nullptr;
1506         scrollCornerLayerChanged = true;
1507     }
1508
1509     if (auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator()) {
1510         if (horizontalScrollbarLayerChanged)
1511             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, HorizontalScrollbar);
1512         if (verticalScrollbarLayerChanged)
1513             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer, VerticalScrollbar);
1514     }
1515
1516     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
1517 }
1518
1519 void RenderLayerBacking::positionOverflowControlsLayers()
1520 {
1521     if (!m_owningLayer.hasScrollbars())
1522         return;
1523
1524     const IntRect borderBox = snappedIntRect(renderBox()->borderBoxRect());
1525
1526     FloatSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
1527     if (auto* layer = layerForHorizontalScrollbar()) {
1528         IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
1529         layer->setPosition(hBarRect.location() - offsetFromRenderer);
1530         layer->setSize(hBarRect.size());
1531         if (layer->usesContentsLayer()) {
1532             IntRect barRect = IntRect(IntPoint(), hBarRect.size());
1533             layer->setContentsRect(barRect);
1534             layer->setContentsClippingRect(FloatRoundedRect(barRect));
1535         }
1536         layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->usesContentsLayer());
1537     }
1538     
1539     if (auto* layer = layerForVerticalScrollbar()) {
1540         IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
1541         layer->setPosition(vBarRect.location() - offsetFromRenderer);
1542         layer->setSize(vBarRect.size());
1543         if (layer->usesContentsLayer()) {
1544             IntRect barRect = IntRect(IntPoint(), vBarRect.size());
1545             layer->setContentsRect(barRect);
1546             layer->setContentsClippingRect(FloatRoundedRect(barRect));
1547         }
1548         layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->usesContentsLayer());
1549     }
1550
1551     if (auto* layer = layerForScrollCorner()) {
1552         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
1553         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
1554         layer->setSize(scrollCornerAndResizer.size());
1555         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
1556     }
1557 }
1558
1559 bool RenderLayerBacking::hasUnpositionedOverflowControlsLayers() const
1560 {
1561     if (auto* layer = layerForHorizontalScrollbar()) {
1562         if (!layer->drawsContent())
1563             return true;
1564     }
1565
1566     if (auto* layer = layerForVerticalScrollbar()) {
1567         if (!layer->drawsContent())
1568             return true;
1569     }
1570
1571     if (auto* layer = layerForScrollCorner()) {
1572         if (!layer->drawsContent())
1573             return true;
1574     }
1575
1576     return false;
1577 }
1578
1579 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
1580 {
1581     bool layerChanged = false;
1582     if (needsForegroundLayer) {
1583         if (!m_foregroundLayer) {
1584             String layerName = m_owningLayer.name() + " (foreground)";
1585             m_foregroundLayer = createGraphicsLayer(layerName);
1586             m_foregroundLayer->setDrawsContent(true);
1587             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
1588             layerChanged = true;
1589         }
1590     } else if (m_foregroundLayer) {
1591         willDestroyLayer(m_foregroundLayer.get());
1592         m_foregroundLayer->removeFromParent();
1593         m_foregroundLayer = nullptr;
1594         layerChanged = true;
1595     }
1596
1597     if (layerChanged) {
1598         m_graphicsLayer->setNeedsDisplay();
1599         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1600     }
1601
1602     return layerChanged;
1603 }
1604
1605 bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
1606 {
1607     bool layerChanged = false;
1608     if (needsBackgroundLayer) {
1609         if (!m_backgroundLayer) {
1610             String layerName = m_owningLayer.name() + " (background)";
1611             m_backgroundLayer = createGraphicsLayer(layerName);
1612             m_backgroundLayer->setDrawsContent(true);
1613             m_backgroundLayer->setAnchorPoint(FloatPoint3D());
1614             m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
1615             layerChanged = true;
1616         }
1617         
1618         if (!m_contentsContainmentLayer) {
1619             String layerName = m_owningLayer.name() + " (contents containment)";
1620             m_contentsContainmentLayer = createGraphicsLayer(layerName);
1621             m_contentsContainmentLayer->setAppliesPageScale(true);
1622             m_graphicsLayer->setAppliesPageScale(false);
1623             layerChanged = true;
1624         }
1625     } else {
1626         if (m_backgroundLayer) {
1627             willDestroyLayer(m_backgroundLayer.get());
1628             m_backgroundLayer->removeFromParent();
1629             m_backgroundLayer = nullptr;
1630             layerChanged = true;
1631         }
1632         if (m_contentsContainmentLayer) {
1633             willDestroyLayer(m_contentsContainmentLayer.get());
1634             m_contentsContainmentLayer->removeFromParent();
1635             m_contentsContainmentLayer = nullptr;
1636             layerChanged = true;
1637             m_graphicsLayer->setAppliesPageScale(true);
1638         }
1639     }
1640     
1641     if (layerChanged) {
1642         m_graphicsLayer->setNeedsDisplay();
1643         // This assumes that the background layer is only used for fixed backgrounds, which is currently a correct assumption.
1644         compositor().fixedRootBackgroundLayerChanged();
1645     }
1646     
1647     return layerChanged;
1648 }
1649
1650 // Masking layer is used for masks or clip-path.
1651 void RenderLayerBacking::updateMaskingLayer(bool hasMask, bool hasClipPath)
1652 {
1653     bool layerChanged = false;
1654     if (hasMask || hasClipPath) {
1655         GraphicsLayerPaintingPhase maskPhases = 0;
1656         if (hasMask)
1657             maskPhases = GraphicsLayerPaintMask;
1658         
1659         if (hasClipPath) {
1660             // If we have a mask, we need to paint the combined clip-path and mask into the mask layer.
1661             if (hasMask || renderer().style().clipPath()->type() == ClipPathOperation::Reference || !GraphicsLayer::supportsLayerType(GraphicsLayer::Type::Shape))
1662                 maskPhases |= GraphicsLayerPaintClipPath;
1663         }
1664
1665         bool paintsContent = maskPhases;
1666         GraphicsLayer::Type requiredLayerType = paintsContent ? GraphicsLayer::Type::Normal : GraphicsLayer::Type::Shape;
1667         if (m_maskLayer && m_maskLayer->type() != requiredLayerType) {
1668             m_graphicsLayer->setMaskLayer(nullptr);
1669             willDestroyLayer(m_maskLayer.get());
1670             m_maskLayer = nullptr;
1671         }
1672
1673         if (!m_maskLayer) {
1674             m_maskLayer = createGraphicsLayer("mask", requiredLayerType);
1675             m_maskLayer->setDrawsContent(paintsContent);
1676             m_maskLayer->setPaintingPhase(maskPhases);
1677             layerChanged = true;
1678             m_graphicsLayer->setMaskLayer(m_maskLayer.get());
1679         }
1680     } else if (m_maskLayer) {
1681         m_graphicsLayer->setMaskLayer(nullptr);
1682         willDestroyLayer(m_maskLayer.get());
1683         m_maskLayer = nullptr;
1684         layerChanged = true;
1685     }
1686
1687     if (layerChanged)
1688         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1689 }
1690
1691 void RenderLayerBacking::updateChildClippingStrategy(bool needsDescendantsClippingLayer)
1692 {
1693     if (hasClippingLayer() && needsDescendantsClippingLayer) {
1694         if (is<RenderBox>(renderer()) && (renderer().style().clipPath() || renderer().style().hasBorderRadius())) {
1695             // FIXME: we shouldn't get geometry here as layout may not have been udpated.
1696             LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
1697             boxRect.move(contentOffsetInCompostingLayer());
1698             FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
1699             if (clippingLayer()->setMasksToBoundsRect(contentsClippingRect)) {
1700                 if (m_childClippingMaskLayer) 
1701                     m_childClippingMaskLayer = nullptr;
1702                 return;
1703             }
1704
1705             if (!m_childClippingMaskLayer) {
1706                 m_childClippingMaskLayer = createGraphicsLayer("child clipping mask");
1707                 m_childClippingMaskLayer->setDrawsContent(true);
1708                 m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
1709                 clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
1710             }
1711         }
1712     } else {
1713         if (m_childClippingMaskLayer) {
1714             if (hasClippingLayer())
1715                 clippingLayer()->setMaskLayer(nullptr);
1716             m_childClippingMaskLayer = nullptr;
1717         } else 
1718             if (hasClippingLayer())
1719                 clippingLayer()->setMasksToBoundsRect(FloatRoundedRect(FloatRect(FloatPoint(), clippingLayer()->size())));
1720     }
1721 }
1722
1723 bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
1724 {
1725     if (needsScrollingLayers == !!m_scrollingLayer)
1726         return false;
1727
1728     if (!m_scrollingLayer) {
1729         // Outer layer which corresponds with the scroll view.
1730         m_scrollingLayer = createGraphicsLayer("scrolling container", GraphicsLayer::Type::Scrolling);
1731         m_scrollingLayer->setDrawsContent(false);
1732         m_scrollingLayer->setMasksToBounds(true);
1733
1734         // Inner layer which renders the content that scrolls.
1735         m_scrollingContentsLayer = createGraphicsLayer("scrolled Contents");
1736         m_scrollingContentsLayer->setDrawsContent(true);
1737
1738         GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
1739         if (!m_foregroundLayer)
1740             paintPhase |= GraphicsLayerPaintForeground;
1741         m_scrollingContentsLayer->setPaintingPhase(paintPhase);
1742         m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
1743     } else {
1744         compositor().willRemoveScrollingLayerWithBacking(m_owningLayer, *this);
1745
1746         willDestroyLayer(m_scrollingLayer.get());
1747         willDestroyLayer(m_scrollingContentsLayer.get());
1748         m_scrollingLayer = nullptr;
1749         m_scrollingContentsLayer = nullptr;
1750     }
1751
1752     m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
1753     m_graphicsLayer->setNeedsDisplay(); // Because painting phases changed.
1754
1755     if (m_scrollingLayer)
1756         compositor().didAddScrollingLayer(m_owningLayer);
1757     
1758     return true;
1759 }
1760
1761 void RenderLayerBacking::detachFromScrollingCoordinator(LayerScrollCoordinationRoles roles)
1762 {
1763     if (!m_scrollingNodeID && !m_viewportConstrainedNodeID)
1764         return;
1765
1766     auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator();
1767     if (!scrollingCoordinator)
1768         return;
1769
1770     if ((roles & Scrolling) && m_scrollingNodeID) {
1771         LOG(Compositing, "Detaching Scrolling node %" PRIu64, m_scrollingNodeID);
1772         scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
1773         m_scrollingNodeID = 0;
1774     }
1775     
1776     if ((roles & ViewportConstrained) && m_viewportConstrainedNodeID) {
1777         LOG(Compositing, "Detaching ViewportConstrained node %" PRIu64, m_viewportConstrainedNodeID);
1778         scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
1779         m_viewportConstrainedNodeID = 0;
1780     }
1781 }
1782
1783 void RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole(bool viewportCoordinated)
1784 {
1785     m_graphicsLayer->setIsViewportConstrained(viewportCoordinated);
1786 }
1787
1788 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
1789 {
1790     unsigned phase = 0;
1791     if (!m_backgroundLayer)
1792         phase |= GraphicsLayerPaintBackground;
1793     if (!m_foregroundLayer)
1794         phase |= GraphicsLayerPaintForeground;
1795
1796     if (m_scrollingContentsLayer) {
1797         phase &= ~GraphicsLayerPaintForeground;
1798         phase |= GraphicsLayerPaintCompositedScroll;
1799     }
1800
1801     return static_cast<GraphicsLayerPaintingPhase>(phase);
1802 }
1803
1804 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
1805 {
1806     float finalOpacity = rendererOpacity;
1807     
1808     for (auto* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
1809         // We only care about parents that are stacking contexts.
1810         // Recall that opacity creates stacking context.
1811         if (!curr->isStackingContainer())
1812             continue;
1813         
1814         // If we found a compositing layer, we want to compute opacity
1815         // relative to it. So we can break here.
1816         if (curr->isComposited())
1817             break;
1818         
1819         finalOpacity *= curr->renderer().opacity();
1820     }
1821
1822     return finalOpacity;
1823 }
1824
1825 // FIXME: Code is duplicated in RenderLayer. Also, we should probably not consider filters a box decoration here.
1826 static inline bool hasVisibleBoxDecorations(const RenderStyle& style)
1827 {
1828     return style.hasVisibleBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
1829 }
1830
1831 static bool canDirectlyCompositeBackgroundBackgroundImage(const RenderStyle& style)
1832 {
1833     if (!GraphicsLayer::supportsContentsTiling())
1834         return false;
1835
1836     auto& fillLayer = style.backgroundLayers();
1837     if (fillLayer.next())
1838         return false;
1839
1840     if (!fillLayer.imagesAreLoaded())
1841         return false;
1842
1843     if (fillLayer.attachment() != ScrollBackgroundAttachment)
1844         return false;
1845
1846     // FIXME: Allow color+image compositing when it makes sense.
1847     // For now bailing out.
1848     if (style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).isVisible())
1849         return false;
1850
1851     // FIXME: support gradients with isGeneratedImage.
1852     auto* styleImage = fillLayer.image();
1853     if (!styleImage->isCachedImage())
1854         return false;
1855
1856     auto* image = styleImage->cachedImage()->image();
1857     if (!image->isBitmapImage())
1858         return false;
1859
1860     return true;
1861 }
1862
1863 static bool hasPaintedBoxDecorationsOrBackgroundImage(const RenderStyle& style)
1864 {
1865     if (hasVisibleBoxDecorations(style))
1866         return true;
1867
1868     if (!style.hasBackgroundImage())
1869         return false;
1870
1871     return !canDirectlyCompositeBackgroundBackgroundImage(style);
1872 }
1873
1874 static inline bool hasPerspectiveOrPreserves3D(const RenderStyle& style)
1875 {
1876     return style.hasPerspective() || style.preserves3D();
1877 }
1878
1879 Color RenderLayerBacking::rendererBackgroundColor() const
1880 {
1881     RenderElement* backgroundRenderer = nullptr;
1882     if (renderer().isDocumentElementRenderer())
1883         backgroundRenderer = renderer().view().rendererForRootBackground();
1884     
1885     if (!backgroundRenderer)
1886         backgroundRenderer = &renderer();
1887
1888     return backgroundRenderer->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
1889 }
1890
1891 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1892 {
1893     if (!contentsInfo.isSimpleContainer() || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
1894         m_graphicsLayer->setContentsToSolidColor(Color());
1895         return;
1896     }
1897
1898     Color backgroundColor = rendererBackgroundColor();
1899
1900     // An unset (invalid) color will remove the solid color.
1901     m_graphicsLayer->setContentsToSolidColor(backgroundColor);
1902     FloatRect contentsRect = backgroundBoxForSimpleContainerPainting();
1903     m_graphicsLayer->setContentsRect(contentsRect);
1904     m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(contentsRect));
1905     didUpdateContentsRect = true;
1906 }
1907
1908 void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1909 {
1910     if (!GraphicsLayer::supportsContentsTiling())
1911         return;
1912
1913     if (contentsInfo.isDirectlyCompositedImage())
1914         return;
1915
1916     auto& style = renderer().style();
1917     if (!contentsInfo.isSimpleContainer() || !style.hasBackgroundImage()) {
1918         m_graphicsLayer->setContentsToImage(0);
1919         return;
1920     }
1921
1922     auto destRect = backgroundBoxForSimpleContainerPainting();
1923     FloatSize phase;
1924     FloatSize tileSize;
1925     // FIXME: Absolute paint location is required here.
1926     downcast<RenderBox>(renderer()).getGeometryForBackgroundImage(&renderer(), LayoutPoint(), destRect, phase, tileSize);
1927
1928     m_graphicsLayer->setContentsTileSize(tileSize);
1929     m_graphicsLayer->setContentsTilePhase(phase);
1930     m_graphicsLayer->setContentsRect(destRect);
1931     m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(destRect));
1932     m_graphicsLayer->setContentsToImage(style.backgroundLayers().image()->cachedImage()->image());
1933
1934     didUpdateContentsRect = true;
1935 }
1936
1937 void RenderLayerBacking::updateRootLayerConfiguration()
1938 {
1939     if (!m_isFrameLayerWithTiledBacking)
1940         return;
1941
1942     Color backgroundColor;
1943     bool viewIsTransparent = compositor().viewHasTransparentBackground(&backgroundColor);
1944
1945     if (m_backgroundLayerPaintsFixedRootBackground && m_backgroundLayer) {
1946         if (m_isMainFrameRenderViewLayer) {
1947             m_backgroundLayer->setBackgroundColor(backgroundColor);
1948             m_backgroundLayer->setContentsOpaque(!viewIsTransparent);
1949         }
1950
1951         m_graphicsLayer->setBackgroundColor(Color());
1952         m_graphicsLayer->setContentsOpaque(false);
1953     } else if (m_isMainFrameRenderViewLayer) {
1954         m_graphicsLayer->setBackgroundColor(backgroundColor);
1955         m_graphicsLayer->setContentsOpaque(!viewIsTransparent);
1956     }
1957 }
1958
1959 static bool supportsDirectlyCompositedBoxDecorations(const RenderLayerModelObject& renderer)
1960 {
1961     if (!GraphicsLayer::supportsBackgroundColorContent())
1962         return false;
1963
1964     const RenderStyle& style = renderer.style();
1965     if (renderer.hasClip())
1966         return false;
1967
1968     if (hasPaintedBoxDecorationsOrBackgroundImage(style))
1969         return false;
1970
1971     // FIXME: We can't create a directly composited background if this
1972     // layer will have children that intersect with the background layer.
1973     // A better solution might be to introduce a flattening layer if
1974     // we do direct box decoration composition.
1975     // https://bugs.webkit.org/show_bug.cgi?id=119461
1976     if (hasPerspectiveOrPreserves3D(style))
1977         return false;
1978
1979     // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
1980     if (style.backgroundComposite() != CompositeSourceOver)
1981         return false;
1982
1983     return true;
1984 }
1985
1986 bool RenderLayerBacking::paintsBoxDecorations() const
1987 {
1988     if (!m_owningLayer.hasVisibleBoxDecorations())
1989         return false;
1990
1991     return !supportsDirectlyCompositedBoxDecorations(renderer());
1992 }
1993
1994 bool RenderLayerBacking::paintsContent(RenderLayer::PaintedContentRequest& request) const
1995 {
1996     bool paintsContent = false;
1997
1998     if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers(request))
1999         paintsContent = true;
2000
2001     if (request.isSatisfied())
2002         return paintsContent;
2003
2004     if (isPaintDestinationForDescendantLayers(request))
2005         paintsContent = true;
2006
2007     if (request.isSatisfied())
2008         return paintsContent;
2009
2010     if (request.hasPaintedContent == RequestState::Unknown)
2011         request.hasPaintedContent = RequestState::False;
2012
2013     if (request.hasSubpixelAntialiasedText == RequestState::Unknown)
2014         request.hasSubpixelAntialiasedText = RequestState::False;
2015
2016     return paintsContent;
2017 }
2018
2019 static bool isRestartedPlugin(RenderObject& renderer)
2020 {
2021     if (!is<RenderEmbeddedObject>(renderer))
2022         return false;
2023
2024     auto& element = downcast<RenderEmbeddedObject>(renderer).frameOwnerElement();
2025     if (!is<HTMLPlugInElement>(element))
2026         return false;
2027
2028     return downcast<HTMLPlugInElement>(element).isRestartedPlugin();
2029 }
2030
2031 static bool isCompositedPlugin(RenderObject& renderer)
2032 {
2033     return is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
2034 }
2035
2036 // A "simple container layer" is a RenderLayer which has no visible content to render.
2037 // It may have no children, or all its children may be themselves composited.
2038 // This is a useful optimization, because it allows us to avoid allocating backing store.
2039 bool RenderLayerBacking::isSimpleContainerCompositingLayer(PaintedContentsInfo& contentsInfo) const
2040 {
2041     if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
2042         return false;
2043
2044     if (renderer().isTextControl())
2045         return false;
2046
2047     if (contentsInfo.paintsBoxDecorations() || contentsInfo.paintsContent())
2048         return false;
2049
2050     if (renderer().style().backgroundClip() == TextFillBox)
2051         return false;
2052     
2053     if (renderer().isDocumentElementRenderer() && m_owningLayer.isolatesCompositedBlending())
2054         return false;
2055
2056     if (renderer().isRenderView()) {
2057         // Look to see if the root object has a non-simple background
2058         auto* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : nullptr;
2059         if (!rootObject)
2060             return false;
2061         
2062         // Reject anything that has a border, a border-radius or outline,
2063         // or is not a simple background (no background, or solid color).
2064         if (hasPaintedBoxDecorationsOrBackgroundImage(rootObject->style()))
2065             return false;
2066         
2067         // Now look at the body's renderer.
2068         auto* body = renderer().document().body();
2069         if (!body)
2070             return false;
2071         auto* bodyRenderer = body->renderer();
2072         if (!bodyRenderer)
2073             return false;
2074         
2075         if (hasPaintedBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
2076             return false;
2077     }
2078
2079     return true;
2080 }
2081
2082 // Returning true stops the traversal.
2083 enum class LayerTraversal { Continue, Stop };
2084
2085 static LayerTraversal traverseVisibleNonCompositedDescendantLayers(RenderLayer& parent, const WTF::Function<LayerTraversal (const RenderLayer&)>& layerFunc)
2086 {
2087     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
2088     parent.updateLayerListsIfNeeded();
2089
2090 #if !ASSERT_DISABLED
2091     LayerListMutationDetector mutationChecker(&parent);
2092 #endif
2093
2094     if (auto* normalFlowList = parent.normalFlowList()) {
2095         for (auto* childLayer : *normalFlowList) {
2096             if (compositedWithOwnBackingStore(*childLayer))
2097                 continue;
2098
2099             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2100                 return LayerTraversal::Stop;
2101             
2102             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2103                 return LayerTraversal::Stop;
2104         }
2105     }
2106
2107     if (parent.isStackingContainer() && !parent.hasVisibleDescendant())
2108         return LayerTraversal::Continue;
2109
2110     // Use the m_hasCompositingDescendant bit to optimize?
2111     if (auto* negZOrderList = parent.negZOrderList()) {
2112         for (auto* childLayer : *negZOrderList) {
2113             if (compositedWithOwnBackingStore(*childLayer))
2114                 continue;
2115
2116             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2117                 return LayerTraversal::Stop;
2118
2119             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2120                 return LayerTraversal::Stop;
2121         }
2122     }
2123
2124     if (auto* posZOrderList = parent.posZOrderList()) {
2125         for (auto* childLayer : *posZOrderList) {
2126             if (compositedWithOwnBackingStore(*childLayer))
2127                 continue;
2128
2129             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2130                 return LayerTraversal::Stop;
2131
2132             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2133                 return LayerTraversal::Stop;
2134         }
2135     }
2136
2137     return LayerTraversal::Continue;
2138 }
2139
2140 // Conservative test for having no rendered children.
2141 bool RenderLayerBacking::isPaintDestinationForDescendantLayers(RenderLayer::PaintedContentRequest& request) const
2142 {
2143     bool hasPaintingDescendant = false;
2144     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasPaintingDescendant, &request](const RenderLayer& layer) {
2145         hasPaintingDescendant |= layer.isVisuallyNonEmpty(&request);
2146         return (hasPaintingDescendant && request.isSatisfied()) ? LayerTraversal::Stop : LayerTraversal::Continue;
2147     });
2148
2149     return hasPaintingDescendant;
2150 }
2151
2152 bool RenderLayerBacking::hasVisibleNonCompositedDescendants() const
2153 {
2154     bool hasVisibleDescendant = false;
2155     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasVisibleDescendant](const RenderLayer& layer) {
2156         hasVisibleDescendant |= layer.hasVisibleContent();
2157         return hasVisibleDescendant ? LayerTraversal::Stop : LayerTraversal::Continue;
2158     });
2159
2160     return hasVisibleDescendant;
2161 }
2162
2163 bool RenderLayerBacking::containsPaintedContent(PaintedContentsInfo& contentsInfo) const
2164 {
2165     if (contentsInfo.isSimpleContainer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
2166         return false;
2167
2168     if (contentsInfo.isDirectlyCompositedImage())
2169         return false;
2170
2171     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
2172     // and set background color on the layer in that case, instead of allocating backing store and painting.
2173 #if ENABLE(VIDEO)
2174     if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
2175         return m_owningLayer.hasVisibleBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
2176 #endif
2177
2178 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2179     if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
2180         return m_owningLayer.hasVisibleBoxDecorationsOrBackground();
2181 #endif
2182
2183     return true;
2184 }
2185
2186 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
2187 // that require painting. Direct compositing saves backing store.
2188 bool RenderLayerBacking::isDirectlyCompositedImage() const
2189 {
2190     if (!is<RenderImage>(renderer()) || m_owningLayer.hasVisibleBoxDecorationsOrBackground() || m_owningLayer.paintsWithFilters() || renderer().hasClip())
2191         return false;
2192
2193 #if ENABLE(VIDEO)
2194     if (is<RenderMedia>(renderer()))
2195         return false;
2196 #endif
2197
2198     auto& imageRenderer = downcast<RenderImage>(renderer());
2199     if (auto* cachedImage = imageRenderer.cachedImage()) {
2200         if (!cachedImage->hasImage())
2201             return false;
2202
2203         auto* image = cachedImage->imageForRenderer(&imageRenderer);
2204         if (!is<BitmapImage>(image))
2205             return false;
2206
2207         if (downcast<BitmapImage>(*image).orientationForCurrentFrame() != DefaultImageOrientation)
2208             return false;
2209
2210 #if (PLATFORM(GTK) || PLATFORM(WPE))
2211         // GTK and WPE ports don't support rounded rect clipping at TextureMapper level, so they cannot
2212         // directly composite images that have border-radius propery. Draw them as non directly composited
2213         // content instead. See https://bugs.webkit.org/show_bug.cgi?id=174157.
2214         if (imageRenderer.style().hasBorderRadius())
2215             return false;
2216 #endif
2217
2218         return m_graphicsLayer->shouldDirectlyCompositeImage(image);
2219     }
2220
2221     return false;
2222 }
2223
2224 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
2225 {
2226     PaintedContentsInfo contentsInfo(*this);
2227     if ((changeType == ImageChanged) && contentsInfo.isDirectlyCompositedImage()) {
2228         updateImageContents(contentsInfo);
2229         return;
2230     }
2231
2232     if ((changeType == BackgroundImageChanged) && canDirectlyCompositeBackgroundBackgroundImage(renderer().style()))
2233         updateGeometry();
2234
2235     if ((changeType == MaskImageChanged) && m_maskLayer) {
2236         // The composited layer bounds relies on box->maskClipRect(), which changes
2237         // when the mask image becomes available.
2238         updateAfterLayout(UpdateAfterLayoutFlags::IsUpdateRoot);
2239     }
2240
2241 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2242     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
2243         m_graphicsLayer->setContentsNeedsDisplay();
2244         return;
2245     }
2246 #endif
2247 }
2248
2249 void RenderLayerBacking::updateImageContents(PaintedContentsInfo& contentsInfo)
2250 {
2251     auto& imageRenderer = downcast<RenderImage>(renderer());
2252
2253     auto* cachedImage = imageRenderer.cachedImage();
2254     if (!cachedImage)
2255         return;
2256
2257     auto* image = cachedImage->imageForRenderer(&imageRenderer);
2258     if (!image)
2259         return;
2260
2261     // We have to wait until the image is fully loaded before setting it on the layer.
2262     if (!cachedImage->isLoaded())
2263         return;
2264
2265     // This is a no-op if the layer doesn't have an inner layer for the image.
2266     m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
2267
2268     LayoutRect boxRect(LayoutPoint(), imageRenderer.size());
2269     boxRect.move(contentOffsetInCompostingLayer());
2270     FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
2271     m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
2272
2273     m_graphicsLayer->setContentsToImage(image);
2274     
2275     updateDrawsContent(contentsInfo);
2276     
2277     // Image animation is "lazy", in that it automatically stops unless someone is drawing
2278     // the image. So we have to kick the animation each time; this has the downside that the
2279     // image will keep animating, even if its layer is not visible.
2280     image->startAnimation();
2281 }
2282
2283 FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
2284 {
2285     const RenderStyle& style = renderer().style();
2286     float deviceScaleFactor = this->deviceScaleFactor();
2287
2288     FloatPoint3D origin;
2289     origin.setX(roundToDevicePixel(floatValueForLength(style.transformOriginX(), borderBox.width()), deviceScaleFactor));
2290     origin.setY(roundToDevicePixel(floatValueForLength(style.transformOriginY(), borderBox.height()), deviceScaleFactor));
2291     origin.setZ(style.transformOriginZ());
2292
2293     return origin;
2294 }
2295
2296 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
2297 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
2298 {
2299     return LayoutSize(-m_compositedBounds.x() + m_compositedBoundsOffsetFromGraphicsLayer.width(), -m_compositedBounds.y() + m_compositedBoundsOffsetFromGraphicsLayer.height());
2300 }
2301
2302 LayoutRect RenderLayerBacking::contentsBox() const
2303 {
2304     if (!is<RenderBox>(renderer()))
2305         return LayoutRect();
2306
2307     auto& renderBox = downcast<RenderBox>(renderer());
2308     LayoutRect contentsRect;
2309 #if ENABLE(VIDEO)
2310     if (is<RenderVideo>(renderBox))
2311         contentsRect = downcast<RenderVideo>(renderBox).videoBox();
2312     else
2313 #endif
2314     if (is<RenderReplaced>(renderBox)) {
2315         RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
2316         contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
2317     } else
2318         contentsRect = renderBox.contentBoxRect();
2319
2320     contentsRect.move(contentOffsetInCompostingLayer());
2321     return contentsRect;
2322 }
2323
2324 static LayoutRect backgroundRectForBox(const RenderBox& box)
2325 {
2326     switch (box.style().backgroundClip()) {
2327     case BorderFillBox:
2328         return box.borderBoxRect();
2329     case PaddingFillBox:
2330         return box.paddingBoxRect();
2331     case ContentFillBox:
2332         return box.contentBoxRect();
2333     default:
2334         break;
2335     }
2336
2337     ASSERT_NOT_REACHED();
2338     return LayoutRect();
2339 }
2340
2341 FloatRect RenderLayerBacking::backgroundBoxForSimpleContainerPainting() const
2342 {
2343     if (!is<RenderBox>(renderer()))
2344         return FloatRect();
2345
2346     LayoutRect backgroundBox = backgroundRectForBox(downcast<RenderBox>(renderer()));
2347     backgroundBox.move(contentOffsetInCompostingLayer());
2348     return snapRectToDevicePixels(backgroundBox, deviceScaleFactor());
2349 }
2350
2351 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
2352 {
2353     if (m_scrollingContentsLayer)
2354         return m_scrollingContentsLayer.get();
2355
2356     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
2357 }
2358
2359 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
2360 {
2361     if (m_ancestorClippingLayer)
2362         return m_ancestorClippingLayer.get();
2363
2364     if (m_contentsContainmentLayer)
2365         return m_contentsContainmentLayer.get();
2366     
2367     return m_graphicsLayer.get();
2368 }
2369
2370 bool RenderLayerBacking::paintsIntoWindow() const
2371 {
2372 #if USE(COORDINATED_GRAPHICS_THREADED)
2373         return false;
2374 #endif
2375
2376     if (m_isFrameLayerWithTiledBacking)
2377         return false;
2378
2379     if (m_owningLayer.isRenderViewLayer()) {
2380 #if PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
2381         if (compositor().inForcedCompositingMode())
2382             return false;
2383 #endif
2384
2385         return compositor().rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
2386     }
2387     
2388     return false;
2389 }
2390
2391 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
2392 {
2393     if (requiresOwnBacking == m_requiresOwnBackingStore)
2394         return;
2395     
2396     m_requiresOwnBackingStore = requiresOwnBacking;
2397
2398     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
2399     // cached clip rects, so when it changes we have to clear clip rects on descendants.
2400     m_owningLayer.clearClipRectsIncludingDescendants(PaintingClipRects);
2401     m_owningLayer.computeRepaintRectsIncludingDescendants();
2402     
2403     compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
2404 }
2405
2406 void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
2407 {
2408     ASSERT(!paintsIntoCompositedAncestor());
2409
2410     auto& frameView = renderer().view().frameView();
2411     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2412         frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBoxForPainting());
2413     
2414     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2415         // By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
2416         // So if the TiledBacking has a margin that needs to be invalidated, we need to send in a rect to setNeedsDisplayInRect
2417         // that is large enough to include the margin. TiledBacking::bounds() includes the margin.
2418         auto* tiledBacking = this->tiledBacking();
2419         FloatRect rectToRepaint = tiledBacking ? tiledBacking->bounds() : FloatRect(FloatPoint(0, 0), m_graphicsLayer->size());
2420         m_graphicsLayer->setNeedsDisplayInRect(rectToRepaint, shouldClip);
2421     }
2422     
2423     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
2424         m_foregroundLayer->setNeedsDisplay();
2425
2426     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
2427         m_backgroundLayer->setNeedsDisplay();
2428
2429     if (m_maskLayer && m_maskLayer->drawsContent())
2430         m_maskLayer->setNeedsDisplay();
2431
2432     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
2433         m_childClippingMaskLayer->setNeedsDisplay();
2434
2435     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
2436         m_scrollingContentsLayer->setNeedsDisplay();
2437 }
2438
2439 // r is in the coordinate space of the layer's render object
2440 void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
2441 {
2442     ASSERT(!paintsIntoCompositedAncestor());
2443
2444     FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
2445     auto& frameView = renderer().view().frameView();
2446     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2447         frameView.addTrackedRepaintRect(pixelSnappedRectForPainting);
2448
2449     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2450         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2451         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2452         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2453     }
2454
2455     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
2456         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2457         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2458         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2459     }
2460
2461     // FIXME: need to split out repaints for the background.
2462     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
2463         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2464         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2465         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2466     }
2467
2468     if (m_maskLayer && m_maskLayer->drawsContent()) {
2469         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2470         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2471         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2472     }
2473
2474     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
2475         FloatRect layerDirtyRect = r;
2476         layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
2477         m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
2478     }
2479
2480     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
2481         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2482         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2483 #if PLATFORM(IOS)
2484         // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS,
2485         // but the repaint rect is computed without taking the scroll position into account (see shouldApplyClipAndScrollPositionForRepaint()).
2486         layerDirtyRect.moveBy(-m_owningLayer.scrollPosition());
2487 #endif
2488         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2489     }
2490 }
2491
2492 void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext& context,
2493     const IntRect& paintDirtyRect, // In the coords of rootLayer.
2494     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
2495 {
2496     if ((paintsIntoWindow() || paintsIntoCompositedAncestor()) && paintingPhase != GraphicsLayerPaintChildClippingMask) {
2497 #if !PLATFORM(IOS) && !OS(WINDOWS)
2498         // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
2499         // when pages are restored from the PageCache.
2500         // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
2501         ASSERT_NOT_REACHED();
2502 #endif
2503         return;
2504     }
2505
2506     RenderLayer::PaintLayerFlags paintFlags = 0;
2507     if (paintingPhase & GraphicsLayerPaintBackground)
2508         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
2509     if (paintingPhase & GraphicsLayerPaintForeground)
2510         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
2511     if (paintingPhase & GraphicsLayerPaintMask)
2512         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
2513     if (paintingPhase & GraphicsLayerPaintClipPath)
2514         paintFlags |= RenderLayer::PaintLayerPaintingCompositingClipPathPhase;
2515     if (paintingPhase & GraphicsLayerPaintChildClippingMask)
2516         paintFlags |= RenderLayer::PaintLayerPaintingChildClippingMaskPhase;
2517     if (paintingPhase & GraphicsLayerPaintOverflowContents)
2518         paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
2519     if (paintingPhase & GraphicsLayerPaintCompositedScroll)
2520         paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
2521
2522     if (graphicsLayer == m_backgroundLayer.get())
2523         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
2524     else if (compositor().fixedRootBackgroundLayer())
2525         paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
2526
2527 #ifndef NDEBUG
2528     RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
2529 #endif
2530
2531     FrameView::PaintingState paintingState;
2532     if (m_owningLayer.isRenderViewLayer())
2533         renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
2534
2535     // FIXME: GraphicsLayers need a way to split for RenderFragmentContainers.
2536     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
2537     m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
2538
2539     if (m_owningLayer.containsDirtyOverlayScrollbars())
2540         m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
2541
2542     if (m_owningLayer.isRenderViewLayer())
2543         renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
2544
2545     compositor().didPaintBacking(this);
2546
2547     ASSERT(!m_owningLayer.m_usedTransparency);
2548 }
2549
2550 // Up-call from compositing layer drawing callback.
2551 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const FloatRect& clip, GraphicsLayerPaintBehavior layerPaintBehavior)
2552 {
2553 #ifndef NDEBUG
2554     renderer().page().setIsPainting(true);
2555 #endif
2556
2557     // The dirtyRect is in the coords of the painting root.
2558     FloatRect adjustedClipRect = clip;
2559     adjustedClipRect.move(m_subpixelOffsetFromRenderer);
2560     IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
2561
2562     if (!graphicsLayer->repaintCount())
2563         layerPaintBehavior |= GraphicsLayerPaintFirstTilePaint;
2564
2565     if (graphicsLayer == m_graphicsLayer.get()
2566         || graphicsLayer == m_foregroundLayer.get()
2567         || graphicsLayer == m_backgroundLayer.get()
2568         || graphicsLayer == m_maskLayer.get()
2569         || graphicsLayer == m_childClippingMaskLayer.get()
2570         || graphicsLayer == m_scrollingContentsLayer.get()) {
2571         InspectorInstrumentation::willPaint(renderer());
2572
2573         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
2574             dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
2575
2576         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
2577         PaintBehavior behavior = PaintBehaviorNormal;
2578         if (layerPaintBehavior == GraphicsLayerPaintSnapshotting)
2579             behavior |= PaintBehaviorSnapshotting;
2580         
2581         if (layerPaintBehavior == GraphicsLayerPaintFirstTilePaint)
2582             behavior |= PaintBehaviorTileFirstPaint;
2583
2584         paintIntoLayer(graphicsLayer, context, dirtyRect, behavior, paintingPhase);
2585
2586         InspectorInstrumentation::didPaint(renderer(), dirtyRect);
2587     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
2588         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
2589     } else if (graphicsLayer == layerForVerticalScrollbar()) {
2590         paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
2591     } else if (graphicsLayer == layerForScrollCorner()) {
2592         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
2593         context.save();
2594         context.translate(-scrollCornerAndResizer.location());
2595         LayoutRect transformedClip = LayoutRect(clip);
2596         transformedClip.moveBy(scrollCornerAndResizer.location());
2597         m_owningLayer.paintScrollCorner(context, IntPoint(), snappedIntRect(transformedClip));
2598         m_owningLayer.paintResizer(context, IntPoint(), transformedClip);
2599         context.restore();
2600     }
2601 #ifndef NDEBUG
2602     renderer().page().setIsPainting(false);
2603 #endif
2604 }
2605
2606 float RenderLayerBacking::pageScaleFactor() const
2607 {
2608     return compositor().pageScaleFactor();
2609 }
2610
2611 float RenderLayerBacking::zoomedOutPageScaleFactor() const
2612 {
2613     return compositor().zoomedOutPageScaleFactor();
2614 }
2615
2616 float RenderLayerBacking::deviceScaleFactor() const
2617 {
2618     return compositor().deviceScaleFactor();
2619 }
2620
2621 float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer* layer) const
2622 {
2623     return compositor().contentsScaleMultiplierForNewTiles(layer);
2624 }
2625
2626 bool RenderLayerBacking::paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const
2627 {
2628     return m_isMainFrameRenderViewLayer;
2629 }
2630
2631 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
2632 {
2633     compositor().didFlushChangesForLayer(m_owningLayer, layer);
2634 }
2635
2636 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
2637 {
2638     auto* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
2639     if (graphicsLayer != transformedLayer)
2640         return false;
2641
2642     if (m_owningLayer.hasTransform()) {
2643         transform = m_owningLayer.currentTransform(RenderStyle::ExcludeTransformOrigin);
2644         return true;
2645     }
2646     return false;
2647 }
2648
2649 bool RenderLayerBacking::isTrackingRepaints() const
2650 {
2651     return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
2652 }
2653
2654 bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer, LayerTreeAsTextBehavior behavior) const
2655 {
2656     if (behavior & LayerTreeAsTextDebug)
2657         return false;
2658
2659     // Skip the root tile cache's flattening layer.
2660     return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
2661 }
2662
2663 bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer, const char* propertyName) const
2664 {
2665     // For backwards compatibility with WebKit1 and other platforms,
2666     // skip some properties on the root tile cache.
2667     if (m_isMainFrameRenderViewLayer && layer == m_graphicsLayer.get()) {
2668         if (!strcmp(propertyName, "drawsContent"))
2669             return false;
2670
2671         // Background color could be of interest to tests or other dumpers if it's non-white.
2672         if (!strcmp(propertyName, "backgroundColor") && layer->backgroundColor() == Color::white)
2673             return false;
2674
2675         // The root tile cache's repaints will show up at the top with FrameView's,
2676         // so don't dump them twice.
2677         if (!strcmp(propertyName, "repaintRects"))
2678             return false;
2679     }
2680
2681     return true;
2682 }
2683
2684 bool RenderLayerBacking::shouldAggressivelyRetainTiles(const GraphicsLayer*) const
2685 {
2686     // Only the main frame TileController has enough information about in-window state to
2687     // correctly implement aggressive tile retention.
2688     if (!m_isMainFrameRenderViewLayer)
2689         return false;
2690
2691     return renderer().settings().aggressiveTileRetentionEnabled();
2692 }
2693
2694 bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const
2695 {
2696     return renderer().settings().temporaryTileCohortRetentionEnabled();
2697 }
2698
2699 bool RenderLayerBacking::useGiantTiles() const
2700 {
2701     return renderer().settings().useGiantTiles();
2702 }
2703
2704 void RenderLayerBacking::logFilledVisibleFreshTile(unsigned blankPixelCount)
2705 {
2706     if (auto* loggingClient = renderer().page().performanceLoggingClient())
2707         loggingClient->logScrollingEvent(PerformanceLoggingClient::ScrollingEvent::FilledTile, MonotonicTime::now(), blankPixelCount);
2708 }
2709
2710 #ifndef NDEBUG
2711 void RenderLayerBacking::verifyNotPainting()
2712 {
2713     ASSERT(!renderer().page().isPainting());
2714 }
2715 #endif
2716
2717 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
2718 {
2719     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
2720     bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyTransform);
2721     bool hasFilter = keyframes.containsProperty(CSSPropertyFilter);
2722
2723     bool hasBackdropFilter = false;
2724 #if ENABLE(FILTERS_LEVEL_2)
2725     hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
2726 #endif
2727
2728     if (!hasOpacity && !hasTransform && !hasFilter && !hasBackdropFilter)
2729         return false;
2730
2731     KeyframeValueList transformVector(AnimatedPropertyTransform);
2732     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2733     KeyframeValueList filterVector(AnimatedPropertyFilter);
2734 #if ENABLE(FILTERS_LEVEL_2)
2735     KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2736 #endif
2737
2738     size_t numKeyframes = keyframes.size();
2739     for (size_t i = 0; i < numKeyframes; ++i) {
2740         const KeyframeValue& currentKeyframe = keyframes[i];
2741         const RenderStyle* keyframeStyle = currentKeyframe.style();
2742         double key = currentKeyframe.key();
2743
2744         if (!keyframeStyle)
2745             continue;
2746             
2747         auto* tf = currentKeyframe.timingFunction();
2748         
2749         bool isFirstOrLastKeyframe = key == 0 || key == 1;
2750         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyTransform))
2751             transformVector.insert(std::make_unique<TransformAnimationValue>(key, keyframeStyle->transform(), tf));
2752
2753         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
2754             opacityVector.insert(std::make_unique<FloatAnimationValue>(key, keyframeStyle->opacity(), tf));
2755
2756         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyFilter))
2757             filterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->filter(), tf));
2758
2759 #if ENABLE(FILTERS_LEVEL_2)
2760         if ((hasBackdropFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
2761             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->backdropFilter(), tf));
2762 #endif
2763     }
2764
2765     if (!renderer().settings().acceleratedCompositedAnimationsEnabled())
2766         return false;
2767
2768     bool didAnimate = false;
2769
2770     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset))
2771         didAnimate = true;
2772
2773     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2774         didAnimate = true;
2775
2776     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2777         didAnimate = true;
2778
2779 #if ENABLE(FILTERS_LEVEL_2)
2780     if (hasBackdropFilter && m_graphicsLayer->addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2781         didAnimate = true;
2782 #endif
2783
2784     return didAnimate;
2785 }
2786
2787 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2788 {
2789     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2790 }
2791
2792 void RenderLayerBacking::animationSeeked(double timeOffset, const String& animationName)
2793 {
2794     m_graphicsLayer->seekAnimation(animationName, timeOffset);
2795 }
2796
2797 void RenderLayerBacking::animationFinished(const String& animationName)
2798 {
2799     m_graphicsLayer->removeAnimation(animationName);
2800 }
2801
2802 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2803 {
2804     bool didAnimate = false;
2805
2806     ASSERT(property != CSSPropertyInvalid);
2807
2808     if (property == CSSPropertyOpacity) {
2809         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2810         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
2811             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2812             opacityVector.insert(std::make_unique<FloatAnimationValue>(0, compositingOpacity(fromStyle->opacity())));
2813             opacityVector.insert(std::make_unique<FloatAnimationValue>(1, compositingOpacity(toStyle->opacity())));
2814             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
2815             if (m_graphicsLayer->addAnimation(opacityVector, FloatSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
2816                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2817                 updateOpacity(*toStyle);
2818                 didAnimate = true;
2819             }
2820         }
2821     }
2822
2823     if (property == CSSPropertyTransform && m_owningLayer.hasTransform()) {
2824         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyTransform);
2825         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
2826             KeyframeValueList transformVector(AnimatedPropertyTransform);
2827             transformVector.insert(std::make_unique<TransformAnimationValue>(0, fromStyle->transform()));
2828             transformVector.insert(std::make_unique<TransformAnimationValue>(1, toStyle->transform()));
2829             if (m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyTransform), timeOffset)) {
2830                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2831                 updateTransform(*toStyle);
2832                 didAnimate = true;
2833             }
2834         }
2835     }
2836
2837     if (property == CSSPropertyFilter && m_owningLayer.hasFilter()) {
2838         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyFilter);
2839         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2840             KeyframeValueList filterVector(AnimatedPropertyFilter);
2841             filterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->filter()));
2842             filterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->filter()));
2843             if (m_graphicsLayer->addAnimation(filterVector, FloatSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyFilter), timeOffset)) {
2844                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2845                 updateFilters(*toStyle);
2846                 didAnimate = true;
2847             }
2848         }
2849     }
2850
2851 #if ENABLE(FILTERS_LEVEL_2)
2852     if (property == CSSPropertyWebkitBackdropFilter && m_owningLayer.hasBackdropFilter()) {
2853         const Animation* backdropFilterAnim = toStyle->transitionForProperty(CSSPropertyWebkitBackdropFilter);
2854         if (backdropFilterAnim && !backdropFilterAnim->isEmptyOrZeroDuration()) {
2855             KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2856             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->backdropFilter()));
2857             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->backdropFilter()));
2858             if (m_graphicsLayer->addAnimation(backdropFilterVector, FloatSize(), backdropFilterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitBackdropFilter), timeOffset)) {
2859                 // To ensure that the correct backdrop filter is visible when the animation ends, also set the final backdrop filter.
2860                 updateBackdropFilters(*toStyle);
2861                 didAnimate = true;
2862             }
2863         }
2864     }
2865 #endif
2866
2867     return didAnimate;
2868 }
2869
2870 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
2871 {
2872     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2873     if (animatedProperty != AnimatedPropertyInvalid)
2874         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2875 }
2876
2877 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
2878 {
2879     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2880     if (animatedProperty != AnimatedPropertyInvalid)
2881         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2882 }
2883
2884 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, MonotonicTime time)
2885 {
2886     renderer().animation().notifyAnimationStarted(renderer(), time);
2887 }
2888
2889 void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
2890 {
2891     if (renderer().renderTreeBeingDestroyed())
2892         return;
2893     compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
2894 }
2895
2896 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2897 {
2898     compositor().notifyFlushBeforeDisplayRefresh(layer);
2899 }
2900
2901 // This is used for the 'freeze' API, for testing only.
2902 void RenderLayerBacking::suspendAnimations(MonotonicTime time)
2903 {
2904     m_graphicsLayer->suspendAnimations(time);
2905 }
2906
2907 void RenderLayerBacking::resumeAnimations()
2908 {
2909     m_graphicsLayer->resumeAnimations();
2910 }
2911
2912 LayoutRect RenderLayerBacking::compositedBounds() const
2913 {
2914     return m_compositedBounds;
2915 }
2916
2917 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
2918 {
2919     m_compositedBounds = bounds;
2920 }
2921
2922 LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
2923 {
2924     auto* tiledBacking = this->tiledBacking();
2925     if (!tiledBacking || !tiledBacking->hasMargins())
2926         return compositedBounds();
2927
2928     LayoutRect boundsIncludingMargin = compositedBounds();
2929     LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
2930     LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
2931
2932     boundsIncludingMargin.moveBy(LayoutPoint(-leftMarginWidth, -topMarginHeight));
2933     boundsIncludingMargin.expand(leftMarginWidth + tiledBacking->rightMarginWidth(), topMarginHeight + tiledBacking->bottomMarginHeight());
2934
2935     return boundsIncludingMargin;
2936 }
2937
2938 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
2939 {
2940     CSSPropertyID cssProperty = CSSPropertyInvalid;
2941     switch (property) {
2942     case AnimatedPropertyTransform:
2943         cssProperty = CSSPropertyTransform;
2944         break;
2945     case AnimatedPropertyOpacity:
2946         cssProperty = CSSPropertyOpacity;
2947         break;
2948     case AnimatedPropertyBackgroundColor:
2949         cssProperty = CSSPropertyBackgroundColor;
2950         break;
2951     case AnimatedPropertyFilter:
2952         cssProperty = CSSPropertyFilter;
2953         break;
2954 #if ENABLE(FILTERS_LEVEL_2)
2955     case AnimatedPropertyWebkitBackdropFilter:
2956         cssProperty = CSSPropertyWebkitBackdropFilter;
2957         break;
2958 #endif
2959     case AnimatedPropertyInvalid:
2960         ASSERT_NOT_REACHED();
2961     }
2962     return cssProperty;
2963 }
2964
2965 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
2966 {
2967     switch (cssProperty) {
2968     case CSSPropertyTransform:
2969         return AnimatedPropertyTransform;
2970     case CSSPropertyOpacity:
2971         return AnimatedPropertyOpacity;
2972     case CSSPropertyBackgroundColor:
2973         return AnimatedPropertyBackgroundColor;
2974     case CSSPropertyFilter:
2975         return AnimatedPropertyFilter;
2976 #if ENABLE(FILTERS_LEVEL_2)
2977     case CSSPropertyWebkitBackdropFilter:
2978         return AnimatedPropertyWebkitBackdropFilter;
2979 #endif
2980     default:
2981         // It's fine if we see other css properties here; they are just not accelerated.
2982         break;
2983     }
2984     return AnimatedPropertyInvalid;
2985 }
2986
2987 CompositingLayerType RenderLayerBacking::compositingLayerType() const
2988 {
2989     if (m_graphicsLayer->usesContentsLayer())
2990         return MediaCompositingLayer;
2991
2992     if (m_graphicsLayer->drawsContent())
2993         return m_graphicsLayer->tiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
2994     
2995     return ContainerCompositingLayer;
2996 }
2997
2998 double RenderLayerBacking::backingStoreMemoryEstimate() const
2999 {
3000     double backingMemory;
3001     
3002     // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
3003     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
3004     if (m_foregroundLayer)
3005         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
3006     if (m_backgroundLayer)
3007         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
3008     if (m_maskLayer)
3009         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
3010     if (m_childClippingMaskLayer)
3011         backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
3012
3013     if (m_scrollingContentsLayer)
3014         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
3015
3016     if (m_layerForHorizontalScrollbar)
3017         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
3018
3019     if (m_layerForVerticalScrollbar)
3020         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
3021
3022     if (m_layerForScrollCorner)
3023         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
3024     
3025     return backingMemory;
3026 }
3027
3028 TextStream& operator<<(TextStream& ts, const RenderLayerBacking& backing)
3029 {
3030     ts << "RenderLayerBacking " << &backing << " bounds " << backing.compositedBounds();
3031
3032     if (backing.isFrameLayerWithTiledBacking())
3033         ts << " frame layer tiled backing";
3034     if (backing.paintsIntoWindow())
3035         ts << " paintsIntoWindow";
3036     if (backing.paintsIntoCompositedAncestor())
3037         ts << " paintsIntoCompositedAncestor";
3038
3039     ts << " primary layer ID " << backing.graphicsLayer()->primaryLayerID();
3040     if (auto nodeID = backing.scrollingNodeIDForRole(ViewportConstrained))
3041         ts << " viewport constrained scrolling node " << nodeID;
3042     if (auto nodeID = backing.scrollingNodeIDForRole(Scrolling))
3043         ts << " scrolling node " << nodeID;
3044     return ts;
3045 }
3046
3047 } // namespace WebCore