Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2011 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #if USE(ACCELERATED_COMPOSITING)
     29 
     30 #include "PlatformCALayer.h"
     31 
     32 #include "AbstractCACFLayerTreeHost.h"
     33 #include "Font.h"
     34 #include "GraphicsContext.h"
     35 #include "PlatformCALayerWinInternal.h"
     36 #include <QuartzCore/CoreAnimationCF.h>
     37 #include <WebKitSystemInterface/WebKitSystemInterface.h>
     38 #include <wtf/CurrentTime.h>
     39 #include <wtf/text/CString.h>
     40 
     41 using namespace WebCore;
     42 
     43 bool PlatformCALayer::isValueFunctionSupported()
     44 {
     45     return true;
     46 }
     47 
     48 void PlatformCALayer::setOwner(PlatformCALayerClient* owner)
     49 {
     50     m_owner = owner;
     51 }
     52 
     53 static CFStringRef toCACFLayerType(PlatformCALayer::LayerType type)
     54 {
     55     return (type == PlatformCALayer::LayerTypeTransformLayer) ? kCACFTransformLayer : kCACFLayer;
     56 }
     57 
     58 static CFStringRef toCACFFilterType(PlatformCALayer::FilterType type)
     59 {
     60     switch (type) {
     61     case PlatformCALayer::Linear: return kCACFFilterLinear;
     62     case PlatformCALayer::Nearest: return kCACFFilterNearest;
     63     case PlatformCALayer::Trilinear: return kCACFFilterTrilinear;
     64     default: return 0;
     65     }
     66 }
     67 
     68 static AbstractCACFLayerTreeHost* layerTreeHostForLayer(const PlatformCALayer* layer)
     69 {
     70     // We need the AbstractCACFLayerTreeHost associated with this layer, which is stored in the UserData of the CACFContext
     71     void* userData = wkCACFLayerGetContextUserData(layer->platformLayer());
     72     if (!userData)
     73         return 0;
     74 
     75     return static_cast<AbstractCACFLayerTreeHost*>(userData);
     76 }
     77 
     78 static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer)
     79 {
     80     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer->platformLayer()));
     81 }
     82 
     83 static PlatformCALayerWinInternal* intern(void* layer)
     84 {
     85     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(static_cast<CACFLayerRef>(layer)));
     86 }
     87 
     88 PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner)
     89 {
     90     return adoptRef(new PlatformCALayer(layerType, 0, owner));
     91 }
     92 
     93 PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner)
     94 {
     95     return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner));
     96 }
     97 
     98 static void displayCallback(CACFLayerRef caLayer, CGContextRef context)
     99 {
    100     ASSERT_ARG(caLayer, CACFLayerGetUserData(caLayer));
    101     intern(caLayer)->displayCallback(caLayer, context);
    102 }
    103 
    104 static void layoutSublayersProc(CACFLayerRef caLayer)
    105 {
    106     PlatformCALayer* layer = PlatformCALayer::platformCALayer(caLayer);
    107     if (layer && layer->owner())
    108         layer->owner()->platformCALayerLayoutSublayersOfLayer(layer);
    109 }
    110 
    111 PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner)
    112     : m_owner(owner)
    113 {
    114     if (layer) {
    115         m_layerType = LayerTypeCustom;
    116         m_layer = layer;
    117     } else {
    118         m_layerType = layerType;
    119         m_layer.adoptCF(CACFLayerCreate(toCACFLayerType(layerType)));
    120 
    121         // Create the PlatformCALayerWinInternal object and point to it in the userdata.
    122         PlatformCALayerWinInternal* intern = new PlatformCALayerWinInternal(this);
    123         CACFLayerSetUserData(m_layer.get(), intern);
    124 
    125         // Set the display callback
    126         CACFLayerSetDisplayCallback(m_layer.get(), displayCallback);
    127         CACFLayerSetLayoutCallback(m_layer.get(), layoutSublayersProc);
    128     }
    129 }
    130 
    131 PlatformCALayer::~PlatformCALayer()
    132 {
    133     // Toss all the kids
    134     removeAllSublayers();
    135 
    136     // Get rid of the user data
    137     PlatformCALayerWinInternal* layerIntern = intern(this);
    138     CACFLayerSetUserData(m_layer.get(), 0);
    139 
    140     delete layerIntern;
    141 }
    142 
    143 PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer)
    144 {
    145     if (!platformLayer)
    146         return 0;
    147 
    148     PlatformCALayerWinInternal* layerIntern = intern(platformLayer);
    149     return layerIntern ? layerIntern->owner() : 0;
    150 }
    151 
    152 PlatformLayer* PlatformCALayer::platformLayer() const
    153 {
    154     return m_layer.get();
    155 }
    156 
    157 PlatformCALayer* PlatformCALayer::rootLayer() const
    158 {
    159     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
    160     return host ? host->rootLayer() : 0;
    161 }
    162 
    163 void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect)
    164 {
    165     intern(this)->setNeedsDisplay(dirtyRect);
    166 }
    167 
    168 void PlatformCALayer::setNeedsCommit()
    169 {
    170     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
    171     if (host)
    172         host->layerTreeDidChange();
    173 }
    174 
    175 void PlatformCALayer::setContentsChanged()
    176 {
    177     // FIXME: There is no equivalent of setContentsChanged in CACF. For now I will
    178     // set contents to 0 and then back to its original value to see if that
    179     // kicks CACF into redisplaying.
    180     RetainPtr<CFTypeRef> contents = CACFLayerGetContents(m_layer.get());
    181     CACFLayerSetContents(m_layer.get(), 0);
    182     CACFLayerSetContents(m_layer.get(), contents.get());
    183     setNeedsCommit();
    184 }
    185 
    186 void PlatformCALayer::setNeedsLayout()
    187 {
    188     if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges())
    189         return;
    190 
    191     CACFLayerSetNeedsLayout(m_layer.get());
    192     setNeedsCommit();
    193 }
    194 
    195 PlatformCALayer* PlatformCALayer::superlayer() const
    196 {
    197     return platformCALayer(CACFLayerGetSuperlayer(m_layer.get()));
    198 }
    199 
    200 void PlatformCALayer::removeFromSuperlayer()
    201 {
    202     CACFLayerRemoveFromSuperlayer(m_layer.get());
    203     setNeedsCommit();
    204 }
    205 
    206 void PlatformCALayer::setSublayers(const PlatformCALayerList& list)
    207 {
    208     intern(this)->setSublayers(list);
    209 }
    210 
    211 void PlatformCALayer::removeAllSublayers()
    212 {
    213     intern(this)->removeAllSublayers();
    214 }
    215 
    216 void PlatformCALayer::appendSublayer(PlatformCALayer* layer)
    217 {
    218     // This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override.
    219     insertSublayer(layer, sublayerCount());
    220 }
    221 
    222 void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index)
    223 {
    224     intern(this)->insertSublayer(layer, index);
    225 }
    226 
    227 void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* newLayer)
    228 {
    229     // This must not use direct calls to allow PlatformCALayerInternal to override.
    230     ASSERT_ARG(reference, reference);
    231     ASSERT_ARG(reference, reference->superlayer() == this);
    232 
    233     if (reference == newLayer)
    234         return;
    235 
    236     int referenceIndex = intern(this)->indexOfSublayer(reference);
    237     ASSERT(referenceIndex != -1);
    238     if (referenceIndex == -1)
    239         return;
    240 
    241     reference->removeFromSuperlayer();
    242 
    243     if (newLayer) {
    244         newLayer->removeFromSuperlayer();
    245         insertSublayer(newLayer, referenceIndex);
    246     }
    247 }
    248 
    249 size_t PlatformCALayer::sublayerCount() const
    250 {
    251     return intern(this)->sublayerCount();
    252 }
    253 
    254 void PlatformCALayer::adoptSublayers(PlatformCALayer* source)
    255 {
    256     PlatformCALayerList sublayers;
    257     intern(source)->getSublayers(sublayers);
    258 
    259     // Use setSublayers() because it properly nulls out the superlayer pointers.
    260     setSublayers(sublayers);
    261 }
    262 
    263 void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation)
    264 {
    265     // Add it to the animation list
    266     m_animations.add(key, animation);
    267 
    268     RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
    269     CACFLayerAddAnimation(m_layer.get(), s.get(), animation->platformAnimation());
    270     setNeedsCommit();
    271 
    272     // Tell the host about it so we can fire the start animation event
    273     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
    274     if (host)
    275         host->addPendingAnimatedLayer(this);
    276 }
    277 
    278 void PlatformCALayer::removeAnimationForKey(const String& key)
    279 {
    280     // Remove it from the animation list
    281     m_animations.remove(key);
    282 
    283     RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
    284     CACFLayerRemoveAnimation(m_layer.get(), s.get());
    285 
    286     // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
    287     // There may be other active animations on the layer and if an animation
    288     // callback is fired on a layer without any animations no harm is done.
    289 
    290     setNeedsCommit();
    291 }
    292 
    293 PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key)
    294 {
    295     HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key);
    296     if (it == m_animations.end())
    297         return 0;
    298 
    299     return it->second;
    300 }
    301 
    302 PlatformCALayer* PlatformCALayer::mask() const
    303 {
    304     return platformCALayer(CACFLayerGetMask(m_layer.get()));
    305 }
    306 
    307 void PlatformCALayer::setMask(PlatformCALayer* layer)
    308 {
    309     CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0);
    310     setNeedsCommit();
    311 }
    312 
    313 bool PlatformCALayer::isOpaque() const
    314 {
    315     return CACFLayerIsOpaque(m_layer.get());
    316 }
    317 
    318 void PlatformCALayer::setOpaque(bool value)
    319 {
    320     CACFLayerSetOpaque(m_layer.get(), value);
    321     setNeedsCommit();
    322 }
    323 
    324 FloatRect PlatformCALayer::bounds() const
    325 {
    326     return CACFLayerGetBounds(m_layer.get());
    327 }
    328 
    329 void PlatformCALayer::setBounds(const FloatRect& value)
    330 {
    331     intern(this)->setBounds(value);
    332     setNeedsLayout();
    333 }
    334 
    335 FloatPoint3D PlatformCALayer::position() const
    336 {
    337     CGPoint point = CACFLayerGetPosition(m_layer.get());
    338     return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get()));
    339 }
    340 
    341 void PlatformCALayer::setPosition(const FloatPoint3D& value)
    342 {
    343     CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y()));
    344     CACFLayerSetZPosition(m_layer.get(), value.z());
    345     setNeedsCommit();
    346 }
    347 
    348 FloatPoint3D PlatformCALayer::anchorPoint() const
    349 {
    350     CGPoint point = CACFLayerGetAnchorPoint(m_layer.get());
    351     float z = CACFLayerGetAnchorPointZ(m_layer.get());
    352     return FloatPoint3D(point.x, point.y, z);
    353 }
    354 
    355 void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value)
    356 {
    357     CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y()));
    358     CACFLayerSetAnchorPointZ(m_layer.get(), value.z());
    359     setNeedsCommit();
    360 }
    361 
    362 TransformationMatrix PlatformCALayer::transform() const
    363 {
    364     return CACFLayerGetTransform(m_layer.get());
    365 }
    366 
    367 void PlatformCALayer::setTransform(const TransformationMatrix& value)
    368 {
    369     CACFLayerSetTransform(m_layer.get(), value);
    370     setNeedsCommit();
    371 }
    372 
    373 TransformationMatrix PlatformCALayer::sublayerTransform() const
    374 {
    375     return CACFLayerGetSublayerTransform(m_layer.get());
    376 }
    377 
    378 void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value)
    379 {
    380     CACFLayerSetSublayerTransform(m_layer.get(), value);
    381     setNeedsCommit();
    382 }
    383 
    384 TransformationMatrix PlatformCALayer::contentsTransform() const
    385 {
    386     // ContentsTransform is not used
    387     return TransformationMatrix();
    388 }
    389 
    390 void PlatformCALayer::setContentsTransform(const TransformationMatrix&)
    391 {
    392     // ContentsTransform is not used
    393 }
    394 
    395 bool PlatformCALayer::isHidden() const
    396 {
    397     return CACFLayerIsHidden(m_layer.get());
    398 }
    399 
    400 void PlatformCALayer::setHidden(bool value)
    401 {
    402     CACFLayerSetHidden(m_layer.get(), value);
    403     setNeedsCommit();
    404 }
    405 
    406 bool PlatformCALayer::isGeometryFlipped() const
    407 {
    408     return CACFLayerIsGeometryFlipped(m_layer.get());
    409 }
    410 
    411 void PlatformCALayer::setGeometryFlipped(bool value)
    412 {
    413     CACFLayerSetGeometryFlipped(m_layer.get(), value);
    414     setNeedsCommit();
    415 }
    416 
    417 bool PlatformCALayer::isDoubleSided() const
    418 {
    419     return CACFLayerIsDoubleSided(m_layer.get());
    420 }
    421 
    422 void PlatformCALayer::setDoubleSided(bool value)
    423 {
    424     CACFLayerSetDoubleSided(m_layer.get(), value);
    425     setNeedsCommit();
    426 }
    427 
    428 bool PlatformCALayer::masksToBounds() const
    429 {
    430     return CACFLayerGetMasksToBounds(m_layer.get());
    431 }
    432 
    433 void PlatformCALayer::setMasksToBounds(bool value)
    434 {
    435     CACFLayerSetMasksToBounds(m_layer.get(), value);
    436     setNeedsCommit();
    437 }
    438 
    439 bool PlatformCALayer::acceleratesDrawing() const
    440 {
    441     return false;
    442 }
    443 
    444 void PlatformCALayer::setAcceleratesDrawing(bool)
    445 {
    446 }
    447 
    448 CFTypeRef PlatformCALayer::contents() const
    449 {
    450     return CACFLayerGetContents(m_layer.get());
    451 }
    452 
    453 void PlatformCALayer::setContents(CFTypeRef value)
    454 {
    455     CACFLayerSetContents(m_layer.get(), value);
    456     setNeedsCommit();
    457 }
    458 
    459 FloatRect PlatformCALayer::contentsRect() const
    460 {
    461     return CACFLayerGetContentsRect(m_layer.get());
    462 }
    463 
    464 void PlatformCALayer::setContentsRect(const FloatRect& value)
    465 {
    466     CACFLayerSetContentsRect(m_layer.get(), value);
    467     setNeedsCommit();
    468 }
    469 
    470 void PlatformCALayer::setMinificationFilter(FilterType value)
    471 {
    472     CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value));
    473 }
    474 
    475 void PlatformCALayer::setMagnificationFilter(FilterType value)
    476 {
    477     CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value));
    478     setNeedsCommit();
    479 }
    480 
    481 Color PlatformCALayer::backgroundColor() const
    482 {
    483     return CACFLayerGetBackgroundColor(m_layer.get());
    484 }
    485 
    486 void PlatformCALayer::setBackgroundColor(const Color& value)
    487 {
    488     CGFloat components[4];
    489     value.getRGBA(components[0], components[1], components[2], components[3]);
    490 
    491     RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    492     RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
    493 
    494     CACFLayerSetBackgroundColor(m_layer.get(), color.get());
    495     setNeedsCommit();
    496 }
    497 
    498 float PlatformCALayer::borderWidth() const
    499 {
    500     return CACFLayerGetBorderWidth(m_layer.get());
    501 }
    502 
    503 void PlatformCALayer::setBorderWidth(float value)
    504 {
    505     CACFLayerSetBorderWidth(m_layer.get(), value);
    506     setNeedsCommit();
    507 }
    508 
    509 Color PlatformCALayer::borderColor() const
    510 {
    511     return CACFLayerGetBorderColor(m_layer.get());
    512 }
    513 
    514 void PlatformCALayer::setBorderColor(const Color& value)
    515 {
    516     CGFloat components[4];
    517     value.getRGBA(components[0], components[1], components[2], components[3]);
    518 
    519     RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    520     RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
    521 
    522     CACFLayerSetBorderColor(m_layer.get(), color.get());
    523     setNeedsCommit();
    524 }
    525 
    526 float PlatformCALayer::opacity() const
    527 {
    528     return CACFLayerGetOpacity(m_layer.get());
    529 }
    530 
    531 void PlatformCALayer::setOpacity(float value)
    532 {
    533     CACFLayerSetOpacity(m_layer.get(), value);
    534     setNeedsCommit();
    535 }
    536 
    537 String PlatformCALayer::name() const
    538 {
    539     return CACFLayerGetName(m_layer.get());
    540 }
    541 
    542 void PlatformCALayer::setName(const String& value)
    543 {
    544     RetainPtr<CFStringRef> s(AdoptCF, value.createCFString());
    545     CACFLayerSetName(m_layer.get(), s.get());
    546     setNeedsCommit();
    547 }
    548 
    549 FloatRect PlatformCALayer::frame() const
    550 {
    551     return CACFLayerGetFrame(m_layer.get());
    552 }
    553 
    554 void PlatformCALayer::setFrame(const FloatRect& value)
    555 {
    556     intern(this)->setFrame(value);
    557     setNeedsLayout();
    558 }
    559 
    560 float PlatformCALayer::speed() const
    561 {
    562     return CACFLayerGetSpeed(m_layer.get());
    563 }
    564 
    565 void PlatformCALayer::setSpeed(float value)
    566 {
    567     CACFLayerSetSpeed(m_layer.get(), value);
    568     setNeedsCommit();
    569 }
    570 
    571 CFTimeInterval PlatformCALayer::timeOffset() const
    572 {
    573     return CACFLayerGetTimeOffset(m_layer.get());
    574 }
    575 
    576 void PlatformCALayer::setTimeOffset(CFTimeInterval value)
    577 {
    578     CACFLayerSetTimeOffset(m_layer.get(), value);
    579     setNeedsCommit();
    580 }
    581 
    582 float PlatformCALayer::contentsScale() const
    583 {
    584     return 1;
    585 }
    586 
    587 void PlatformCALayer::setContentsScale(float)
    588 {
    589 }
    590 
    591 #ifndef NDEBUG
    592 static void printIndent(int indent)
    593 {
    594     for ( ; indent > 0; --indent)
    595         fprintf(stderr, "  ");
    596 }
    597 
    598 static void printTransform(const CATransform3D& transform)
    599 {
    600     fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
    601                     transform.m11, transform.m12, transform.m13, transform.m14,
    602                     transform.m21, transform.m22, transform.m23, transform.m24,
    603                     transform.m31, transform.m32, transform.m33, transform.m34,
    604                     transform.m41, transform.m42, transform.m43, transform.m44);
    605 }
    606 
    607 static void printLayer(const PlatformCALayer* layer, int indent)
    608 {
    609     FloatPoint3D layerPosition = layer->position();
    610     FloatPoint3D layerAnchorPoint = layer->anchorPoint();
    611     FloatRect layerBounds = layer->bounds();
    612     printIndent(indent);
    613 
    614     char* layerTypeName = 0;
    615     switch (layer->layerType()) {
    616     case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break;
    617     case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break;
    618     case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break;
    619     case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break;
    620     case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break;
    621     case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break;
    622     }
    623 
    624     fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n",
    625         layerTypeName,
    626         layerPosition.x(), layerPosition.y(), layerPosition.z(),
    627         layerBounds.x(), layerBounds.y(), layerBounds.width(), layerBounds.height(),
    628         layerAnchorPoint.x(), layerAnchorPoint.y(), layerAnchorPoint.z(), layer->superlayer());
    629 
    630     // Print name if needed
    631     String layerName = layer->name();
    632     if (!layerName.isEmpty()) {
    633         printIndent(indent + 1);
    634         fprintf(stderr, "(name %s)\n", layerName.utf8().data());
    635     }
    636 
    637     // Print masksToBounds if needed
    638     bool layerMasksToBounds = layer->masksToBounds();
    639     if (layerMasksToBounds) {
    640         printIndent(indent + 1);
    641         fprintf(stderr, "(masksToBounds true)\n");
    642     }
    643 
    644     // Print opacity if needed
    645     float layerOpacity = layer->opacity();
    646     if (layerOpacity != 1) {
    647         printIndent(indent + 1);
    648         fprintf(stderr, "(opacity %hf)\n", layerOpacity);
    649     }
    650 
    651     // Print sublayerTransform if needed
    652     TransformationMatrix layerTransform = layer->sublayerTransform();
    653     if (!layerTransform.isIdentity()) {
    654         printIndent(indent + 1);
    655         fprintf(stderr, "(sublayerTransform ");
    656         printTransform(layerTransform);
    657         fprintf(stderr, ")\n");
    658     }
    659 
    660     // Print transform if needed
    661     layerTransform = layer->transform();
    662     if (!layerTransform.isIdentity()) {
    663         printIndent(indent + 1);
    664         fprintf(stderr, "(transform ");
    665         printTransform(layerTransform);
    666         fprintf(stderr, ")\n");
    667     }
    668 
    669     // Print contents if needed
    670     CFTypeRef layerContents = layer->contents();
    671     if (layerContents) {
    672         if (CFGetTypeID(layerContents) == CGImageGetTypeID()) {
    673             CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents));
    674             printIndent(indent + 1);
    675             fprintf(stderr, "(contents (image [%d %d]))\n",
    676                 CGImageGetWidth(imageContents), CGImageGetHeight(imageContents));
    677         }
    678     }
    679 
    680     // Print sublayers if needed
    681     int n = layer->sublayerCount();
    682     if (n > 0) {
    683         printIndent(indent + 1);
    684         fprintf(stderr, "(sublayers\n");
    685 
    686         PlatformCALayerList sublayers;
    687         intern(layer)->getSublayers(sublayers);
    688         ASSERT(n == sublayers.size());
    689         for (int i = 0; i < n; ++i)
    690             printLayer(sublayers[i].get(), indent + 2);
    691 
    692         printIndent(indent + 1);
    693         fprintf(stderr, ")\n");
    694     }
    695 
    696     printIndent(indent);
    697     fprintf(stderr, ")\n");
    698 }
    699 
    700 void PlatformCALayer::printTree() const
    701 {
    702     // Print heading info
    703     CGRect rootBounds = bounds();
    704     fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n",
    705         currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height);
    706 
    707     // Print layer tree from the root
    708     printLayer(this, 0);
    709 }
    710 #endif // #ifndef NDEBUG
    711 
    712 #endif // USE(ACCELERATED_COMPOSITING)
    713