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