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