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