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