Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2009 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 "platform/graphics/GraphicsLayer.h"
     29 
     30 #include "SkImageFilter.h"
     31 #include "SkMatrix44.h"
     32 #include "platform/geometry/FloatRect.h"
     33 #include "platform/geometry/LayoutRect.h"
     34 #include "platform/graphics/GraphicsContext.h"
     35 #include "platform/graphics/GraphicsLayerFactory.h"
     36 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
     37 #include "platform/graphics/skia/NativeImageSkia.h"
     38 #include "platform/scroll/ScrollableArea.h"
     39 #include "platform/text/TextStream.h"
     40 #include "public/platform/Platform.h"
     41 #include "public/platform/WebAnimation.h"
     42 #include "public/platform/WebCompositorSupport.h"
     43 #include "public/platform/WebFilterOperations.h"
     44 #include "public/platform/WebFloatPoint.h"
     45 #include "public/platform/WebFloatRect.h"
     46 #include "public/platform/WebGraphicsLayerDebugInfo.h"
     47 #include "public/platform/WebLayer.h"
     48 #include "public/platform/WebPoint.h"
     49 #include "public/platform/WebSize.h"
     50 #include "wtf/CurrentTime.h"
     51 #include "wtf/HashMap.h"
     52 #include "wtf/HashSet.h"
     53 #include "wtf/text/WTFString.h"
     54 
     55 #ifndef NDEBUG
     56 #include <stdio.h>
     57 #endif
     58 
     59 using blink::Platform;
     60 using blink::WebAnimation;
     61 using blink::WebFilterOperations;
     62 using blink::WebLayer;
     63 using blink::WebPoint;
     64 
     65 namespace WebCore {
     66 
     67 typedef HashMap<const GraphicsLayer*, Vector<FloatRect> > RepaintMap;
     68 static RepaintMap& repaintRectMap()
     69 {
     70     DEFINE_STATIC_LOCAL(RepaintMap, map, ());
     71     return map;
     72 }
     73 
     74 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
     75 {
     76     return factory->createGraphicsLayer(client);
     77 }
     78 
     79 GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
     80     : m_client(client)
     81     , m_anchorPoint(0.5f, 0.5f, 0)
     82     , m_opacity(1)
     83     , m_zPosition(0)
     84     , m_blendMode(blink::WebBlendModeNormal)
     85     , m_contentsOpaque(false)
     86     , m_preserves3D(false)
     87     , m_backfaceVisibility(true)
     88     , m_masksToBounds(false)
     89     , m_drawsContent(false)
     90     , m_contentsVisible(true)
     91     , m_isRootForIsolatedGroup(false)
     92     , m_hasScrollParent(false)
     93     , m_hasClipParent(false)
     94     , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
     95     , m_contentsOrientation(CompositingCoordinatesTopDown)
     96     , m_parent(0)
     97     , m_maskLayer(0)
     98     , m_contentsClippingMaskLayer(0)
     99     , m_replicaLayer(0)
    100     , m_replicatedLayer(0)
    101     , m_paintCount(0)
    102     , m_contentsLayer(0)
    103     , m_contentsLayerId(0)
    104     , m_scrollableArea(0)
    105     , m_compositingReasons(blink::CompositingReasonUnknown)
    106     , m_debugInfo(0)
    107 {
    108 #ifndef NDEBUG
    109     if (m_client)
    110         m_client->verifyNotPainting();
    111 #endif
    112 
    113     m_opaqueRectTrackingContentLayerDelegate = adoptPtr(new OpaqueRectTrackingContentLayerDelegate(this));
    114     m_layer = adoptPtr(Platform::current()->compositorSupport()->createContentLayer(m_opaqueRectTrackingContentLayerDelegate.get()));
    115     m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
    116     m_layer->layer()->setWebLayerClient(this);
    117     m_layer->setAutomaticallyComputeRasterScale(true);
    118 }
    119 
    120 GraphicsLayer::~GraphicsLayer()
    121 {
    122     for (size_t i = 0; i < m_linkHighlights.size(); ++i)
    123         m_linkHighlights[i]->clearCurrentGraphicsLayer();
    124     m_linkHighlights.clear();
    125 
    126 #ifndef NDEBUG
    127     if (m_client)
    128         m_client->verifyNotPainting();
    129 #endif
    130 
    131     if (m_replicaLayer)
    132         m_replicaLayer->setReplicatedLayer(0);
    133 
    134     if (m_replicatedLayer)
    135         m_replicatedLayer->setReplicatedByLayer(0);
    136 
    137     removeAllChildren();
    138     removeFromParent();
    139 
    140     resetTrackedRepaints();
    141     ASSERT(!m_parent);
    142 }
    143 
    144 void GraphicsLayer::setParent(GraphicsLayer* layer)
    145 {
    146     ASSERT(!layer || !layer->hasAncestor(this));
    147     m_parent = layer;
    148 }
    149 
    150 bool GraphicsLayer::hasAncestor(GraphicsLayer* ancestor) const
    151 {
    152     for (GraphicsLayer* curr = parent(); curr; curr = curr->parent()) {
    153         if (curr == ancestor)
    154             return true;
    155     }
    156 
    157     return false;
    158 }
    159 
    160 bool GraphicsLayer::setChildren(const Vector<GraphicsLayer*>& newChildren)
    161 {
    162     // If the contents of the arrays are the same, nothing to do.
    163     if (newChildren == m_children)
    164         return false;
    165 
    166     removeAllChildren();
    167 
    168     size_t listSize = newChildren.size();
    169     for (size_t i = 0; i < listSize; ++i)
    170         addChildInternal(newChildren[i]);
    171 
    172     updateChildList();
    173 
    174     return true;
    175 }
    176 
    177 void GraphicsLayer::addChildInternal(GraphicsLayer* childLayer)
    178 {
    179     ASSERT(childLayer != this);
    180 
    181     if (childLayer->parent())
    182         childLayer->removeFromParent();
    183 
    184     childLayer->setParent(this);
    185     m_children.append(childLayer);
    186 
    187     // Don't call updateChildList here, this function is used in cases where it
    188     // should not be called until all children are processed.
    189 }
    190 
    191 void GraphicsLayer::addChild(GraphicsLayer* childLayer)
    192 {
    193     addChildInternal(childLayer);
    194     updateChildList();
    195 }
    196 
    197 void GraphicsLayer::addChildAtIndex(GraphicsLayer* childLayer, int index)
    198 {
    199     ASSERT(childLayer != this);
    200 
    201     if (childLayer->parent())
    202         childLayer->removeFromParent();
    203 
    204     childLayer->setParent(this);
    205     m_children.insert(index, childLayer);
    206 
    207     updateChildList();
    208 }
    209 
    210 void GraphicsLayer::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
    211 {
    212     ASSERT(childLayer != this);
    213     childLayer->removeFromParent();
    214 
    215     bool found = false;
    216     for (unsigned i = 0; i < m_children.size(); i++) {
    217         if (sibling == m_children[i]) {
    218             m_children.insert(i, childLayer);
    219             found = true;
    220             break;
    221         }
    222     }
    223 
    224     childLayer->setParent(this);
    225 
    226     if (!found)
    227         m_children.append(childLayer);
    228 
    229     updateChildList();
    230 }
    231 
    232 void GraphicsLayer::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
    233 {
    234     childLayer->removeFromParent();
    235     ASSERT(childLayer != this);
    236 
    237     bool found = false;
    238     for (unsigned i = 0; i < m_children.size(); i++) {
    239         if (sibling == m_children[i]) {
    240             m_children.insert(i+1, childLayer);
    241             found = true;
    242             break;
    243         }
    244     }
    245 
    246     childLayer->setParent(this);
    247 
    248     if (!found)
    249         m_children.append(childLayer);
    250 
    251     updateChildList();
    252 }
    253 
    254 bool GraphicsLayer::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
    255 {
    256     ASSERT(!newChild->parent());
    257     bool found = false;
    258     for (unsigned i = 0; i < m_children.size(); i++) {
    259         if (oldChild == m_children[i]) {
    260             m_children[i] = newChild;
    261             found = true;
    262             break;
    263         }
    264     }
    265 
    266     if (found) {
    267         oldChild->setParent(0);
    268 
    269         newChild->removeFromParent();
    270         newChild->setParent(this);
    271 
    272         updateChildList();
    273         return true;
    274     }
    275 
    276     return false;
    277 }
    278 
    279 void GraphicsLayer::removeAllChildren()
    280 {
    281     while (m_children.size()) {
    282         GraphicsLayer* curLayer = m_children[0];
    283         ASSERT(curLayer->parent());
    284         curLayer->removeFromParent();
    285     }
    286 }
    287 
    288 void GraphicsLayer::removeFromParent()
    289 {
    290     if (m_parent) {
    291         unsigned i;
    292         for (i = 0; i < m_parent->m_children.size(); i++) {
    293             if (this == m_parent->m_children[i]) {
    294                 m_parent->m_children.remove(i);
    295                 break;
    296             }
    297         }
    298 
    299         setParent(0);
    300     }
    301 
    302     platformLayer()->removeFromParent();
    303 }
    304 
    305 void GraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer)
    306 {
    307     // FIXME: this could probably be a full early exit.
    308     if (m_replicaLayer != layer) {
    309         if (m_replicaLayer)
    310             m_replicaLayer->setReplicatedLayer(0);
    311 
    312         if (layer)
    313             layer->setReplicatedLayer(this);
    314 
    315         m_replicaLayer = layer;
    316     }
    317 
    318     WebLayer* webReplicaLayer = layer ? layer->platformLayer() : 0;
    319     platformLayer()->setReplicaLayer(webReplicaLayer);
    320 }
    321 
    322 void GraphicsLayer::setOffsetFromRenderer(const IntSize& offset, ShouldSetNeedsDisplay shouldSetNeedsDisplay)
    323 {
    324     if (offset == m_offsetFromRenderer)
    325         return;
    326 
    327     m_offsetFromRenderer = offset;
    328 
    329     // If the compositing layer offset changes, we need to repaint.
    330     if (shouldSetNeedsDisplay == SetNeedsDisplay)
    331         setNeedsDisplay();
    332 }
    333 
    334 void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const IntRect& clip)
    335 {
    336     if (!m_client)
    337         return;
    338     incrementPaintCount();
    339     m_client->paintContents(this, context, m_paintingPhase, clip);
    340 }
    341 
    342 void GraphicsLayer::setZPosition(float position)
    343 {
    344     m_zPosition = position;
    345 }
    346 
    347 float GraphicsLayer::accumulatedOpacity() const
    348 {
    349     if (!preserves3D())
    350         return 1;
    351 
    352     return m_opacity * (parent() ? parent()->accumulatedOpacity() : 1);
    353 }
    354 
    355 void GraphicsLayer::distributeOpacity(float accumulatedOpacity)
    356 {
    357     // If this is a transform layer we need to distribute our opacity to all our children
    358 
    359     // Incoming accumulatedOpacity is the contribution from our parent(s). We mutiply this by our own
    360     // opacity to get the total contribution
    361     accumulatedOpacity *= m_opacity;
    362 
    363     if (preserves3D()) {
    364         size_t numChildren = children().size();
    365         for (size_t i = 0; i < numChildren; ++i)
    366             children()[i]->distributeOpacity(accumulatedOpacity);
    367     }
    368 }
    369 
    370 void GraphicsLayer::updateChildList()
    371 {
    372     WebLayer* childHost = m_layer->layer();
    373     childHost->removeAllChildren();
    374 
    375     clearContentsLayerIfUnregistered();
    376 
    377     if (m_contentsLayer) {
    378         // FIXME: add the contents layer in the correct order with negative z-order children.
    379         // This does not cause visible rendering issues because currently contents layers are only used
    380         // for replaced elements that don't have children.
    381         childHost->addChild(m_contentsLayer);
    382     }
    383 
    384     const Vector<GraphicsLayer*>& childLayers = children();
    385     size_t numChildren = childLayers.size();
    386     for (size_t i = 0; i < numChildren; ++i) {
    387         GraphicsLayer* curChild = childLayers[i];
    388 
    389         childHost->addChild(curChild->platformLayer());
    390     }
    391 
    392     for (size_t i = 0; i < m_linkHighlights.size(); ++i)
    393         childHost->addChild(m_linkHighlights[i]->layer());
    394 }
    395 
    396 void GraphicsLayer::updateLayerIsDrawable()
    397 {
    398     // For the rest of the accelerated compositor code, there is no reason to make a
    399     // distinction between drawsContent and contentsVisible. So, for m_layer->layer(), these two
    400     // flags are combined here. m_contentsLayer shouldn't receive the drawsContent flag
    401     // so it is only given contentsVisible.
    402 
    403     m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
    404     if (WebLayer* contentsLayer = contentsLayerIfRegistered())
    405         contentsLayer->setDrawsContent(m_contentsVisible);
    406 
    407     if (m_drawsContent) {
    408         m_layer->layer()->invalidate();
    409         for (size_t i = 0; i < m_linkHighlights.size(); ++i)
    410             m_linkHighlights[i]->invalidate();
    411     }
    412 }
    413 
    414 void GraphicsLayer::updateContentsRect()
    415 {
    416     WebLayer* contentsLayer = contentsLayerIfRegistered();
    417     if (!contentsLayer)
    418         return;
    419 
    420     contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y()));
    421     contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height()));
    422 
    423     if (m_contentsClippingMaskLayer) {
    424         if (m_contentsClippingMaskLayer->size() != m_contentsRect.size()) {
    425             m_contentsClippingMaskLayer->setSize(m_contentsRect.size());
    426             m_contentsClippingMaskLayer->setNeedsDisplay();
    427         }
    428         m_contentsClippingMaskLayer->setPosition(FloatPoint());
    429         m_contentsClippingMaskLayer->setOffsetFromRenderer(offsetFromRenderer() + IntSize(m_contentsRect.location().x(), m_contentsRect.location().y()));
    430     }
    431 }
    432 
    433 static HashSet<int>* s_registeredLayerSet;
    434 
    435 void GraphicsLayer::registerContentsLayer(WebLayer* layer)
    436 {
    437     if (!s_registeredLayerSet)
    438         s_registeredLayerSet = new HashSet<int>;
    439     if (s_registeredLayerSet->contains(layer->id()))
    440         CRASH();
    441     s_registeredLayerSet->add(layer->id());
    442 }
    443 
    444 void GraphicsLayer::unregisterContentsLayer(WebLayer* layer)
    445 {
    446     ASSERT(s_registeredLayerSet);
    447     if (!s_registeredLayerSet->contains(layer->id()))
    448         CRASH();
    449     s_registeredLayerSet->remove(layer->id());
    450 }
    451 
    452 void GraphicsLayer::setContentsTo(WebLayer* layer)
    453 {
    454     bool childrenChanged = false;
    455     if (layer) {
    456         ASSERT(s_registeredLayerSet);
    457         if (!s_registeredLayerSet->contains(layer->id()))
    458             CRASH();
    459         if (m_contentsLayerId != layer->id()) {
    460             setupContentsLayer(layer);
    461             childrenChanged = true;
    462         }
    463         updateContentsRect();
    464     } else {
    465         if (m_contentsLayer) {
    466             childrenChanged = true;
    467 
    468             // The old contents layer will be removed via updateChildList.
    469             m_contentsLayer = 0;
    470             m_contentsLayerId = 0;
    471         }
    472     }
    473 
    474     if (childrenChanged)
    475         updateChildList();
    476 }
    477 
    478 void GraphicsLayer::setupContentsLayer(WebLayer* contentsLayer)
    479 {
    480     ASSERT(contentsLayer);
    481     m_contentsLayer = contentsLayer;
    482     m_contentsLayerId = m_contentsLayer->id();
    483 
    484     m_contentsLayer->setWebLayerClient(this);
    485     m_contentsLayer->setAnchorPoint(FloatPoint(0, 0));
    486     m_contentsLayer->setUseParentBackfaceVisibility(true);
    487 
    488     // It is necessary to call setDrawsContent as soon as we receive the new contentsLayer, for
    489     // the correctness of early exit conditions in setDrawsContent() and setContentsVisible().
    490     m_contentsLayer->setDrawsContent(m_contentsVisible);
    491 
    492     // Insert the content layer first. Video elements require this, because they have
    493     // shadow content that must display in front of the video.
    494     m_layer->layer()->insertChild(m_contentsLayer, 0);
    495     WebLayer* borderWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0;
    496     m_contentsLayer->setMaskLayer(borderWebLayer);
    497 }
    498 
    499 void GraphicsLayer::clearContentsLayerIfUnregistered()
    500 {
    501     if (!m_contentsLayerId || s_registeredLayerSet->contains(m_contentsLayerId))
    502         return;
    503 
    504     m_contentsLayer = 0;
    505     m_contentsLayerId = 0;
    506 }
    507 
    508 void GraphicsLayer::setDebugInfo(blink::WebGraphicsLayerDebugInfo* debugInfo)
    509 {
    510     if (m_debugInfo)
    511         delete m_debugInfo;
    512     m_debugInfo = debugInfo;
    513 }
    514 
    515 blink::WebGraphicsLayerDebugInfo* GraphicsLayer::takeDebugInfo()
    516 {
    517     blink::WebGraphicsLayerDebugInfo* tempDebugInfo = m_debugInfo;
    518     m_debugInfo = 0;
    519     return tempDebugInfo;
    520 }
    521 
    522 WebLayer* GraphicsLayer::contentsLayerIfRegistered()
    523 {
    524     clearContentsLayerIfUnregistered();
    525     return m_contentsLayer;
    526 }
    527 
    528 double GraphicsLayer::backingStoreMemoryEstimate() const
    529 {
    530     if (!drawsContent())
    531         return 0;
    532 
    533     // Effects of page and device scale are ignored; subclasses should override to take these into account.
    534     return static_cast<double>(4 * size().width()) * size().height();
    535 }
    536 
    537 void GraphicsLayer::resetTrackedRepaints()
    538 {
    539     repaintRectMap().remove(this);
    540 }
    541 
    542 void GraphicsLayer::addRepaintRect(const FloatRect& repaintRect)
    543 {
    544     if (m_client->isTrackingRepaints()) {
    545         FloatRect largestRepaintRect(FloatPoint(), m_size);
    546         largestRepaintRect.intersect(repaintRect);
    547         RepaintMap::iterator repaintIt = repaintRectMap().find(this);
    548         if (repaintIt == repaintRectMap().end()) {
    549             Vector<FloatRect> repaintRects;
    550             repaintRects.append(largestRepaintRect);
    551             repaintRectMap().set(this, repaintRects);
    552         } else {
    553             Vector<FloatRect>& repaintRects = repaintIt->value;
    554             repaintRects.append(largestRepaintRect);
    555         }
    556     }
    557 }
    558 
    559 void GraphicsLayer::collectTrackedRepaintRects(Vector<FloatRect>& rects) const
    560 {
    561     if (!m_client->isTrackingRepaints())
    562         return;
    563 
    564     RepaintMap::iterator repaintIt = repaintRectMap().find(this);
    565     if (repaintIt != repaintRectMap().end())
    566         rects.append(repaintIt->value);
    567 }
    568 
    569 void GraphicsLayer::dumpLayer(TextStream& ts, int indent, LayerTreeFlags flags) const
    570 {
    571     writeIndent(ts, indent);
    572     ts << "(" << "GraphicsLayer";
    573 
    574     if (flags & LayerTreeIncludesDebugInfo) {
    575         ts << " " << static_cast<void*>(const_cast<GraphicsLayer*>(this));
    576         ts << " \"" << m_client->debugName(this) << "\"";
    577     }
    578 
    579     ts << "\n";
    580     dumpProperties(ts, indent, flags);
    581     writeIndent(ts, indent);
    582     ts << ")\n";
    583 }
    584 
    585 void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeFlags flags) const
    586 {
    587     if (m_position != FloatPoint()) {
    588         writeIndent(ts, indent + 1);
    589         ts << "(position " << m_position.x() << " " << m_position.y() << ")\n";
    590     }
    591 
    592     if (m_boundsOrigin != FloatPoint()) {
    593         writeIndent(ts, indent + 1);
    594         ts << "(bounds origin " << m_boundsOrigin.x() << " " << m_boundsOrigin.y() << ")\n";
    595     }
    596 
    597     if (m_anchorPoint != FloatPoint3D(0.5f, 0.5f, 0)) {
    598         writeIndent(ts, indent + 1);
    599         ts << "(anchor " << m_anchorPoint.x() << " " << m_anchorPoint.y() << ")\n";
    600     }
    601 
    602     if (m_size != IntSize()) {
    603         writeIndent(ts, indent + 1);
    604         ts << "(bounds " << m_size.width() << " " << m_size.height() << ")\n";
    605     }
    606 
    607     if (m_opacity != 1) {
    608         writeIndent(ts, indent + 1);
    609         ts << "(opacity " << m_opacity << ")\n";
    610     }
    611 
    612     if (m_blendMode != blink::WebBlendModeNormal) {
    613         writeIndent(ts, indent + 1);
    614         ts << "(blendMode " << compositeOperatorName(CompositeSourceOver, m_blendMode) << ")\n";
    615     }
    616 
    617     if (m_isRootForIsolatedGroup) {
    618         writeIndent(ts, indent + 1);
    619         ts << "(isolate " << m_isRootForIsolatedGroup << ")\n";
    620     }
    621 
    622     if (m_contentsOpaque) {
    623         writeIndent(ts, indent + 1);
    624         ts << "(contentsOpaque " << m_contentsOpaque << ")\n";
    625     }
    626 
    627     if (m_preserves3D) {
    628         writeIndent(ts, indent + 1);
    629         ts << "(preserves3D " << m_preserves3D << ")\n";
    630     }
    631 
    632     if (m_drawsContent) {
    633         writeIndent(ts, indent + 1);
    634         ts << "(drawsContent " << m_drawsContent << ")\n";
    635     }
    636 
    637     if (!m_contentsVisible) {
    638         writeIndent(ts, indent + 1);
    639         ts << "(contentsVisible " << m_contentsVisible << ")\n";
    640     }
    641 
    642     if (!m_backfaceVisibility) {
    643         writeIndent(ts, indent + 1);
    644         ts << "(backfaceVisibility " << (m_backfaceVisibility ? "visible" : "hidden") << ")\n";
    645     }
    646 
    647     if (flags & LayerTreeIncludesDebugInfo) {
    648         writeIndent(ts, indent + 1);
    649         ts << "(";
    650         if (m_client)
    651             ts << "client " << static_cast<void*>(m_client);
    652         else
    653             ts << "no client";
    654         ts << ")\n";
    655     }
    656 
    657     if (m_backgroundColor.isValid() && m_backgroundColor != Color::transparent) {
    658         writeIndent(ts, indent + 1);
    659         ts << "(backgroundColor " << m_backgroundColor.nameForRenderTreeAsText() << ")\n";
    660     }
    661 
    662     if (!m_transform.isIdentity()) {
    663         writeIndent(ts, indent + 1);
    664         ts << "(transform ";
    665         ts << "[" << m_transform.m11() << " " << m_transform.m12() << " " << m_transform.m13() << " " << m_transform.m14() << "] ";
    666         ts << "[" << m_transform.m21() << " " << m_transform.m22() << " " << m_transform.m23() << " " << m_transform.m24() << "] ";
    667         ts << "[" << m_transform.m31() << " " << m_transform.m32() << " " << m_transform.m33() << " " << m_transform.m34() << "] ";
    668         ts << "[" << m_transform.m41() << " " << m_transform.m42() << " " << m_transform.m43() << " " << m_transform.m44() << "])\n";
    669     }
    670 
    671     // Avoid dumping the sublayer transform on the root layer, because it's used for geometry flipping, whose behavior
    672     // differs between platforms.
    673     if (parent() && !m_childrenTransform.isIdentity()) {
    674         writeIndent(ts, indent + 1);
    675         ts << "(childrenTransform ";
    676         ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] ";
    677         ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] ";
    678         ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] ";
    679         ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "])\n";
    680     }
    681 
    682     if (m_replicaLayer) {
    683         writeIndent(ts, indent + 1);
    684         ts << "(replica layer";
    685         if (flags & LayerTreeIncludesDebugInfo)
    686             ts << " " << m_replicaLayer;
    687         ts << ")\n";
    688         m_replicaLayer->dumpLayer(ts, indent + 2, flags);
    689     }
    690 
    691     if (m_replicatedLayer) {
    692         writeIndent(ts, indent + 1);
    693         ts << "(replicated layer";
    694         if (flags & LayerTreeIncludesDebugInfo)
    695             ts << " " << m_replicatedLayer;
    696         ts << ")\n";
    697     }
    698 
    699     if ((flags & LayerTreeIncludesRepaintRects) && repaintRectMap().contains(this) && !repaintRectMap().get(this).isEmpty()) {
    700         writeIndent(ts, indent + 1);
    701         ts << "(repaint rects\n";
    702         for (size_t i = 0; i < repaintRectMap().get(this).size(); ++i) {
    703             if (repaintRectMap().get(this)[i].isEmpty())
    704                 continue;
    705             writeIndent(ts, indent + 2);
    706             ts << "(rect ";
    707             ts << repaintRectMap().get(this)[i].x() << " ";
    708             ts << repaintRectMap().get(this)[i].y() << " ";
    709             ts << repaintRectMap().get(this)[i].width() << " ";
    710             ts << repaintRectMap().get(this)[i].height();
    711             ts << ")\n";
    712         }
    713         writeIndent(ts, indent + 1);
    714         ts << ")\n";
    715     }
    716 
    717     if ((flags & LayerTreeIncludesPaintingPhases) && paintingPhase()) {
    718         writeIndent(ts, indent + 1);
    719         ts << "(paintingPhases\n";
    720         if (paintingPhase() & GraphicsLayerPaintBackground) {
    721             writeIndent(ts, indent + 2);
    722             ts << "GraphicsLayerPaintBackground\n";
    723         }
    724         if (paintingPhase() & GraphicsLayerPaintForeground) {
    725             writeIndent(ts, indent + 2);
    726             ts << "GraphicsLayerPaintForeground\n";
    727         }
    728         if (paintingPhase() & GraphicsLayerPaintMask) {
    729             writeIndent(ts, indent + 2);
    730             ts << "GraphicsLayerPaintMask\n";
    731         }
    732         if (paintingPhase() & GraphicsLayerPaintChildClippingMask) {
    733             writeIndent(ts, indent + 2);
    734             ts << "GraphicsLayerPaintChildClippingMask\n";
    735         }
    736         if (paintingPhase() & GraphicsLayerPaintOverflowContents) {
    737             writeIndent(ts, indent + 2);
    738             ts << "GraphicsLayerPaintOverflowContents\n";
    739         }
    740         if (paintingPhase() & GraphicsLayerPaintCompositedScroll) {
    741             writeIndent(ts, indent + 2);
    742             ts << "GraphicsLayerPaintCompositedScroll\n";
    743         }
    744         writeIndent(ts, indent + 1);
    745         ts << ")\n";
    746     }
    747 
    748     if (flags & LayerTreeIncludesClipAndScrollParents) {
    749         if (m_hasScrollParent) {
    750             writeIndent(ts, indent + 1);
    751             ts << "(hasScrollParent 1)\n";
    752         }
    753         if (m_hasClipParent) {
    754             writeIndent(ts, indent + 1);
    755             ts << "(hasClipParent 1)\n";
    756         }
    757     }
    758 
    759     if (m_children.size()) {
    760         writeIndent(ts, indent + 1);
    761         ts << "(children " << m_children.size() << "\n";
    762 
    763         unsigned i;
    764         for (i = 0; i < m_children.size(); i++)
    765             m_children[i]->dumpLayer(ts, indent + 2, flags);
    766         writeIndent(ts, indent + 1);
    767         ts << ")\n";
    768     }
    769 }
    770 
    771 String GraphicsLayer::layerTreeAsText(LayerTreeFlags flags) const
    772 {
    773     TextStream ts;
    774 
    775     dumpLayer(ts, 0, flags);
    776     return ts.release();
    777 }
    778 
    779 blink::WebString GraphicsLayer::debugName(blink::WebLayer* webLayer)
    780 {
    781     String name;
    782     if (!m_client)
    783         return name;
    784 
    785     String highlightDebugName;
    786     for (size_t i = 0; i < m_linkHighlights.size(); ++i) {
    787         if (webLayer == m_linkHighlights[i]->layer()) {
    788             highlightDebugName = "LinkHighlight[" + String::number(i) + "] for " + m_client->debugName(this);
    789             break;
    790         }
    791     }
    792 
    793     if (webLayer == m_contentsLayer) {
    794         name = "ContentsLayer for " + m_client->debugName(this);
    795     } else if (!highlightDebugName.isEmpty()) {
    796         name = highlightDebugName;
    797     } else if (webLayer == m_layer->layer()) {
    798         name = m_client->debugName(this);
    799     } else {
    800         ASSERT_NOT_REACHED();
    801     }
    802     return name;
    803 }
    804 
    805 void GraphicsLayer::setCompositingReasons(blink::WebCompositingReasons reasons)
    806 {
    807     m_compositingReasons = reasons;
    808     m_layer->layer()->setCompositingReasons(reasons);
    809 }
    810 
    811 void GraphicsLayer::setPosition(const FloatPoint& point)
    812 {
    813     m_position = point;
    814     platformLayer()->setPosition(m_position);
    815 }
    816 
    817 void GraphicsLayer::setAnchorPoint(const FloatPoint3D& point)
    818 {
    819     m_anchorPoint = point;
    820     platformLayer()->setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y()));
    821     platformLayer()->setAnchorPointZ(m_anchorPoint.z());
    822 }
    823 
    824 void GraphicsLayer::setSize(const FloatSize& size)
    825 {
    826     // We are receiving negative sizes here that cause assertions to fail in the compositor. Clamp them to 0 to
    827     // avoid those assertions.
    828     // FIXME: This should be an ASSERT instead, as negative sizes should not exist in WebCore.
    829     FloatSize clampedSize = size;
    830     if (clampedSize.width() < 0 || clampedSize.height() < 0)
    831         clampedSize = FloatSize();
    832 
    833     if (clampedSize == m_size)
    834         return;
    835 
    836     m_size = clampedSize;
    837 
    838     m_layer->layer()->setBounds(flooredIntSize(m_size));
    839     // Note that we don't resize m_contentsLayer. It's up the caller to do that.
    840 }
    841 
    842 void GraphicsLayer::setTransform(const TransformationMatrix& transform)
    843 {
    844     m_transform = transform;
    845     platformLayer()->setTransform(TransformationMatrix::toSkMatrix44(m_transform));
    846 }
    847 
    848 void GraphicsLayer::setChildrenTransform(const TransformationMatrix& transform)
    849 {
    850     m_childrenTransform = transform;
    851     platformLayer()->setSublayerTransform(TransformationMatrix::toSkMatrix44(m_childrenTransform));
    852 }
    853 
    854 void GraphicsLayer::setPreserves3D(bool preserves3D)
    855 {
    856     if (preserves3D == m_preserves3D)
    857         return;
    858 
    859     m_preserves3D = preserves3D;
    860     m_layer->layer()->setPreserves3D(m_preserves3D);
    861 }
    862 
    863 void GraphicsLayer::setMasksToBounds(bool masksToBounds)
    864 {
    865     m_masksToBounds = masksToBounds;
    866     m_layer->layer()->setMasksToBounds(m_masksToBounds);
    867 }
    868 
    869 void GraphicsLayer::setDrawsContent(bool drawsContent)
    870 {
    871     // Note carefully this early-exit is only correct because we also properly call
    872     // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer().
    873     if (drawsContent == m_drawsContent)
    874         return;
    875 
    876     m_drawsContent = drawsContent;
    877     updateLayerIsDrawable();
    878 }
    879 
    880 void GraphicsLayer::setContentsVisible(bool contentsVisible)
    881 {
    882     // Note carefully this early-exit is only correct because we also properly call
    883     // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer().
    884     if (contentsVisible == m_contentsVisible)
    885         return;
    886 
    887     m_contentsVisible = contentsVisible;
    888     updateLayerIsDrawable();
    889 }
    890 
    891 void GraphicsLayer::setClipParent(blink::WebLayer* parent)
    892 {
    893     m_hasClipParent = !!parent;
    894     m_layer->layer()->setClipParent(parent);
    895 }
    896 
    897 void GraphicsLayer::setScrollParent(blink::WebLayer* parent)
    898 {
    899     m_hasScrollParent = !!parent;
    900     m_layer->layer()->setScrollParent(parent);
    901 }
    902 
    903 void GraphicsLayer::setBackgroundColor(const Color& color)
    904 {
    905     if (color == m_backgroundColor)
    906         return;
    907 
    908     m_backgroundColor = color;
    909     m_layer->layer()->setBackgroundColor(m_backgroundColor.rgb());
    910 }
    911 
    912 void GraphicsLayer::setContentsOpaque(bool opaque)
    913 {
    914     m_contentsOpaque = opaque;
    915     m_layer->layer()->setOpaque(m_contentsOpaque);
    916     m_opaqueRectTrackingContentLayerDelegate->setOpaque(m_contentsOpaque);
    917 }
    918 
    919 void GraphicsLayer::setMaskLayer(GraphicsLayer* maskLayer)
    920 {
    921     if (maskLayer == m_maskLayer)
    922         return;
    923 
    924     m_maskLayer = maskLayer;
    925     WebLayer* maskWebLayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
    926     m_layer->layer()->setMaskLayer(maskWebLayer);
    927 }
    928 
    929 void GraphicsLayer::setContentsClippingMaskLayer(GraphicsLayer* contentsClippingMaskLayer)
    930 {
    931     if (contentsClippingMaskLayer == m_contentsClippingMaskLayer)
    932         return;
    933 
    934     m_contentsClippingMaskLayer = contentsClippingMaskLayer;
    935     WebLayer* contentsLayer = contentsLayerIfRegistered();
    936     if (!contentsLayer)
    937         return;
    938     WebLayer* contentsClippingMaskWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0;
    939     contentsLayer->setMaskLayer(contentsClippingMaskWebLayer);
    940     updateContentsRect();
    941 }
    942 
    943 void GraphicsLayer::setBackfaceVisibility(bool visible)
    944 {
    945     m_backfaceVisibility = visible;
    946     m_layer->setDoubleSided(m_backfaceVisibility);
    947 }
    948 
    949 void GraphicsLayer::setOpacity(float opacity)
    950 {
    951     float clampedOpacity = std::max(std::min(opacity, 1.0f), 0.0f);
    952     m_opacity = clampedOpacity;
    953     platformLayer()->setOpacity(opacity);
    954 }
    955 
    956 void GraphicsLayer::setBlendMode(blink::WebBlendMode blendMode)
    957 {
    958     if (m_blendMode == blendMode)
    959         return;
    960     m_blendMode = blendMode;
    961     platformLayer()->setBlendMode(blink::WebBlendMode(blendMode));
    962 }
    963 
    964 void GraphicsLayer::setIsRootForIsolatedGroup(bool isolated)
    965 {
    966     if (m_isRootForIsolatedGroup == isolated)
    967         return;
    968     m_isRootForIsolatedGroup = isolated;
    969     platformLayer()->setIsRootForIsolatedGroup(isolated);
    970 }
    971 
    972 void GraphicsLayer::setContentsNeedsDisplay()
    973 {
    974     if (WebLayer* contentsLayer = contentsLayerIfRegistered()) {
    975         contentsLayer->invalidate();
    976         addRepaintRect(contentsRect());
    977     }
    978 }
    979 
    980 void GraphicsLayer::setNeedsDisplay()
    981 {
    982     if (drawsContent()) {
    983         m_layer->layer()->invalidate();
    984         addRepaintRect(FloatRect(FloatPoint(), m_size));
    985         for (size_t i = 0; i < m_linkHighlights.size(); ++i)
    986             m_linkHighlights[i]->invalidate();
    987     }
    988 }
    989 
    990 void GraphicsLayer::setNeedsDisplayInRect(const FloatRect& rect)
    991 {
    992     if (drawsContent()) {
    993         m_layer->layer()->invalidateRect(rect);
    994         addRepaintRect(rect);
    995         for (size_t i = 0; i < m_linkHighlights.size(); ++i)
    996             m_linkHighlights[i]->invalidate();
    997     }
    998 }
    999 
   1000 void GraphicsLayer::setContentsRect(const IntRect& rect)
   1001 {
   1002     if (rect == m_contentsRect)
   1003         return;
   1004 
   1005     m_contentsRect = rect;
   1006     updateContentsRect();
   1007 }
   1008 
   1009 void GraphicsLayer::setContentsToImage(Image* image)
   1010 {
   1011     RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : 0;
   1012     if (nativeImage) {
   1013         if (!m_imageLayer) {
   1014             m_imageLayer = adoptPtr(Platform::current()->compositorSupport()->createImageLayer());
   1015             registerContentsLayer(m_imageLayer->layer());
   1016         }
   1017         m_imageLayer->setBitmap(nativeImage->bitmap());
   1018         m_imageLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque());
   1019         updateContentsRect();
   1020     } else {
   1021         if (m_imageLayer) {
   1022             unregisterContentsLayer(m_imageLayer->layer());
   1023             m_imageLayer.clear();
   1024         }
   1025     }
   1026 
   1027     setContentsTo(m_imageLayer ? m_imageLayer->layer() : 0);
   1028 }
   1029 
   1030 void GraphicsLayer::setContentsToNinePatch(Image* image, const IntRect& aperture)
   1031 {
   1032     if (m_ninePatchLayer) {
   1033         unregisterContentsLayer(m_ninePatchLayer->layer());
   1034         m_ninePatchLayer.clear();
   1035     }
   1036     RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : 0;
   1037     if (nativeImage) {
   1038         m_ninePatchLayer = adoptPtr(Platform::current()->compositorSupport()->createNinePatchLayer());
   1039         m_ninePatchLayer->setBitmap(nativeImage->bitmap(), aperture);
   1040         m_ninePatchLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque());
   1041         registerContentsLayer(m_ninePatchLayer->layer());
   1042     }
   1043     setContentsTo(m_ninePatchLayer ? m_ninePatchLayer->layer() : 0);
   1044 }
   1045 
   1046 void GraphicsLayer::setContentsToSolidColor(const Color& color)
   1047 {
   1048     if (color == m_contentsSolidColor)
   1049         return;
   1050 
   1051     m_contentsSolidColor = color;
   1052     if (color.isValid() && color.alpha()) {
   1053         if (!m_solidColorLayer) {
   1054             m_solidColorLayer = adoptPtr(Platform::current()->compositorSupport()->createSolidColorLayer());
   1055             registerContentsLayer(m_solidColorLayer->layer());
   1056         }
   1057         m_solidColorLayer->setBackgroundColor(color.rgb());
   1058     } else {
   1059         if (!m_solidColorLayer)
   1060             return;
   1061         unregisterContentsLayer(m_solidColorLayer->layer());
   1062         m_solidColorLayer.clear();
   1063     }
   1064     setContentsTo(m_solidColorLayer ? m_solidColorLayer->layer() : 0);
   1065 }
   1066 
   1067 bool GraphicsLayer::addAnimation(PassOwnPtr<WebAnimation> popAnimation)
   1068 {
   1069     OwnPtr<WebAnimation> animation(popAnimation);
   1070     ASSERT(animation);
   1071     platformLayer()->setAnimationDelegate(this);
   1072 
   1073     // Remove any existing animations with the same animation id and target property.
   1074     platformLayer()->removeAnimation(animation->id(), animation->targetProperty());
   1075     return platformLayer()->addAnimation(animation.leakPtr());
   1076 }
   1077 
   1078 void GraphicsLayer::pauseAnimation(int animationId, double timeOffset)
   1079 {
   1080     platformLayer()->pauseAnimation(animationId, timeOffset);
   1081 }
   1082 
   1083 void GraphicsLayer::removeAnimation(int animationId)
   1084 {
   1085     platformLayer()->removeAnimation(animationId);
   1086 }
   1087 
   1088 WebLayer* GraphicsLayer::platformLayer() const
   1089 {
   1090     return m_layer->layer();
   1091 }
   1092 
   1093 static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperations& filters, WebFilterOperations& webFilters)
   1094 {
   1095     for (size_t i = 0; i < filters.size(); ++i) {
   1096         const FilterOperation& op = *filters.at(i);
   1097         switch (op.type()) {
   1098         case FilterOperation::REFERENCE:
   1099             return false; // Not supported.
   1100         case FilterOperation::GRAYSCALE:
   1101         case FilterOperation::SEPIA:
   1102         case FilterOperation::SATURATE:
   1103         case FilterOperation::HUE_ROTATE: {
   1104             float amount = toBasicColorMatrixFilterOperation(op).amount();
   1105             switch (op.type()) {
   1106             case FilterOperation::GRAYSCALE:
   1107                 webFilters.appendGrayscaleFilter(amount);
   1108                 break;
   1109             case FilterOperation::SEPIA:
   1110                 webFilters.appendSepiaFilter(amount);
   1111                 break;
   1112             case FilterOperation::SATURATE:
   1113                 webFilters.appendSaturateFilter(amount);
   1114                 break;
   1115             case FilterOperation::HUE_ROTATE:
   1116                 webFilters.appendHueRotateFilter(amount);
   1117                 break;
   1118             default:
   1119                 ASSERT_NOT_REACHED();
   1120             }
   1121             break;
   1122         }
   1123         case FilterOperation::INVERT:
   1124         case FilterOperation::OPACITY:
   1125         case FilterOperation::BRIGHTNESS:
   1126         case FilterOperation::CONTRAST: {
   1127             float amount = toBasicComponentTransferFilterOperation(op).amount();
   1128             switch (op.type()) {
   1129             case FilterOperation::INVERT:
   1130                 webFilters.appendInvertFilter(amount);
   1131                 break;
   1132             case FilterOperation::OPACITY:
   1133                 webFilters.appendOpacityFilter(amount);
   1134                 break;
   1135             case FilterOperation::BRIGHTNESS:
   1136                 webFilters.appendBrightnessFilter(amount);
   1137                 break;
   1138             case FilterOperation::CONTRAST:
   1139                 webFilters.appendContrastFilter(amount);
   1140                 break;
   1141             default:
   1142                 ASSERT_NOT_REACHED();
   1143             }
   1144             break;
   1145         }
   1146         case FilterOperation::BLUR: {
   1147             float pixelRadius = toBlurFilterOperation(op).stdDeviation().getFloatValue();
   1148             webFilters.appendBlurFilter(pixelRadius);
   1149             break;
   1150         }
   1151         case FilterOperation::DROP_SHADOW: {
   1152             const DropShadowFilterOperation& dropShadowOp = toDropShadowFilterOperation(op);
   1153             webFilters.appendDropShadowFilter(WebPoint(dropShadowOp.x(), dropShadowOp.y()), dropShadowOp.stdDeviation(), dropShadowOp.color().rgb());
   1154             break;
   1155         }
   1156         case FilterOperation::CUSTOM:
   1157         case FilterOperation::VALIDATED_CUSTOM:
   1158             return false; // Not supported.
   1159         case FilterOperation::NONE:
   1160             break;
   1161         }
   1162     }
   1163     return true;
   1164 }
   1165 
   1166 bool GraphicsLayer::setFilters(const FilterOperations& filters)
   1167 {
   1168     SkiaImageFilterBuilder builder;
   1169     OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations());
   1170     FilterOutsets outsets = filters.outsets();
   1171     builder.setCropOffset(FloatSize(outsets.left(), outsets.top()));
   1172     if (!builder.buildFilterOperations(filters, webFilters.get())) {
   1173         // Make sure the filters are removed from the platform layer, as they are
   1174         // going to fallback to software mode.
   1175         webFilters->clear();
   1176         m_layer->layer()->setFilters(*webFilters);
   1177         m_filters = FilterOperations();
   1178         return false;
   1179     }
   1180 
   1181     m_layer->layer()->setFilters(*webFilters);
   1182     m_filters = filters;
   1183     return true;
   1184 }
   1185 
   1186 void GraphicsLayer::setBackgroundFilters(const FilterOperations& filters)
   1187 {
   1188     OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations());
   1189     if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, *webFilters))
   1190         return;
   1191     m_layer->layer()->setBackgroundFilters(*webFilters);
   1192 }
   1193 
   1194 void GraphicsLayer::addLinkHighlight(LinkHighlightClient* linkHighlight)
   1195 {
   1196     ASSERT(linkHighlight && !m_linkHighlights.contains(linkHighlight));
   1197     m_linkHighlights.append(linkHighlight);
   1198     linkHighlight->layer()->setWebLayerClient(this);
   1199     updateChildList();
   1200 }
   1201 
   1202 void GraphicsLayer::removeLinkHighlight(LinkHighlightClient* linkHighlight)
   1203 {
   1204     m_linkHighlights.remove(m_linkHighlights.find(linkHighlight));
   1205     updateChildList();
   1206 }
   1207 
   1208 void GraphicsLayer::setScrollableArea(ScrollableArea* scrollableArea, bool isMainFrame)
   1209 {
   1210     if (m_scrollableArea == scrollableArea)
   1211         return;
   1212 
   1213     m_scrollableArea = scrollableArea;
   1214 
   1215     // Main frame scrolling may involve pinch zoom and gets routed through
   1216     // WebViewImpl explicitly rather than via GraphicsLayer::didScroll.
   1217     if (isMainFrame)
   1218         m_layer->layer()->setScrollClient(0);
   1219     else
   1220         m_layer->layer()->setScrollClient(this);
   1221 }
   1222 
   1223 void GraphicsLayer::paint(GraphicsContext& context, const IntRect& clip)
   1224 {
   1225     paintGraphicsLayerContents(context, clip);
   1226 }
   1227 
   1228 
   1229 void GraphicsLayer::notifyAnimationStarted(double wallClockTime, double monotonicTime, WebAnimation::TargetProperty)
   1230 {
   1231     if (m_client)
   1232         m_client->notifyAnimationStarted(this, wallClockTime, monotonicTime);
   1233 }
   1234 
   1235 void GraphicsLayer::notifyAnimationFinished(double, double, WebAnimation::TargetProperty)
   1236 {
   1237     // Do nothing.
   1238 }
   1239 
   1240 void GraphicsLayer::didScroll()
   1241 {
   1242     if (m_scrollableArea)
   1243         m_scrollableArea->scrollToOffsetWithoutAnimation(m_scrollableArea->minimumScrollPosition() + toIntSize(m_layer->layer()->scrollPosition()));
   1244 }
   1245 
   1246 } // namespace WebCore
   1247 
   1248 #ifndef NDEBUG
   1249 void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer)
   1250 {
   1251     if (!layer)
   1252         return;
   1253 
   1254     String output = layer->layerTreeAsText(WebCore::LayerTreeIncludesDebugInfo);
   1255     fprintf(stderr, "%s\n", output.utf8().data());
   1256 }
   1257 #endif
   1258