Home | History | Annotate | Download | only in mac
      1 /*
      2  * Copyright (C) 2010 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 #import "PlatformCALayer.h"
     31 
     32 #import "BlockExceptions.h"
     33 #import "FloatConversion.h"
     34 #import "GraphicsContext.h"
     35 #import "GraphicsLayerCA.h"
     36 #import "WebLayer.h"
     37 #import "WebTiledLayer.h"
     38 #import <objc/objc-auto.h>
     39 #import <objc/objc-runtime.h>
     40 #import <QuartzCore/QuartzCore.h>
     41 #import <wtf/CurrentTime.h>
     42 #import <wtf/UnusedParam.h>
     43 
     44 #define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))
     45 
     46 using namespace WebCore;
     47 
     48 // This value must be the same as in PlatformCAAnimationMac.mm
     49 static NSString * const WKNonZeroBeginTimeFlag = @"WKPlatformCAAnimationNonZeroBeginTimeFlag";
     50 
     51 static double mediaTimeToCurrentTime(CFTimeInterval t)
     52 {
     53     return WTF::currentTime() + t - CACurrentMediaTime();
     54 }
     55 
     56 // Delegate for animationDidStart callback
     57 @interface WebAnimationDelegate : NSObject {
     58     PlatformCALayer* m_owner;
     59 }
     60 
     61 - (void)animationDidStart:(CAAnimation *)anim;
     62 - (void)setOwner:(PlatformCALayer*)owner;
     63 
     64 @end
     65 
     66 @implementation WebAnimationDelegate
     67 
     68 - (void)animationDidStart:(CAAnimation *)animation
     69 {
     70     // hasNonZeroBeginTime is stored in a key in the animation
     71     bool hasNonZeroBeginTime = [[animation valueForKey:WKNonZeroBeginTimeFlag] boolValue];
     72     CFTimeInterval startTime;
     73 
     74     if (hasNonZeroBeginTime) {
     75         // We don't know what time CA used to commit the animation, so just use the current time
     76         // (even though this will be slightly off).
     77         startTime = mediaTimeToCurrentTime(CACurrentMediaTime());
     78     } else
     79         startTime = mediaTimeToCurrentTime([animation beginTime]);
     80 
     81     if (m_owner)
     82         m_owner->animationStarted(startTime);
     83 }
     84 
     85 - (void)setOwner:(PlatformCALayer*)owner
     86 {
     87     m_owner = owner;
     88 }
     89 
     90 @end
     91 
     92 @interface CALayer(Private)
     93 - (void)setContentsChanged;
     94 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
     95 - (void)setAcceleratesDrawing:(BOOL)flag;
     96 - (BOOL)acceleratesDrawing;
     97 #endif
     98 @end
     99 
    100 static NSString * const platformCALayerPointer = @"WKPlatformCALayer";
    101 
    102 bool PlatformCALayer::isValueFunctionSupported()
    103 {
    104     static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)];
    105     return sHaveValueFunction;
    106 }
    107 
    108 void PlatformCALayer::setOwner(PlatformCALayerClient* owner)
    109 {
    110     m_owner = owner;
    111 
    112     // Change the delegate's owner if needed
    113     if (m_delegate)
    114         [static_cast<WebAnimationDelegate*>(m_delegate.get()) setOwner:this];
    115 }
    116 
    117 static NSDictionary* nullActionsDictionary()
    118 {
    119     NSNull* nullValue = [NSNull null];
    120     NSDictionary* actions = [NSDictionary dictionaryWithObjectsAndKeys:
    121                              nullValue, @"anchorPoint",
    122                              nullValue, @"bounds",
    123                              nullValue, @"contents",
    124                              nullValue, @"contentsRect",
    125                              nullValue, @"opacity",
    126                              nullValue, @"position",
    127                              nullValue, @"shadowColor",
    128                              nullValue, @"sublayerTransform",
    129                              nullValue, @"sublayers",
    130                              nullValue, @"transform",
    131                              nullValue, @"zPosition",
    132                              nil];
    133     return actions;
    134 }
    135 
    136 #if HAVE_MODERN_QUARTZCORE
    137 static NSString* toCAFilterType(PlatformCALayer::FilterType type)
    138 {
    139     switch (type) {
    140     case PlatformCALayer::Linear: return kCAFilterLinear;
    141     case PlatformCALayer::Nearest: return kCAFilterNearest;
    142     case PlatformCALayer::Trilinear: return kCAFilterTrilinear;
    143     default: return 0;
    144     }
    145 }
    146 #endif
    147 
    148 PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner)
    149 {
    150     return adoptRef(new PlatformCALayer(layerType, 0, owner));
    151 }
    152 
    153 PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner)
    154 {
    155     return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner));
    156 }
    157 
    158 PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner)
    159     : m_owner(owner)
    160 {
    161     BEGIN_BLOCK_OBJC_EXCEPTIONS
    162     if (layer) {
    163         m_layerType = LayerTypeCustom;
    164         m_layer = layer;
    165     } else {
    166         m_layerType = layerType;
    167 
    168         Class layerClass = Nil;
    169         switch(layerType) {
    170             case LayerTypeLayer:
    171             case LayerTypeRootLayer:
    172                 layerClass = [CALayer class];
    173                 break;
    174             case LayerTypeWebLayer:
    175                 layerClass = [WebLayer class];
    176                 break;
    177             case LayerTypeTransformLayer:
    178                 layerClass = NSClassFromString(@"CATransformLayer");
    179                 break;
    180             case LayerTypeWebTiledLayer:
    181                 layerClass = [WebTiledLayer class];
    182                 break;
    183             case LayerTypeCustom:
    184                 break;
    185         }
    186 
    187         if (layerClass)
    188             m_layer.adoptNS([[layerClass alloc] init]);
    189     }
    190 
    191     // Save a pointer to 'this' in the CALayer
    192     [m_layer.get() setValue:[NSValue valueWithPointer:this] forKey:platformCALayerPointer];
    193 
    194     // Clear all the implicit animations on the CALayer
    195     [m_layer.get() setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
    196 
    197     // If this is a TiledLayer, set some initial values
    198     if (m_layerType == LayerTypeWebTiledLayer) {
    199         WebTiledLayer* tiledLayer = static_cast<WebTiledLayer*>(m_layer.get());
    200         [tiledLayer setTileSize:CGSizeMake(GraphicsLayerCA::kTiledLayerTileSize, GraphicsLayerCA::kTiledLayerTileSize)];
    201         [tiledLayer setLevelsOfDetail:1];
    202         [tiledLayer setLevelsOfDetailBias:0];
    203         [tiledLayer setContentsGravity:@"bottomLeft"];
    204     }
    205 
    206     END_BLOCK_OBJC_EXCEPTIONS
    207 }
    208 
    209 PlatformCALayer::~PlatformCALayer()
    210 {
    211     [m_layer.get() setValue:nil forKey:platformCALayerPointer];
    212 
    213     // Clear the owner, which also clears it in the delegate to prevent attempts
    214     // to use the GraphicsLayerCA after it has been destroyed.
    215     setOwner(0);
    216 
    217     // Remove the owner pointer from the delegate in case there is a pending animationStarted event.
    218     [static_cast<WebAnimationDelegate*>(m_delegate.get()) setOwner:nil];
    219 }
    220 
    221 PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer)
    222 {
    223     if (!platformLayer)
    224         return 0;
    225 
    226     // Pointer to PlatformCALayer is kept in a key of the CALayer
    227     PlatformCALayer* platformCALayer = nil;
    228     BEGIN_BLOCK_OBJC_EXCEPTIONS
    229     platformCALayer = static_cast<PlatformCALayer*>([[static_cast<CALayer*>(platformLayer) valueForKey:platformCALayerPointer] pointerValue]);
    230     END_BLOCK_OBJC_EXCEPTIONS
    231     return platformCALayer;
    232 }
    233 
    234 PlatformLayer* PlatformCALayer::platformLayer() const
    235 {
    236     return m_layer.get();
    237 }
    238 
    239 void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect)
    240 {
    241     BEGIN_BLOCK_OBJC_EXCEPTIONS
    242     if (dirtyRect)
    243         [m_layer.get() setNeedsDisplayInRect:*dirtyRect];
    244     else
    245         [m_layer.get() setNeedsDisplay];
    246     END_BLOCK_OBJC_EXCEPTIONS
    247 }
    248 
    249 void PlatformCALayer::setContentsChanged()
    250 {
    251     BEGIN_BLOCK_OBJC_EXCEPTIONS
    252     [m_layer.get() setContentsChanged];
    253     END_BLOCK_OBJC_EXCEPTIONS
    254 }
    255 
    256 PlatformCALayer* PlatformCALayer::superlayer() const
    257 {
    258     return platformCALayer([m_layer.get() superlayer]);
    259 }
    260 
    261 void PlatformCALayer::removeFromSuperlayer()
    262 {
    263     BEGIN_BLOCK_OBJC_EXCEPTIONS
    264     [m_layer.get() removeFromSuperlayer];
    265     END_BLOCK_OBJC_EXCEPTIONS
    266 }
    267 
    268 void PlatformCALayer::setSublayers(const PlatformCALayerList& list)
    269 {
    270     // Short circuiting here not only avoids the allocation of sublayers, but avoids <rdar://problem/7390716> (see below)
    271     if (list.size() == 0) {
    272         removeAllSublayers();
    273         return;
    274     }
    275 
    276     BEGIN_BLOCK_OBJC_EXCEPTIONS
    277     NSMutableArray* sublayers = [[NSMutableArray alloc] init];
    278     for (size_t i = 0; i < list.size(); ++i)
    279         [sublayers addObject:list[i]->m_layer.get()];
    280 
    281     [m_layer.get() setSublayers:sublayers];
    282     [sublayers release];
    283     END_BLOCK_OBJC_EXCEPTIONS
    284 }
    285 
    286 void PlatformCALayer::removeAllSublayers()
    287 {
    288     // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC.
    289     BEGIN_BLOCK_OBJC_EXCEPTIONS
    290     if (objc_collectingEnabled())
    291         while ([[m_layer.get() sublayers] count])
    292             [[[m_layer.get() sublayers] objectAtIndex:0] removeFromSuperlayer];
    293     else
    294         [m_layer.get() setSublayers:nil];
    295     END_BLOCK_OBJC_EXCEPTIONS
    296 }
    297 
    298 void PlatformCALayer::appendSublayer(PlatformCALayer* layer)
    299 {
    300     BEGIN_BLOCK_OBJC_EXCEPTIONS
    301     [m_layer.get() addSublayer:layer->m_layer.get()];
    302     END_BLOCK_OBJC_EXCEPTIONS
    303 }
    304 
    305 void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index)
    306 {
    307     BEGIN_BLOCK_OBJC_EXCEPTIONS
    308     [m_layer.get() insertSublayer:layer->m_layer.get() atIndex:index];
    309     END_BLOCK_OBJC_EXCEPTIONS
    310 }
    311 
    312 void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* layer)
    313 {
    314     BEGIN_BLOCK_OBJC_EXCEPTIONS
    315     [m_layer.get() replaceSublayer:reference->m_layer.get() with:layer->m_layer.get()];
    316     END_BLOCK_OBJC_EXCEPTIONS
    317 }
    318 
    319 size_t PlatformCALayer::sublayerCount() const
    320 {
    321     return [[m_layer.get() sublayers] count];
    322 }
    323 
    324 void PlatformCALayer::adoptSublayers(PlatformCALayer* source)
    325 {
    326     // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC.
    327     NSArray* sublayers = [source->m_layer.get() sublayers];
    328 
    329     if (objc_collectingEnabled() && ![sublayers count]) {
    330         BEGIN_BLOCK_OBJC_EXCEPTIONS
    331         while ([[m_layer.get() sublayers] count])
    332             [[[m_layer.get() sublayers] objectAtIndex:0] removeFromSuperlayer];
    333         END_BLOCK_OBJC_EXCEPTIONS
    334         return;
    335     }
    336 
    337     BEGIN_BLOCK_OBJC_EXCEPTIONS
    338     [m_layer.get() setSublayers:sublayers];
    339     END_BLOCK_OBJC_EXCEPTIONS
    340 }
    341 
    342 void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation)
    343 {
    344     // Add the delegate
    345     if (!m_delegate) {
    346         WebAnimationDelegate* webAnimationDelegate = [[WebAnimationDelegate alloc] init];
    347         m_delegate.adoptNS(webAnimationDelegate);
    348         [webAnimationDelegate setOwner:this];
    349     }
    350 
    351     CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>(animation->platformAnimation());
    352 
    353     if (![propertyAnimation delegate])
    354         [propertyAnimation setDelegate:static_cast<id>(m_delegate.get())];
    355 
    356     BEGIN_BLOCK_OBJC_EXCEPTIONS
    357     [m_layer.get() addAnimation:animation->m_animation.get() forKey:key];
    358     END_BLOCK_OBJC_EXCEPTIONS
    359 }
    360 
    361 void PlatformCALayer::removeAnimationForKey(const String& key)
    362 {
    363     BEGIN_BLOCK_OBJC_EXCEPTIONS
    364     [m_layer.get() removeAnimationForKey:key];
    365     END_BLOCK_OBJC_EXCEPTIONS
    366 }
    367 
    368 PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key)
    369 {
    370     CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>([m_layer.get() animationForKey:key]);
    371     if (!propertyAnimation)
    372         return 0;
    373     return PlatformCAAnimation::create(propertyAnimation);
    374 }
    375 
    376 PlatformCALayer* PlatformCALayer::mask() const
    377 {
    378     return platformCALayer([m_layer.get() mask]);
    379 }
    380 
    381 void PlatformCALayer::setMask(PlatformCALayer* layer)
    382 {
    383     BEGIN_BLOCK_OBJC_EXCEPTIONS
    384     [m_layer.get() setMask:layer ? layer->platformLayer() : 0];
    385     END_BLOCK_OBJC_EXCEPTIONS
    386 }
    387 
    388 bool PlatformCALayer::isOpaque() const
    389 {
    390     return [m_layer.get() isOpaque];
    391 }
    392 
    393 void PlatformCALayer::setOpaque(bool value)
    394 {
    395     BEGIN_BLOCK_OBJC_EXCEPTIONS
    396     [m_layer.get() setOpaque:value];
    397     END_BLOCK_OBJC_EXCEPTIONS
    398 }
    399 
    400 FloatRect PlatformCALayer::bounds() const
    401 {
    402     return [m_layer.get() bounds];
    403 }
    404 
    405 void PlatformCALayer::setBounds(const FloatRect& value)
    406 {
    407     BEGIN_BLOCK_OBJC_EXCEPTIONS
    408     [m_layer.get() setBounds:value];
    409     END_BLOCK_OBJC_EXCEPTIONS
    410 }
    411 
    412 FloatPoint3D PlatformCALayer::position() const
    413 {
    414     CGPoint point = [m_layer.get() position];
    415     return FloatPoint3D(point.x, point.y, [m_layer.get() zPosition]);
    416 }
    417 
    418 void PlatformCALayer::setPosition(const FloatPoint3D& value)
    419 {
    420     BEGIN_BLOCK_OBJC_EXCEPTIONS
    421     [m_layer.get() setPosition:CGPointMake(value.x(), value.y())];
    422     [m_layer.get() setZPosition:value.z()];
    423     END_BLOCK_OBJC_EXCEPTIONS
    424 }
    425 
    426 FloatPoint3D PlatformCALayer::anchorPoint() const
    427 {
    428     CGPoint point = [m_layer.get() anchorPoint];
    429     float z = 0;
    430 #if HAVE_MODERN_QUARTZCORE
    431     z = [m_layer.get() anchorPointZ];
    432 #endif
    433     return FloatPoint3D(point.x, point.y, z);
    434 }
    435 
    436 void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value)
    437 {
    438     BEGIN_BLOCK_OBJC_EXCEPTIONS
    439     [m_layer.get() setAnchorPoint:CGPointMake(value.x(), value.y())];
    440 #if HAVE_MODERN_QUARTZCORE
    441     [m_layer.get() setAnchorPointZ:value.z()];
    442 #endif
    443     END_BLOCK_OBJC_EXCEPTIONS
    444 }
    445 
    446 TransformationMatrix PlatformCALayer::transform() const
    447 {
    448     return [m_layer.get() transform];
    449 }
    450 
    451 void PlatformCALayer::setTransform(const TransformationMatrix& value)
    452 {
    453     BEGIN_BLOCK_OBJC_EXCEPTIONS
    454     [m_layer.get() setTransform:value];
    455     END_BLOCK_OBJC_EXCEPTIONS
    456 }
    457 
    458 TransformationMatrix PlatformCALayer::sublayerTransform() const
    459 {
    460     return [m_layer.get() sublayerTransform];
    461 }
    462 
    463 void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value)
    464 {
    465     BEGIN_BLOCK_OBJC_EXCEPTIONS
    466     [m_layer.get() setSublayerTransform:value];
    467     END_BLOCK_OBJC_EXCEPTIONS
    468 }
    469 
    470 TransformationMatrix PlatformCALayer::contentsTransform() const
    471 {
    472 #if !HAVE_MODERN_QUARTZCORE
    473     if (m_layerType != LayerTypeWebLayer)
    474         return TransformationMatrix();
    475 
    476     return [static_cast<WebLayer*>(m_layer.get()) contentsTransform];
    477 #else
    478     return TransformationMatrix();
    479 #endif
    480 }
    481 
    482 void PlatformCALayer::setContentsTransform(const TransformationMatrix& value)
    483 {
    484 #if !HAVE_MODERN_QUARTZCORE
    485     if (m_layerType != LayerTypeWebLayer)
    486         return;
    487 
    488     BEGIN_BLOCK_OBJC_EXCEPTIONS
    489     [m_layer.get() setContentsTransform:value];
    490     END_BLOCK_OBJC_EXCEPTIONS
    491 #else
    492     UNUSED_PARAM(value);
    493 #endif
    494 }
    495 
    496 bool PlatformCALayer::isHidden() const
    497 {
    498     return [m_layer.get() isHidden];
    499 }
    500 
    501 void PlatformCALayer::setHidden(bool value)
    502 {
    503     BEGIN_BLOCK_OBJC_EXCEPTIONS
    504     [m_layer.get() setHidden:value];
    505     END_BLOCK_OBJC_EXCEPTIONS
    506 }
    507 
    508 bool PlatformCALayer::isGeometryFlipped() const
    509 {
    510 #if HAVE_MODERN_QUARTZCORE
    511     return [m_layer.get() isGeometryFlipped];
    512 #else
    513     return false;
    514 #endif
    515 }
    516 
    517 void PlatformCALayer::setGeometryFlipped(bool value)
    518 {
    519 #if HAVE_MODERN_QUARTZCORE
    520     BEGIN_BLOCK_OBJC_EXCEPTIONS
    521     [m_layer.get() setGeometryFlipped:value];
    522     END_BLOCK_OBJC_EXCEPTIONS
    523 #else
    524     UNUSED_PARAM(value);
    525 #endif
    526 }
    527 
    528 bool PlatformCALayer::isDoubleSided() const
    529 {
    530     return [m_layer.get() isDoubleSided];
    531 }
    532 
    533 void PlatformCALayer::setDoubleSided(bool value)
    534 {
    535     BEGIN_BLOCK_OBJC_EXCEPTIONS
    536     [m_layer.get() setDoubleSided:value];
    537     END_BLOCK_OBJC_EXCEPTIONS
    538 }
    539 
    540 bool PlatformCALayer::masksToBounds() const
    541 {
    542     return [m_layer.get() masksToBounds];
    543 }
    544 
    545 void PlatformCALayer::setMasksToBounds(bool value)
    546 {
    547     BEGIN_BLOCK_OBJC_EXCEPTIONS
    548     [m_layer.get() setMasksToBounds:value];
    549     END_BLOCK_OBJC_EXCEPTIONS
    550 }
    551 
    552 bool PlatformCALayer::acceleratesDrawing() const
    553 {
    554 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    555     return [m_layer.get() acceleratesDrawing];
    556 #else
    557     return false;
    558 #endif
    559 }
    560 
    561 void PlatformCALayer::setAcceleratesDrawing(bool acceleratesDrawing)
    562 {
    563 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    564     BEGIN_BLOCK_OBJC_EXCEPTIONS
    565     [m_layer.get() setAcceleratesDrawing:acceleratesDrawing];
    566     END_BLOCK_OBJC_EXCEPTIONS
    567 #else
    568     UNUSED_PARAM(acceleratesDrawing);
    569 #endif
    570 }
    571 
    572 CFTypeRef PlatformCALayer::contents() const
    573 {
    574     return [m_layer.get() contents];
    575 }
    576 
    577 void PlatformCALayer::setContents(CFTypeRef value)
    578 {
    579     BEGIN_BLOCK_OBJC_EXCEPTIONS
    580     [m_layer.get() setContents:static_cast<id>(const_cast<void*>(value))];
    581     END_BLOCK_OBJC_EXCEPTIONS
    582 }
    583 
    584 FloatRect PlatformCALayer::contentsRect() const
    585 {
    586     return [m_layer.get() contentsRect];
    587 }
    588 
    589 void PlatformCALayer::setContentsRect(const FloatRect& value)
    590 {
    591     BEGIN_BLOCK_OBJC_EXCEPTIONS
    592     [m_layer.get() setContentsRect:value];
    593     END_BLOCK_OBJC_EXCEPTIONS
    594 }
    595 
    596 void PlatformCALayer::setMinificationFilter(FilterType value)
    597 {
    598 #if HAVE_MODERN_QUARTZCORE
    599     BEGIN_BLOCK_OBJC_EXCEPTIONS
    600     [m_layer.get() setMinificationFilter:toCAFilterType(value)];
    601     END_BLOCK_OBJC_EXCEPTIONS
    602 #else
    603     UNUSED_PARAM(value);
    604 #endif
    605 }
    606 
    607 void PlatformCALayer::setMagnificationFilter(FilterType value)
    608 {
    609 #if HAVE_MODERN_QUARTZCORE
    610     BEGIN_BLOCK_OBJC_EXCEPTIONS
    611     [m_layer.get() setMagnificationFilter:toCAFilterType(value)];
    612     END_BLOCK_OBJC_EXCEPTIONS
    613 #else
    614     UNUSED_PARAM(value);
    615 #endif
    616 }
    617 
    618 Color PlatformCALayer::backgroundColor() const
    619 {
    620     return [m_layer.get() backgroundColor];
    621 }
    622 
    623 void PlatformCALayer::setBackgroundColor(const Color& value)
    624 {
    625     CGFloat components[4];
    626     value.getRGBA(components[0], components[1], components[2], components[3]);
    627 
    628     RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    629     RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
    630 
    631     BEGIN_BLOCK_OBJC_EXCEPTIONS
    632     [m_layer.get() setBackgroundColor:color.get()];
    633     END_BLOCK_OBJC_EXCEPTIONS
    634 }
    635 
    636 float PlatformCALayer::borderWidth() const
    637 {
    638     return [m_layer.get() borderWidth];
    639 }
    640 
    641 void PlatformCALayer::setBorderWidth(float value)
    642 {
    643     BEGIN_BLOCK_OBJC_EXCEPTIONS
    644     [m_layer.get() setBorderWidth:value];
    645     END_BLOCK_OBJC_EXCEPTIONS
    646 }
    647 
    648 Color PlatformCALayer::borderColor() const
    649 {
    650     return [m_layer.get() borderColor];
    651 }
    652 
    653 void PlatformCALayer::setBorderColor(const Color& value)
    654 {
    655     CGFloat components[4];
    656     value.getRGBA(components[0], components[1], components[2], components[3]);
    657 
    658     RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    659     RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
    660 
    661     BEGIN_BLOCK_OBJC_EXCEPTIONS
    662     [m_layer.get() setBorderColor:color.get()];
    663     END_BLOCK_OBJC_EXCEPTIONS
    664 }
    665 
    666 float PlatformCALayer::opacity() const
    667 {
    668     return [m_layer.get() opacity];
    669 }
    670 
    671 void PlatformCALayer::setOpacity(float value)
    672 {
    673     BEGIN_BLOCK_OBJC_EXCEPTIONS
    674     [m_layer.get() setOpacity:value];
    675     END_BLOCK_OBJC_EXCEPTIONS
    676 }
    677 
    678 String PlatformCALayer::name() const
    679 {
    680     return [m_layer.get() name];
    681 }
    682 
    683 void PlatformCALayer::setName(const String& value)
    684 {
    685     BEGIN_BLOCK_OBJC_EXCEPTIONS
    686     [m_layer.get() setName:value];
    687     END_BLOCK_OBJC_EXCEPTIONS
    688 }
    689 
    690 FloatRect PlatformCALayer::frame() const
    691 {
    692     return [m_layer.get() frame];
    693 }
    694 
    695 void PlatformCALayer::setFrame(const FloatRect& value)
    696 {
    697     BEGIN_BLOCK_OBJC_EXCEPTIONS
    698     [m_layer.get() setFrame:value];
    699     END_BLOCK_OBJC_EXCEPTIONS
    700 }
    701 
    702 float PlatformCALayer::speed() const
    703 {
    704     return [m_layer.get() speed];
    705 }
    706 
    707 void PlatformCALayer::setSpeed(float value)
    708 {
    709     BEGIN_BLOCK_OBJC_EXCEPTIONS
    710     [m_layer.get() setSpeed:value];
    711     END_BLOCK_OBJC_EXCEPTIONS
    712 }
    713 
    714 CFTimeInterval PlatformCALayer::timeOffset() const
    715 {
    716     return [m_layer.get() timeOffset];
    717 }
    718 
    719 void PlatformCALayer::setTimeOffset(CFTimeInterval value)
    720 {
    721     BEGIN_BLOCK_OBJC_EXCEPTIONS
    722     [m_layer.get() setTimeOffset:value];
    723     END_BLOCK_OBJC_EXCEPTIONS
    724 }
    725 
    726 float PlatformCALayer::contentsScale() const
    727 {
    728 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    729     return [m_layer.get() contentsScale];
    730 #else
    731     return 1;
    732 #endif
    733 }
    734 
    735 void PlatformCALayer::setContentsScale(float value)
    736 {
    737 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    738     BEGIN_BLOCK_OBJC_EXCEPTIONS
    739     [m_layer.get() setContentsScale:value];
    740     END_BLOCK_OBJC_EXCEPTIONS
    741 #else
    742     UNUSED_PARAM(value);
    743 #endif
    744 }
    745 
    746 #endif // USE(ACCELERATED_COMPOSITING)
    747