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