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