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