13c423de4246df7a3acc1fda9550c7c00384a5cc
[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 "Logging.h"
48 #include "MainFrame.h"
49 #include "Page.h"
50 #include "PluginViewBase.h"
51 #include "ProgressTracker.h"
52 #include "RenderFlowThread.h"
53 #include "RenderHTMLCanvas.h"
54 #include "RenderIFrame.h"
55 #include "RenderImage.h"
56 #include "RenderLayerCompositor.h"
57 #include "RenderEmbeddedObject.h"
58 #include "RenderMedia.h"
59 #include "RenderNamedFlowFragment.h"
60 #include "RenderRegion.h"
61 #include "RenderVideo.h"
62 #include "RenderView.h"
63 #include "ScrollingCoordinator.h"
64 #include "Settings.h"
65 #include "StyleResolver.h"
66 #include "TiledBacking.h"
67
68 #if PLATFORM(IOS)
69 #include "RuntimeApplicationChecks.h"
70 #endif
71
72 namespace WebCore {
73
74 using namespace HTMLNames;
75
76 CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject& renderer)
77 {
78     ASSERT(renderer.isCanvas());
79     
80     const HTMLCanvasElement* canvas = downcast<HTMLCanvasElement>(renderer.node());
81     CanvasRenderingContext* context = canvas->renderingContext();
82     if (!context || !context->isAccelerated())
83         return UnacceleratedCanvas;
84     
85     if (context->isGPUBased())
86         return CanvasAsLayerContents;
87
88 #if ENABLE(ACCELERATED_2D_CANVAS)
89     return CanvasAsLayerContents;
90 #else
91     return CanvasPaintedToLayer; // On Mac and iOS we paint accelerated canvases into their layers.
92 #endif
93 }
94
95 // This acts as a cache of what we know about what is painting into this RenderLayerBacking.
96 class PaintedContentsInfo {
97 public:
98     enum class ContentsTypeDetermination {
99         Unknown,
100         SimpleContainer,
101         DirectlyCompositedImage,
102         Painted
103     };
104
105     PaintedContentsInfo(RenderLayerBacking& inBacking)
106         : m_backing(inBacking)
107     {
108     }
109     
110     void setWantsSubpixelAntialiasedTextState(bool wantsSubpixelAntialiasedTextState)
111     {
112         m_subpixelAntialiasedText = wantsSubpixelAntialiasedTextState ? RequestState::Unknown : RequestState::DontCare;
113     }
114
115     RequestState paintsBoxDecorationsDetermination();
116     bool paintsBoxDecorations()
117     {
118         RequestState state = paintsBoxDecorationsDetermination();
119         return state == RequestState::True || state == RequestState::Undetermined;
120     }
121
122     RequestState paintsContentDetermination();
123     bool paintsContent()
124     {
125         RequestState state = paintsContentDetermination();
126         return state == RequestState::True || state == RequestState::Undetermined;
127     }
128
129     RequestState paintsSubpixelAntialiasedTextDetermination();
130     bool paintsSubpixelAntialiasedText()
131     {
132         RequestState state = paintsSubpixelAntialiasedTextDetermination();
133         return state == RequestState::True || state == RequestState::Undetermined;
134     }
135
136     ContentsTypeDetermination contentsTypeDetermination();
137     bool isSimpleContainer()
138     {
139         return contentsTypeDetermination() == ContentsTypeDetermination::SimpleContainer;
140     }
141
142     bool isDirectlyCompositedImage()
143     {
144         return contentsTypeDetermination() == ContentsTypeDetermination::DirectlyCompositedImage;
145     }
146
147     RenderLayerBacking& m_backing;
148     RequestState m_boxDecorations { RequestState::Unknown };
149     RequestState m_content { RequestState::Unknown };
150     RequestState m_subpixelAntialiasedText { RequestState::DontCare };
151
152     ContentsTypeDetermination m_contentsType { ContentsTypeDetermination::Unknown };
153 };
154
155 RequestState PaintedContentsInfo::paintsBoxDecorationsDetermination()
156 {
157     if (m_boxDecorations != RequestState::Unknown)
158         return m_boxDecorations;
159
160     m_boxDecorations = m_backing.paintsBoxDecorations() ? RequestState::True : RequestState::False;
161     return m_boxDecorations;
162 }
163
164 RequestState PaintedContentsInfo::paintsContentDetermination()
165 {
166     if (m_content != RequestState::Unknown && m_subpixelAntialiasedText != RequestState::Unknown)
167         return m_content;
168
169     RenderLayer::PaintedContentRequest contentRequest;
170     if (m_subpixelAntialiasedText == RequestState::Unknown)
171         contentRequest.hasSubpixelAntialiasedText = RequestState::Unknown;
172
173     m_content = m_backing.paintsContent(contentRequest) ? RequestState::True : RequestState::False;
174
175     if (m_subpixelAntialiasedText == RequestState::Unknown)
176         m_subpixelAntialiasedText = contentRequest.hasSubpixelAntialiasedText;
177
178     return m_content;
179 }
180
181 RequestState PaintedContentsInfo::paintsSubpixelAntialiasedTextDetermination()
182 {
183     if (m_subpixelAntialiasedText != RequestState::Unknown)
184         return m_subpixelAntialiasedText;
185
186     paintsContentDetermination();
187
188     return m_subpixelAntialiasedText;
189 }
190
191 PaintedContentsInfo::ContentsTypeDetermination PaintedContentsInfo::contentsTypeDetermination()
192 {
193     if (m_contentsType != ContentsTypeDetermination::Unknown)
194         return m_contentsType;
195
196     if (m_backing.isSimpleContainerCompositingLayer(*this))
197         m_contentsType = ContentsTypeDetermination::SimpleContainer;
198     else if (m_backing.isDirectlyCompositedImage())
199         m_contentsType = ContentsTypeDetermination::DirectlyCompositedImage;
200     else
201         m_contentsType = ContentsTypeDetermination::Painted;
202
203     return m_contentsType;
204 }
205
206
207 RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
208     : m_owningLayer(layer)
209 {
210     if (layer.isRootLayer()) {
211         m_isMainFrameRenderViewLayer = renderer().frame().isMainFrame();
212         m_isMainFrameLayerWithTiledBacking = renderer().page().chrome().client().shouldUseTiledBackingForFrameView(renderer().view().frameView());
213     }
214     
215     createPrimaryGraphicsLayer();
216
217     if (TiledBacking* tiledBacking = this->tiledBacking()) {
218         tiledBacking->setIsInWindow(renderer().page().isInWindow());
219
220         if (m_isMainFrameLayerWithTiledBacking) {
221             tiledBacking->setScrollingPerformanceLoggingEnabled(renderer().settings().scrollingPerformanceLoggingEnabled());
222             adjustTiledBackingCoverage();
223         }
224     }
225 }
226
227 RenderLayerBacking::~RenderLayerBacking()
228 {
229     updateAncestorClippingLayer(false);
230     updateChildClippingStrategy(false);
231     updateDescendantClippingLayer(false);
232     updateOverflowControlsLayers(false, false, false);
233     updateForegroundLayer(false);
234     updateBackgroundLayer(false);
235     updateMaskingLayer(false, false);
236     updateScrollingLayers(false);
237     detachFromScrollingCoordinator(Scrolling | ViewportConstrained);
238     destroyGraphicsLayers();
239 }
240
241 void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
242 {
243     if (layer && layer->type() == GraphicsLayer::Type::Normal && layer->tiledBacking())
244         compositor().layerTiledBackingUsageChanged(layer, false);
245 }
246
247 std::unique_ptr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name, GraphicsLayer::Type layerType)
248 {
249     auto* graphicsLayerFactory = renderer().page().chrome().client().graphicsLayerFactory();
250
251     std::unique_ptr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, *this, layerType);
252
253     graphicsLayer->setName(name);
254
255 #if PLATFORM(COCOA) && USE(CA)
256     graphicsLayer->setAcceleratesDrawing(compositor().acceleratedDrawingEnabled());
257     graphicsLayer->setUsesDisplayListDrawing(compositor().displayListDrawingEnabled());
258 #endif
259     
260     return graphicsLayer;
261 }
262
263 void RenderLayerBacking::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
264 {
265     // Note that this only affects the primary layer.
266     if (usesDisplayListDrawing == m_graphicsLayer->usesDisplayListDrawing())
267         return;
268
269     m_graphicsLayer->setUsesDisplayListDrawing(usesDisplayListDrawing);
270     if (m_graphicsLayer->drawsContent())
271         m_graphicsLayer->setNeedsDisplay();
272 }
273
274 String RenderLayerBacking::displayListAsText(DisplayList::AsTextFlags flags) const
275 {
276     return m_graphicsLayer->displayListAsText(flags);
277 }
278
279 void RenderLayerBacking::setIsTrackingDisplayListReplay(bool isTrackingReplay)
280 {
281     m_graphicsLayer->setIsTrackingDisplayListReplay(isTrackingReplay);
282 }
283
284 String RenderLayerBacking::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
285 {
286     return m_graphicsLayer->replayDisplayListAsText(flags);
287 }
288
289 void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
290 {
291     compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
292 }
293
294 TiledBacking* RenderLayerBacking::tiledBacking() const
295 {
296     return m_graphicsLayer->tiledBacking();
297 }
298
299 static TiledBacking::TileCoverage computePageTiledBackingCoverage(RenderLayerBacking* backing)
300 {
301     // FIXME: When we use TiledBacking for overflow, this should look at RenderView scrollability.
302     FrameView& frameView = backing->owningLayer().renderer().view().frameView();
303
304     // If the page is non-visible, don't incur the cost of keeping extra tiles for scrolling.
305     if (!backing->owningLayer().page().isVisible())
306         return TiledBacking::CoverageForVisibleArea;
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         LOG(Compositing, "Detaching Scrolling node %" PRIu64, m_scrollingNodeID);
1785         scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
1786         m_scrollingNodeID = 0;
1787     }
1788     
1789     if ((roles & ViewportConstrained) && m_viewportConstrainedNodeID) {
1790         LOG(Compositing, "Detaching ViewportConstrained node %" PRIu64, m_viewportConstrainedNodeID);
1791         scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
1792         m_viewportConstrainedNodeID = 0;
1793     }
1794 }
1795
1796 void RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole(bool viewportCoordinated)
1797 {
1798     m_graphicsLayer->setIsViewportConstrained(viewportCoordinated);
1799 }
1800
1801 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
1802 {
1803     unsigned phase = 0;
1804     if (!m_backgroundLayer)
1805         phase |= GraphicsLayerPaintBackground;
1806     if (!m_foregroundLayer)
1807         phase |= GraphicsLayerPaintForeground;
1808
1809     if (m_scrollingContentsLayer) {
1810         phase &= ~GraphicsLayerPaintForeground;
1811         phase |= GraphicsLayerPaintCompositedScroll;
1812     }
1813
1814     return static_cast<GraphicsLayerPaintingPhase>(phase);
1815 }
1816
1817 float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
1818 {
1819     float finalOpacity = rendererOpacity;
1820     
1821     for (RenderLayer* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
1822         // We only care about parents that are stacking contexts.
1823         // Recall that opacity creates stacking context.
1824         if (!curr->isStackingContainer())
1825             continue;
1826         
1827         // If we found a compositing layer, we want to compute opacity
1828         // relative to it. So we can break here.
1829         if (curr->isComposited())
1830             break;
1831         
1832         finalOpacity *= curr->renderer().opacity();
1833     }
1834
1835     return finalOpacity;
1836 }
1837
1838 // FIXME: Code is duplicated in RenderLayer. Also, we should probably not consider filters a box decoration here.
1839 static inline bool hasVisibleBoxDecorations(const RenderStyle& style)
1840 {
1841     return style.hasVisibleBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
1842 }
1843
1844 static bool canDirectlyCompositeBackgroundBackgroundImage(const RenderStyle& style)
1845 {
1846     if (!GraphicsLayer::supportsContentsTiling())
1847         return false;
1848
1849     auto& fillLayer = style.backgroundLayers();
1850     if (fillLayer.next())
1851         return false;
1852
1853     if (!fillLayer.imagesAreLoaded())
1854         return false;
1855
1856     if (fillLayer.attachment() != ScrollBackgroundAttachment)
1857         return false;
1858
1859     // FIXME: Allow color+image compositing when it makes sense.
1860     // For now bailing out.
1861     if (style.visitedDependentColor(CSSPropertyBackgroundColor).isVisible())
1862         return false;
1863
1864     // FIXME: support gradients with isGeneratedImage.
1865     auto* styleImage = fillLayer.image();
1866     if (!styleImage->isCachedImage())
1867         return false;
1868
1869     auto* image = styleImage->cachedImage()->image();
1870     if (!image->isBitmapImage())
1871         return false;
1872
1873     return true;
1874 }
1875
1876 static bool hasPaintedBoxDecorationsOrBackgroundImage(const RenderStyle& style)
1877 {
1878     if (hasVisibleBoxDecorations(style))
1879         return true;
1880
1881     if (!style.hasBackgroundImage())
1882         return false;
1883
1884     return !canDirectlyCompositeBackgroundBackgroundImage(style);
1885 }
1886
1887 static inline bool hasPerspectiveOrPreserves3D(const RenderStyle& style)
1888 {
1889     return style.hasPerspective() || style.preserves3D();
1890 }
1891
1892 Color RenderLayerBacking::rendererBackgroundColor() const
1893 {
1894     RenderElement* backgroundRenderer = nullptr;
1895     if (renderer().isDocumentElementRenderer())
1896         backgroundRenderer = renderer().view().rendererForRootBackground();
1897     
1898     if (!backgroundRenderer)
1899         backgroundRenderer = &renderer();
1900
1901     return backgroundRenderer->style().visitedDependentColor(CSSPropertyBackgroundColor);
1902 }
1903
1904 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1905 {
1906     if (!contentsInfo.isSimpleContainer() || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
1907         m_graphicsLayer->setContentsToSolidColor(Color());
1908         return;
1909     }
1910
1911     Color backgroundColor = rendererBackgroundColor();
1912
1913     // An unset (invalid) color will remove the solid color.
1914     m_graphicsLayer->setContentsToSolidColor(backgroundColor);
1915     FloatRect contentsRect = backgroundBoxForSimpleContainerPainting();
1916     m_graphicsLayer->setContentsRect(contentsRect);
1917     m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(contentsRect));
1918     didUpdateContentsRect = true;
1919 }
1920
1921 void RenderLayerBacking::updateDirectlyCompositedBackgroundImage(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
1922 {
1923     if (!GraphicsLayer::supportsContentsTiling())
1924         return;
1925
1926     if (contentsInfo.isDirectlyCompositedImage())
1927         return;
1928
1929     auto& style = renderer().style();
1930     if (!contentsInfo.isSimpleContainer() || !style.hasBackgroundImage()) {
1931         m_graphicsLayer->setContentsToImage(0);
1932         return;
1933     }
1934
1935     auto destRect = backgroundBoxForSimpleContainerPainting();
1936     FloatSize phase;
1937     FloatSize tileSize;
1938     // FIXME: Absolute paint location is required here.
1939     downcast<RenderBox>(renderer()).getGeometryForBackgroundImage(&renderer(), LayoutPoint(), destRect, phase, tileSize);
1940
1941     m_graphicsLayer->setContentsTileSize(tileSize);
1942     m_graphicsLayer->setContentsTilePhase(phase);
1943     m_graphicsLayer->setContentsRect(destRect);
1944     m_graphicsLayer->setContentsClippingRect(FloatRoundedRect(destRect));
1945     m_graphicsLayer->setContentsToImage(style.backgroundLayers().image()->cachedImage()->image());
1946
1947     didUpdateContentsRect = true;
1948 }
1949
1950 void RenderLayerBacking::updateRootLayerConfiguration()
1951 {
1952     if (!m_isMainFrameLayerWithTiledBacking)
1953         return;
1954
1955     Color backgroundColor;
1956     bool viewIsTransparent = compositor().viewHasTransparentBackground(&backgroundColor);
1957
1958     if (m_backgroundLayerPaintsFixedRootBackground && m_backgroundLayer) {
1959         m_backgroundLayer->setBackgroundColor(backgroundColor);
1960         m_backgroundLayer->setContentsOpaque(!viewIsTransparent);
1961
1962         m_graphicsLayer->setBackgroundColor(Color());
1963         m_graphicsLayer->setContentsOpaque(false);
1964     } else {
1965         m_graphicsLayer->setBackgroundColor(backgroundColor);
1966         m_graphicsLayer->setContentsOpaque(!viewIsTransparent);
1967     }
1968 }
1969
1970 static bool supportsDirectlyCompositedBoxDecorations(const RenderLayerModelObject& renderer)
1971 {
1972     if (!GraphicsLayer::supportsBackgroundColorContent())
1973         return false;
1974
1975     const RenderStyle& style = renderer.style();
1976     if (renderer.hasClip())
1977         return false;
1978
1979     if (hasPaintedBoxDecorationsOrBackgroundImage(style))
1980         return false;
1981
1982     // FIXME: We can't create a directly composited background if this
1983     // layer will have children that intersect with the background layer.
1984     // A better solution might be to introduce a flattening layer if
1985     // we do direct box decoration composition.
1986     // https://bugs.webkit.org/show_bug.cgi?id=119461
1987     if (hasPerspectiveOrPreserves3D(style))
1988         return false;
1989
1990     // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
1991     if (style.backgroundComposite() != CompositeSourceOver)
1992         return false;
1993
1994     return true;
1995 }
1996
1997 bool RenderLayerBacking::paintsBoxDecorations() const
1998 {
1999     if (!m_owningLayer.hasVisibleBoxDecorations())
2000         return false;
2001
2002     return !supportsDirectlyCompositedBoxDecorations(renderer());
2003 }
2004
2005 bool RenderLayerBacking::paintsContent(RenderLayer::PaintedContentRequest& request) const
2006 {
2007     bool paintsContent = false;
2008
2009     if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers(request))
2010         paintsContent = true;
2011
2012     if (request.isSatisfied())
2013         return paintsContent;
2014
2015     if (isPaintDestinationForDescendantLayers(request))
2016         paintsContent = true;
2017
2018     if (request.isSatisfied())
2019         return paintsContent;
2020
2021     if (request.hasPaintedContent == RequestState::Unknown)
2022         request.hasPaintedContent = RequestState::False;
2023
2024     if (request.hasSubpixelAntialiasedText == RequestState::Unknown)
2025         request.hasSubpixelAntialiasedText = RequestState::False;
2026
2027     return paintsContent;
2028 }
2029
2030 static bool isRestartedPlugin(RenderObject& renderer)
2031 {
2032     if (!is<RenderEmbeddedObject>(renderer))
2033         return false;
2034
2035     HTMLFrameOwnerElement& element = downcast<RenderEmbeddedObject>(renderer).frameOwnerElement();
2036     if (!is<HTMLPlugInElement>(element))
2037         return false;
2038
2039     return downcast<HTMLPlugInElement>(element).isRestartedPlugin();
2040 }
2041
2042 static bool isCompositedPlugin(RenderObject& renderer)
2043 {
2044     return is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
2045 }
2046
2047 // A "simple container layer" is a RenderLayer which has no visible content to render.
2048 // It may have no children, or all its children may be themselves composited.
2049 // This is a useful optimization, because it allows us to avoid allocating backing store.
2050 bool RenderLayerBacking::isSimpleContainerCompositingLayer(PaintedContentsInfo& contentsInfo) const
2051 {
2052     if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
2053         return false;
2054
2055     if (renderer().isTextControl())
2056         return false;
2057
2058     if (contentsInfo.paintsBoxDecorations() || contentsInfo.paintsContent())
2059         return false;
2060
2061     if (renderer().style().backgroundClip() == TextFillBox)
2062         return false;
2063     
2064     if (renderer().isRenderNamedFlowFragmentContainer())
2065         return false;
2066
2067     if (renderer().isDocumentElementRenderer() && m_owningLayer.isolatesCompositedBlending())
2068         return false;
2069
2070     if (renderer().isRenderView()) {
2071         // Look to see if the root object has a non-simple background
2072         auto* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : nullptr;
2073         if (!rootObject)
2074             return false;
2075         
2076         // Reject anything that has a border, a border-radius or outline,
2077         // or is not a simple background (no background, or solid color).
2078         if (hasPaintedBoxDecorationsOrBackgroundImage(rootObject->style()))
2079             return false;
2080         
2081         // Now look at the body's renderer.
2082         auto* body = renderer().document().body();
2083         if (!body)
2084             return false;
2085         auto* bodyRenderer = body->renderer();
2086         if (!bodyRenderer)
2087             return false;
2088         
2089         if (hasPaintedBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
2090             return false;
2091     }
2092
2093     return true;
2094 }
2095
2096 // Returning true stops the traversal.
2097 enum class LayerTraversal { Continue, Stop };
2098
2099 static LayerTraversal traverseVisibleNonCompositedDescendantLayers(RenderLayer& parent, std::function<LayerTraversal (const RenderLayer&)> layerFunc)
2100 {
2101     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
2102     parent.updateLayerListsIfNeeded();
2103
2104 #if !ASSERT_DISABLED
2105     LayerListMutationDetector mutationChecker(&parent);
2106 #endif
2107
2108     if (auto* normalFlowList = parent.normalFlowList()) {
2109         for (auto* childLayer : *normalFlowList) {
2110             if (compositedWithOwnBackingStore(*childLayer))
2111                 continue;
2112
2113             if (layerFunc(*childLayer) == LayerTraversal::Stop)
2114                 return LayerTraversal::Stop;
2115             
2116             if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2117                 return LayerTraversal::Stop;
2118         }
2119     }
2120
2121     if (parent.isStackingContainer()) {
2122         if (!parent.hasVisibleDescendant())
2123             return LayerTraversal::Continue;
2124
2125         // Use the m_hasCompositingDescendant bit to optimize?
2126         if (auto* negZOrderList = parent.negZOrderList()) {
2127             for (auto* childLayer : *negZOrderList) {
2128                 if (compositedWithOwnBackingStore(*childLayer))
2129                     continue;
2130
2131                 if (layerFunc(*childLayer) == LayerTraversal::Stop)
2132                     return LayerTraversal::Stop;
2133
2134                 if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2135                     return LayerTraversal::Stop;
2136             }
2137         }
2138
2139         if (auto* posZOrderList = parent.posZOrderList()) {
2140             for (auto* childLayer : *posZOrderList) {
2141                 if (compositedWithOwnBackingStore(*childLayer))
2142                     continue;
2143
2144                 if (layerFunc(*childLayer) == LayerTraversal::Stop)
2145                     return LayerTraversal::Stop;
2146
2147                 if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
2148                     return LayerTraversal::Stop;
2149             }
2150         }
2151     }
2152
2153     return LayerTraversal::Continue;
2154 }
2155
2156 // Conservative test for having no rendered children.
2157 bool RenderLayerBacking::isPaintDestinationForDescendantLayers(RenderLayer::PaintedContentRequest& request) const
2158 {
2159     bool hasPaintingDescendant = false;
2160     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasPaintingDescendant, &request](const RenderLayer& layer) {
2161         hasPaintingDescendant |= layer.isVisuallyNonEmpty(&request);
2162         return (hasPaintingDescendant && request.isSatisfied()) ? LayerTraversal::Stop : LayerTraversal::Continue;
2163     });
2164
2165     return hasPaintingDescendant;
2166 }
2167
2168 bool RenderLayerBacking::hasVisibleNonCompositedDescendants() const
2169 {
2170     bool hasVisibleDescendant = false;
2171     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasVisibleDescendant](const RenderLayer& layer) {
2172         hasVisibleDescendant |= layer.hasVisibleContent();
2173         return hasVisibleDescendant ? LayerTraversal::Stop : LayerTraversal::Continue;
2174     });
2175
2176     return hasVisibleDescendant;
2177 }
2178
2179 bool RenderLayerBacking::containsPaintedContent(PaintedContentsInfo& contentsInfo) const
2180 {
2181     if (contentsInfo.isSimpleContainer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
2182         return false;
2183
2184     if (contentsInfo.isDirectlyCompositedImage())
2185         return false;
2186
2187     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
2188     // and set background color on the layer in that case, instead of allocating backing store and painting.
2189 #if ENABLE(VIDEO)
2190     if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
2191         return m_owningLayer.hasVisibleBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
2192 #endif
2193
2194 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2195     if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
2196         return m_owningLayer.hasVisibleBoxDecorationsOrBackground();
2197 #endif
2198
2199     return true;
2200 }
2201
2202 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
2203 // that require painting. Direct compositing saves backing store.
2204 bool RenderLayerBacking::isDirectlyCompositedImage() const
2205 {
2206     if (!is<RenderImage>(renderer()) || m_owningLayer.hasVisibleBoxDecorationsOrBackground() || m_owningLayer.paintsWithFilters() || renderer().hasClip())
2207         return false;
2208
2209 #if ENABLE(VIDEO)
2210     if (is<RenderMedia>(renderer()))
2211         return false;
2212 #endif
2213
2214     auto& imageRenderer = downcast<RenderImage>(renderer());
2215     if (CachedImage* cachedImage = imageRenderer.cachedImage()) {
2216         if (!cachedImage->hasImage())
2217             return false;
2218
2219         Image* image = cachedImage->imageForRenderer(&imageRenderer);
2220         if (!image->isBitmapImage())
2221             return false;
2222
2223         if (image->orientationForCurrentFrame() != DefaultImageOrientation)
2224             return false;
2225
2226         return m_graphicsLayer->shouldDirectlyCompositeImage(image);
2227     }
2228
2229     return false;
2230 }
2231
2232 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
2233 {
2234     PaintedContentsInfo contentsInfo(*this);
2235     if ((changeType == ImageChanged) && contentsInfo.isDirectlyCompositedImage()) {
2236         updateImageContents(contentsInfo);
2237         return;
2238     }
2239
2240     if ((changeType == BackgroundImageChanged) && canDirectlyCompositeBackgroundBackgroundImage(renderer().style()))
2241         updateGeometry();
2242
2243     if ((changeType == MaskImageChanged) && m_maskLayer) {
2244         // The composited layer bounds relies on box->maskClipRect(), which changes
2245         // when the mask image becomes available.
2246         updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
2247     }
2248
2249 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2250     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
2251         m_graphicsLayer->setContentsNeedsDisplay();
2252         return;
2253     }
2254 #endif
2255 }
2256
2257 void RenderLayerBacking::updateImageContents(PaintedContentsInfo& contentsInfo)
2258 {
2259     auto& imageRenderer = downcast<RenderImage>(renderer());
2260
2261     CachedImage* cachedImage = imageRenderer.cachedImage();
2262     if (!cachedImage)
2263         return;
2264
2265     Image* image = cachedImage->imageForRenderer(&imageRenderer);
2266     if (!image)
2267         return;
2268
2269     // We have to wait until the image is fully loaded before setting it on the layer.
2270     if (!cachedImage->isLoaded())
2271         return;
2272
2273     // This is a no-op if the layer doesn't have an inner layer for the image.
2274     m_graphicsLayer->setContentsRect(snapRectToDevicePixels(contentsBox(), deviceScaleFactor()));
2275
2276     LayoutRect boxRect(LayoutPoint(), imageRenderer.size());
2277     boxRect.move(contentOffsetInCompostingLayer());
2278     FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
2279     m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
2280
2281     m_graphicsLayer->setContentsToImage(image);
2282     
2283     updateDrawsContent(contentsInfo);
2284     
2285     // Image animation is "lazy", in that it automatically stops unless someone is drawing
2286     // the image. So we have to kick the animation each time; this has the downside that the
2287     // image will keep animating, even if its layer is not visible.
2288     image->startAnimation();
2289 }
2290
2291 FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
2292 {
2293     const RenderStyle& style = renderer().style();
2294     float deviceScaleFactor = this->deviceScaleFactor();
2295
2296     FloatPoint3D origin;
2297     origin.setX(roundToDevicePixel(floatValueForLength(style.transformOriginX(), borderBox.width()), deviceScaleFactor));
2298     origin.setY(roundToDevicePixel(floatValueForLength(style.transformOriginY(), borderBox.height()), deviceScaleFactor));
2299     origin.setZ(style.transformOriginZ());
2300
2301     return origin;
2302 }
2303
2304 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
2305 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
2306 {
2307     return LayoutSize(-m_compositedBounds.x() + m_compositedBoundsOffsetFromGraphicsLayer.width(), -m_compositedBounds.y() + m_compositedBoundsOffsetFromGraphicsLayer.height());
2308 }
2309
2310 LayoutRect RenderLayerBacking::contentsBox() const
2311 {
2312     if (!is<RenderBox>(renderer()))
2313         return LayoutRect();
2314
2315     auto& renderBox = downcast<RenderBox>(renderer());
2316     LayoutRect contentsRect;
2317 #if ENABLE(VIDEO)
2318     if (is<RenderVideo>(renderBox))
2319         contentsRect = downcast<RenderVideo>(renderBox).videoBox();
2320     else
2321 #endif
2322     if (is<RenderReplaced>(renderBox)) {
2323         RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
2324         contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
2325     } else
2326         contentsRect = renderBox.contentBoxRect();
2327
2328     contentsRect.move(contentOffsetInCompostingLayer());
2329     return contentsRect;
2330 }
2331
2332 static LayoutRect backgroundRectForBox(const RenderBox& box)
2333 {
2334     switch (box.style().backgroundClip()) {
2335     case BorderFillBox:
2336         return box.borderBoxRect();
2337     case PaddingFillBox:
2338         return box.paddingBoxRect();
2339     case ContentFillBox:
2340         return box.contentBoxRect();
2341     default:
2342         break;
2343     }
2344
2345     ASSERT_NOT_REACHED();
2346     return LayoutRect();
2347 }
2348
2349 FloatRect RenderLayerBacking::backgroundBoxForSimpleContainerPainting() const
2350 {
2351     if (!is<RenderBox>(renderer()))
2352         return FloatRect();
2353
2354     LayoutRect backgroundBox = backgroundRectForBox(downcast<RenderBox>(renderer()));
2355     backgroundBox.move(contentOffsetInCompostingLayer());
2356     return snapRectToDevicePixels(backgroundBox, deviceScaleFactor());
2357 }
2358
2359 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
2360 {
2361     if (m_scrollingContentsLayer)
2362         return m_scrollingContentsLayer.get();
2363
2364     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
2365 }
2366
2367 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
2368 {
2369     if (m_ancestorClippingLayer)
2370         return m_ancestorClippingLayer.get();
2371
2372     if (m_contentsContainmentLayer)
2373         return m_contentsContainmentLayer.get();
2374     
2375     return m_graphicsLayer.get();
2376 }
2377
2378 bool RenderLayerBacking::paintsIntoWindow() const
2379 {
2380 #if USE(COORDINATED_GRAPHICS_THREADED)
2381         return false;
2382 #endif
2383
2384     if (m_isMainFrameLayerWithTiledBacking)
2385         return false;
2386
2387     if (m_owningLayer.isRootLayer()) {
2388 #if PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
2389         if (compositor().inForcedCompositingMode())
2390             return false;
2391 #endif
2392
2393         return compositor().rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
2394     }
2395     
2396     return false;
2397 }
2398
2399 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
2400 {
2401     if (requiresOwnBacking == m_requiresOwnBackingStore)
2402         return;
2403     
2404     m_requiresOwnBackingStore = requiresOwnBacking;
2405
2406     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
2407     // cached clip rects, so when it changes we have to clear clip rects on descendants.
2408     m_owningLayer.clearClipRectsIncludingDescendants(PaintingClipRects);
2409     m_owningLayer.computeRepaintRectsIncludingDescendants();
2410     
2411     compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
2412 }
2413
2414 void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
2415 {
2416     ASSERT(!paintsIntoCompositedAncestor());
2417
2418     FrameView& frameView = owningLayer().renderer().view().frameView();
2419     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2420         frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBoxForPainting());
2421     
2422     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2423         // By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
2424         // So if the TiledBacking has a margin that needs to be invalidated, we need to send in a rect to setNeedsDisplayInRect
2425         // that is large enough to include the margin. TiledBacking::bounds() includes the margin.
2426         TiledBacking* tiledBacking = this->tiledBacking();
2427         FloatRect rectToRepaint = tiledBacking ? tiledBacking->bounds() : FloatRect(FloatPoint(0, 0), m_graphicsLayer->size());
2428         m_graphicsLayer->setNeedsDisplayInRect(rectToRepaint, shouldClip);
2429     }
2430     
2431     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
2432         m_foregroundLayer->setNeedsDisplay();
2433
2434     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
2435         m_backgroundLayer->setNeedsDisplay();
2436
2437     if (m_maskLayer && m_maskLayer->drawsContent())
2438         m_maskLayer->setNeedsDisplay();
2439
2440     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
2441         m_childClippingMaskLayer->setNeedsDisplay();
2442
2443     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
2444         m_scrollingContentsLayer->setNeedsDisplay();
2445 }
2446
2447 // r is in the coordinate space of the layer's render object
2448 void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
2449 {
2450     ASSERT(!paintsIntoCompositedAncestor());
2451
2452     FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
2453     FrameView& frameView = owningLayer().renderer().view().frameView();
2454     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2455         frameView.addTrackedRepaintRect(pixelSnappedRectForPainting);
2456
2457     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2458         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2459         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2460         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2461     }
2462
2463     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
2464         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2465         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2466         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2467     }
2468
2469     // FIXME: need to split out repaints for the background.
2470     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
2471         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2472         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2473         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2474     }
2475
2476     if (m_maskLayer && m_maskLayer->drawsContent()) {
2477         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2478         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2479         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2480     }
2481
2482     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
2483         FloatRect layerDirtyRect = r;
2484         layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
2485         m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
2486     }
2487
2488     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
2489         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2490         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
2491 #if PLATFORM(IOS)
2492         // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS,
2493         // but the repaint rect is computed without taking the scroll position into account (see shouldApplyClipAndScrollPositionForRepaint()).
2494         layerDirtyRect.moveBy(-m_owningLayer.scrollPosition());
2495 #endif
2496         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2497     }
2498 }
2499
2500 void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext& context,
2501     const IntRect& paintDirtyRect, // In the coords of rootLayer.
2502     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
2503 {
2504     if ((paintsIntoWindow() || paintsIntoCompositedAncestor()) && paintingPhase != GraphicsLayerPaintChildClippingMask) {
2505 #if !PLATFORM(IOS) && !OS(WINDOWS)
2506         // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
2507         // when pages are restored from the PageCache.
2508         // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
2509         ASSERT_NOT_REACHED();
2510 #endif
2511         return;
2512     }
2513
2514     RenderLayer::PaintLayerFlags paintFlags = 0;
2515     if (paintingPhase & GraphicsLayerPaintBackground)
2516         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
2517     if (paintingPhase & GraphicsLayerPaintForeground)
2518         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
2519     if (paintingPhase & GraphicsLayerPaintMask)
2520         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
2521     if (paintingPhase & GraphicsLayerPaintClipPath)
2522         paintFlags |= RenderLayer::PaintLayerPaintingCompositingClipPathPhase;
2523     if (paintingPhase & GraphicsLayerPaintChildClippingMask)
2524         paintFlags |= RenderLayer::PaintLayerPaintingChildClippingMaskPhase;
2525     if (paintingPhase & GraphicsLayerPaintOverflowContents)
2526         paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
2527     if (paintingPhase & GraphicsLayerPaintCompositedScroll)
2528         paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
2529
2530     if (graphicsLayer == m_backgroundLayer.get())
2531         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
2532     else if (compositor().fixedRootBackgroundLayer())
2533         paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
2534
2535 #ifndef NDEBUG
2536     RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
2537 #endif
2538
2539     FrameView::PaintingState paintingState;
2540     if (m_owningLayer.isRootLayer())
2541         renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
2542
2543     // FIXME: GraphicsLayers need a way to split for RenderRegions.
2544     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
2545     m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
2546
2547     if (m_owningLayer.containsDirtyOverlayScrollbars())
2548         m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
2549
2550     if (m_owningLayer.isRootLayer())
2551         renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
2552
2553     compositor().didPaintBacking(this);
2554
2555     ASSERT(!m_owningLayer.m_usedTransparency);
2556 }
2557
2558 // Up-call from compositing layer drawing callback.
2559 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const FloatRect& clip)
2560 {
2561 #ifndef NDEBUG
2562     renderer().page().setIsPainting(true);
2563 #endif
2564
2565     // The dirtyRect is in the coords of the painting root.
2566     FloatRect adjustedClipRect = clip;
2567     adjustedClipRect.move(m_subpixelOffsetFromRenderer);
2568     IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
2569
2570     if (graphicsLayer == m_graphicsLayer.get()
2571         || graphicsLayer == m_foregroundLayer.get()
2572         || graphicsLayer == m_backgroundLayer.get()
2573         || graphicsLayer == m_maskLayer.get()
2574         || graphicsLayer == m_childClippingMaskLayer.get()
2575         || graphicsLayer == m_scrollingContentsLayer.get()) {
2576         InspectorInstrumentation::willPaint(renderer());
2577
2578         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
2579             dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
2580
2581         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
2582         paintIntoLayer(graphicsLayer, context, dirtyRect, PaintBehaviorNormal, paintingPhase);
2583
2584         InspectorInstrumentation::didPaint(renderer(), dirtyRect);
2585     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
2586         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
2587     } else if (graphicsLayer == layerForVerticalScrollbar()) {
2588         paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
2589     } else if (graphicsLayer == layerForScrollCorner()) {
2590         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
2591         context.save();
2592         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
2593         LayoutRect transformedClip = LayoutRect(clip);
2594         transformedClip.moveBy(scrollCornerAndResizer.location());
2595         m_owningLayer.paintScrollCorner(context, IntPoint(), snappedIntRect(transformedClip));
2596         m_owningLayer.paintResizer(context, IntPoint(), transformedClip);
2597         context.restore();
2598     }
2599 #ifndef NDEBUG
2600     renderer().page().setIsPainting(false);
2601 #endif
2602 }
2603
2604 float RenderLayerBacking::pageScaleFactor() const
2605 {
2606     return compositor().pageScaleFactor();
2607 }
2608
2609 float RenderLayerBacking::zoomedOutPageScaleFactor() const
2610 {
2611     return compositor().zoomedOutPageScaleFactor();
2612 }
2613
2614 float RenderLayerBacking::deviceScaleFactor() const
2615 {
2616     return compositor().deviceScaleFactor();
2617 }
2618
2619 float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer* layer) const
2620 {
2621     return compositor().contentsScaleMultiplierForNewTiles(layer);
2622 }
2623
2624 bool RenderLayerBacking::paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const
2625 {
2626     return m_isMainFrameRenderViewLayer;
2627 }
2628
2629 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
2630 {
2631     compositor().didFlushChangesForLayer(m_owningLayer, layer);
2632 }
2633
2634 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
2635 {
2636     GraphicsLayer* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
2637     if (graphicsLayer != transformedLayer)
2638         return false;
2639
2640     if (m_owningLayer.hasTransform()) {
2641         transform = m_owningLayer.currentTransform(RenderStyle::ExcludeTransformOrigin);
2642         return true;
2643     }
2644     return false;
2645 }
2646
2647 bool RenderLayerBacking::isTrackingRepaints() const
2648 {
2649     return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
2650 }
2651
2652 bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer, LayerTreeAsTextBehavior behavior) const
2653 {
2654     if (behavior & LayerTreeAsTextDebug)
2655         return false;
2656
2657     // Skip the root tile cache's flattening layer.
2658     return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
2659 }
2660
2661 bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer, const char* propertyName) const
2662 {
2663     // For backwards compatibility with WebKit1 and other platforms,
2664     // skip some properties on the root tile cache.
2665     if (m_isMainFrameRenderViewLayer && layer == m_graphicsLayer.get()) {
2666         if (!strcmp(propertyName, "drawsContent"))
2667             return false;
2668
2669         // Background color could be of interest to tests or other dumpers if it's non-white.
2670         if (!strcmp(propertyName, "backgroundColor") && layer->backgroundColor() == Color::white)
2671             return false;
2672
2673         // The root tile cache's repaints will show up at the top with FrameView's,
2674         // so don't dump them twice.
2675         if (!strcmp(propertyName, "repaintRects"))
2676             return false;
2677     }
2678
2679     return true;
2680 }
2681
2682 bool RenderLayerBacking::shouldAggressivelyRetainTiles(const GraphicsLayer*) const
2683 {
2684     // Only the main frame TileController has enough information about in-window state to
2685     // correctly implement aggressive tile retention.
2686     if (!m_isMainFrameRenderViewLayer)
2687         return false;
2688
2689     return renderer().settings().aggressiveTileRetentionEnabled();
2690 }
2691
2692 bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const
2693 {
2694     return renderer().settings().temporaryTileCohortRetentionEnabled();
2695 }
2696
2697 bool RenderLayerBacking::useGiantTiles() const
2698 {
2699     return renderer().settings().useGiantTiles();
2700 }
2701
2702 #ifndef NDEBUG
2703 void RenderLayerBacking::verifyNotPainting()
2704 {
2705     ASSERT(!renderer().page().isPainting());
2706 }
2707 #endif
2708
2709 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
2710 {
2711     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
2712     bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyTransform);
2713     bool hasFilter = keyframes.containsProperty(CSSPropertyFilter);
2714
2715     bool hasBackdropFilter = false;
2716 #if ENABLE(FILTERS_LEVEL_2)
2717     hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
2718 #endif
2719
2720     if (!hasOpacity && !hasTransform && !hasFilter && !hasBackdropFilter)
2721         return false;
2722
2723     KeyframeValueList transformVector(AnimatedPropertyTransform);
2724     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2725     KeyframeValueList filterVector(AnimatedPropertyFilter);
2726 #if ENABLE(FILTERS_LEVEL_2)
2727     KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2728 #endif
2729
2730     size_t numKeyframes = keyframes.size();
2731     for (size_t i = 0; i < numKeyframes; ++i) {
2732         const KeyframeValue& currentKeyframe = keyframes[i];
2733         const RenderStyle* keyframeStyle = currentKeyframe.style();
2734         double key = currentKeyframe.key();
2735
2736         if (!keyframeStyle)
2737             continue;
2738             
2739         TimingFunction* tf = currentKeyframe.timingFunction(keyframes.animationName());
2740         
2741         bool isFirstOrLastKeyframe = key == 0 || key == 1;
2742         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyTransform))
2743             transformVector.insert(std::make_unique<TransformAnimationValue>(key, keyframeStyle->transform(), tf));
2744
2745         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
2746             opacityVector.insert(std::make_unique<FloatAnimationValue>(key, keyframeStyle->opacity(), tf));
2747
2748         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyFilter))
2749             filterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->filter(), tf));
2750
2751 #if ENABLE(FILTERS_LEVEL_2)
2752         if ((hasBackdropFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
2753             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->backdropFilter(), tf));
2754 #endif
2755     }
2756
2757     if (!renderer().settings().acceleratedCompositedAnimationsEnabled())
2758         return false;
2759
2760     bool didAnimate = false;
2761
2762     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset))
2763         didAnimate = true;
2764
2765     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2766         didAnimate = true;
2767
2768     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2769         didAnimate = true;
2770
2771 #if ENABLE(FILTERS_LEVEL_2)
2772     if (hasBackdropFilter && m_graphicsLayer->addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2773         didAnimate = true;
2774 #endif
2775
2776     return didAnimate;
2777 }
2778
2779 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2780 {
2781     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2782 }
2783
2784 void RenderLayerBacking::animationFinished(const String& animationName)
2785 {
2786     m_graphicsLayer->removeAnimation(animationName);
2787 }
2788
2789 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2790 {
2791     bool didAnimate = false;
2792
2793     ASSERT(property != CSSPropertyInvalid);
2794
2795     if (property == CSSPropertyOpacity) {
2796         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2797         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
2798             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2799             opacityVector.insert(std::make_unique<FloatAnimationValue>(0, compositingOpacity(fromStyle->opacity())));
2800             opacityVector.insert(std::make_unique<FloatAnimationValue>(1, compositingOpacity(toStyle->opacity())));
2801             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
2802             if (m_graphicsLayer->addAnimation(opacityVector, FloatSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
2803                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2804                 updateOpacity(*toStyle);
2805                 didAnimate = true;
2806             }
2807         }
2808     }
2809
2810     if (property == CSSPropertyTransform && m_owningLayer.hasTransform()) {
2811         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyTransform);
2812         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
2813             KeyframeValueList transformVector(AnimatedPropertyTransform);
2814             transformVector.insert(std::make_unique<TransformAnimationValue>(0, fromStyle->transform()));
2815             transformVector.insert(std::make_unique<TransformAnimationValue>(1, toStyle->transform()));
2816             if (m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyTransform), timeOffset)) {
2817                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2818                 updateTransform(*toStyle);
2819                 didAnimate = true;
2820             }
2821         }
2822     }
2823
2824     if (property == CSSPropertyFilter && m_owningLayer.hasFilter()) {
2825         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyFilter);
2826         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2827             KeyframeValueList filterVector(AnimatedPropertyFilter);
2828             filterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->filter()));
2829             filterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->filter()));
2830             if (m_graphicsLayer->addAnimation(filterVector, FloatSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyFilter), timeOffset)) {
2831                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2832                 updateFilters(*toStyle);
2833                 didAnimate = true;
2834             }
2835         }
2836     }
2837
2838 #if ENABLE(FILTERS_LEVEL_2)
2839     if (property == CSSPropertyWebkitBackdropFilter && m_owningLayer.hasBackdropFilter()) {
2840         const Animation* backdropFilterAnim = toStyle->transitionForProperty(CSSPropertyWebkitBackdropFilter);
2841         if (backdropFilterAnim && !backdropFilterAnim->isEmptyOrZeroDuration()) {
2842             KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2843             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->backdropFilter()));
2844             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->backdropFilter()));
2845             if (m_graphicsLayer->addAnimation(backdropFilterVector, FloatSize(), backdropFilterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitBackdropFilter), timeOffset)) {
2846                 // To ensure that the correct backdrop filter is visible when the animation ends, also set the final backdrop filter.
2847                 updateBackdropFilters(*toStyle);
2848                 didAnimate = true;
2849             }
2850         }
2851     }
2852 #endif
2853
2854     return didAnimate;
2855 }
2856
2857 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
2858 {
2859     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2860     if (animatedProperty != AnimatedPropertyInvalid)
2861         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2862 }
2863
2864 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
2865 {
2866     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2867     if (animatedProperty != AnimatedPropertyInvalid)
2868         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2869 }
2870
2871 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, double time)
2872 {
2873     renderer().animation().notifyAnimationStarted(renderer(), time);
2874 }
2875
2876 void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
2877 {
2878     if (renderer().renderTreeBeingDestroyed())
2879         return;
2880     compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
2881 }
2882
2883 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2884 {
2885     compositor().notifyFlushBeforeDisplayRefresh(layer);
2886 }
2887
2888 // This is used for the 'freeze' API, for testing only.
2889 void RenderLayerBacking::suspendAnimations(double time)
2890 {
2891     m_graphicsLayer->suspendAnimations(time);
2892 }
2893
2894 void RenderLayerBacking::resumeAnimations()
2895 {
2896     m_graphicsLayer->resumeAnimations();
2897 }
2898
2899 LayoutRect RenderLayerBacking::compositedBounds() const
2900 {
2901     return m_compositedBounds;
2902 }
2903
2904 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
2905 {
2906     m_compositedBounds = bounds;
2907 }
2908
2909 LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
2910 {
2911     TiledBacking* tiledBacking = this->tiledBacking();
2912     if (!tiledBacking || !tiledBacking->hasMargins())
2913         return compositedBounds();
2914
2915     LayoutRect boundsIncludingMargin = compositedBounds();
2916     LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
2917     LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
2918
2919     boundsIncludingMargin.moveBy(LayoutPoint(-leftMarginWidth, -topMarginHeight));
2920     boundsIncludingMargin.expand(leftMarginWidth + tiledBacking->rightMarginWidth(), topMarginHeight + tiledBacking->bottomMarginHeight());
2921
2922     return boundsIncludingMargin;
2923 }
2924
2925 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
2926 {
2927     CSSPropertyID cssProperty = CSSPropertyInvalid;
2928     switch (property) {
2929     case AnimatedPropertyTransform:
2930         cssProperty = CSSPropertyTransform;
2931         break;
2932     case AnimatedPropertyOpacity:
2933         cssProperty = CSSPropertyOpacity;
2934         break;
2935     case AnimatedPropertyBackgroundColor:
2936         cssProperty = CSSPropertyBackgroundColor;
2937         break;
2938     case AnimatedPropertyFilter:
2939         cssProperty = CSSPropertyFilter;
2940         break;
2941 #if ENABLE(FILTERS_LEVEL_2)
2942     case AnimatedPropertyWebkitBackdropFilter:
2943         cssProperty = CSSPropertyWebkitBackdropFilter;
2944         break;
2945 #endif
2946     case AnimatedPropertyInvalid:
2947         ASSERT_NOT_REACHED();
2948     }
2949     return cssProperty;
2950 }
2951
2952 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
2953 {
2954     switch (cssProperty) {
2955     case CSSPropertyTransform:
2956         return AnimatedPropertyTransform;
2957     case CSSPropertyOpacity:
2958         return AnimatedPropertyOpacity;
2959     case CSSPropertyBackgroundColor:
2960         return AnimatedPropertyBackgroundColor;
2961     case CSSPropertyFilter:
2962         return AnimatedPropertyFilter;
2963 #if ENABLE(FILTERS_LEVEL_2)
2964     case CSSPropertyWebkitBackdropFilter:
2965         return AnimatedPropertyWebkitBackdropFilter;
2966 #endif
2967     default:
2968         // It's fine if we see other css properties here; they are just not accelerated.
2969         break;
2970     }
2971     return AnimatedPropertyInvalid;
2972 }
2973
2974 CompositingLayerType RenderLayerBacking::compositingLayerType() const
2975 {
2976     if (m_graphicsLayer->usesContentsLayer())
2977         return MediaCompositingLayer;
2978
2979     if (m_graphicsLayer->drawsContent())
2980         return m_graphicsLayer->tiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
2981     
2982     return ContainerCompositingLayer;
2983 }
2984
2985 double RenderLayerBacking::backingStoreMemoryEstimate() const
2986 {
2987     double backingMemory;
2988     
2989     // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
2990     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
2991     if (m_foregroundLayer)
2992         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
2993     if (m_backgroundLayer)
2994         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
2995     if (m_maskLayer)
2996         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
2997     if (m_childClippingMaskLayer)
2998         backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
2999
3000     if (m_scrollingContentsLayer)
3001         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
3002
3003     if (m_layerForHorizontalScrollbar)
3004         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
3005
3006     if (m_layerForVerticalScrollbar)
3007         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
3008
3009     if (m_layerForScrollCorner)
3010         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
3011     
3012     return backingMemory;
3013 }
3014
3015 } // namespace WebCore