61f22037a4996ccd64c0cd70c65ff60053c82923
[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 = frameView.scrollPositionForFixedPosition();
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 = backgroundBoxForSimpleContainerPainting();
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 = backgroundBoxForSimpleContainerPainting();
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     return true;
1802 }
1803
1804 bool RenderLayerBacking::paintsNonDirectCompositedBoxDecoration() const
1805 {
1806     if (!m_owningLayer.hasVisibleBoxDecorations())
1807         return false;
1808
1809     return !supportsDirectBoxDecorationsComposition(renderer());
1810 }
1811
1812 bool RenderLayerBacking::paintsChildren() const
1813 {
1814     if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
1815         return true;
1816
1817     if (isPaintDestinationForDescendantLayers())
1818         return true;
1819
1820     return false;
1821 }
1822
1823 static bool isRestartedPlugin(RenderObject& renderer)
1824 {
1825     if (!is<RenderEmbeddedObject>(renderer))
1826         return false;
1827
1828     HTMLFrameOwnerElement& element = downcast<RenderEmbeddedObject>(renderer).frameOwnerElement();
1829     if (!is<HTMLPlugInElement>(element))
1830         return false;
1831
1832     return downcast<HTMLPlugInElement>(element).isRestartedPlugin();
1833 }
1834
1835 static bool isCompositedPlugin(RenderObject& renderer)
1836 {
1837     return is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
1838 }
1839
1840 // A "simple container layer" is a RenderLayer which has no visible content to render.
1841 // It may have no children, or all its children may be themselves composited.
1842 // This is a useful optimization, because it allows us to avoid allocating backing store.
1843 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
1844 {
1845     if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
1846         return false;
1847
1848     if (renderer().isTextControl())
1849         return false;
1850
1851     if (paintsNonDirectCompositedBoxDecoration() || paintsChildren())
1852         return false;
1853
1854     if (renderer().style().backgroundClip() == TextFillBox)
1855         return false;
1856     
1857     if (renderer().isRenderNamedFlowFragmentContainer())
1858         return false;
1859
1860     if (renderer().isDocumentElementRenderer() && m_owningLayer.isolatesCompositedBlending())
1861         return false;
1862
1863     if (renderer().isRenderView()) {
1864         // Look to see if the root object has a non-simple background
1865         auto* rootObject = renderer().document().documentElement() ? renderer().document().documentElement()->renderer() : nullptr;
1866         if (!rootObject)
1867             return false;
1868         
1869         // Reject anything that has a border, a border-radius or outline,
1870         // or is not a simple background (no background, or solid color).
1871         if (hasBoxDecorationsOrBackgroundImage(rootObject->style()))
1872             return false;
1873         
1874         // Now look at the body's renderer.
1875         auto* body = renderer().document().body();
1876         if (!body)
1877             return false;
1878         auto* bodyRenderer = body->renderer();
1879         if (!bodyRenderer)
1880             return false;
1881         
1882         if (hasBoxDecorationsOrBackgroundImage(bodyRenderer->style()))
1883             return false;
1884     }
1885
1886     return true;
1887 }
1888
1889 static bool descendantLayerPaintsIntoAncestor(RenderLayer& parent)
1890 {
1891     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
1892     parent.updateLayerListsIfNeeded();
1893
1894 #if !ASSERT_DISABLED
1895     LayerListMutationDetector mutationChecker(&parent);
1896 #endif
1897
1898     if (Vector<RenderLayer*>* normalFlowList = parent.normalFlowList()) {
1899         size_t listSize = normalFlowList->size();
1900         for (size_t i = 0; i < listSize; ++i) {
1901             RenderLayer* curLayer = normalFlowList->at(i);
1902             if (!compositedWithOwnBackingStore(*curLayer)
1903                 && (curLayer->isVisuallyNonEmpty() || descendantLayerPaintsIntoAncestor(*curLayer)))
1904                 return true;
1905         }
1906     }
1907
1908     if (parent.isStackingContainer()) {
1909         if (!parent.hasVisibleDescendant())
1910             return false;
1911
1912         // Use the m_hasCompositingDescendant bit to optimize?
1913         if (Vector<RenderLayer*>* negZOrderList = parent.negZOrderList()) {
1914             size_t listSize = negZOrderList->size();
1915             for (size_t i = 0; i < listSize; ++i) {
1916                 RenderLayer* curLayer = negZOrderList->at(i);
1917                 if (!compositedWithOwnBackingStore(*curLayer)
1918                     && (curLayer->isVisuallyNonEmpty() || descendantLayerPaintsIntoAncestor(*curLayer)))
1919                     return true;
1920             }
1921         }
1922
1923         if (Vector<RenderLayer*>* posZOrderList = parent.posZOrderList()) {
1924             size_t listSize = posZOrderList->size();
1925             for (size_t i = 0; i < listSize; ++i) {
1926                 RenderLayer* curLayer = posZOrderList->at(i);
1927                 if (!compositedWithOwnBackingStore(*curLayer)
1928                     && (curLayer->isVisuallyNonEmpty() || descendantLayerPaintsIntoAncestor(*curLayer)))
1929                     return true;
1930             }
1931         }
1932     }
1933
1934     return false;
1935 }
1936
1937 // Conservative test for having no rendered children.
1938 bool RenderLayerBacking::isPaintDestinationForDescendantLayers() const
1939 {
1940     return descendantLayerPaintsIntoAncestor(m_owningLayer);
1941 }
1942
1943 bool RenderLayerBacking::containsPaintedContent(bool isSimpleContainer) const
1944 {
1945     if (isSimpleContainer || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
1946         return false;
1947
1948     if (isDirectlyCompositedImage())
1949         return false;
1950
1951     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
1952     // and set background color on the layer in that case, instead of allocating backing store and painting.
1953 #if ENABLE(VIDEO)
1954     if (is<RenderVideo>(renderer()) && downcast<RenderVideo>(renderer()).shouldDisplayVideo())
1955         return m_owningLayer.hasBoxDecorationsOrBackground() || (!(downcast<RenderVideo>(renderer()).supportsAcceleratedRendering()) && m_requiresOwnBackingStore);
1956 #endif
1957
1958 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
1959     if (is<RenderHTMLCanvas>(renderer()) && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents)
1960         return m_owningLayer.hasBoxDecorationsOrBackground();
1961 #endif
1962
1963     return true;
1964 }
1965
1966 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
1967 // that require painting. Direct compositing saves backing store.
1968 bool RenderLayerBacking::isDirectlyCompositedImage() const
1969 {
1970     if (!is<RenderImage>(renderer()) || m_owningLayer.hasBoxDecorationsOrBackground() || renderer().hasClip())
1971         return false;
1972
1973 #if ENABLE(VIDEO)
1974     if (is<RenderMedia>(renderer()))
1975         return false;
1976 #endif
1977
1978     auto& imageRenderer = downcast<RenderImage>(renderer());
1979     if (CachedImage* cachedImage = imageRenderer.cachedImage()) {
1980         if (!cachedImage->hasImage())
1981             return false;
1982
1983         Image* image = cachedImage->imageForRenderer(&imageRenderer);
1984         if (!image->isBitmapImage())
1985             return false;
1986
1987         if (image->orientationForCurrentFrame() != DefaultImageOrientation)
1988             return false;
1989
1990         return m_graphicsLayer->shouldDirectlyCompositeImage(image);
1991     }
1992
1993     return false;
1994 }
1995
1996 void RenderLayerBacking::contentChanged(ContentChangeType changeType)
1997 {
1998     if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
1999         updateImageContents();
2000         return;
2001     }
2002
2003     if ((changeType == BackgroundImageChanged) && canCreateTiledImage(renderer().style()))
2004         updateGeometry();
2005
2006     if ((changeType == MaskImageChanged) && m_maskLayer) {
2007         // The composited layer bounds relies on box->maskClipRect(), which changes
2008         // when the mask image becomes available.
2009         updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
2010     }
2011
2012 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
2013     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && renderer().isCanvas() && canvasCompositingStrategy(renderer()) == CanvasAsLayerContents) {
2014         m_graphicsLayer->setContentsNeedsDisplay();
2015         return;
2016     }
2017 #endif
2018 }
2019
2020 void RenderLayerBacking::updateImageContents()
2021 {
2022     auto& imageRenderer = downcast<RenderImage>(renderer());
2023
2024     CachedImage* cachedImage = imageRenderer.cachedImage();
2025     if (!cachedImage)
2026         return;
2027
2028     Image* image = cachedImage->imageForRenderer(&imageRenderer);
2029     if (!image)
2030         return;
2031
2032     // We have to wait until the image is fully loaded before setting it on the layer.
2033     if (!cachedImage->isLoaded())
2034         return;
2035
2036     // This is a no-op if the layer doesn't have an inner layer for the image.
2037     m_graphicsLayer->setContentsRect(snappedIntRect(contentsBox()));
2038
2039     LayoutRect boxRect(LayoutPoint(), imageRenderer.size());
2040     FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
2041     contentsClippingRect.move(contentOffsetInCompostingLayer());
2042     m_graphicsLayer->setContentsClippingRect(contentsClippingRect);
2043
2044     m_graphicsLayer->setContentsToImage(image);
2045     bool isSimpleContainer = false;
2046     updateDrawsContent(isSimpleContainer);
2047     
2048     // Image animation is "lazy", in that it automatically stops unless someone is drawing
2049     // the image. So we have to kick the animation each time; this has the downside that the
2050     // image will keep animating, even if its layer is not visible.
2051     image->startAnimation();
2052 }
2053
2054 FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
2055 {
2056     const RenderStyle& style = renderer().style();
2057     float deviceScaleFactor = this->deviceScaleFactor();
2058
2059     FloatPoint3D origin;
2060     origin.setX(roundToDevicePixel(floatValueForLength(style.transformOriginX(), borderBox.width()), deviceScaleFactor));
2061     origin.setY(roundToDevicePixel(floatValueForLength(style.transformOriginY(), borderBox.height()), deviceScaleFactor));
2062     origin.setZ(style.transformOriginZ());
2063
2064     return origin;
2065 }
2066
2067 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
2068 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
2069 {
2070     return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y()) + m_devicePixelFractionFromRenderer;
2071 }
2072
2073 LayoutRect RenderLayerBacking::contentsBox() const
2074 {
2075     if (!is<RenderBox>(renderer()))
2076         return LayoutRect();
2077
2078     auto& renderBox = downcast<RenderBox>(renderer());
2079     LayoutRect contentsRect;
2080 #if ENABLE(VIDEO)
2081     if (is<RenderVideo>(renderBox))
2082         contentsRect = downcast<RenderVideo>(renderBox).videoBox();
2083     else
2084 #endif
2085     if (is<RenderReplaced>(renderBox)) {
2086         RenderReplaced& renderReplaced = downcast<RenderReplaced>(renderBox);
2087         contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
2088     } else
2089         contentsRect = renderBox.contentBoxRect();
2090
2091     contentsRect.move(contentOffsetInCompostingLayer());
2092     return contentsRect;
2093 }
2094
2095 static LayoutRect backgroundRectForBox(const RenderBox& box)
2096 {
2097     switch (box.style().backgroundClip()) {
2098     case BorderFillBox:
2099         return box.borderBoxRect();
2100     case PaddingFillBox:
2101         return box.paddingBoxRect();
2102     case ContentFillBox:
2103         return box.contentBoxRect();
2104     default:
2105         break;
2106     }
2107
2108     ASSERT_NOT_REACHED();
2109     return LayoutRect();
2110 }
2111
2112 FloatRect RenderLayerBacking::backgroundBoxForSimpleContainerPainting() const
2113 {
2114     if (!is<RenderBox>(renderer()))
2115         return FloatRect();
2116
2117     LayoutRect backgroundBox = backgroundRectForBox(downcast<RenderBox>(renderer()));
2118     backgroundBox.move(contentOffsetInCompostingLayer());
2119     return snapRectToDevicePixels(backgroundBox, deviceScaleFactor());
2120 }
2121
2122 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
2123 {
2124     if (m_scrollingContentsLayer)
2125         return m_scrollingContentsLayer.get();
2126
2127     return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
2128 }
2129
2130 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
2131 {
2132     if (m_ancestorClippingLayer)
2133         return m_ancestorClippingLayer.get();
2134
2135     if (m_contentsContainmentLayer)
2136         return m_contentsContainmentLayer.get();
2137     
2138     return m_graphicsLayer.get();
2139 }
2140
2141 bool RenderLayerBacking::paintsIntoWindow() const
2142 {
2143     if (m_usingTiledCacheLayer)
2144         return false;
2145
2146     if (m_owningLayer.isRootLayer()) {
2147 #if PLATFORM(IOS) || USE(COORDINATED_GRAPHICS)
2148         if (compositor().inForcedCompositingMode())
2149             return false;
2150 #endif
2151
2152         return compositor().rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
2153     }
2154     
2155     return false;
2156 }
2157
2158 void RenderLayerBacking::setRequiresOwnBackingStore(bool requiresOwnBacking)
2159 {
2160     if (requiresOwnBacking == m_requiresOwnBackingStore)
2161         return;
2162     
2163     m_requiresOwnBackingStore = requiresOwnBacking;
2164
2165     // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
2166     // cached clip rects, so when it changes we have to clear clip rects on descendants.
2167     m_owningLayer.clearClipRectsIncludingDescendants(PaintingClipRects);
2168     m_owningLayer.computeRepaintRectsIncludingDescendants();
2169     
2170     compositor().repaintInCompositedAncestor(m_owningLayer, compositedBounds());
2171 }
2172
2173 void RenderLayerBacking::setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer shouldClip)
2174 {
2175     ASSERT(!paintsIntoCompositedAncestor());
2176
2177     FrameView& frameView = owningLayer().renderer().view().frameView();
2178     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2179         frameView.addTrackedRepaintRect(owningLayer().absoluteBoundingBoxForPainting());
2180     
2181     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2182         // By default, setNeedsDisplay will clip to the size of the GraphicsLayer, which does not include margin tiles.
2183         // So if the TiledBacking has a margin that needs to be invalidated, we need to send in a rect to setNeedsDisplayInRect
2184         // that is large enough to include the margin. TiledBacking::bounds() includes the margin.
2185         TiledBacking* tiledBacking = this->tiledBacking();
2186         FloatRect rectToRepaint = tiledBacking ? tiledBacking->bounds() : FloatRect(FloatPoint(0, 0), m_graphicsLayer->size());
2187         m_graphicsLayer->setNeedsDisplayInRect(rectToRepaint, shouldClip);
2188     }
2189     
2190     if (m_foregroundLayer && m_foregroundLayer->drawsContent())
2191         m_foregroundLayer->setNeedsDisplay();
2192
2193     if (m_backgroundLayer && m_backgroundLayer->drawsContent())
2194         m_backgroundLayer->setNeedsDisplay();
2195
2196     if (m_maskLayer && m_maskLayer->drawsContent())
2197         m_maskLayer->setNeedsDisplay();
2198
2199     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
2200         m_childClippingMaskLayer->setNeedsDisplay();
2201
2202     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
2203         m_scrollingContentsLayer->setNeedsDisplay();
2204 }
2205
2206 // r is in the coordinate space of the layer's render object
2207 void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r, GraphicsLayer::ShouldClipToLayer shouldClip)
2208 {
2209     ASSERT(!paintsIntoCompositedAncestor());
2210
2211     FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
2212     FrameView& frameView = owningLayer().renderer().view().frameView();
2213     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
2214         frameView.addTrackedRepaintRect(pixelSnappedRectForPainting);
2215
2216     if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
2217         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2218         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
2219         m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2220     }
2221
2222     if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
2223         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2224         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
2225         m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2226     }
2227
2228     // FIXME: need to split out repaints for the background.
2229     if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
2230         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2231         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
2232         m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2233     }
2234
2235     if (m_maskLayer && m_maskLayer->drawsContent()) {
2236         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2237         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
2238         m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2239     }
2240
2241     if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
2242         FloatRect layerDirtyRect = r;
2243         layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
2244         m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
2245     }
2246
2247     if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
2248         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
2249         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
2250 #if PLATFORM(IOS)
2251         // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS.
2252         layerDirtyRect.move(-m_owningLayer.scrollOffset() + m_devicePixelFractionFromRenderer);
2253 #endif
2254         m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
2255     }
2256 }
2257
2258 void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext& context,
2259     const IntRect& paintDirtyRect, // In the coords of rootLayer.
2260     PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
2261 {
2262     if ((paintsIntoWindow() || paintsIntoCompositedAncestor()) && paintingPhase != GraphicsLayerPaintChildClippingMask) {
2263 #if !PLATFORM(IOS) && !OS(WINDOWS)
2264         // FIXME: Looks like the CALayer tree is out of sync with the GraphicsLayer heirarchy
2265         // when pages are restored from the PageCache.
2266         // <rdar://problem/8712587> ASSERT: When Going Back to Page with Plugins in PageCache
2267         ASSERT_NOT_REACHED();
2268 #endif
2269         return;
2270     }
2271
2272     RenderLayer::PaintLayerFlags paintFlags = 0;
2273     if (paintingPhase & GraphicsLayerPaintBackground)
2274         paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
2275     if (paintingPhase & GraphicsLayerPaintForeground)
2276         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
2277     if (paintingPhase & GraphicsLayerPaintMask)
2278         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
2279     if (paintingPhase & GraphicsLayerPaintClipPath)
2280         paintFlags |= RenderLayer::PaintLayerPaintingCompositingClipPathPhase;
2281     if (paintingPhase & GraphicsLayerPaintChildClippingMask)
2282         paintFlags |= RenderLayer::PaintLayerPaintingChildClippingMaskPhase;
2283     if (paintingPhase & GraphicsLayerPaintOverflowContents)
2284         paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
2285     if (paintingPhase & GraphicsLayerPaintCompositedScroll)
2286         paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
2287
2288     if (graphicsLayer == m_backgroundLayer.get())
2289         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
2290     else if (compositor().fixedRootBackgroundLayer())
2291         paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
2292
2293 #ifndef NDEBUG
2294     RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
2295 #endif
2296
2297     FrameView::PaintingState paintingState;
2298     if (m_owningLayer.isRootLayer())
2299         renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
2300
2301     // FIXME: GraphicsLayers need a way to split for RenderRegions.
2302     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_devicePixelFractionFromRenderer);
2303     m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
2304
2305     if (m_owningLayer.containsDirtyOverlayScrollbars())
2306         m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
2307
2308     if (m_owningLayer.isRootLayer())
2309         renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
2310
2311     compositor().didPaintBacking(this);
2312
2313     ASSERT(!m_owningLayer.m_usedTransparency);
2314 }
2315
2316 // Up-call from compositing layer drawing callback.
2317 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const FloatRect& clip)
2318 {
2319 #ifndef NDEBUG
2320     if (Page* page = renderer().frame().page())
2321         page->setIsPainting(true);
2322 #endif
2323
2324     // The dirtyRect is in the coords of the painting root.
2325     FloatRect adjustedClipRect = clip;
2326     adjustedClipRect.move(-m_devicePixelFractionFromRenderer);
2327     IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
2328
2329     if (graphicsLayer == m_graphicsLayer.get()
2330         || graphicsLayer == m_foregroundLayer.get()
2331         || graphicsLayer == m_backgroundLayer.get()
2332         || graphicsLayer == m_maskLayer.get()
2333         || graphicsLayer == m_childClippingMaskLayer.get()
2334         || graphicsLayer == m_scrollingContentsLayer.get()) {
2335         InspectorInstrumentation::willPaint(&renderer());
2336
2337         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
2338             dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
2339
2340         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
2341         paintIntoLayer(graphicsLayer, context, dirtyRect, PaintBehaviorNormal, paintingPhase);
2342
2343         InspectorInstrumentation::didPaint(&renderer(), dirtyRect);
2344     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
2345         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
2346     } else if (graphicsLayer == layerForVerticalScrollbar()) {
2347         paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
2348     } else if (graphicsLayer == layerForScrollCorner()) {
2349         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
2350         context.save();
2351         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
2352         LayoutRect transformedClip = LayoutRect(clip);
2353         transformedClip.moveBy(scrollCornerAndResizer.location());
2354         m_owningLayer.paintScrollCorner(context, IntPoint(), snappedIntRect(transformedClip));
2355         m_owningLayer.paintResizer(context, IntPoint(), transformedClip);
2356         context.restore();
2357     }
2358 #ifndef NDEBUG
2359     if (Page* page = renderer().frame().page())
2360         page->setIsPainting(false);
2361 #endif
2362 }
2363
2364 float RenderLayerBacking::pageScaleFactor() const
2365 {
2366     return compositor().pageScaleFactor();
2367 }
2368
2369 float RenderLayerBacking::zoomedOutPageScaleFactor() const
2370 {
2371     return compositor().zoomedOutPageScaleFactor();
2372 }
2373
2374 float RenderLayerBacking::deviceScaleFactor() const
2375 {
2376     return compositor().deviceScaleFactor();
2377 }
2378
2379 float RenderLayerBacking::contentsScaleMultiplierForNewTiles(const GraphicsLayer* layer) const
2380 {
2381     return compositor().contentsScaleMultiplierForNewTiles(layer);
2382 }
2383
2384 bool RenderLayerBacking::paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const
2385 {
2386     return m_isMainFrameRenderViewLayer;
2387 }
2388
2389 void RenderLayerBacking::didCommitChangesForLayer(const GraphicsLayer* layer) const
2390 {
2391     compositor().didFlushChangesForLayer(m_owningLayer, layer);
2392 }
2393
2394 bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
2395 {
2396     GraphicsLayer* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
2397     if (graphicsLayer != transformedLayer)
2398         return false;
2399
2400     if (m_owningLayer.hasTransform()) {
2401         transform = m_owningLayer.currentTransform(RenderStyle::ExcludeTransformOrigin);
2402         return true;
2403     }
2404     return false;
2405 }
2406
2407 bool RenderLayerBacking::isTrackingRepaints() const
2408 {
2409     return static_cast<GraphicsLayerClient&>(compositor()).isTrackingRepaints();
2410 }
2411
2412 bool RenderLayerBacking::shouldSkipLayerInDump(const GraphicsLayer* layer, LayerTreeAsTextBehavior behavior) const
2413 {
2414     if (behavior & LayerTreeAsTextDebug)
2415         return false;
2416
2417     // Skip the root tile cache's flattening layer.
2418     return m_isMainFrameRenderViewLayer && layer && layer == m_childContainmentLayer.get();
2419 }
2420
2421 bool RenderLayerBacking::shouldDumpPropertyForLayer(const GraphicsLayer* layer, const char* propertyName) const
2422 {
2423     // For backwards compatibility with WebKit1 and other platforms,
2424     // skip some properties on the root tile cache.
2425     if (m_isMainFrameRenderViewLayer && layer == m_graphicsLayer.get()) {
2426         if (!strcmp(propertyName, "drawsContent"))
2427             return false;
2428
2429         // Background color could be of interest to tests or other dumpers if it's non-white.
2430         if (!strcmp(propertyName, "backgroundColor") && layer->backgroundColor() == Color::white)
2431             return false;
2432
2433         // The root tile cache's repaints will show up at the top with FrameView's,
2434         // so don't dump them twice.
2435         if (!strcmp(propertyName, "repaintRects"))
2436             return false;
2437     }
2438
2439     return true;
2440 }
2441
2442 bool RenderLayerBacking::shouldAggressivelyRetainTiles(const GraphicsLayer*) const
2443 {
2444     // Only the main frame TileController has enough information about in-window state to
2445     // correctly implement aggressive tile retention.
2446     if (!m_isMainFrameRenderViewLayer)
2447         return false;
2448
2449     if (Page* page = renderer().frame().page())
2450         return page->settings().aggressiveTileRetentionEnabled();
2451     return false;
2452 }
2453
2454 bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const
2455 {
2456     if (Page* page = renderer().frame().page())
2457         return page->settings().temporaryTileCohortRetentionEnabled();
2458     return true;
2459 }
2460
2461 IntSize RenderLayerBacking::tileSize() const
2462 {
2463     TileSizeMode tileSizeMode = renderer().frame().page()->settings().useGiantTiles() ? GiantTileSizeMode : StandardTileSizeMode;
2464     return defaultTileSize(tileSizeMode);
2465 }
2466
2467 #ifndef NDEBUG
2468 void RenderLayerBacking::verifyNotPainting()
2469 {
2470     ASSERT(!renderer().frame().page() || !renderer().frame().page()->isPainting());
2471 }
2472 #endif
2473
2474 bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
2475 {
2476     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
2477     bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyTransform);
2478     bool hasFilter = keyframes.containsProperty(CSSPropertyFilter);
2479
2480     bool hasBackdropFilter = false;
2481 #if ENABLE(FILTERS_LEVEL_2)
2482     hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
2483 #endif
2484
2485     if (!hasOpacity && !hasTransform && !hasFilter && !hasBackdropFilter)
2486         return false;
2487
2488     KeyframeValueList transformVector(AnimatedPropertyTransform);
2489     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2490     KeyframeValueList filterVector(AnimatedPropertyFilter);
2491 #if ENABLE(FILTERS_LEVEL_2)
2492     KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2493 #endif
2494
2495     size_t numKeyframes = keyframes.size();
2496     for (size_t i = 0; i < numKeyframes; ++i) {
2497         const KeyframeValue& currentKeyframe = keyframes[i];
2498         const RenderStyle* keyframeStyle = currentKeyframe.style();
2499         double key = currentKeyframe.key();
2500
2501         if (!keyframeStyle)
2502             continue;
2503             
2504         TimingFunction* tf = currentKeyframe.timingFunction(keyframes.animationName());
2505         
2506         bool isFirstOrLastKeyframe = key == 0 || key == 1;
2507         if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyTransform))
2508             transformVector.insert(std::make_unique<TransformAnimationValue>(key, keyframeStyle->transform(), tf));
2509
2510         if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
2511             opacityVector.insert(std::make_unique<FloatAnimationValue>(key, keyframeStyle->opacity(), tf));
2512
2513         if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyFilter))
2514             filterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->filter(), tf));
2515
2516 #if ENABLE(FILTERS_LEVEL_2)
2517         if ((hasBackdropFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
2518             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->backdropFilter(), tf));
2519 #endif
2520     }
2521
2522     if (renderer().frame().page() && !renderer().frame().page()->settings().acceleratedCompositedAnimationsEnabled())
2523         return false;
2524
2525     bool didAnimate = false;
2526
2527     if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset))
2528         didAnimate = true;
2529
2530     if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2531         didAnimate = true;
2532
2533     if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2534         didAnimate = true;
2535
2536 #if ENABLE(FILTERS_LEVEL_2)
2537     if (hasBackdropFilter && m_graphicsLayer->addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
2538         didAnimate = true;
2539 #endif
2540
2541     return didAnimate;
2542 }
2543
2544 void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
2545 {
2546     m_graphicsLayer->pauseAnimation(animationName, timeOffset);
2547 }
2548
2549 void RenderLayerBacking::animationFinished(const String& animationName)
2550 {
2551     m_graphicsLayer->removeAnimation(animationName);
2552 }
2553
2554 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
2555 {
2556     bool didAnimate = false;
2557
2558     ASSERT(property != CSSPropertyInvalid);
2559
2560     if (property == CSSPropertyOpacity) {
2561         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
2562         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
2563             KeyframeValueList opacityVector(AnimatedPropertyOpacity);
2564             opacityVector.insert(std::make_unique<FloatAnimationValue>(0, compositingOpacity(fromStyle->opacity())));
2565             opacityVector.insert(std::make_unique<FloatAnimationValue>(1, compositingOpacity(toStyle->opacity())));
2566             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
2567             if (m_graphicsLayer->addAnimation(opacityVector, FloatSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
2568                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
2569                 updateOpacity(*toStyle);
2570                 didAnimate = true;
2571             }
2572         }
2573     }
2574
2575     if (property == CSSPropertyTransform && m_owningLayer.hasTransform()) {
2576         const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyTransform);
2577         if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
2578             KeyframeValueList transformVector(AnimatedPropertyTransform);
2579             transformVector.insert(std::make_unique<TransformAnimationValue>(0, fromStyle->transform()));
2580             transformVector.insert(std::make_unique<TransformAnimationValue>(1, toStyle->transform()));
2581             if (m_graphicsLayer->addAnimation(transformVector, snappedIntRect(renderBox()->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyTransform), timeOffset)) {
2582                 // To ensure that the correct transform is visible when the animation ends, also set the final transform.
2583                 updateTransform(*toStyle);
2584                 didAnimate = true;
2585             }
2586         }
2587     }
2588
2589     if (property == CSSPropertyFilter && m_owningLayer.hasFilter()) {
2590         const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyFilter);
2591         if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
2592             KeyframeValueList filterVector(AnimatedPropertyFilter);
2593             filterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->filter()));
2594             filterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->filter()));
2595             if (m_graphicsLayer->addAnimation(filterVector, FloatSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyFilter), timeOffset)) {
2596                 // To ensure that the correct filter is visible when the animation ends, also set the final filter.
2597                 updateFilters(*toStyle);
2598                 didAnimate = true;
2599             }
2600         }
2601     }
2602
2603 #if ENABLE(FILTERS_LEVEL_2)
2604     if (property == CSSPropertyWebkitBackdropFilter && m_owningLayer.hasBackdropFilter()) {
2605         const Animation* backdropFilterAnim = toStyle->transitionForProperty(CSSPropertyWebkitBackdropFilter);
2606         if (backdropFilterAnim && !backdropFilterAnim->isEmptyOrZeroDuration()) {
2607             KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
2608             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->backdropFilter()));
2609             backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->backdropFilter()));
2610             if (m_graphicsLayer->addAnimation(backdropFilterVector, FloatSize(), backdropFilterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitBackdropFilter), timeOffset)) {
2611                 // To ensure that the correct backdrop filter is visible when the animation ends, also set the final backdrop filter.
2612                 updateBackdropFilters(*toStyle);
2613                 didAnimate = true;
2614             }
2615         }
2616     }
2617 #endif
2618
2619     return didAnimate;
2620 }
2621
2622 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID property)
2623 {
2624     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2625     if (animatedProperty != AnimatedPropertyInvalid)
2626         m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
2627 }
2628
2629 void RenderLayerBacking::transitionFinished(CSSPropertyID property)
2630 {
2631     AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
2632     if (animatedProperty != AnimatedPropertyInvalid)
2633         m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
2634 }
2635
2636 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, double time)
2637 {
2638     renderer().animation().notifyAnimationStarted(renderer(), time);
2639 }
2640
2641 void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer* layer)
2642 {
2643     if (renderer().documentBeingDestroyed())
2644         return;
2645     compositor().scheduleLayerFlush(layer->canThrottleLayerFlush());
2646 }
2647
2648 void RenderLayerBacking::notifyFlushBeforeDisplayRefresh(const GraphicsLayer* layer)
2649 {
2650     compositor().notifyFlushBeforeDisplayRefresh(layer);
2651 }
2652
2653 // This is used for the 'freeze' API, for testing only.
2654 void RenderLayerBacking::suspendAnimations(double time)
2655 {
2656     m_graphicsLayer->suspendAnimations(time);
2657 }
2658
2659 void RenderLayerBacking::resumeAnimations()
2660 {
2661     m_graphicsLayer->resumeAnimations();
2662 }
2663
2664 LayoutRect RenderLayerBacking::compositedBounds() const
2665 {
2666     return m_compositedBounds;
2667 }
2668
2669 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
2670 {
2671     m_compositedBounds = bounds;
2672 }
2673
2674 LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
2675 {
2676     TiledBacking* tiledBacking = this->tiledBacking();
2677     if (!tiledBacking || !tiledBacking->hasMargins())
2678         return compositedBounds();
2679
2680     LayoutRect boundsIncludingMargin = compositedBounds();
2681     LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
2682     LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
2683
2684     boundsIncludingMargin.moveBy(LayoutPoint(-leftMarginWidth, -topMarginHeight));
2685     boundsIncludingMargin.expand(leftMarginWidth + tiledBacking->rightMarginWidth(), topMarginHeight + tiledBacking->bottomMarginHeight());
2686
2687     return boundsIncludingMargin;
2688 }
2689
2690 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
2691 {
2692     CSSPropertyID cssProperty = CSSPropertyInvalid;
2693     switch (property) {
2694     case AnimatedPropertyTransform:
2695         cssProperty = CSSPropertyTransform;
2696         break;
2697     case AnimatedPropertyOpacity:
2698         cssProperty = CSSPropertyOpacity;
2699         break;
2700     case AnimatedPropertyBackgroundColor:
2701         cssProperty = CSSPropertyBackgroundColor;
2702         break;
2703     case AnimatedPropertyFilter:
2704         cssProperty = CSSPropertyFilter;
2705         break;
2706 #if ENABLE(FILTERS_LEVEL_2)
2707     case AnimatedPropertyWebkitBackdropFilter:
2708         cssProperty = CSSPropertyWebkitBackdropFilter;
2709         break;
2710 #endif
2711     case AnimatedPropertyInvalid:
2712         ASSERT_NOT_REACHED();
2713     }
2714     return cssProperty;
2715 }
2716
2717 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
2718 {
2719     switch (cssProperty) {
2720     case CSSPropertyTransform:
2721         return AnimatedPropertyTransform;
2722     case CSSPropertyOpacity:
2723         return AnimatedPropertyOpacity;
2724     case CSSPropertyBackgroundColor:
2725         return AnimatedPropertyBackgroundColor;
2726     case CSSPropertyFilter:
2727         return AnimatedPropertyFilter;
2728 #if ENABLE(FILTERS_LEVEL_2)
2729     case CSSPropertyWebkitBackdropFilter:
2730         return AnimatedPropertyWebkitBackdropFilter;
2731 #endif
2732     default:
2733         // It's fine if we see other css properties here; they are just not accelerated.
2734         break;
2735     }
2736     return AnimatedPropertyInvalid;
2737 }
2738
2739 CompositingLayerType RenderLayerBacking::compositingLayerType() const
2740 {
2741     if (m_graphicsLayer->usesContentsLayer())
2742         return MediaCompositingLayer;
2743
2744     if (m_graphicsLayer->drawsContent())
2745         return m_graphicsLayer->usingTiledBacking() ? TiledCompositingLayer : NormalCompositingLayer;
2746     
2747     return ContainerCompositingLayer;
2748 }
2749
2750 double RenderLayerBacking::backingStoreMemoryEstimate() const
2751 {
2752     double backingMemory;
2753     
2754     // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
2755     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
2756     if (m_foregroundLayer)
2757         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
2758     if (m_backgroundLayer)
2759         backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
2760     if (m_maskLayer)
2761         backingMemory += m_maskLayer->backingStoreMemoryEstimate();
2762     if (m_childClippingMaskLayer)
2763         backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
2764
2765     if (m_scrollingContentsLayer)
2766         backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
2767
2768     if (m_layerForHorizontalScrollbar)
2769         backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
2770
2771     if (m_layerForVerticalScrollbar)
2772         backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
2773
2774     if (m_layerForScrollCorner)
2775         backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
2776     
2777     return backingMemory;
2778 }
2779
2780 } // namespace WebCore