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