Home | History | Annotate | Download | only in compositing
      1 /*
      2  * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #include "core/rendering/compositing/CompositedLayerMapping.h"
     29 
     30 #include "core/HTMLNames.h"
     31 #include "core/fetch/ImageResource.h"
     32 #include "core/frame/FrameView.h"
     33 #include "core/html/HTMLCanvasElement.h"
     34 #include "core/html/HTMLIFrameElement.h"
     35 #include "core/html/HTMLMediaElement.h"
     36 #include "core/html/canvas/CanvasRenderingContext.h"
     37 #include "core/inspector/InspectorInstrumentation.h"
     38 #include "core/inspector/InspectorNodeIds.h"
     39 #include "core/page/Chrome.h"
     40 #include "core/page/ChromeClient.h"
     41 #include "core/page/Page.h"
     42 #include "core/page/scrolling/ScrollingCoordinator.h"
     43 #include "core/plugins/PluginView.h"
     44 #include "core/rendering/FilterEffectRenderer.h"
     45 #include "core/rendering/RenderEmbeddedObject.h"
     46 #include "core/rendering/RenderImage.h"
     47 #include "core/rendering/RenderLayerStackingNodeIterator.h"
     48 #include "core/rendering/RenderPart.h"
     49 #include "core/rendering/RenderVideo.h"
     50 #include "core/rendering/RenderView.h"
     51 #include "core/rendering/compositing/RenderLayerCompositor.h"
     52 #include "core/rendering/style/KeyframeList.h"
     53 #include "platform/LengthFunctions.h"
     54 #include "platform/RuntimeEnabledFeatures.h"
     55 #include "platform/fonts/FontCache.h"
     56 #include "platform/geometry/TransformState.h"
     57 #include "platform/graphics/GraphicsContext.h"
     58 #include "wtf/CurrentTime.h"
     59 #include "wtf/text/StringBuilder.h"
     60 
     61 namespace blink {
     62 
     63 using namespace HTMLNames;
     64 
     65 static IntRect clipBox(RenderBox* renderer);
     66 
     67 static IntRect contentsRect(const RenderObject* renderer)
     68 {
     69     if (!renderer->isBox())
     70         return IntRect();
     71 
     72     return renderer->isVideo() ?
     73         toRenderVideo(renderer)->videoBox() :
     74         pixelSnappedIntRect(toRenderBox(renderer)->contentBoxRect());
     75 }
     76 
     77 static IntRect backgroundRect(const RenderObject* renderer)
     78 {
     79     if (!renderer->isBox())
     80         return IntRect();
     81 
     82     LayoutRect rect;
     83     const RenderBox* box = toRenderBox(renderer);
     84     EFillBox clip = box->style()->backgroundClip();
     85     switch (clip) {
     86     case BorderFillBox:
     87         rect = box->borderBoxRect();
     88         break;
     89     case PaddingFillBox:
     90         rect = box->paddingBoxRect();
     91         break;
     92     case ContentFillBox:
     93         rect = box->contentBoxRect();
     94         break;
     95     case TextFillBox:
     96         break;
     97     }
     98 
     99     return pixelSnappedIntRect(rect);
    100 }
    101 
    102 static inline bool isAcceleratedCanvas(const RenderObject* renderer)
    103 {
    104     if (renderer->isCanvas()) {
    105         HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
    106         if (CanvasRenderingContext* context = canvas->renderingContext())
    107             return context->isAccelerated();
    108     }
    109     return false;
    110 }
    111 
    112 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
    113 {
    114     return style->hasBoxDecorations() || style->hasBackgroundImage();
    115 }
    116 
    117 static bool contentLayerSupportsDirectBackgroundComposition(const RenderObject* renderer)
    118 {
    119     // No support for decorations - border, border-radius or outline.
    120     // Only simple background - solid color or transparent.
    121     if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
    122         return false;
    123 
    124     // If there is no background, there is nothing to support.
    125     if (!renderer->style()->hasBackground())
    126         return true;
    127 
    128     // Simple background that is contained within the contents rect.
    129     return contentsRect(renderer).contains(backgroundRect(renderer));
    130 }
    131 
    132 static WebLayer* platformLayerForPlugin(RenderObject* renderer)
    133 {
    134     if (!renderer->isEmbeddedObject())
    135         return 0;
    136     Widget* widget = toRenderEmbeddedObject(renderer)->widget();
    137     if (!widget || !widget->isPluginView())
    138         return 0;
    139     return toPluginView(widget)->platformLayer();
    140 
    141 }
    142 
    143 static inline bool isAcceleratedContents(RenderObject* renderer)
    144 {
    145     return isAcceleratedCanvas(renderer)
    146         || (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->requiresAcceleratedCompositing())
    147         || renderer->isVideo();
    148 }
    149 
    150 // Get the scrolling coordinator in a way that works inside CompositedLayerMapping's destructor.
    151 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer& layer)
    152 {
    153     Page* page = layer.renderer()->frame()->page();
    154     if (!page)
    155         return 0;
    156 
    157     return page->scrollingCoordinator();
    158 }
    159 
    160 CompositedLayerMapping::CompositedLayerMapping(RenderLayer& layer)
    161     : m_owningLayer(layer)
    162     , m_contentOffsetInCompositingLayerDirty(false)
    163     , m_pendingUpdateScope(GraphicsLayerUpdateNone)
    164     , m_isMainFrameRenderViewLayer(false)
    165     , m_requiresOwnBackingStoreForIntrinsicReasons(false)
    166     , m_requiresOwnBackingStoreForAncestorReasons(false)
    167     , m_backgroundLayerPaintsFixedRootBackground(false)
    168     , m_scrollingContentsAreEmpty(false)
    169 {
    170     if (layer.isRootLayer() && renderer()->frame()->isMainFrame())
    171         m_isMainFrameRenderViewLayer = true;
    172 
    173     createPrimaryGraphicsLayer();
    174 }
    175 
    176 CompositedLayerMapping::~CompositedLayerMapping()
    177 {
    178     // Hits in compositing/squashing/squash-onto-nephew.html.
    179     DisableCompositingQueryAsserts disabler;
    180 
    181     // Do not leave the destroyed pointer dangling on any RenderLayers that painted to this mapping's squashing layer.
    182     for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
    183         RenderLayer* oldSquashedLayer = m_squashedLayers[i].renderLayer;
    184         if (oldSquashedLayer->groupedMapping() == this) {
    185             oldSquashedLayer->setGroupedMapping(0, true);
    186             oldSquashedLayer->setLostGroupedMapping(true);
    187         }
    188     }
    189 
    190     updateClippingLayers(false, false);
    191     updateOverflowControlsLayers(false, false, false, false);
    192     updateChildTransformLayer(false);
    193     updateForegroundLayer(false);
    194     updateBackgroundLayer(false);
    195     updateMaskLayer(false);
    196     updateClippingMaskLayers(false);
    197     updateScrollingLayers(false);
    198     updateSquashingLayers(false);
    199     destroyGraphicsLayers();
    200 }
    201 
    202 PassOwnPtr<GraphicsLayer> CompositedLayerMapping::createGraphicsLayer(CompositingReasons reasons)
    203 {
    204     GraphicsLayerFactory* graphicsLayerFactory = 0;
    205     if (Page* page = renderer()->frame()->page())
    206         graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
    207 
    208     OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
    209 
    210     graphicsLayer->setCompositingReasons(reasons);
    211     if (Node* owningNode = m_owningLayer.renderer()->generatingNode())
    212         graphicsLayer->setOwnerNodeId(InspectorNodeIds::idForNode(owningNode));
    213 
    214     return graphicsLayer.release();
    215 }
    216 
    217 void CompositedLayerMapping::createPrimaryGraphicsLayer()
    218 {
    219     m_graphicsLayer = createGraphicsLayer(m_owningLayer.compositingReasons());
    220 
    221 #if !OS(ANDROID)
    222     if (m_isMainFrameRenderViewLayer)
    223         m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
    224 #endif
    225 
    226     updateOpacity(renderer()->style());
    227     updateTransform(renderer()->style());
    228     updateFilters(renderer()->style());
    229 
    230     if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
    231         updateLayerBlendMode(renderer()->style());
    232         updateIsRootForIsolatedGroup();
    233     }
    234 }
    235 
    236 void CompositedLayerMapping::destroyGraphicsLayers()
    237 {
    238     if (m_graphicsLayer)
    239         m_graphicsLayer->removeFromParent();
    240 
    241     m_ancestorClippingLayer = nullptr;
    242     m_graphicsLayer = nullptr;
    243     m_foregroundLayer = nullptr;
    244     m_backgroundLayer = nullptr;
    245     m_childContainmentLayer = nullptr;
    246     m_childTransformLayer = nullptr;
    247     m_maskLayer = nullptr;
    248     m_childClippingMaskLayer = nullptr;
    249 
    250     m_scrollingLayer = nullptr;
    251     m_scrollingContentsLayer = nullptr;
    252     m_scrollingBlockSelectionLayer = nullptr;
    253 }
    254 
    255 void CompositedLayerMapping::updateOpacity(const RenderStyle* style)
    256 {
    257     m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
    258 }
    259 
    260 void CompositedLayerMapping::updateTransform(const RenderStyle* style)
    261 {
    262     // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
    263     // baked into it, and we don't want that.
    264     TransformationMatrix t;
    265     if (m_owningLayer.hasTransform()) {
    266         style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
    267         makeMatrixRenderable(t, compositor()->hasAcceleratedCompositing());
    268     }
    269 
    270     m_graphicsLayer->setTransform(t);
    271 }
    272 
    273 void CompositedLayerMapping::updateFilters(const RenderStyle* style)
    274 {
    275     m_graphicsLayer->setFilters(owningLayer().computeFilterOperations(style));
    276 }
    277 
    278 void CompositedLayerMapping::updateLayerBlendMode(const RenderStyle* style)
    279 {
    280     setBlendMode(style->blendMode());
    281 }
    282 
    283 void CompositedLayerMapping::updateIsRootForIsolatedGroup()
    284 {
    285     bool isolate = m_owningLayer.shouldIsolateCompositedDescendants();
    286 
    287     // non stacking context layers should never isolate
    288     ASSERT(m_owningLayer.stackingNode()->isStackingContext() || !isolate);
    289 
    290     m_graphicsLayer->setIsRootForIsolatedGroup(isolate);
    291 }
    292 
    293 void CompositedLayerMapping::updateContentsOpaque()
    294 {
    295     ASSERT(m_isMainFrameRenderViewLayer || !m_backgroundLayer);
    296     if (isAcceleratedCanvas(renderer())) {
    297         // Determine whether the rendering context's external texture layer is opaque.
    298         CanvasRenderingContext* context = toHTMLCanvasElement(renderer()->node())->renderingContext();
    299         if (!context->hasAlpha())
    300             m_graphicsLayer->setContentsOpaque(true);
    301         else if (WebLayer* layer = context->platformLayer())
    302             m_graphicsLayer->setContentsOpaque(!Color(layer->backgroundColor()).hasAlpha());
    303         else
    304             m_graphicsLayer->setContentsOpaque(false);
    305     } else if (m_backgroundLayer) {
    306         m_graphicsLayer->setContentsOpaque(false);
    307         m_backgroundLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
    308     } else {
    309         // For non-root layers, background is always painted by the primary graphics layer.
    310         m_graphicsLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
    311     }
    312 }
    313 
    314 void CompositedLayerMapping::updateCompositedBounds()
    315 {
    316     ASSERT(m_owningLayer.compositor()->lifecycle().state() == DocumentLifecycle::InCompositingUpdate);
    317     // FIXME: if this is really needed for performance, it would be better to store it on RenderLayer.
    318     m_compositedBounds = m_owningLayer.boundingBoxForCompositing();
    319     m_contentOffsetInCompositingLayerDirty = true;
    320 }
    321 
    322 void CompositedLayerMapping::updateAfterWidgetResize()
    323 {
    324     if (renderer()->isRenderPart()) {
    325         if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
    326             innerCompositor->frameViewDidChangeSize();
    327             // We can floor this point because our frameviews are always aligned to pixel boundaries.
    328             ASSERT(m_compositedBounds.location() == flooredIntPoint(m_compositedBounds.location()));
    329             innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
    330         }
    331     }
    332 }
    333 
    334 void CompositedLayerMapping::updateCompositingReasons()
    335 {
    336     // All other layers owned by this mapping will have the same compositing reason
    337     // for their lifetime, so they are initialized only when created.
    338     m_graphicsLayer->setCompositingReasons(m_owningLayer.compositingReasons());
    339 }
    340 
    341 bool CompositedLayerMapping::owningLayerClippedByLayerNotAboveCompositedAncestor()
    342 {
    343     if (!m_owningLayer.parent())
    344         return false;
    345 
    346     const RenderLayer* compositingAncestor = m_owningLayer.enclosingLayerWithCompositedLayerMapping(ExcludeSelf);
    347     if (!compositingAncestor)
    348         return false;
    349 
    350     const RenderObject* clippingContainer = m_owningLayer.clippingContainer();
    351     if (!clippingContainer)
    352         return false;
    353 
    354     if (compositingAncestor->renderer()->isDescendantOf(clippingContainer))
    355         return false;
    356 
    357     // We ignore overflow clip here; we want composited overflow content to
    358     // behave as if it lives in an unclipped universe so it can prepaint, etc.
    359     // This means that we need to check if we are actually clipped before
    360     // setting up m_ancestorClippingLayer otherwise
    361     // updateAncestorClippingLayerGeometry will fail as the clip rect will be
    362     // infinite.
    363     // FIXME: this should use cached clip rects, but this sometimes give
    364     // inaccurate results (and trips the ASSERTS in RenderLayerClipper).
    365     ClipRectsContext clipRectsContext(compositingAncestor, UncachedClipRects, IgnoreOverlayScrollbarSize);
    366     clipRectsContext.setIgnoreOverflowClip();
    367     IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect());
    368     return parentClipRect != PaintInfo::infiniteRect();
    369 }
    370 
    371 bool CompositedLayerMapping::updateGraphicsLayerConfiguration()
    372 {
    373     ASSERT(m_owningLayer.compositor()->lifecycle().state() == DocumentLifecycle::InCompositingUpdate);
    374 
    375     // Note carefully: here we assume that the compositing state of all descendants have been updated already,
    376     // so it is legitimate to compute and cache the composited bounds for this layer.
    377     updateCompositedBounds();
    378 
    379     if (RenderLayerReflectionInfo* reflection = m_owningLayer.reflectionInfo()) {
    380         if (reflection->reflectionLayer()->hasCompositedLayerMapping())
    381             reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds();
    382     }
    383 
    384     RenderLayerCompositor* compositor = this->compositor();
    385     RenderObject* renderer = this->renderer();
    386 
    387     bool layerConfigChanged = false;
    388     setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(&m_owningLayer));
    389 
    390     // The background layer is currently only used for fixed root backgrounds.
    391     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
    392         layerConfigChanged = true;
    393 
    394     if (updateForegroundLayer(compositor->needsContentsCompositingLayer(&m_owningLayer)))
    395         layerConfigChanged = true;
    396 
    397     bool needsDescendantsClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer);
    398 
    399     // Our scrolling layer will clip.
    400     if (m_owningLayer.needsCompositedScrolling())
    401         needsDescendantsClippingLayer = false;
    402 
    403     RenderLayer* scrollParent = compositor->preferCompositingToLCDTextEnabled() ? m_owningLayer.scrollParent() : 0;
    404 
    405     // This is required because compositing layers are parented
    406     // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
    407     // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
    408     // but a sibling in the z-order hierarchy. Further, that sibling need not be composited at all.
    409     // In such scenarios, an ancestor clipping layer is necessary to apply the composited clip for this layer.
    410     bool needsAncestorClip = owningLayerClippedByLayerNotAboveCompositedAncestor();
    411 
    412     if (scrollParent) {
    413         // If our containing block is our ancestor scrolling layer, then we'll already be clipped
    414         // to it via our scroll parent and we don't need an ancestor clipping layer.
    415         if (m_owningLayer.renderer()->containingBlock()->enclosingLayer() == m_owningLayer.ancestorScrollingLayer())
    416             needsAncestorClip = false;
    417     }
    418 
    419     if (updateClippingLayers(needsAncestorClip, needsDescendantsClippingLayer))
    420         layerConfigChanged = true;
    421 
    422     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer(), needsAncestorClip))
    423         layerConfigChanged = true;
    424 
    425     bool scrollingConfigChanged = false;
    426     if (updateScrollingLayers(m_owningLayer.needsCompositedScrolling())) {
    427         layerConfigChanged = true;
    428         scrollingConfigChanged = true;
    429     }
    430 
    431     bool hasPerspective = false;
    432     if (RenderStyle* style = renderer->style())
    433         hasPerspective = style->hasPerspective();
    434     bool needsChildTransformLayer = hasPerspective && (layerForChildrenTransform() == m_childTransformLayer.get()) && renderer->isBox();
    435     if (updateChildTransformLayer(needsChildTransformLayer))
    436         layerConfigChanged = true;
    437 
    438     updateScrollParent(scrollParent);
    439     updateClipParent();
    440 
    441     if (updateSquashingLayers(!m_squashedLayers.isEmpty()))
    442         layerConfigChanged = true;
    443 
    444     if (layerConfigChanged)
    445         updateInternalHierarchy();
    446 
    447     if (scrollingConfigChanged) {
    448         if (renderer->view())
    449             compositor->scrollingLayerDidChange(&m_owningLayer);
    450     }
    451 
    452     // A mask layer is not part of the hierarchy proper, it's an auxiliary layer
    453     // that's plugged into another GraphicsLayer that is part of the hierarchy.
    454     // It has no parent or child GraphicsLayer. For that reason, we process it
    455     // here, after the hierarchy has been updated.
    456     bool maskLayerChanged = false;
    457     if (updateMaskLayer(renderer->hasMask())) {
    458         maskLayerChanged = true;
    459         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
    460     }
    461 
    462     bool hasChildClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer) && (hasClippingLayer() || hasScrollingLayer());
    463     // If we have a border radius or clip path on a scrolling layer, we need a clipping mask to properly
    464     // clip the scrolled contents, even if there are no composited descendants.
    465     bool hasClipPath = renderer->style()->clipPath();
    466     bool needsChildClippingMask = (hasClipPath || renderer->style()->hasBorderRadius()) && (hasChildClippingLayer || isAcceleratedContents(renderer) || hasScrollingLayer());
    467     if (updateClippingMaskLayers(needsChildClippingMask)) {
    468         // Clip path clips the entire subtree, including scrollbars. It must be attached directly onto
    469         // the main m_graphicsLayer.
    470         if (hasClipPath)
    471             m_graphicsLayer->setMaskLayer(m_childClippingMaskLayer.get());
    472         else if (hasClippingLayer())
    473             clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
    474         else if (hasScrollingLayer())
    475             scrollingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
    476         else if (isAcceleratedContents(renderer))
    477             m_graphicsLayer->setContentsClippingMaskLayer(m_childClippingMaskLayer.get());
    478     }
    479 
    480     if (m_owningLayer.reflectionInfo()) {
    481         if (m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
    482             GraphicsLayer* reflectionLayer = m_owningLayer.reflectionInfo()->reflectionLayer()->compositedLayerMapping()->mainGraphicsLayer();
    483             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
    484         }
    485     } else {
    486         m_graphicsLayer->setReplicatedByLayer(0);
    487     }
    488 
    489     updateBackgroundColor();
    490 
    491     if (renderer->isImage()) {
    492         if (isDirectlyCompositedImage()) {
    493             updateImageContents();
    494         } else if (m_graphicsLayer->hasContentsLayer()) {
    495             m_graphicsLayer->setContentsToImage(0);
    496         }
    497     }
    498 
    499     if (WebLayer* layer = platformLayerForPlugin(renderer)) {
    500         m_graphicsLayer->setContentsToPlatformLayer(layer);
    501     } else if (renderer->node() && renderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(renderer->node())->contentFrame()) {
    502         WebLayer* layer = toHTMLFrameOwnerElement(renderer->node())->contentFrame()->remotePlatformLayer();
    503         if (layer)
    504             m_graphicsLayer->setContentsToPlatformLayer(layer);
    505     } else if (renderer->isVideo()) {
    506         HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer->node());
    507         m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer());
    508     } else if (isAcceleratedCanvas(renderer)) {
    509         HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
    510         if (CanvasRenderingContext* context = canvas->renderingContext())
    511             m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer());
    512         layerConfigChanged = true;
    513     }
    514     if (renderer->isRenderPart())
    515         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
    516 
    517     // Changes to either the internal hierarchy or the mask layer have an impact
    518     // on painting phases, so we need to update when either are updated.
    519     if (layerConfigChanged || maskLayerChanged)
    520         updatePaintingPhases();
    521 
    522     return layerConfigChanged;
    523 }
    524 
    525 static IntRect clipBox(RenderBox* renderer)
    526 {
    527     LayoutRect result = PaintInfo::infiniteRect();
    528     if (renderer->hasOverflowClip())
    529         result = renderer->overflowClipRect(LayoutPoint());
    530 
    531     if (renderer->hasClip())
    532         result.intersect(renderer->clipRect(LayoutPoint()));
    533 
    534     return pixelSnappedIntRect(result);
    535 }
    536 
    537 static LayoutPoint computeOffsetFromCompositedAncestor(const RenderLayer* layer, const RenderLayer* compositedAncestor)
    538 {
    539     LayoutPoint offset;
    540     layer->convertToLayerCoords(compositedAncestor, offset);
    541     if (compositedAncestor)
    542         offset.move(compositedAncestor->compositedLayerMapping()->owningLayer().subpixelAccumulation());
    543     return offset;
    544 }
    545 
    546 void CompositedLayerMapping::computeBoundsOfOwningLayer(const RenderLayer* compositedAncestor, IntRect& localBounds, IntRect& compositingBoundsRelativeToCompositedAncestor, LayoutPoint& offsetFromCompositedAncestor,
    547     IntPoint& snappedOffsetFromCompositedAncestor)
    548 {
    549     LayoutRect localRawCompositingBounds = compositedBounds();
    550     offsetFromCompositedAncestor = computeOffsetFromCompositedAncestor(&m_owningLayer, compositedAncestor);
    551     snappedOffsetFromCompositedAncestor = IntPoint(offsetFromCompositedAncestor.x().round(), offsetFromCompositedAncestor.y().round());
    552 
    553     LayoutSize subpixelAccumulation = offsetFromCompositedAncestor - snappedOffsetFromCompositedAncestor;
    554     m_owningLayer.setSubpixelAccumulation(subpixelAccumulation);
    555 
    556     // Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates.
    557     localRawCompositingBounds.move(subpixelAccumulation);
    558     localBounds = pixelSnappedIntRect(localRawCompositingBounds);
    559 
    560     compositingBoundsRelativeToCompositedAncestor = localBounds;
    561     compositingBoundsRelativeToCompositedAncestor.moveBy(snappedOffsetFromCompositedAncestor);
    562 }
    563 
    564 void CompositedLayerMapping::updateSquashingLayerGeometry(const LayoutPoint& offsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation, const RenderLayer& referenceLayer,
    565     Vector<GraphicsLayerPaintInfo>& layers, GraphicsLayer* squashingLayer, LayoutPoint* offsetFromTransformedAncestor, Vector<RenderLayer*>& layersNeedingPaintInvalidation)
    566 {
    567     if (!squashingLayer)
    568         return;
    569     ASSERT(compositor()->layerSquashingEnabled());
    570 
    571     LayoutPoint offsetFromReferenceLayerToParentGraphicsLayer(offsetFromCompositedAncestor);
    572     offsetFromReferenceLayerToParentGraphicsLayer.moveBy(-graphicsLayerParentLocation);
    573 
    574     // FIXME: Cache these offsets.
    575     LayoutPoint referenceOffsetFromTransformedAncestor = referenceLayer.computeOffsetFromTransformedAncestor();
    576 
    577     LayoutRect totalSquashBounds;
    578     for (size_t i = 0; i < layers.size(); ++i) {
    579         LayoutRect squashedBounds = layers[i].renderLayer->boundingBoxForCompositing();
    580 
    581         // Store the local bounds of the RenderLayer subtree before applying the offset.
    582         layers[i].compositedBounds = squashedBounds;
    583 
    584         LayoutPoint offsetFromTransformedAncestorForSquashedLayer = layers[i].renderLayer->computeOffsetFromTransformedAncestor();
    585         LayoutSize offsetFromSquashingLayer = offsetFromTransformedAncestorForSquashedLayer - referenceOffsetFromTransformedAncestor;
    586 
    587         squashedBounds.move(offsetFromSquashingLayer);
    588         totalSquashBounds.unite(squashedBounds);
    589     }
    590 
    591     // The totalSquashBounds is positioned with respect to referenceLayer of this CompositedLayerMapping.
    592     // But the squashingLayer needs to be positioned with respect to the ancestor CompositedLayerMapping.
    593     // The conversion between referenceLayer and the ancestor CLM is already computed as
    594     // offsetFromReferenceLayerToParentGraphicsLayer.
    595     totalSquashBounds.moveBy(offsetFromReferenceLayerToParentGraphicsLayer);
    596     const IntRect squashLayerBounds = enclosingIntRect(totalSquashBounds);
    597     const IntPoint squashLayerOrigin = squashLayerBounds.location();
    598     const LayoutSize squashLayerOriginInOwningLayerSpace = squashLayerOrigin - offsetFromReferenceLayerToParentGraphicsLayer;
    599 
    600     // Now that the squashing bounds are known, we can convert the RenderLayer painting offsets
    601     // from CLM owning layer space to the squashing layer space.
    602     //
    603     // The painting offset we want to compute for each squashed RenderLayer is essentially the position of
    604     // the squashed RenderLayer described w.r.t. referenceLayer's origin.
    605     // So we just need to convert that point from referenceLayer space to the squashing layer's
    606     // space. This is simply done by subtracing squashLayerOriginInOwningLayerSpace, but then the offset
    607     // overall needs to be negated because that's the direction that the painting code expects the
    608     // offset to be.
    609     for (size_t i = 0; i < layers.size(); ++i) {
    610         const LayoutPoint offsetFromTransformedAncestorForSquashedLayer = layers[i].renderLayer->computeOffsetFromTransformedAncestor();
    611         const LayoutSize offsetFromSquashLayerOrigin = (offsetFromTransformedAncestorForSquashedLayer - referenceOffsetFromTransformedAncestor) - squashLayerOriginInOwningLayerSpace;
    612 
    613         IntSize newOffsetFromRenderer = -IntSize(offsetFromSquashLayerOrigin.width().round(), offsetFromSquashLayerOrigin.height().round());
    614         LayoutSize subpixelAccumulation = offsetFromSquashLayerOrigin + newOffsetFromRenderer;
    615         if (layers[i].offsetFromRendererSet && layers[i].offsetFromRenderer != newOffsetFromRenderer) {
    616             // It is ok to issue paint invalidation here, because all of the geometry needed to correctly invalidate paint is computed by this point.
    617             layers[i].renderLayer->renderer()->invalidatePaintIncludingNonCompositingDescendants();
    618 
    619             TRACE_LAYER_INVALIDATION(layers[i].renderLayer, InspectorLayerInvalidationTrackingEvent::SquashingLayerGeometryWasUpdated);
    620             layersNeedingPaintInvalidation.append(layers[i].renderLayer);
    621         }
    622         layers[i].offsetFromRenderer = newOffsetFromRenderer;
    623         layers[i].offsetFromRendererSet = true;
    624 
    625         layers[i].renderLayer->setSubpixelAccumulation(subpixelAccumulation);
    626     }
    627 
    628     squashingLayer->setPosition(squashLayerBounds.location());
    629     squashingLayer->setSize(squashLayerBounds.size());
    630 
    631     *offsetFromTransformedAncestor = referenceOffsetFromTransformedAncestor;
    632     offsetFromTransformedAncestor->move(squashLayerOriginInOwningLayerSpace);
    633 
    634     for (size_t i = 0; i < layers.size(); ++i)
    635         layers[i].localClipRectForSquashedLayer = localClipRectForSquashedLayer(referenceLayer, layers[i], layers);
    636 }
    637 
    638 void CompositedLayerMapping::updateGraphicsLayerGeometry(const RenderLayer* compositingContainer, const RenderLayer* compositingStackingContext, Vector<RenderLayer*>& layersNeedingPaintInvalidation)
    639 {
    640     ASSERT(m_owningLayer.compositor()->lifecycle().state() == DocumentLifecycle::InCompositingUpdate);
    641 
    642     // Set transform property, if it is not animating. We have to do this here because the transform
    643     // is affected by the layer dimensions.
    644     if (!renderer()->style()->isRunningTransformAnimationOnCompositor())
    645         updateTransform(renderer()->style());
    646 
    647     // Set opacity, if it is not animating.
    648     if (!renderer()->style()->isRunningOpacityAnimationOnCompositor())
    649         updateOpacity(renderer()->style());
    650 
    651     if (!renderer()->style()->isRunningFilterAnimationOnCompositor())
    652         updateFilters(renderer()->style());
    653 
    654     // We compute everything relative to the enclosing compositing layer.
    655     IntRect ancestorCompositingBounds;
    656     if (compositingContainer) {
    657         ASSERT(compositingContainer->hasCompositedLayerMapping());
    658         ancestorCompositingBounds = compositingContainer->compositedLayerMapping()->pixelSnappedCompositedBounds();
    659     }
    660 
    661     IntRect localCompositingBounds;
    662     IntRect relativeCompositingBounds;
    663     LayoutPoint offsetFromCompositedAncestor;
    664     IntPoint snappedOffsetFromCompositedAncestor;
    665     computeBoundsOfOwningLayer(compositingContainer, localCompositingBounds, relativeCompositingBounds, offsetFromCompositedAncestor, snappedOffsetFromCompositedAncestor);
    666 
    667     IntPoint graphicsLayerParentLocation;
    668     computeGraphicsLayerParentLocation(compositingContainer, ancestorCompositingBounds, graphicsLayerParentLocation);
    669 
    670     // Might update graphicsLayerParentLocation.
    671     updateAncestorClippingLayerGeometry(compositingContainer, snappedOffsetFromCompositedAncestor, graphicsLayerParentLocation);
    672     updateOverflowControlsHostLayerGeometry(compositingStackingContext);
    673 
    674     FloatSize contentsSize = relativeCompositingBounds.size();
    675 
    676     updateMainGraphicsLayerGeometry(relativeCompositingBounds, localCompositingBounds, graphicsLayerParentLocation);
    677     updateContentsOffsetInCompositingLayer(snappedOffsetFromCompositedAncestor, graphicsLayerParentLocation);
    678     updateSquashingLayerGeometry(offsetFromCompositedAncestor, graphicsLayerParentLocation, m_owningLayer, m_squashedLayers, m_squashingLayer.get(), &m_squashingLayerOffsetFromTransformedAncestor, layersNeedingPaintInvalidation);
    679 
    680     // If we have a layer that clips children, position it.
    681     IntRect clippingBox;
    682     if (m_childContainmentLayer)
    683         clippingBox = clipBox(toRenderBox(renderer()));
    684 
    685     updateChildContainmentLayerGeometry(clippingBox, localCompositingBounds);
    686     updateChildTransformLayerGeometry();
    687 
    688     updateMaskLayerGeometry();
    689     updateTransformGeometry(snappedOffsetFromCompositedAncestor, relativeCompositingBounds);
    690     updateForegroundLayerGeometry(contentsSize, clippingBox);
    691     updateBackgroundLayerGeometry(contentsSize);
    692     updateReflectionLayerGeometry(layersNeedingPaintInvalidation);
    693     updateScrollingLayerGeometry(localCompositingBounds);
    694     updateChildClippingMaskLayerGeometry();
    695 
    696     if (m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->scrollsOverflow())
    697         m_owningLayer.scrollableArea()->positionOverflowControls(IntSize());
    698 
    699     if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
    700         updateLayerBlendMode(renderer()->style());
    701         updateIsRootForIsolatedGroup();
    702     }
    703 
    704     updateContentsRect();
    705     updateBackgroundColor();
    706     updateDrawsContent();
    707     updateContentsOpaque();
    708     updateAfterWidgetResize();
    709     updateRenderingContext();
    710     updateShouldFlattenTransform();
    711     updateChildrenTransform();
    712     updateScrollParent(compositor()->preferCompositingToLCDTextEnabled() ? m_owningLayer.scrollParent() : 0);
    713     registerScrollingLayers();
    714 
    715     updateCompositingReasons();
    716 }
    717 
    718 void CompositedLayerMapping::updateMainGraphicsLayerGeometry(const IntRect& relativeCompositingBounds, const IntRect& localCompositingBounds, const IntPoint& graphicsLayerParentLocation)
    719 {
    720     m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
    721     m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
    722 
    723     FloatSize oldSize = m_graphicsLayer->size();
    724     const IntSize& contentsSize = relativeCompositingBounds.size();
    725     if (oldSize != contentsSize)
    726         m_graphicsLayer->setSize(contentsSize);
    727 
    728     // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
    729     // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
    730     // non-compositing visible layers.
    731     bool contentsVisible = m_owningLayer.hasVisibleContent() || hasVisibleNonCompositingDescendant(&m_owningLayer);
    732     if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer()->isVideo()) {
    733         HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer()->node());
    734         if (mediaElement->isFullscreen())
    735             contentsVisible = false;
    736     }
    737     m_graphicsLayer->setContentsVisible(contentsVisible);
    738 
    739     m_graphicsLayer->setBackfaceVisibility(renderer()->style()->backfaceVisibility() == BackfaceVisibilityVisible);
    740 }
    741 
    742 void CompositedLayerMapping::computeGraphicsLayerParentLocation(const RenderLayer* compositingContainer, const IntRect& ancestorCompositingBounds, IntPoint& graphicsLayerParentLocation)
    743 {
    744     if (compositingContainer && compositingContainer->compositedLayerMapping()->hasClippingLayer()) {
    745         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
    746         // position relative to it.
    747         IntRect clippingBox = clipBox(toRenderBox(compositingContainer->renderer()));
    748         graphicsLayerParentLocation = clippingBox.location() + roundedIntSize(compositingContainer->subpixelAccumulation());
    749     } else if (compositingContainer && compositingContainer->compositedLayerMapping()->childTransformLayer()) {
    750         // Similarly, if the compositing ancestor has a child transform layer, we parent in that, and therefore
    751         // position relative to it. It's already taken into account the contents offset, so we do not need to here.
    752         graphicsLayerParentLocation = roundedIntPoint(compositingContainer->subpixelAccumulation());
    753     } else if (compositingContainer) {
    754         graphicsLayerParentLocation = ancestorCompositingBounds.location();
    755     } else {
    756         graphicsLayerParentLocation = renderer()->view()->documentRect().location();
    757     }
    758 
    759     if (compositingContainer && compositingContainer->needsCompositedScrolling()) {
    760         RenderBox* renderBox = toRenderBox(compositingContainer->renderer());
    761         IntSize scrollOffset = renderBox->scrolledContentOffset();
    762         IntPoint scrollOrigin(renderBox->borderLeft(), renderBox->borderTop());
    763         graphicsLayerParentLocation = scrollOrigin - scrollOffset;
    764     }
    765 }
    766 
    767 void CompositedLayerMapping::updateAncestorClippingLayerGeometry(const RenderLayer* compositingContainer, const IntPoint& snappedOffsetFromCompositedAncestor, IntPoint& graphicsLayerParentLocation)
    768 {
    769     if (!compositingContainer || !m_ancestorClippingLayer)
    770         return;
    771 
    772     ClipRectsContext clipRectsContext(compositingContainer, PaintingClipRectsIgnoringOverflowClip, IgnoreOverlayScrollbarSize);
    773     IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect());
    774     ASSERT(parentClipRect != PaintInfo::infiniteRect());
    775     m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
    776     m_ancestorClippingLayer->setSize(parentClipRect.size());
    777 
    778     // backgroundRect is relative to compositingContainer, so subtract snappedOffsetFromCompositedAncestor.X/snappedOffsetFromCompositedAncestor.Y to get back to local coords.
    779     m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - snappedOffsetFromCompositedAncestor);
    780 
    781     // The primary layer is then parented in, and positioned relative to this clipping layer.
    782     graphicsLayerParentLocation = parentClipRect.location();
    783 }
    784 
    785 void CompositedLayerMapping::updateOverflowControlsHostLayerGeometry(const RenderLayer* compositingStackingContext)
    786 {
    787     if (!m_overflowControlsHostLayer)
    788         return;
    789 
    790     if (needsToReparentOverflowControls()) {
    791         if (m_overflowControlsClippingLayer) {
    792             m_overflowControlsClippingLayer->setPosition(m_ancestorClippingLayer->position());
    793             m_overflowControlsClippingLayer->setSize(m_ancestorClippingLayer->size());
    794             m_overflowControlsClippingLayer->setOffsetFromRenderer(m_ancestorClippingLayer->offsetFromRenderer());
    795             m_overflowControlsClippingLayer->setMasksToBounds(true);
    796 
    797             m_overflowControlsHostLayer->setPosition(IntPoint(-m_overflowControlsClippingLayer->offsetFromRenderer()));
    798         } else {
    799             // The controls are in the same 2D space as the compositing container, so we can map them into the space of the container.
    800             TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
    801             m_owningLayer.renderer()->mapLocalToContainer(compositingStackingContext->renderer(), transformState, ApplyContainerFlip);
    802             transformState.flatten();
    803             LayoutPoint offsetFromStackingContainer = LayoutPoint(transformState.lastPlanarPoint());
    804             m_overflowControlsHostLayer->setPosition(FloatPoint(offsetFromStackingContainer));
    805         }
    806     } else {
    807         m_overflowControlsHostLayer->setPosition(FloatPoint());
    808     }
    809 }
    810 
    811 void CompositedLayerMapping::updateChildContainmentLayerGeometry(const IntRect& clippingBox, const IntRect& localCompositingBounds)
    812 {
    813     if (!m_childContainmentLayer)
    814         return;
    815 
    816     m_childContainmentLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location() + roundedIntSize(m_owningLayer.subpixelAccumulation())));
    817     m_childContainmentLayer->setSize(clippingBox.size());
    818     m_childContainmentLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
    819     if (m_childClippingMaskLayer && !m_scrollingLayer && !renderer()->style()->clipPath()) {
    820         m_childClippingMaskLayer->setPosition(m_childContainmentLayer->position());
    821         m_childClippingMaskLayer->setSize(m_childContainmentLayer->size());
    822         m_childClippingMaskLayer->setOffsetFromRenderer(m_childContainmentLayer->offsetFromRenderer());
    823     }
    824 }
    825 
    826 void CompositedLayerMapping::updateChildTransformLayerGeometry()
    827 {
    828     if (!m_childTransformLayer)
    829         return;
    830     const IntRect borderBox = toRenderBox(m_owningLayer.renderer())->pixelSnappedBorderBoxRect();
    831     m_childTransformLayer->setSize(borderBox.size());
    832     m_childTransformLayer->setPosition(FloatPoint(contentOffsetInCompositingLayer()));
    833 }
    834 
    835 void CompositedLayerMapping::updateMaskLayerGeometry()
    836 {
    837     if (!m_maskLayer)
    838         return;
    839 
    840     if (m_maskLayer->size() != m_graphicsLayer->size()) {
    841         m_maskLayer->setSize(m_graphicsLayer->size());
    842         m_maskLayer->setNeedsDisplay();
    843     }
    844     m_maskLayer->setPosition(FloatPoint());
    845     m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
    846 }
    847 
    848 void CompositedLayerMapping::updateTransformGeometry(const IntPoint& snappedOffsetFromCompositedAncestor, const IntRect& relativeCompositingBounds)
    849 {
    850     if (m_owningLayer.hasTransform()) {
    851         const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
    852 
    853         // Get layout bounds in the coords of compositingContainer to match relativeCompositingBounds.
    854         IntRect layerBounds = pixelSnappedIntRect(toLayoutPoint(m_owningLayer.subpixelAccumulation()), borderBox.size());
    855         layerBounds.moveBy(snappedOffsetFromCompositedAncestor);
    856 
    857         // Update properties that depend on layer dimensions
    858         FloatPoint3D transformOrigin = computeTransformOrigin(IntRect(IntPoint(), layerBounds.size()));
    859 
    860         // |transformOrigin| is in the local space of this layer. layerBounds - relativeCompositingBounds converts to the space of the
    861         // compositing bounds relative to the composited ancestor. This does not apply to the z direction, since the page is 2D.
    862         FloatPoint3D compositedTransformOrigin(
    863             layerBounds.x() - relativeCompositingBounds.x() + transformOrigin.x(),
    864             layerBounds.y() - relativeCompositingBounds.y() + transformOrigin.y(),
    865             transformOrigin.z());
    866         m_graphicsLayer->setTransformOrigin(compositedTransformOrigin);
    867     } else {
    868         FloatPoint3D compositedTransformOrigin(
    869             relativeCompositingBounds.width() * 0.5f,
    870             relativeCompositingBounds.height() * 0.5f,
    871             0.f);
    872         m_graphicsLayer->setTransformOrigin(compositedTransformOrigin);
    873     }
    874 }
    875 
    876 void CompositedLayerMapping::updateReflectionLayerGeometry(Vector<RenderLayer*>& layersNeedingPaintInvalidation)
    877 {
    878     if (!m_owningLayer.reflectionInfo() || !m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
    879         return;
    880 
    881     CompositedLayerMapping* reflectionCompositedLayerMapping = m_owningLayer.reflectionInfo()->reflectionLayer()->compositedLayerMapping();
    882     reflectionCompositedLayerMapping->updateGraphicsLayerGeometry(&m_owningLayer, &m_owningLayer, layersNeedingPaintInvalidation);
    883 }
    884 
    885 void CompositedLayerMapping::updateScrollingLayerGeometry(const IntRect& localCompositingBounds)
    886 {
    887     if (!m_scrollingLayer)
    888         return;
    889 
    890     ASSERT(m_scrollingContentsLayer);
    891     RenderBox* renderBox = toRenderBox(renderer());
    892     IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
    893 
    894     IntSize adjustedScrollOffset = m_owningLayer.scrollableArea()->adjustedScrollOffset();
    895     m_scrollingLayer->setPosition(FloatPoint(clientBox.location() - localCompositingBounds.location() + roundedIntSize(m_owningLayer.subpixelAccumulation())));
    896     m_scrollingLayer->setSize(clientBox.size());
    897 
    898     IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
    899     m_scrollingLayer->setOffsetFromRenderer(-toIntSize(clientBox.location()));
    900 
    901     if (m_childClippingMaskLayer && !renderer()->style()->clipPath()) {
    902         m_childClippingMaskLayer->setPosition(m_scrollingLayer->position());
    903         m_childClippingMaskLayer->setSize(m_scrollingLayer->size());
    904         m_childClippingMaskLayer->setOffsetFromRenderer(toIntSize(clientBox.location()));
    905     }
    906 
    907     bool clientBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
    908 
    909     IntSize scrollSize(renderBox->scrollWidth(), renderBox->scrollHeight());
    910     if (scrollSize != m_scrollingContentsLayer->size() || clientBoxOffsetChanged)
    911         m_scrollingContentsLayer->setNeedsDisplay();
    912 
    913     IntSize scrollingContentsOffset = toIntSize(clientBox.location() - adjustedScrollOffset);
    914     if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) {
    915         bool coordinatorHandlesOffset = compositor()->scrollingLayerDidChange(&m_owningLayer);
    916         m_scrollingContentsLayer->setPosition(coordinatorHandlesOffset ? FloatPoint() : FloatPoint(-adjustedScrollOffset));
    917     }
    918 
    919     m_scrollingContentsLayer->setSize(scrollSize);
    920     // FIXME: The paint offset and the scroll offset should really be separate concepts.
    921     m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
    922 
    923     if (m_foregroundLayer) {
    924         if (m_foregroundLayer->size() != m_scrollingContentsLayer->size())
    925             m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
    926         m_foregroundLayer->setNeedsDisplay();
    927         m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
    928     }
    929 
    930     updateScrollingBlockSelection();
    931 }
    932 
    933 void CompositedLayerMapping::updateChildClippingMaskLayerGeometry()
    934 {
    935     if (!m_childClippingMaskLayer || !renderer()->style()->clipPath())
    936         return;
    937     RenderBox* renderBox = toRenderBox(renderer());
    938     IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
    939 
    940     m_childClippingMaskLayer->setPosition(m_graphicsLayer->position());
    941     m_childClippingMaskLayer->setSize(m_graphicsLayer->size());
    942     m_childClippingMaskLayer->setOffsetFromRenderer(toIntSize(clientBox.location()));
    943 
    944     // NOTE: also some stuff happening in updateChildContainmentLayerGeometry().
    945 }
    946 
    947 void CompositedLayerMapping::updateForegroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize, const IntRect& clippingBox)
    948 {
    949     if (!m_foregroundLayer)
    950         return;
    951 
    952     FloatSize foregroundSize = relativeCompositingBoundsSize;
    953     IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
    954     m_foregroundLayer->setPosition(FloatPoint());
    955 
    956     if (hasClippingLayer()) {
    957         // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
    958         // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
    959         foregroundSize = FloatSize(clippingBox.size());
    960         foregroundOffset = toIntSize(clippingBox.location());
    961     } else if (m_childTransformLayer) {
    962         // Things are different if we have a child transform layer rather
    963         // than a clipping layer. In this case, we want to actually change
    964         // the position of the layer (to compensate for our ancestor
    965         // compositing layer's position) rather than leave the position the
    966         // same and use offset-from-renderer + size to describe a clipped
    967         // "window" onto the clipped layer.
    968 
    969         m_foregroundLayer->setPosition(-m_childTransformLayer->position());
    970     }
    971 
    972     if (foregroundSize != m_foregroundLayer->size()) {
    973         m_foregroundLayer->setSize(foregroundSize);
    974         m_foregroundLayer->setNeedsDisplay();
    975     }
    976     m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
    977 
    978     // NOTE: there is some more configuring going on in updateScrollingLayerGeometry().
    979 }
    980 
    981 void CompositedLayerMapping::updateBackgroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize)
    982 {
    983     if (!m_backgroundLayer)
    984         return;
    985 
    986     FloatSize backgroundSize = relativeCompositingBoundsSize;
    987     if (backgroundLayerPaintsFixedRootBackground()) {
    988         FrameView* frameView = toRenderView(renderer())->frameView();
    989         backgroundSize = frameView->visibleContentRect().size();
    990     }
    991     m_backgroundLayer->setPosition(FloatPoint());
    992     if (backgroundSize != m_backgroundLayer->size()) {
    993         m_backgroundLayer->setSize(backgroundSize);
    994         m_backgroundLayer->setNeedsDisplay();
    995     }
    996     m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
    997 }
    998 
    999 void CompositedLayerMapping::registerScrollingLayers()
   1000 {
   1001     // Register fixed position layers and their containers with the scrolling coordinator.
   1002     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
   1003     if (!scrollingCoordinator)
   1004         return;
   1005 
   1006     scrollingCoordinator->updateLayerPositionConstraint(&m_owningLayer);
   1007 
   1008     // Page scale is applied as a transform on the root render view layer. Because the scroll
   1009     // layer is further up in the hierarchy, we need to avoid marking the root render view
   1010     // layer as a container.
   1011     bool isContainer = m_owningLayer.hasTransform() && !m_owningLayer.isRootLayer();
   1012     // FIXME: we should make certain that childForSuperLayers will never be the m_squashingContainmentLayer here
   1013     scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
   1014 }
   1015 
   1016 void CompositedLayerMapping::updateInternalHierarchy()
   1017 {
   1018     // m_foregroundLayer has to be inserted in the correct order with child layers,
   1019     // so it's not inserted here.
   1020     if (m_ancestorClippingLayer)
   1021         m_ancestorClippingLayer->removeAllChildren();
   1022 
   1023     m_graphicsLayer->removeFromParent();
   1024 
   1025     if (m_ancestorClippingLayer)
   1026         m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
   1027 
   1028     if (m_childContainmentLayer)
   1029         m_graphicsLayer->addChild(m_childContainmentLayer.get());
   1030     else if (m_childTransformLayer)
   1031         m_graphicsLayer->addChild(m_childTransformLayer.get());
   1032 
   1033     if (m_scrollingLayer) {
   1034         GraphicsLayer* superLayer = m_graphicsLayer.get();
   1035 
   1036         if (m_childContainmentLayer)
   1037             superLayer = m_childContainmentLayer.get();
   1038 
   1039         if (m_childTransformLayer)
   1040             superLayer = m_childTransformLayer.get();
   1041 
   1042         superLayer->addChild(m_scrollingLayer.get());
   1043     }
   1044 
   1045     // The clip for child layers does not include space for overflow controls, so they exist as
   1046     // siblings of the clipping layer if we have one. Normal children of this layer are set as
   1047     // children of the clipping layer.
   1048     if (m_overflowControlsClippingLayer) {
   1049         ASSERT(m_overflowControlsHostLayer);
   1050         m_graphicsLayer->addChild(m_overflowControlsClippingLayer.get());
   1051         m_overflowControlsClippingLayer->addChild(m_overflowControlsHostLayer.get());
   1052     } else if (m_overflowControlsHostLayer) {
   1053         m_graphicsLayer->addChild(m_overflowControlsHostLayer.get());
   1054     }
   1055 
   1056     if (m_layerForHorizontalScrollbar)
   1057         m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
   1058     if (m_layerForVerticalScrollbar)
   1059         m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
   1060     if (m_layerForScrollCorner)
   1061         m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
   1062 
   1063     // The squashing containment layer, if it exists, becomes a no-op parent.
   1064     if (m_squashingLayer) {
   1065         ASSERT(compositor()->layerSquashingEnabled());
   1066         ASSERT((m_ancestorClippingLayer && !m_squashingContainmentLayer) || (!m_ancestorClippingLayer && m_squashingContainmentLayer));
   1067 
   1068         if (m_squashingContainmentLayer) {
   1069             m_squashingContainmentLayer->removeAllChildren();
   1070             m_squashingContainmentLayer->addChild(m_graphicsLayer.get());
   1071             m_squashingContainmentLayer->addChild(m_squashingLayer.get());
   1072         } else {
   1073             // The ancestor clipping layer is already set up and has m_graphicsLayer under it.
   1074             m_ancestorClippingLayer->addChild(m_squashingLayer.get());
   1075         }
   1076     }
   1077 }
   1078 
   1079 void CompositedLayerMapping::updatePaintingPhases()
   1080 {
   1081     m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
   1082     if (m_scrollingContentsLayer) {
   1083         GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
   1084         if (!m_foregroundLayer)
   1085             paintPhase |= GraphicsLayerPaintForeground;
   1086         m_scrollingContentsLayer->setPaintingPhase(paintPhase);
   1087         m_scrollingBlockSelectionLayer->setPaintingPhase(paintPhase);
   1088     }
   1089 }
   1090 
   1091 void CompositedLayerMapping::updateContentsRect()
   1092 {
   1093     m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
   1094 }
   1095 
   1096 void CompositedLayerMapping::updateContentsOffsetInCompositingLayer(const IntPoint& snappedOffsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation)
   1097 {
   1098     // m_graphicsLayer is positioned relative to our compositing ancestor
   1099     // RenderLayer, but it's not positioned at the origin of m_owningLayer, it's
   1100     // offset by m_contentBounds.location(). This is what
   1101     // contentOffsetInCompositingLayer is meant to capture, roughly speaking
   1102     // (ignoring rounding and subpixel accumulation).
   1103     //
   1104     // Our ancestor graphics layers in this CLM (m_graphicsLayer and potentially
   1105     // m_ancestorClippingLayer) have pixel snapped, so if we don't adjust this
   1106     // offset, we'll see accumulated rounding errors due to that snapping.
   1107     //
   1108     // In order to ensure that we account for this rounding, we compute
   1109     // contentsOffsetInCompositingLayer in a somewhat roundabout way.
   1110     //
   1111     // our position = (desired position) - (inherited graphics layer offset).
   1112     //
   1113     // Precisely,
   1114     // Offset = snappedOffsetFromCompositedAncestor - offsetDueToAncestorGraphicsLayers (See code below)
   1115     //      = snappedOffsetFromCompositedAncestor - (m_graphicsLayer->position() + graphicsLayerParentLocation)
   1116     //      = snappedOffsetFromCompositedAncestor - (relativeCompositingBounds.location() - graphicsLayerParentLocation + graphicsLayerParentLocation) (See updateMainGraphicsLayerGeometry)
   1117     //      = snappedOffsetFromCompositedAncestor - relativeCompositingBounds.location()
   1118     //      = snappedOffsetFromCompositedAncestor - (pixelSnappedIntRect(contentBounds.location()) + snappedOffsetFromCompositedAncestor) (See computeBoundsOfOwningLayer)
   1119     //      = -pixelSnappedIntRect(contentBounds.location())
   1120     //
   1121     // As you can see, we've ended up at the same spot (-contentBounds.location()),
   1122     // but by subtracting off our ancestor graphics layers positions, we can be
   1123     // sure we've accounted correctly for any pixel snapping due to ancestor
   1124     // graphics layers.
   1125     //
   1126     // And drawing of composited children takes into account the subpixel
   1127     // accumulation of this CLM already (through its own
   1128     // graphicsLayerParentLocation it appears).
   1129     FloatPoint offsetDueToAncestorGraphicsLayers = m_graphicsLayer->position() + graphicsLayerParentLocation;
   1130     m_contentOffsetInCompositingLayer = LayoutSize(snappedOffsetFromCompositedAncestor - offsetDueToAncestorGraphicsLayers);
   1131     m_contentOffsetInCompositingLayerDirty = false;
   1132 }
   1133 
   1134 void CompositedLayerMapping::updateScrollingBlockSelection()
   1135 {
   1136     if (!m_scrollingBlockSelectionLayer)
   1137         return;
   1138 
   1139     if (!m_scrollingContentsAreEmpty) {
   1140         // In this case, the selection will be painted directly into m_scrollingContentsLayer.
   1141         m_scrollingBlockSelectionLayer->setDrawsContent(false);
   1142         return;
   1143     }
   1144 
   1145     const IntRect blockSelectionGapsBounds = m_owningLayer.blockSelectionGapsBounds();
   1146     const bool shouldDrawContent = !blockSelectionGapsBounds.isEmpty();
   1147     m_scrollingBlockSelectionLayer->setDrawsContent(!paintsIntoCompositedAncestor() && shouldDrawContent);
   1148     if (!shouldDrawContent)
   1149         return;
   1150 
   1151     const IntPoint position = blockSelectionGapsBounds.location() + m_owningLayer.scrollableArea()->adjustedScrollOffset();
   1152     if (m_scrollingBlockSelectionLayer->size() == blockSelectionGapsBounds.size() && m_scrollingBlockSelectionLayer->position() == position)
   1153         return;
   1154 
   1155     m_scrollingBlockSelectionLayer->setPosition(position);
   1156     m_scrollingBlockSelectionLayer->setSize(blockSelectionGapsBounds.size());
   1157     m_scrollingBlockSelectionLayer->setOffsetFromRenderer(toIntSize(blockSelectionGapsBounds.location()), GraphicsLayer::SetNeedsDisplay);
   1158 }
   1159 
   1160 void CompositedLayerMapping::updateDrawsContent()
   1161 {
   1162     bool hasPaintedContent = containsPaintedContent();
   1163     m_graphicsLayer->setDrawsContent(hasPaintedContent);
   1164 
   1165     if (m_scrollingLayer) {
   1166         // m_scrollingLayer never has backing store.
   1167         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
   1168         m_scrollingContentsAreEmpty = !m_owningLayer.hasVisibleContent() || !(renderer()->hasBackground() || paintsChildren());
   1169         m_scrollingContentsLayer->setDrawsContent(!paintsIntoCompositedAncestor() && !m_scrollingContentsAreEmpty);
   1170         updateScrollingBlockSelection();
   1171     }
   1172 
   1173     if (hasPaintedContent && isAcceleratedCanvas(renderer())) {
   1174         CanvasRenderingContext* context = toHTMLCanvasElement(renderer()->node())->renderingContext();
   1175         // Content layer may be null if context is lost.
   1176         if (WebLayer* contentLayer = context->platformLayer()) {
   1177             Color bgColor(Color::transparent);
   1178             if (contentLayerSupportsDirectBackgroundComposition(renderer())) {
   1179                 bgColor = rendererBackgroundColor();
   1180                 hasPaintedContent = false;
   1181             }
   1182             contentLayer->setBackgroundColor(bgColor.rgb());
   1183         }
   1184     }
   1185 
   1186     // FIXME: we could refine this to only allocate backings for one of these layers if possible.
   1187     if (m_foregroundLayer)
   1188         m_foregroundLayer->setDrawsContent(hasPaintedContent);
   1189 
   1190     if (m_backgroundLayer)
   1191         m_backgroundLayer->setDrawsContent(hasPaintedContent);
   1192 
   1193     if (m_maskLayer)
   1194         m_maskLayer->setDrawsContent(!paintsIntoCompositedAncestor());
   1195 
   1196     if (m_childClippingMaskLayer)
   1197         m_childClippingMaskLayer->setDrawsContent(!paintsIntoCompositedAncestor());
   1198 }
   1199 
   1200 void CompositedLayerMapping::updateChildrenTransform()
   1201 {
   1202     if (GraphicsLayer* childTransformLayer = layerForChildrenTransform()) {
   1203         childTransformLayer->setTransform(owningLayer().perspectiveTransform());
   1204         childTransformLayer->setTransformOrigin(FloatPoint3D(childTransformLayer->size().width() * 0.5f, childTransformLayer->size().height() * 0.5f, 0.f));
   1205     }
   1206 
   1207     updateShouldFlattenTransform();
   1208 }
   1209 
   1210 // Return true if the layers changed.
   1211 bool CompositedLayerMapping::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
   1212 {
   1213     bool layersChanged = false;
   1214 
   1215     if (needsAncestorClip) {
   1216         if (!m_ancestorClippingLayer) {
   1217             m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForAncestorClip);
   1218             m_ancestorClippingLayer->setMasksToBounds(true);
   1219             m_ancestorClippingLayer->setShouldFlattenTransform(false);
   1220             layersChanged = true;
   1221         }
   1222     } else if (m_ancestorClippingLayer) {
   1223         m_ancestorClippingLayer->removeFromParent();
   1224         m_ancestorClippingLayer = nullptr;
   1225         layersChanged = true;
   1226     }
   1227 
   1228     if (needsDescendantClip) {
   1229         // We don't need a child containment layer if we're the main frame render view
   1230         // layer. It's redundant as the frame clip above us will handle this clipping.
   1231         if (!m_childContainmentLayer && !m_isMainFrameRenderViewLayer) {
   1232             m_childContainmentLayer = createGraphicsLayer(CompositingReasonLayerForDescendantClip);
   1233             m_childContainmentLayer->setMasksToBounds(true);
   1234             layersChanged = true;
   1235         }
   1236     } else if (hasClippingLayer()) {
   1237         m_childContainmentLayer->removeFromParent();
   1238         m_childContainmentLayer = nullptr;
   1239         layersChanged = true;
   1240     }
   1241 
   1242     return layersChanged;
   1243 }
   1244 
   1245 bool CompositedLayerMapping::updateChildTransformLayer(bool needsChildTransformLayer)
   1246 {
   1247     bool layersChanged = false;
   1248 
   1249     if (needsChildTransformLayer) {
   1250         if (!m_childTransformLayer) {
   1251             m_childTransformLayer = createGraphicsLayer(CompositingReasonLayerForPerspective);
   1252             m_childTransformLayer->setDrawsContent(false);
   1253             layersChanged = true;
   1254         }
   1255     } else if (m_childTransformLayer) {
   1256         m_childTransformLayer->removeFromParent();
   1257         m_childTransformLayer = nullptr;
   1258         layersChanged = true;
   1259     }
   1260 
   1261     return layersChanged;
   1262 }
   1263 
   1264 void CompositedLayerMapping::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
   1265 {
   1266     m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
   1267 }
   1268 
   1269 // Only a member function so it can call createGraphicsLayer.
   1270 bool CompositedLayerMapping::toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>& layer, bool needsLayer, CompositingReasons reason)
   1271 {
   1272     if (needsLayer == !!layer)
   1273         return false;
   1274     layer = needsLayer ? createGraphicsLayer(reason) : nullptr;
   1275     return true;
   1276 }
   1277 
   1278 bool CompositedLayerMapping::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer, bool needsAncestorClip)
   1279 {
   1280     bool horizontalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForHorizontalScrollbar, needsHorizontalScrollbarLayer, CompositingReasonLayerForHorizontalScrollbar);
   1281     bool verticalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForVerticalScrollbar, needsVerticalScrollbarLayer, CompositingReasonLayerForVerticalScrollbar);
   1282     bool scrollCornerLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForScrollCorner, needsScrollCornerLayer, CompositingReasonLayerForScrollCorner);
   1283 
   1284     bool needsOverflowControlsHostLayer = needsHorizontalScrollbarLayer || needsVerticalScrollbarLayer || needsScrollCornerLayer;
   1285     toggleScrollbarLayerIfNeeded(m_overflowControlsHostLayer, needsOverflowControlsHostLayer, CompositingReasonLayerForOverflowControlsHost);
   1286     bool needsOverflowClipLayer = needsOverflowControlsHostLayer && needsAncestorClip;
   1287     toggleScrollbarLayerIfNeeded(m_overflowControlsClippingLayer, needsOverflowClipLayer, CompositingReasonLayerForOverflowControlsHost);
   1288 
   1289     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
   1290         if (horizontalScrollbarLayerChanged)
   1291             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer.scrollableArea(), HorizontalScrollbar);
   1292         if (verticalScrollbarLayerChanged)
   1293             scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer.scrollableArea(), VerticalScrollbar);
   1294     }
   1295 
   1296     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
   1297 }
   1298 
   1299 void CompositedLayerMapping::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
   1300 {
   1301     IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer() - roundedIntSize(m_owningLayer.subpixelAccumulation());
   1302     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
   1303         Scrollbar* hBar = m_owningLayer.scrollableArea()->horizontalScrollbar();
   1304         if (hBar) {
   1305             layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
   1306             layer->setSize(hBar->frameRect().size());
   1307             if (layer->hasContentsLayer())
   1308                 layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
   1309         }
   1310         layer->setDrawsContent(hBar && !layer->hasContentsLayer());
   1311     }
   1312 
   1313     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
   1314         Scrollbar* vBar = m_owningLayer.scrollableArea()->verticalScrollbar();
   1315         if (vBar) {
   1316             layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
   1317             layer->setSize(vBar->frameRect().size());
   1318             if (layer->hasContentsLayer())
   1319                 layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
   1320         }
   1321         layer->setDrawsContent(vBar && !layer->hasContentsLayer());
   1322     }
   1323 
   1324     if (GraphicsLayer* layer = layerForScrollCorner()) {
   1325         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
   1326         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
   1327         layer->setSize(scrollCornerAndResizer.size());
   1328         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
   1329     }
   1330 }
   1331 
   1332 bool CompositedLayerMapping::hasUnpositionedOverflowControlsLayers() const
   1333 {
   1334     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
   1335         if (!layer->drawsContent())
   1336             return true;
   1337     }
   1338 
   1339     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
   1340         if (!layer->drawsContent())
   1341             return true;
   1342     }
   1343 
   1344     if (GraphicsLayer* layer = layerForScrollCorner()) {
   1345         if (!layer->drawsContent())
   1346             return true;
   1347     }
   1348 
   1349     return false;
   1350 }
   1351 
   1352 enum ApplyToGraphicsLayersModeFlags {
   1353     ApplyToLayersAffectedByPreserve3D = (1 << 0),
   1354     ApplyToSquashingLayer = (1 << 1),
   1355     ApplyToScrollbarLayers = (1 << 2),
   1356     ApplyToBackgroundLayer = (1 << 3),
   1357     ApplyToMaskLayers = (1 << 4),
   1358     ApplyToContentLayers = (1 << 5),
   1359     ApplyToAllGraphicsLayers = (ApplyToSquashingLayer | ApplyToScrollbarLayers | ApplyToBackgroundLayer | ApplyToMaskLayers | ApplyToLayersAffectedByPreserve3D | ApplyToContentLayers)
   1360 };
   1361 typedef unsigned ApplyToGraphicsLayersMode;
   1362 
   1363 template <typename Func>
   1364 static void ApplyToGraphicsLayers(const CompositedLayerMapping* mapping, const Func& f, ApplyToGraphicsLayersMode mode)
   1365 {
   1366     ASSERT(mode);
   1367 
   1368     if ((mode & ApplyToLayersAffectedByPreserve3D) && mapping->childTransformLayer())
   1369         f(mapping->childTransformLayer());
   1370     if (((mode & ApplyToLayersAffectedByPreserve3D) || (mode & ApplyToContentLayers)) && mapping->mainGraphicsLayer())
   1371         f(mapping->mainGraphicsLayer());
   1372     if ((mode & ApplyToLayersAffectedByPreserve3D) && mapping->clippingLayer())
   1373         f(mapping->clippingLayer());
   1374     if ((mode & ApplyToLayersAffectedByPreserve3D) && mapping->scrollingLayer())
   1375         f(mapping->scrollingLayer());
   1376     if ((mode & ApplyToLayersAffectedByPreserve3D) && mapping->scrollingBlockSelectionLayer())
   1377         f(mapping->scrollingBlockSelectionLayer());
   1378     if (((mode & ApplyToLayersAffectedByPreserve3D) || (mode & ApplyToContentLayers)) && mapping->scrollingContentsLayer())
   1379         f(mapping->scrollingContentsLayer());
   1380     if (((mode & ApplyToLayersAffectedByPreserve3D) || (mode & ApplyToContentLayers)) && mapping->foregroundLayer())
   1381         f(mapping->foregroundLayer());
   1382 
   1383     if ((mode & ApplyToSquashingLayer) && mapping->squashingLayer())
   1384         f(mapping->squashingLayer());
   1385 
   1386     if (((mode & ApplyToMaskLayers) || (mode & ApplyToContentLayers)) && mapping->maskLayer())
   1387         f(mapping->maskLayer());
   1388     if (((mode & ApplyToMaskLayers) || (mode & ApplyToContentLayers)) && mapping->childClippingMaskLayer())
   1389         f(mapping->childClippingMaskLayer());
   1390 
   1391     if (((mode & ApplyToBackgroundLayer) || (mode & ApplyToContentLayers)) && mapping->backgroundLayer())
   1392         f(mapping->backgroundLayer());
   1393 
   1394     if ((mode & ApplyToScrollbarLayers) && mapping->layerForHorizontalScrollbar())
   1395         f(mapping->layerForHorizontalScrollbar());
   1396     if ((mode & ApplyToScrollbarLayers) && mapping->layerForVerticalScrollbar())
   1397         f(mapping->layerForVerticalScrollbar());
   1398     if ((mode & ApplyToScrollbarLayers) && mapping->layerForScrollCorner())
   1399         f(mapping->layerForScrollCorner());
   1400 }
   1401 
   1402 struct UpdateRenderingContextFunctor {
   1403     void operator() (GraphicsLayer* layer) const { layer->setRenderingContext(renderingContext); }
   1404     int renderingContext;
   1405 };
   1406 
   1407 void CompositedLayerMapping::updateRenderingContext()
   1408 {
   1409     // All layers but the squashing layer (which contains 'alien' content) should be included in this
   1410     // rendering context.
   1411     int id = 0;
   1412 
   1413     // NB, it is illegal at this point to query an ancestor's compositing state. Some compositing
   1414     // reasons depend on the compositing state of ancestors. So if we want a rendering context id
   1415     // for the context root, we cannot ask for the id of its associated WebLayer now; it may not have
   1416     // one yet. We could do a second past after doing the compositing updates to get these ids,
   1417     // but this would actually be harmful. We do not want to attach any semantic meaning to
   1418     // the context id other than the fact that they group a number of layers together for the
   1419     // sake of 3d sorting. So instead we will ask the compositor to vend us an arbitrary, but
   1420     // consistent id.
   1421     if (RenderLayer* root = m_owningLayer.renderingContextRoot()) {
   1422         if (Node* node = root->renderer()->node())
   1423             id = static_cast<int>(WTF::PtrHash<Node*>::hash(node));
   1424     }
   1425 
   1426     UpdateRenderingContextFunctor functor = { id };
   1427     ApplyToGraphicsLayersMode mode = ApplyToAllGraphicsLayers & ~ApplyToSquashingLayer;
   1428     ApplyToGraphicsLayers<UpdateRenderingContextFunctor>(this, functor, mode);
   1429 }
   1430 
   1431 struct UpdateShouldFlattenTransformFunctor {
   1432     void operator() (GraphicsLayer* layer) const { layer->setShouldFlattenTransform(shouldFlatten); }
   1433     bool shouldFlatten;
   1434 };
   1435 
   1436 void CompositedLayerMapping::updateShouldFlattenTransform()
   1437 {
   1438     // All CLM-managed layers that could affect a descendant layer should update their
   1439     // should-flatten-transform value (the other layers' transforms don't matter here).
   1440     UpdateShouldFlattenTransformFunctor functor = { !m_owningLayer.shouldPreserve3D() };
   1441     ApplyToGraphicsLayersMode mode = ApplyToLayersAffectedByPreserve3D;
   1442     ApplyToGraphicsLayers(this, functor, mode);
   1443 
   1444     // Note, if we apply perspective, we have to set should flatten differently
   1445     // so that the transform propagates to child layers correctly.
   1446     if (GraphicsLayer* childTransformLayer = layerForChildrenTransform()) {
   1447         bool hasPerspective = false;
   1448         if (RenderStyle* style = m_owningLayer.renderer()->style())
   1449             hasPerspective = style->hasPerspective();
   1450         if (hasPerspective)
   1451             childTransformLayer->setShouldFlattenTransform(false);
   1452 
   1453         // Note, if the target is the scrolling layer, we need to ensure that the
   1454         // scrolling content layer doesn't flatten the transform. (It would be nice
   1455         // if we could apply transform to the scrolling content layer, but that's
   1456         // too late, we need the children transform to be applied _before_ the
   1457         // scrolling offset.)
   1458         if (childTransformLayer == m_scrollingLayer.get()) {
   1459             m_scrollingContentsLayer->setShouldFlattenTransform(false);
   1460             m_scrollingBlockSelectionLayer->setShouldFlattenTransform(false);
   1461         }
   1462     }
   1463 }
   1464 
   1465 bool CompositedLayerMapping::updateForegroundLayer(bool needsForegroundLayer)
   1466 {
   1467     bool layerChanged = false;
   1468     if (needsForegroundLayer) {
   1469         if (!m_foregroundLayer) {
   1470             m_foregroundLayer = createGraphicsLayer(CompositingReasonLayerForForeground);
   1471             m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
   1472             layerChanged = true;
   1473         }
   1474     } else if (m_foregroundLayer) {
   1475         m_foregroundLayer->removeFromParent();
   1476         m_foregroundLayer = nullptr;
   1477         layerChanged = true;
   1478     }
   1479 
   1480     return layerChanged;
   1481 }
   1482 
   1483 bool CompositedLayerMapping::updateBackgroundLayer(bool needsBackgroundLayer)
   1484 {
   1485     bool layerChanged = false;
   1486     if (needsBackgroundLayer) {
   1487         if (!m_backgroundLayer) {
   1488             m_backgroundLayer = createGraphicsLayer(CompositingReasonLayerForBackground);
   1489             m_backgroundLayer->setTransformOrigin(FloatPoint3D());
   1490             m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
   1491 #if !OS(ANDROID)
   1492             m_backgroundLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
   1493             m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(false);
   1494 #endif
   1495             layerChanged = true;
   1496         }
   1497     } else {
   1498         if (m_backgroundLayer) {
   1499             m_backgroundLayer->removeFromParent();
   1500             m_backgroundLayer = nullptr;
   1501 #if !OS(ANDROID)
   1502             m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
   1503 #endif
   1504             layerChanged = true;
   1505         }
   1506     }
   1507 
   1508     if (layerChanged && !m_owningLayer.renderer()->documentBeingDestroyed())
   1509         compositor()->rootFixedBackgroundsChanged();
   1510 
   1511     return layerChanged;
   1512 }
   1513 
   1514 bool CompositedLayerMapping::updateMaskLayer(bool needsMaskLayer)
   1515 {
   1516     bool layerChanged = false;
   1517     if (needsMaskLayer) {
   1518         if (!m_maskLayer) {
   1519             m_maskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
   1520             m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
   1521             layerChanged = true;
   1522         }
   1523     } else if (m_maskLayer) {
   1524         m_maskLayer = nullptr;
   1525         layerChanged = true;
   1526     }
   1527 
   1528     return layerChanged;
   1529 }
   1530 
   1531 bool CompositedLayerMapping::updateClippingMaskLayers(bool needsChildClippingMaskLayer)
   1532 {
   1533     bool layerChanged = false;
   1534     if (needsChildClippingMaskLayer) {
   1535         if (!m_childClippingMaskLayer) {
   1536             m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForClippingMask);
   1537             m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
   1538             layerChanged = true;
   1539         }
   1540     } else if (m_childClippingMaskLayer) {
   1541         m_childClippingMaskLayer = nullptr;
   1542         layerChanged = true;
   1543     }
   1544     return layerChanged;
   1545 }
   1546 
   1547 bool CompositedLayerMapping::updateScrollingLayers(bool needsScrollingLayers)
   1548 {
   1549     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
   1550 
   1551     bool layerChanged = false;
   1552     if (needsScrollingLayers) {
   1553         if (!m_scrollingLayer) {
   1554             // Outer layer which corresponds with the scroll view.
   1555             m_scrollingLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContainer);
   1556             m_scrollingLayer->setDrawsContent(false);
   1557             m_scrollingLayer->setMasksToBounds(true);
   1558 
   1559             // Inner layer which renders the content that scrolls.
   1560             m_scrollingContentsLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContents);
   1561             m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
   1562 
   1563             m_scrollingBlockSelectionLayer = createGraphicsLayer(CompositingReasonLayerForScrollingBlockSelection);
   1564             m_scrollingBlockSelectionLayer->setDrawsContent(true);
   1565             m_scrollingContentsLayer->addChild(m_scrollingBlockSelectionLayer.get());
   1566 
   1567             layerChanged = true;
   1568             if (scrollingCoordinator)
   1569                 scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
   1570         }
   1571     } else if (m_scrollingLayer) {
   1572         m_scrollingLayer = nullptr;
   1573         m_scrollingContentsLayer = nullptr;
   1574         m_scrollingBlockSelectionLayer = nullptr;
   1575         layerChanged = true;
   1576         if (scrollingCoordinator)
   1577             scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
   1578     }
   1579 
   1580     return layerChanged;
   1581 }
   1582 
   1583 static void updateScrollParentForGraphicsLayer(GraphicsLayer* layer, GraphicsLayer* topmostLayer, RenderLayer* scrollParent, ScrollingCoordinator* scrollingCoordinator)
   1584 {
   1585     if (!layer)
   1586         return;
   1587 
   1588     // Only the topmost layer has a scroll parent. All other layers have a null scroll parent.
   1589     if (layer != topmostLayer)
   1590         scrollParent = 0;
   1591 
   1592     scrollingCoordinator->updateScrollParentForGraphicsLayer(layer, scrollParent);
   1593 }
   1594 
   1595 void CompositedLayerMapping::updateScrollParent(RenderLayer* scrollParent)
   1596 {
   1597     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
   1598         GraphicsLayer* topmostLayer = childForSuperlayers();
   1599         updateScrollParentForGraphicsLayer(m_squashingContainmentLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
   1600         updateScrollParentForGraphicsLayer(m_ancestorClippingLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
   1601         updateScrollParentForGraphicsLayer(m_graphicsLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
   1602     }
   1603 }
   1604 
   1605 void CompositedLayerMapping::updateClipParent()
   1606 {
   1607     if (owningLayerClippedByLayerNotAboveCompositedAncestor())
   1608         return;
   1609 
   1610     RenderLayer* clipParent = m_owningLayer.clipParent();
   1611     if (clipParent)
   1612         clipParent = clipParent->enclosingLayerWithCompositedLayerMapping(IncludeSelf);
   1613 
   1614     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer))
   1615         scrollingCoordinator->updateClipParentForGraphicsLayer(m_graphicsLayer.get(), clipParent);
   1616 }
   1617 
   1618 bool CompositedLayerMapping::updateSquashingLayers(bool needsSquashingLayers)
   1619 {
   1620     bool layersChanged = false;
   1621 
   1622     if (needsSquashingLayers) {
   1623         ASSERT(compositor()->layerSquashingEnabled());
   1624 
   1625         if (!m_squashingLayer) {
   1626             m_squashingLayer = createGraphicsLayer(CompositingReasonLayerForSquashingContents);
   1627             m_squashingLayer->setDrawsContent(true);
   1628             layersChanged = true;
   1629         }
   1630 
   1631         if (m_ancestorClippingLayer) {
   1632             if (m_squashingContainmentLayer) {
   1633                 m_squashingContainmentLayer->removeFromParent();
   1634                 m_squashingContainmentLayer = nullptr;
   1635                 layersChanged = true;
   1636             }
   1637         } else {
   1638             if (!m_squashingContainmentLayer) {
   1639                 m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonLayerForSquashingContainer);
   1640                 m_squashingContainmentLayer->setShouldFlattenTransform(false);
   1641                 layersChanged = true;
   1642             }
   1643         }
   1644 
   1645         ASSERT((m_ancestorClippingLayer && !m_squashingContainmentLayer) || (!m_ancestorClippingLayer && m_squashingContainmentLayer));
   1646         ASSERT(m_squashingLayer);
   1647     } else {
   1648         if (m_squashingLayer) {
   1649             m_squashingLayer->removeFromParent();
   1650             m_squashingLayer = nullptr;
   1651             layersChanged = true;
   1652         }
   1653         if (m_squashingContainmentLayer) {
   1654             m_squashingContainmentLayer->removeFromParent();
   1655             m_squashingContainmentLayer = nullptr;
   1656             layersChanged = true;
   1657         }
   1658         ASSERT(!m_squashingLayer && !m_squashingContainmentLayer);
   1659     }
   1660 
   1661     return layersChanged;
   1662 }
   1663 
   1664 GraphicsLayerPaintingPhase CompositedLayerMapping::paintingPhaseForPrimaryLayer() const
   1665 {
   1666     unsigned phase = 0;
   1667     if (!m_backgroundLayer)
   1668         phase |= GraphicsLayerPaintBackground;
   1669     if (!m_foregroundLayer)
   1670         phase |= GraphicsLayerPaintForeground;
   1671     if (!m_maskLayer)
   1672         phase |= GraphicsLayerPaintMask;
   1673 
   1674     if (m_scrollingContentsLayer) {
   1675         phase &= ~GraphicsLayerPaintForeground;
   1676         phase |= GraphicsLayerPaintCompositedScroll;
   1677     }
   1678 
   1679     return static_cast<GraphicsLayerPaintingPhase>(phase);
   1680 }
   1681 
   1682 float CompositedLayerMapping::compositingOpacity(float rendererOpacity) const
   1683 {
   1684     float finalOpacity = rendererOpacity;
   1685 
   1686     for (RenderLayer* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
   1687         // We only care about parents that are stacking contexts.
   1688         // Recall that opacity creates stacking context.
   1689         if (!curr->stackingNode()->isStackingContext())
   1690             continue;
   1691 
   1692         // If we found a composited layer, regardless of whether it actually
   1693         // paints into it, we want to compute opacity relative to it. So we can
   1694         // break here.
   1695         //
   1696         // FIXME: with grouped backings, a composited descendant will have to
   1697         // continue past the grouped (squashed) layers that its parents may
   1698         // contribute to. This whole confusion can be avoided by specifying
   1699         // explicitly the composited ancestor where we would stop accumulating
   1700         // opacity.
   1701         if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == HasOwnBackingButPaintsIntoAncestor)
   1702             break;
   1703 
   1704         finalOpacity *= curr->renderer()->opacity();
   1705     }
   1706 
   1707     return finalOpacity;
   1708 }
   1709 
   1710 Color CompositedLayerMapping::rendererBackgroundColor() const
   1711 {
   1712     RenderObject* backgroundRenderer = renderer();
   1713     if (backgroundRenderer->isDocumentElement())
   1714         backgroundRenderer = backgroundRenderer->rendererForRootBackground();
   1715 
   1716     return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor);
   1717 }
   1718 
   1719 void CompositedLayerMapping::updateBackgroundColor()
   1720 {
   1721     m_graphicsLayer->setBackgroundColor(rendererBackgroundColor());
   1722 }
   1723 
   1724 bool CompositedLayerMapping::paintsChildren() const
   1725 {
   1726     if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
   1727         return true;
   1728 
   1729     if (hasVisibleNonCompositingDescendant(&m_owningLayer))
   1730         return true;
   1731 
   1732     return false;
   1733 }
   1734 
   1735 static bool isCompositedPlugin(RenderObject* renderer)
   1736 {
   1737     return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->requiresAcceleratedCompositing();
   1738 }
   1739 
   1740 bool CompositedLayerMapping::hasVisibleNonCompositingDescendant(RenderLayer* parent)
   1741 {
   1742     if (!parent->hasVisibleDescendant())
   1743         return false;
   1744 
   1745     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
   1746     parent->stackingNode()->updateLayerListsIfNeeded();
   1747 
   1748 #if ENABLE(ASSERT)
   1749     LayerListMutationDetector mutationChecker(parent->stackingNode());
   1750 #endif
   1751 
   1752     RenderLayerStackingNodeIterator normalFlowIterator(*parent->stackingNode(), AllChildren);
   1753     while (RenderLayerStackingNode* curNode = normalFlowIterator.next()) {
   1754         RenderLayer* curLayer = curNode->layer();
   1755         if (curLayer->hasCompositedLayerMapping())
   1756             continue;
   1757         if (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer))
   1758             return true;
   1759     }
   1760 
   1761     return false;
   1762 }
   1763 
   1764 bool CompositedLayerMapping::containsPaintedContent() const
   1765 {
   1766     if (paintsIntoCompositedAncestor() || m_owningLayer.isReflection())
   1767         return false;
   1768 
   1769     if (renderer()->isImage() && isDirectlyCompositedImage())
   1770         return false;
   1771 
   1772     RenderObject* renderObject = renderer();
   1773     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
   1774     // and set background color on the layer in that case, instead of allocating backing store and painting.
   1775     if (renderObject->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
   1776         return m_owningLayer.hasBoxDecorationsOrBackground();
   1777 
   1778     if (m_owningLayer.hasVisibleBoxDecorations())
   1779         return true;
   1780 
   1781     if (renderObject->hasMask()) // masks require special treatment
   1782         return true;
   1783 
   1784     if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
   1785         return true;
   1786 
   1787     if (renderObject->isRenderRegion())
   1788         return true;
   1789 
   1790     if (renderObject->node() && renderObject->node()->isDocumentNode()) {
   1791         // Look to see if the root object has a non-simple background
   1792         RenderObject* rootObject = renderObject->document().documentElement() ? renderObject->document().documentElement()->renderer() : 0;
   1793         // Reject anything that has a border, a border-radius or outline,
   1794         // or is not a simple background (no background, or solid color).
   1795         if (rootObject && hasBoxDecorationsOrBackgroundImage(rootObject->style()))
   1796             return true;
   1797 
   1798         // Now look at the body's renderer.
   1799         HTMLElement* body = renderObject->document().body();
   1800         RenderObject* bodyObject = isHTMLBodyElement(body) ? body->renderer() : 0;
   1801         if (bodyObject && hasBoxDecorationsOrBackgroundImage(bodyObject->style()))
   1802             return true;
   1803     }
   1804 
   1805     // FIXME: it's O(n^2). A better solution is needed.
   1806     return paintsChildren();
   1807 }
   1808 
   1809 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
   1810 // that require painting. Direct compositing saves backing store.
   1811 bool CompositedLayerMapping::isDirectlyCompositedImage() const
   1812 {
   1813     ASSERT(renderer()->isImage());
   1814 
   1815     RenderObject* renderObject = renderer();
   1816     if (m_owningLayer.hasBoxDecorationsOrBackground() || renderObject->hasClip() || renderObject->hasClipPath())
   1817         return false;
   1818 
   1819     RenderImage* imageRenderer = toRenderImage(renderObject);
   1820     if (ImageResource* cachedImage = imageRenderer->cachedImage()) {
   1821         if (!cachedImage->hasImage())
   1822             return false;
   1823 
   1824         Image* image = cachedImage->imageForRenderer(imageRenderer);
   1825         return image->isBitmapImage();
   1826     }
   1827 
   1828     return false;
   1829 }
   1830 
   1831 void CompositedLayerMapping::contentChanged(ContentChangeType changeType)
   1832 {
   1833     if ((changeType == ImageChanged) && renderer()->isImage() && isDirectlyCompositedImage()) {
   1834         updateImageContents();
   1835         return;
   1836     }
   1837 
   1838     if (changeType == CanvasChanged && isAcceleratedCanvas(renderer())) {
   1839         m_graphicsLayer->setContentsNeedsDisplay();
   1840         return;
   1841     }
   1842 }
   1843 
   1844 void CompositedLayerMapping::updateImageContents()
   1845 {
   1846     ASSERT(renderer()->isImage());
   1847     RenderImage* imageRenderer = toRenderImage(renderer());
   1848 
   1849     ImageResource* cachedImage = imageRenderer->cachedImage();
   1850     if (!cachedImage)
   1851         return;
   1852 
   1853     Image* image = cachedImage->imageForRenderer(imageRenderer);
   1854     if (!image)
   1855         return;
   1856 
   1857     // We have to wait until the image is fully loaded before setting it on the layer.
   1858     if (!cachedImage->isLoaded())
   1859         return;
   1860 
   1861     // This is a no-op if the layer doesn't have an inner layer for the image.
   1862     m_graphicsLayer->setContentsToImage(image);
   1863 
   1864     // Prevent double-drawing: https://bugs.webkit.org/show_bug.cgi?id=58632
   1865     updateDrawsContent();
   1866 
   1867     // Image animation is "lazy", in that it automatically stops unless someone is drawing
   1868     // the image. So we have to kick the animation each time; this has the downside that the
   1869     // image will keep animating, even if its layer is not visible.
   1870     image->startAnimation();
   1871 }
   1872 
   1873 FloatPoint3D CompositedLayerMapping::computeTransformOrigin(const IntRect& borderBox) const
   1874 {
   1875     RenderStyle* style = renderer()->style();
   1876 
   1877     FloatPoint3D origin;
   1878     origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width()));
   1879     origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height()));
   1880     origin.setZ(style->transformOriginZ());
   1881 
   1882     return origin;
   1883 }
   1884 
   1885 // Return the offset from the top-left of this compositing layer at which the
   1886 // renderer's contents are painted.
   1887 LayoutSize CompositedLayerMapping::contentOffsetInCompositingLayer() const
   1888 {
   1889     ASSERT(!m_contentOffsetInCompositingLayerDirty);
   1890     return m_contentOffsetInCompositingLayer;
   1891 }
   1892 
   1893 LayoutRect CompositedLayerMapping::contentsBox() const
   1894 {
   1895     LayoutRect contentsBox = contentsRect(renderer());
   1896     contentsBox.move(contentOffsetInCompositingLayer());
   1897     return contentsBox;
   1898 }
   1899 
   1900 bool CompositedLayerMapping::needsToReparentOverflowControls() const
   1901 {
   1902     return m_owningLayer.scrollableArea()
   1903         && m_owningLayer.scrollableArea()->hasOverlayScrollbars()
   1904         && m_owningLayer.scrollableArea()->topmostScrollChild();
   1905 }
   1906 
   1907 GraphicsLayer* CompositedLayerMapping::detachLayerForOverflowControls(const RenderLayer& enclosingLayer)
   1908 {
   1909     GraphicsLayer* host = m_overflowControlsClippingLayer.get();
   1910     if (!host)
   1911         host = m_overflowControlsHostLayer.get();
   1912     host->removeFromParent();
   1913     return host;
   1914 }
   1915 
   1916 GraphicsLayer* CompositedLayerMapping::parentForSublayers() const
   1917 {
   1918     if (m_scrollingBlockSelectionLayer)
   1919         return m_scrollingBlockSelectionLayer.get();
   1920 
   1921     if (m_scrollingContentsLayer)
   1922         return m_scrollingContentsLayer.get();
   1923 
   1924     if (m_childContainmentLayer)
   1925         return m_childContainmentLayer.get();
   1926 
   1927     if (m_childTransformLayer)
   1928         return m_childTransformLayer.get();
   1929 
   1930     return m_graphicsLayer.get();
   1931 }
   1932 
   1933 GraphicsLayer* CompositedLayerMapping::childForSuperlayers() const
   1934 {
   1935     if (m_squashingContainmentLayer)
   1936         return m_squashingContainmentLayer.get();
   1937 
   1938     if (m_ancestorClippingLayer)
   1939         return m_ancestorClippingLayer.get();
   1940 
   1941     return m_graphicsLayer.get();
   1942 }
   1943 
   1944 GraphicsLayer* CompositedLayerMapping::layerForChildrenTransform() const
   1945 {
   1946     if (GraphicsLayer* clipLayer = clippingLayer())
   1947         return clipLayer;
   1948     if (m_scrollingLayer)
   1949         return m_scrollingLayer.get();
   1950     return m_childTransformLayer.get();
   1951 }
   1952 
   1953 bool CompositedLayerMapping::updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestorLayer)
   1954 {
   1955     unsigned previousRequiresOwnBackingStoreForAncestorReasons = m_requiresOwnBackingStoreForAncestorReasons;
   1956     bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
   1957     bool canPaintIntoAncestor = compositingAncestorLayer
   1958         && (compositingAncestorLayer->compositedLayerMapping()->mainGraphicsLayer()->drawsContent()
   1959             || compositingAncestorLayer->compositedLayerMapping()->paintsIntoCompositedAncestor());
   1960 
   1961     m_requiresOwnBackingStoreForAncestorReasons = !canPaintIntoAncestor;
   1962     if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor) {
   1963         // Back out the change temporarily while invalidating with respect to the old container.
   1964         m_requiresOwnBackingStoreForAncestorReasons = !m_requiresOwnBackingStoreForAncestorReasons;
   1965         compositor()->paintInvalidationOnCompositingChange(&m_owningLayer);
   1966         m_requiresOwnBackingStoreForAncestorReasons = !m_requiresOwnBackingStoreForAncestorReasons;
   1967     }
   1968 
   1969     return m_requiresOwnBackingStoreForAncestorReasons != previousRequiresOwnBackingStoreForAncestorReasons;
   1970 }
   1971 
   1972 bool CompositedLayerMapping::updateRequiresOwnBackingStoreForIntrinsicReasons()
   1973 {
   1974     unsigned previousRequiresOwnBackingStoreForIntrinsicReasons = m_requiresOwnBackingStoreForIntrinsicReasons;
   1975     bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
   1976     RenderObject* renderer = m_owningLayer.renderer();
   1977     m_requiresOwnBackingStoreForIntrinsicReasons = m_owningLayer.isRootLayer()
   1978         || (m_owningLayer.compositingReasons() & CompositingReasonComboReasonsThatRequireOwnBacking)
   1979         || m_owningLayer.transform()
   1980         || m_owningLayer.clipsCompositingDescendantsWithBorderRadius() // FIXME: Revisit this if the paintsIntoCompositedAncestor state is removed.
   1981         || renderer->isTransparent()
   1982         || renderer->hasMask()
   1983         || renderer->hasReflection()
   1984         || renderer->hasFilter();
   1985 
   1986     if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor) {
   1987         // Back out the change temporarily while invalidating with respect to the old container.
   1988         m_requiresOwnBackingStoreForIntrinsicReasons = !m_requiresOwnBackingStoreForIntrinsicReasons;
   1989         compositor()->paintInvalidationOnCompositingChange(&m_owningLayer);
   1990         m_requiresOwnBackingStoreForIntrinsicReasons = !m_requiresOwnBackingStoreForIntrinsicReasons;
   1991     }
   1992 
   1993     return m_requiresOwnBackingStoreForIntrinsicReasons != previousRequiresOwnBackingStoreForIntrinsicReasons;
   1994 }
   1995 
   1996 void CompositedLayerMapping::setBlendMode(WebBlendMode blendMode)
   1997 {
   1998     if (m_ancestorClippingLayer) {
   1999         m_ancestorClippingLayer->setBlendMode(blendMode);
   2000         m_graphicsLayer->setBlendMode(WebBlendModeNormal);
   2001     } else {
   2002         m_graphicsLayer->setBlendMode(blendMode);
   2003     }
   2004 }
   2005 
   2006 GraphicsLayerUpdater::UpdateType CompositedLayerMapping::updateTypeForChildren(GraphicsLayerUpdater::UpdateType updateType) const
   2007 {
   2008     if (m_pendingUpdateScope >= GraphicsLayerUpdateSubtree)
   2009         return GraphicsLayerUpdater::ForceUpdate;
   2010     return updateType;
   2011 }
   2012 
   2013 struct SetContentsNeedsDisplayFunctor {
   2014     void operator() (GraphicsLayer* layer) const
   2015     {
   2016         if (layer->drawsContent())
   2017             layer->setNeedsDisplay();
   2018     }
   2019 };
   2020 
   2021 void CompositedLayerMapping::setSquashingContentsNeedDisplay()
   2022 {
   2023     ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(), ApplyToSquashingLayer);
   2024 }
   2025 
   2026 void CompositedLayerMapping::setContentsNeedDisplay()
   2027 {
   2028     // FIXME: need to split out paint invalidations for the background.
   2029     ASSERT(!paintsIntoCompositedAncestor());
   2030     ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(), ApplyToContentLayers);
   2031 }
   2032 
   2033 struct SetContentsNeedsDisplayInRectFunctor {
   2034     void operator() (GraphicsLayer* layer) const
   2035     {
   2036         if (layer->drawsContent()) {
   2037             IntRect layerDirtyRect = r;
   2038             layerDirtyRect.move(-layer->offsetFromRenderer());
   2039             layer->setNeedsDisplayInRect(layerDirtyRect, annotations);
   2040         }
   2041     }
   2042 
   2043     IntRect r;
   2044     WebInvalidationDebugAnnotations annotations;
   2045 };
   2046 
   2047 // r is in the coordinate space of the layer's render object
   2048 void CompositedLayerMapping::setContentsNeedDisplayInRect(const LayoutRect& r, WebInvalidationDebugAnnotations annotations)
   2049 {
   2050     // FIXME: need to split out paint invalidations for the background.
   2051     ASSERT(!paintsIntoCompositedAncestor());
   2052 
   2053     SetContentsNeedsDisplayInRectFunctor functor = {
   2054         pixelSnappedIntRect(r.location() + m_owningLayer.subpixelAccumulation(), r.size()),
   2055         annotations
   2056     };
   2057     ApplyToGraphicsLayers(this, functor, ApplyToContentLayers);
   2058 }
   2059 
   2060 const GraphicsLayerPaintInfo* CompositedLayerMapping::containingSquashedLayer(const RenderObject* renderObject, const Vector<GraphicsLayerPaintInfo>& layers, unsigned maxSquashedLayerIndex)
   2061 {
   2062     for (size_t i = 0; i < layers.size() && i < maxSquashedLayerIndex; ++i) {
   2063         if (renderObject->isDescendantOf(layers[i].renderLayer->renderer()))
   2064             return &layers[i];
   2065     }
   2066     return 0;
   2067 }
   2068 
   2069 const GraphicsLayerPaintInfo* CompositedLayerMapping::containingSquashedLayer(const RenderObject* renderObject, unsigned maxSquashedLayerIndex)
   2070 {
   2071     return CompositedLayerMapping::containingSquashedLayer(renderObject, m_squashedLayers, maxSquashedLayerIndex);
   2072 }
   2073 
   2074 IntRect CompositedLayerMapping::localClipRectForSquashedLayer(const RenderLayer& referenceLayer, const GraphicsLayerPaintInfo& paintInfo, const Vector<GraphicsLayerPaintInfo>& layers)
   2075 {
   2076     const RenderObject* clippingContainer = paintInfo.renderLayer->clippingContainer();
   2077     if (clippingContainer == referenceLayer.clippingContainer())
   2078         return PaintInfo::infiniteRect();
   2079 
   2080     ASSERT(clippingContainer);
   2081 
   2082     const GraphicsLayerPaintInfo* ancestorPaintInfo = containingSquashedLayer(clippingContainer, layers, layers.size());
   2083     // Must be there, otherwise CompositingLayerAssigner::canSquashIntoCurrentSquashingOwner would have disallowed squashing.
   2084     ASSERT(ancestorPaintInfo);
   2085 
   2086     // FIXME: this is a potential performance issue. We shoudl consider caching these clip rects or otherwise optimizing.
   2087     ClipRectsContext clipRectsContext(ancestorPaintInfo->renderLayer, UncachedClipRects);
   2088     IntRect parentClipRect = pixelSnappedIntRect(paintInfo.renderLayer->clipper().backgroundClipRect(clipRectsContext).rect());
   2089     ASSERT(parentClipRect != PaintInfo::infiniteRect());
   2090 
   2091     // Convert from ancestor to local coordinates.
   2092     IntSize ancestorToLocalOffset = paintInfo.offsetFromRenderer - ancestorPaintInfo->offsetFromRenderer;
   2093     parentClipRect.move(ancestorToLocalOffset);
   2094     return parentClipRect;
   2095 }
   2096 
   2097 void CompositedLayerMapping::doPaintTask(const GraphicsLayerPaintInfo& paintInfo, const PaintLayerFlags& paintLayerFlags, GraphicsContext* context,
   2098     const IntRect& clip) // In the coords of rootLayer.
   2099 {
   2100     RELEASE_ASSERT(paintInfo.renderLayer->compositingState() == PaintsIntoGroupedBacking || !paintsIntoCompositedAncestor());
   2101 
   2102     FontCachePurgePreventer fontCachePurgePreventer;
   2103 
   2104     // Note carefully: in theory it is appropriate to invoke context->save() here
   2105     // and restore the context after painting. For efficiency, we are assuming that
   2106     // it is equivalent to manually undo this offset translation, which means we are
   2107     // assuming that the context's space was not affected by the RenderLayer
   2108     // painting code.
   2109 
   2110     IntSize offset = paintInfo.offsetFromRenderer;
   2111     context->translate(-offset.width(), -offset.height());
   2112 
   2113     // The dirtyRect is in the coords of the painting root.
   2114     IntRect dirtyRect(clip);
   2115     dirtyRect.move(offset);
   2116 
   2117     if (!(paintLayerFlags & PaintLayerPaintingOverflowContents)) {
   2118         LayoutRect bounds = paintInfo.compositedBounds;
   2119         bounds.move(paintInfo.renderLayer->subpixelAccumulation());
   2120         dirtyRect.intersect(pixelSnappedIntRect(bounds));
   2121     } else {
   2122         dirtyRect.move(roundedIntSize(paintInfo.renderLayer->subpixelAccumulation()));
   2123     }
   2124 
   2125 #if ENABLE(ASSERT)
   2126     paintInfo.renderLayer->renderer()->assertSubtreeIsLaidOut();
   2127 #endif
   2128 
   2129     if (paintInfo.renderLayer->compositingState() != PaintsIntoGroupedBacking) {
   2130         // FIXME: GraphicsLayers need a way to split for RenderRegions.
   2131         LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, paintInfo.renderLayer->subpixelAccumulation());
   2132         paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintLayerFlags);
   2133 
   2134         if (paintInfo.renderLayer->containsDirtyOverlayScrollbars())
   2135             paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintLayerFlags | PaintLayerPaintingOverlayScrollbars);
   2136     } else {
   2137         ASSERT(compositor()->layerSquashingEnabled());
   2138         LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, paintInfo.renderLayer->subpixelAccumulation());
   2139 
   2140         // RenderLayer::paintLayer assumes that the caller clips to the passed rect. Squashed layers need to do this clipping in software,
   2141         // since there is no graphics layer to clip them precisely. Furthermore, in some cases we squash layers that need clipping in software
   2142         // from clipping ancestors (see CompositedLayerMapping::localClipRectForSquashedLayer()).
   2143         context->save();
   2144         dirtyRect.intersect(paintInfo.localClipRectForSquashedLayer);
   2145         context->clip(dirtyRect);
   2146         paintInfo.renderLayer->paintLayer(context, paintingInfo, paintLayerFlags);
   2147         context->restore();
   2148     }
   2149 
   2150     ASSERT(!paintInfo.renderLayer->usedTransparency());
   2151 
   2152     // Manually restore the context to its original state by applying the opposite translation.
   2153     context->translate(offset.width(), offset.height());
   2154 }
   2155 
   2156 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
   2157 {
   2158     if (!scrollbar)
   2159         return;
   2160 
   2161     context.save();
   2162     const IntRect& scrollbarRect = scrollbar->frameRect();
   2163     context.translate(-scrollbarRect.x(), -scrollbarRect.y());
   2164     IntRect transformedClip = clip;
   2165     transformedClip.moveBy(scrollbarRect.location());
   2166     scrollbar->paint(&context, transformedClip);
   2167     context.restore();
   2168 }
   2169 
   2170 // Up-call from compositing layer drawing callback.
   2171 void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect& clip)
   2172 {
   2173     // https://code.google.com/p/chromium/issues/detail?id=343772
   2174     DisableCompositingQueryAsserts disabler;
   2175 #if ENABLE(ASSERT)
   2176     // FIXME: once the state machine is ready, this can be removed and we can refer to that instead.
   2177     if (Page* page = renderer()->frame()->page())
   2178         page->setIsPainting(true);
   2179 #endif
   2180     TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Paint", "data", InspectorPaintEvent::data(m_owningLayer.renderer(), clip, graphicsLayer));
   2181     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
   2182     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
   2183     InspectorInstrumentation::willPaint(m_owningLayer.renderer(), graphicsLayer);
   2184 
   2185     PaintLayerFlags paintLayerFlags = 0;
   2186     if (graphicsLayerPaintingPhase & GraphicsLayerPaintBackground)
   2187         paintLayerFlags |= PaintLayerPaintingCompositingBackgroundPhase;
   2188     if (graphicsLayerPaintingPhase & GraphicsLayerPaintForeground)
   2189         paintLayerFlags |= PaintLayerPaintingCompositingForegroundPhase;
   2190     if (graphicsLayerPaintingPhase & GraphicsLayerPaintMask)
   2191         paintLayerFlags |= PaintLayerPaintingCompositingMaskPhase;
   2192     if (graphicsLayerPaintingPhase & GraphicsLayerPaintChildClippingMask)
   2193         paintLayerFlags |= PaintLayerPaintingChildClippingMaskPhase;
   2194     if (graphicsLayerPaintingPhase & GraphicsLayerPaintOverflowContents)
   2195         paintLayerFlags |= PaintLayerPaintingOverflowContents;
   2196     if (graphicsLayerPaintingPhase & GraphicsLayerPaintCompositedScroll)
   2197         paintLayerFlags |= PaintLayerPaintingCompositingScrollingPhase;
   2198 
   2199     if (graphicsLayer == m_backgroundLayer)
   2200         paintLayerFlags |= (PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
   2201     else if (compositor()->fixedRootBackgroundLayer())
   2202         paintLayerFlags |= PaintLayerPaintingSkipRootBackground;
   2203 
   2204     if (graphicsLayer == m_graphicsLayer.get()
   2205         || graphicsLayer == m_foregroundLayer.get()
   2206         || graphicsLayer == m_backgroundLayer.get()
   2207         || graphicsLayer == m_maskLayer.get()
   2208         || graphicsLayer == m_childClippingMaskLayer.get()
   2209         || graphicsLayer == m_scrollingContentsLayer.get()
   2210         || graphicsLayer == m_scrollingBlockSelectionLayer.get()) {
   2211 
   2212         GraphicsLayerPaintInfo paintInfo;
   2213         paintInfo.renderLayer = &m_owningLayer;
   2214         paintInfo.compositedBounds = compositedBounds();
   2215         paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer();
   2216 
   2217         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
   2218         doPaintTask(paintInfo, paintLayerFlags, &context, clip);
   2219     } else if (graphicsLayer == m_squashingLayer.get()) {
   2220         ASSERT(compositor()->layerSquashingEnabled());
   2221         for (size_t i = 0; i < m_squashedLayers.size(); ++i)
   2222             doPaintTask(m_squashedLayers[i], paintLayerFlags, &context, clip);
   2223     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
   2224         paintScrollbar(m_owningLayer.scrollableArea()->horizontalScrollbar(), context, clip);
   2225     } else if (graphicsLayer == layerForVerticalScrollbar()) {
   2226         paintScrollbar(m_owningLayer.scrollableArea()->verticalScrollbar(), context, clip);
   2227     } else if (graphicsLayer == layerForScrollCorner()) {
   2228         const IntRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
   2229         context.save();
   2230         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
   2231         IntRect transformedClip = clip;
   2232         transformedClip.moveBy(scrollCornerAndResizer.location());
   2233         m_owningLayer.scrollableArea()->paintScrollCorner(&context, IntPoint(), transformedClip);
   2234         m_owningLayer.scrollableArea()->paintResizer(&context, IntPoint(), transformedClip);
   2235         context.restore();
   2236     }
   2237     InspectorInstrumentation::didPaint(m_owningLayer.renderer(), graphicsLayer, &context, clip);
   2238 #if ENABLE(ASSERT)
   2239     if (Page* page = renderer()->frame()->page())
   2240         page->setIsPainting(false);
   2241 #endif
   2242 }
   2243 
   2244 bool CompositedLayerMapping::isTrackingPaintInvalidations() const
   2245 {
   2246     GraphicsLayerClient* client = compositor();
   2247     return client ? client->isTrackingPaintInvalidations() : false;
   2248 }
   2249 
   2250 #if ENABLE(ASSERT)
   2251 void CompositedLayerMapping::verifyNotPainting()
   2252 {
   2253     ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
   2254 }
   2255 #endif
   2256 
   2257 void CompositedLayerMapping::notifyAnimationStarted(const GraphicsLayer*, double monotonicTime)
   2258 {
   2259     renderer()->node()->document().compositorPendingAnimations().notifyCompositorAnimationStarted(monotonicTime);
   2260 }
   2261 
   2262 IntRect CompositedLayerMapping::pixelSnappedCompositedBounds() const
   2263 {
   2264     LayoutRect bounds = m_compositedBounds;
   2265     bounds.move(m_owningLayer.subpixelAccumulation());
   2266     return pixelSnappedIntRect(bounds);
   2267 }
   2268 
   2269 bool CompositedLayerMapping::updateSquashingLayerAssignment(RenderLayer* squashedLayer, const RenderLayer& owningLayer, size_t nextSquashedLayerIndex)
   2270 {
   2271     ASSERT(compositor()->layerSquashingEnabled());
   2272 
   2273     GraphicsLayerPaintInfo paintInfo;
   2274     paintInfo.renderLayer = squashedLayer;
   2275     // NOTE: composited bounds are updated elsewhere
   2276     // NOTE: offsetFromRenderer is updated elsewhere
   2277 
   2278     // Change tracking on squashing layers: at the first sign of something changed, just invalidate the layer.
   2279     // FIXME: Perhaps we can find a tighter more clever mechanism later.
   2280     bool updatedAssignment = false;
   2281     if (nextSquashedLayerIndex < m_squashedLayers.size()) {
   2282         if (paintInfo.renderLayer != m_squashedLayers[nextSquashedLayerIndex].renderLayer) {
   2283             compositor()->paintInvalidationOnCompositingChange(squashedLayer);
   2284             updatedAssignment = true;
   2285             m_squashedLayers[nextSquashedLayerIndex] = paintInfo;
   2286         }
   2287     } else {
   2288         compositor()->paintInvalidationOnCompositingChange(squashedLayer);
   2289         m_squashedLayers.append(paintInfo);
   2290         updatedAssignment = true;
   2291     }
   2292     squashedLayer->setGroupedMapping(this);
   2293     return updatedAssignment;
   2294 }
   2295 
   2296 void CompositedLayerMapping::removeRenderLayerFromSquashingGraphicsLayer(const RenderLayer* layer)
   2297 {
   2298     size_t layerIndex = kNotFound;
   2299 
   2300     for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
   2301         if (m_squashedLayers[i].renderLayer == layer) {
   2302             layerIndex = i;
   2303             break;
   2304         }
   2305     }
   2306 
   2307     if (layerIndex == kNotFound)
   2308         return;
   2309 
   2310     m_squashedLayers.remove(layerIndex);
   2311 }
   2312 
   2313 void CompositedLayerMapping::finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex)
   2314 {
   2315     ASSERT(compositor()->layerSquashingEnabled());
   2316 
   2317     // Any additional squashed RenderLayers in the array no longer exist, and removing invalidates the squashingLayer contents.
   2318     if (nextSquashedLayerIndex < m_squashedLayers.size())
   2319         m_squashedLayers.remove(nextSquashedLayerIndex, m_squashedLayers.size() - nextSquashedLayerIndex);
   2320 }
   2321 
   2322 String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer)
   2323 {
   2324     String name;
   2325     if (graphicsLayer == m_graphicsLayer.get()) {
   2326         name = m_owningLayer.debugName();
   2327     } else if (graphicsLayer == m_squashingContainmentLayer.get()) {
   2328         name = "Squashing Containment Layer";
   2329     } else if (graphicsLayer == m_squashingLayer.get()) {
   2330         name = "Squashing Layer";
   2331     } else if (graphicsLayer == m_ancestorClippingLayer.get()) {
   2332         name = "Ancestor Clipping Layer";
   2333     } else if (graphicsLayer == m_foregroundLayer.get()) {
   2334         name = m_owningLayer.debugName() + " (foreground) Layer";
   2335     } else if (graphicsLayer == m_backgroundLayer.get()) {
   2336         name = m_owningLayer.debugName() + " (background) Layer";
   2337     } else if (graphicsLayer == m_childContainmentLayer.get()) {
   2338         name = "Child Containment Layer";
   2339     } else if (graphicsLayer == m_childTransformLayer.get()) {
   2340         name = "Child Transform Layer";
   2341     } else if (graphicsLayer == m_maskLayer.get()) {
   2342         name = "Mask Layer";
   2343     } else if (graphicsLayer == m_childClippingMaskLayer.get()) {
   2344         name = "Child Clipping Mask Layer";
   2345     } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
   2346         name = "Horizontal Scrollbar Layer";
   2347     } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
   2348         name = "Vertical Scrollbar Layer";
   2349     } else if (graphicsLayer == m_layerForScrollCorner.get()) {
   2350         name = "Scroll Corner Layer";
   2351     } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
   2352         name = "Overflow Controls Host Layer";
   2353     } else if (graphicsLayer == m_overflowControlsClippingLayer.get()) {
   2354         name = "Overflow Controls ClipLayer Layer";
   2355     } else if (graphicsLayer == m_scrollingLayer.get()) {
   2356         name = "Scrolling Layer";
   2357     } else if (graphicsLayer == m_scrollingContentsLayer.get()) {
   2358         name = "Scrolling Contents Layer";
   2359     } else if (graphicsLayer == m_scrollingBlockSelectionLayer.get()) {
   2360         name = "Scrolling Block Selection Layer";
   2361     } else {
   2362         ASSERT_NOT_REACHED();
   2363     }
   2364 
   2365     return name;
   2366 }
   2367 
   2368 } // namespace blink
   2369