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