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 
isValueFunctionSupported()43 bool PlatformCALayer::isValueFunctionSupported()
44 {
45     return true;
46 }
47 
setOwner(PlatformCALayerClient * owner)48 void PlatformCALayer::setOwner(PlatformCALayerClient* owner)
49 {
50     m_owner = owner;
51 }
52 
toCACFLayerType(PlatformCALayer::LayerType type)53 static CFStringRef toCACFLayerType(PlatformCALayer::LayerType type)
54 {
55     return (type == PlatformCALayer::LayerTypeTransformLayer) ? kCACFTransformLayer : kCACFLayer;
56 }
57 
toCACFFilterType(PlatformCALayer::FilterType type)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 
layerTreeHostForLayer(const PlatformCALayer * layer)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 
intern(const PlatformCALayer * layer)78 static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer)
79 {
80     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer->platformLayer()));
81 }
82 
intern(void * layer)83 static PlatformCALayerWinInternal* intern(void* layer)
84 {
85     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(static_cast<CACFLayerRef>(layer)));
86 }
87 
create(LayerType layerType,PlatformCALayerClient * owner)88 PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner)
89 {
90     return adoptRef(new PlatformCALayer(layerType, 0, owner));
91 }
92 
create(void * platformLayer,PlatformCALayerClient * owner)93 PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner)
94 {
95     return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner));
96 }
97 
displayCallback(CACFLayerRef caLayer,CGContextRef context)98 static void displayCallback(CACFLayerRef caLayer, CGContextRef context)
99 {
100     ASSERT_ARG(caLayer, CACFLayerGetUserData(caLayer));
101     intern(caLayer)->displayCallback(caLayer, context);
102 }
103 
layoutSublayersProc(CACFLayerRef caLayer)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 
PlatformCALayer(LayerType layerType,PlatformLayer * layer,PlatformCALayerClient * owner)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 
~PlatformCALayer()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 
platformCALayer(void * platformLayer)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 
platformLayer() const152 PlatformLayer* PlatformCALayer::platformLayer() const
153 {
154     return m_layer.get();
155 }
156 
rootLayer() const157 PlatformCALayer* PlatformCALayer::rootLayer() const
158 {
159     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
160     return host ? host->rootLayer() : 0;
161 }
162 
animationStarted(CFTimeInterval beginTime)163 void PlatformCALayer::animationStarted(CFTimeInterval beginTime)
164 {
165     // Update start time for any animation not yet started
166     CFTimeInterval cacfBeginTime = currentTimeToMediaTime(beginTime);
167 
168     HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = m_animations.end();
169     for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = m_animations.begin(); it != end; ++it)
170         it->second->setActualStartTimeIfNeeded(cacfBeginTime);
171 
172     if (m_owner)
173         m_owner->platformCALayerAnimationStarted(beginTime);
174 }
175 
resubmitAllAnimations(PlatformCALayer * layer)176 static void resubmitAllAnimations(PlatformCALayer* layer)
177 {
178     HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = layer->animations().end();
179     for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = layer->animations().begin(); it != end; ++it) {
180         RetainPtr<CFStringRef> s(AdoptCF, it->first.createCFString());
181         CACFLayerAddAnimation(layer->platformLayer(), s.get(), it->second->platformAnimation());
182     }
183 }
184 
ensureAnimationsSubmitted()185 void PlatformCALayer::ensureAnimationsSubmitted()
186 {
187     resubmitAllAnimations(this);
188 
189     PlatformCALayerList children;
190     intern(this)->getSublayers(children);
191     for (size_t i = 0; i < children.size(); ++i)
192         children[i]->ensureAnimationsSubmitted();
193 }
194 
setNeedsDisplay(const FloatRect * dirtyRect)195 void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect)
196 {
197     intern(this)->setNeedsDisplay(dirtyRect);
198 }
199 
setNeedsCommit()200 void PlatformCALayer::setNeedsCommit()
201 {
202     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
203     if (host)
204         host->layerTreeDidChange();
205 }
206 
setContentsChanged()207 void PlatformCALayer::setContentsChanged()
208 {
209     // FIXME: There is no equivalent of setContentsChanged in CACF. For now I will
210     // set contents to 0 and then back to its original value to see if that
211     // kicks CACF into redisplaying.
212     RetainPtr<CFTypeRef> contents = CACFLayerGetContents(m_layer.get());
213     CACFLayerSetContents(m_layer.get(), 0);
214     CACFLayerSetContents(m_layer.get(), contents.get());
215     setNeedsCommit();
216 }
217 
setNeedsLayout()218 void PlatformCALayer::setNeedsLayout()
219 {
220     if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges())
221         return;
222 
223     CACFLayerSetNeedsLayout(m_layer.get());
224     setNeedsCommit();
225 }
226 
superlayer() const227 PlatformCALayer* PlatformCALayer::superlayer() const
228 {
229     return platformCALayer(CACFLayerGetSuperlayer(m_layer.get()));
230 }
231 
removeFromSuperlayer()232 void PlatformCALayer::removeFromSuperlayer()
233 {
234     CACFLayerRemoveFromSuperlayer(m_layer.get());
235     setNeedsCommit();
236 }
237 
setSublayers(const PlatformCALayerList & list)238 void PlatformCALayer::setSublayers(const PlatformCALayerList& list)
239 {
240     intern(this)->setSublayers(list);
241 }
242 
removeAllSublayers()243 void PlatformCALayer::removeAllSublayers()
244 {
245     intern(this)->removeAllSublayers();
246 }
247 
appendSublayer(PlatformCALayer * layer)248 void PlatformCALayer::appendSublayer(PlatformCALayer* layer)
249 {
250     // This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override.
251     insertSublayer(layer, sublayerCount());
252 }
253 
insertSublayer(PlatformCALayer * layer,size_t index)254 void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index)
255 {
256     intern(this)->insertSublayer(layer, index);
257 }
258 
replaceSublayer(PlatformCALayer * reference,PlatformCALayer * newLayer)259 void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* newLayer)
260 {
261     // This must not use direct calls to allow PlatformCALayerInternal to override.
262     ASSERT_ARG(reference, reference);
263     ASSERT_ARG(reference, reference->superlayer() == this);
264 
265     if (reference == newLayer)
266         return;
267 
268     int referenceIndex = intern(this)->indexOfSublayer(reference);
269     ASSERT(referenceIndex != -1);
270     if (referenceIndex == -1)
271         return;
272 
273     reference->removeFromSuperlayer();
274 
275     if (newLayer) {
276         newLayer->removeFromSuperlayer();
277         insertSublayer(newLayer, referenceIndex);
278     }
279 }
280 
sublayerCount() const281 size_t PlatformCALayer::sublayerCount() const
282 {
283     return intern(this)->sublayerCount();
284 }
285 
adoptSublayers(PlatformCALayer * source)286 void PlatformCALayer::adoptSublayers(PlatformCALayer* source)
287 {
288     PlatformCALayerList sublayers;
289     intern(source)->getSublayers(sublayers);
290 
291     // Use setSublayers() because it properly nulls out the superlayer pointers.
292     setSublayers(sublayers);
293 }
294 
addAnimationForKey(const String & key,PlatformCAAnimation * animation)295 void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation)
296 {
297     // Add it to the animation list
298     m_animations.add(key, animation);
299 
300     RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
301     CACFLayerAddAnimation(m_layer.get(), s.get(), animation->platformAnimation());
302     setNeedsCommit();
303 
304     // Tell the host about it so we can fire the start animation event
305     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
306     if (host)
307         host->addPendingAnimatedLayer(this);
308 }
309 
removeAnimationForKey(const String & key)310 void PlatformCALayer::removeAnimationForKey(const String& key)
311 {
312     // Remove it from the animation list
313     m_animations.remove(key);
314 
315     RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
316     CACFLayerRemoveAnimation(m_layer.get(), s.get());
317 
318     // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
319     // There may be other active animations on the layer and if an animation
320     // callback is fired on a layer without any animations no harm is done.
321 
322     setNeedsCommit();
323 }
324 
animationForKey(const String & key)325 PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key)
326 {
327     HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key);
328     if (it == m_animations.end())
329         return 0;
330 
331     return it->second;
332 }
333 
mask() const334 PlatformCALayer* PlatformCALayer::mask() const
335 {
336     return platformCALayer(CACFLayerGetMask(m_layer.get()));
337 }
338 
setMask(PlatformCALayer * layer)339 void PlatformCALayer::setMask(PlatformCALayer* layer)
340 {
341     CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0);
342     setNeedsCommit();
343 }
344 
isOpaque() const345 bool PlatformCALayer::isOpaque() const
346 {
347     return CACFLayerIsOpaque(m_layer.get());
348 }
349 
setOpaque(bool value)350 void PlatformCALayer::setOpaque(bool value)
351 {
352     CACFLayerSetOpaque(m_layer.get(), value);
353     setNeedsCommit();
354 }
355 
bounds() const356 FloatRect PlatformCALayer::bounds() const
357 {
358     return CACFLayerGetBounds(m_layer.get());
359 }
360 
setBounds(const FloatRect & value)361 void PlatformCALayer::setBounds(const FloatRect& value)
362 {
363     intern(this)->setBounds(value);
364     setNeedsLayout();
365 }
366 
position() const367 FloatPoint3D PlatformCALayer::position() const
368 {
369     CGPoint point = CACFLayerGetPosition(m_layer.get());
370     return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get()));
371 }
372 
setPosition(const FloatPoint3D & value)373 void PlatformCALayer::setPosition(const FloatPoint3D& value)
374 {
375     CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y()));
376     CACFLayerSetZPosition(m_layer.get(), value.z());
377     setNeedsCommit();
378 }
379 
anchorPoint() const380 FloatPoint3D PlatformCALayer::anchorPoint() const
381 {
382     CGPoint point = CACFLayerGetAnchorPoint(m_layer.get());
383     float z = CACFLayerGetAnchorPointZ(m_layer.get());
384     return FloatPoint3D(point.x, point.y, z);
385 }
386 
setAnchorPoint(const FloatPoint3D & value)387 void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value)
388 {
389     CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y()));
390     CACFLayerSetAnchorPointZ(m_layer.get(), value.z());
391     setNeedsCommit();
392 }
393 
transform() const394 TransformationMatrix PlatformCALayer::transform() const
395 {
396     return CACFLayerGetTransform(m_layer.get());
397 }
398 
setTransform(const TransformationMatrix & value)399 void PlatformCALayer::setTransform(const TransformationMatrix& value)
400 {
401     CACFLayerSetTransform(m_layer.get(), value);
402     setNeedsCommit();
403 }
404 
sublayerTransform() const405 TransformationMatrix PlatformCALayer::sublayerTransform() const
406 {
407     return CACFLayerGetSublayerTransform(m_layer.get());
408 }
409 
setSublayerTransform(const TransformationMatrix & value)410 void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value)
411 {
412     CACFLayerSetSublayerTransform(m_layer.get(), value);
413     setNeedsCommit();
414 }
415 
contentsTransform() const416 TransformationMatrix PlatformCALayer::contentsTransform() const
417 {
418     // ContentsTransform is not used
419     return TransformationMatrix();
420 }
421 
setContentsTransform(const TransformationMatrix &)422 void PlatformCALayer::setContentsTransform(const TransformationMatrix&)
423 {
424     // ContentsTransform is not used
425 }
426 
isHidden() const427 bool PlatformCALayer::isHidden() const
428 {
429     return CACFLayerIsHidden(m_layer.get());
430 }
431 
setHidden(bool value)432 void PlatformCALayer::setHidden(bool value)
433 {
434     CACFLayerSetHidden(m_layer.get(), value);
435     setNeedsCommit();
436 }
437 
isGeometryFlipped() const438 bool PlatformCALayer::isGeometryFlipped() const
439 {
440     return CACFLayerIsGeometryFlipped(m_layer.get());
441 }
442 
setGeometryFlipped(bool value)443 void PlatformCALayer::setGeometryFlipped(bool value)
444 {
445     CACFLayerSetGeometryFlipped(m_layer.get(), value);
446     setNeedsCommit();
447 }
448 
isDoubleSided() const449 bool PlatformCALayer::isDoubleSided() const
450 {
451     return CACFLayerIsDoubleSided(m_layer.get());
452 }
453 
setDoubleSided(bool value)454 void PlatformCALayer::setDoubleSided(bool value)
455 {
456     CACFLayerSetDoubleSided(m_layer.get(), value);
457     setNeedsCommit();
458 }
459 
masksToBounds() const460 bool PlatformCALayer::masksToBounds() const
461 {
462     return CACFLayerGetMasksToBounds(m_layer.get());
463 }
464 
setMasksToBounds(bool value)465 void PlatformCALayer::setMasksToBounds(bool value)
466 {
467     CACFLayerSetMasksToBounds(m_layer.get(), value);
468     setNeedsCommit();
469 }
470 
acceleratesDrawing() const471 bool PlatformCALayer::acceleratesDrawing() const
472 {
473     return false;
474 }
475 
setAcceleratesDrawing(bool)476 void PlatformCALayer::setAcceleratesDrawing(bool)
477 {
478 }
479 
contents() const480 CFTypeRef PlatformCALayer::contents() const
481 {
482     return CACFLayerGetContents(m_layer.get());
483 }
484 
setContents(CFTypeRef value)485 void PlatformCALayer::setContents(CFTypeRef value)
486 {
487     CACFLayerSetContents(m_layer.get(), value);
488     setNeedsCommit();
489 }
490 
contentsRect() const491 FloatRect PlatformCALayer::contentsRect() const
492 {
493     return CACFLayerGetContentsRect(m_layer.get());
494 }
495 
setContentsRect(const FloatRect & value)496 void PlatformCALayer::setContentsRect(const FloatRect& value)
497 {
498     CACFLayerSetContentsRect(m_layer.get(), value);
499     setNeedsCommit();
500 }
501 
setMinificationFilter(FilterType value)502 void PlatformCALayer::setMinificationFilter(FilterType value)
503 {
504     CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value));
505 }
506 
setMagnificationFilter(FilterType value)507 void PlatformCALayer::setMagnificationFilter(FilterType value)
508 {
509     CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value));
510     setNeedsCommit();
511 }
512 
backgroundColor() const513 Color PlatformCALayer::backgroundColor() const
514 {
515     return CACFLayerGetBackgroundColor(m_layer.get());
516 }
517 
setBackgroundColor(const Color & value)518 void PlatformCALayer::setBackgroundColor(const Color& value)
519 {
520     CGFloat components[4];
521     value.getRGBA(components[0], components[1], components[2], components[3]);
522 
523     RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
524     RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
525 
526     CACFLayerSetBackgroundColor(m_layer.get(), color.get());
527     setNeedsCommit();
528 }
529 
borderWidth() const530 float PlatformCALayer::borderWidth() const
531 {
532     return CACFLayerGetBorderWidth(m_layer.get());
533 }
534 
setBorderWidth(float value)535 void PlatformCALayer::setBorderWidth(float value)
536 {
537     CACFLayerSetBorderWidth(m_layer.get(), value);
538     setNeedsCommit();
539 }
540 
borderColor() const541 Color PlatformCALayer::borderColor() const
542 {
543     return CACFLayerGetBorderColor(m_layer.get());
544 }
545 
setBorderColor(const Color & value)546 void PlatformCALayer::setBorderColor(const Color& value)
547 {
548     CGFloat components[4];
549     value.getRGBA(components[0], components[1], components[2], components[3]);
550 
551     RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
552     RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
553 
554     CACFLayerSetBorderColor(m_layer.get(), color.get());
555     setNeedsCommit();
556 }
557 
opacity() const558 float PlatformCALayer::opacity() const
559 {
560     return CACFLayerGetOpacity(m_layer.get());
561 }
562 
setOpacity(float value)563 void PlatformCALayer::setOpacity(float value)
564 {
565     CACFLayerSetOpacity(m_layer.get(), value);
566     setNeedsCommit();
567 }
568 
name() const569 String PlatformCALayer::name() const
570 {
571     return CACFLayerGetName(m_layer.get());
572 }
573 
setName(const String & value)574 void PlatformCALayer::setName(const String& value)
575 {
576     RetainPtr<CFStringRef> s(AdoptCF, value.createCFString());
577     CACFLayerSetName(m_layer.get(), s.get());
578     setNeedsCommit();
579 }
580 
frame() const581 FloatRect PlatformCALayer::frame() const
582 {
583     return CACFLayerGetFrame(m_layer.get());
584 }
585 
setFrame(const FloatRect & value)586 void PlatformCALayer::setFrame(const FloatRect& value)
587 {
588     intern(this)->setFrame(value);
589     setNeedsLayout();
590 }
591 
speed() const592 float PlatformCALayer::speed() const
593 {
594     return CACFLayerGetSpeed(m_layer.get());
595 }
596 
setSpeed(float value)597 void PlatformCALayer::setSpeed(float value)
598 {
599     CACFLayerSetSpeed(m_layer.get(), value);
600     setNeedsCommit();
601 }
602 
timeOffset() const603 CFTimeInterval PlatformCALayer::timeOffset() const
604 {
605     return CACFLayerGetTimeOffset(m_layer.get());
606 }
607 
setTimeOffset(CFTimeInterval value)608 void PlatformCALayer::setTimeOffset(CFTimeInterval value)
609 {
610     CACFLayerSetTimeOffset(m_layer.get(), value);
611     setNeedsCommit();
612 }
613 
contentsScale() const614 float PlatformCALayer::contentsScale() const
615 {
616     return 1;
617 }
618 
setContentsScale(float)619 void PlatformCALayer::setContentsScale(float)
620 {
621 }
622 
623 #ifndef NDEBUG
printIndent(int indent)624 static void printIndent(int indent)
625 {
626     for ( ; indent > 0; --indent)
627         fprintf(stderr, "  ");
628 }
629 
printTransform(const CATransform3D & transform)630 static void printTransform(const CATransform3D& transform)
631 {
632     fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
633                     transform.m11, transform.m12, transform.m13, transform.m14,
634                     transform.m21, transform.m22, transform.m23, transform.m24,
635                     transform.m31, transform.m32, transform.m33, transform.m34,
636                     transform.m41, transform.m42, transform.m43, transform.m44);
637 }
638 
printLayer(const PlatformCALayer * layer,int indent)639 static void printLayer(const PlatformCALayer* layer, int indent)
640 {
641     FloatPoint3D layerPosition = layer->position();
642     FloatPoint3D layerAnchorPoint = layer->anchorPoint();
643     FloatRect layerBounds = layer->bounds();
644     printIndent(indent);
645 
646     char* layerTypeName = 0;
647     switch (layer->layerType()) {
648     case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break;
649     case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break;
650     case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break;
651     case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break;
652     case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break;
653     case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break;
654     }
655 
656     fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n",
657         layerTypeName,
658         layerPosition.x(), layerPosition.y(), layerPosition.z(),
659         layerBounds.x(), layerBounds.y(), layerBounds.width(), layerBounds.height(),
660         layerAnchorPoint.x(), layerAnchorPoint.y(), layerAnchorPoint.z(), layer->superlayer());
661 
662     // Print name if needed
663     String layerName = layer->name();
664     if (!layerName.isEmpty()) {
665         printIndent(indent + 1);
666         fprintf(stderr, "(name %s)\n", layerName.utf8().data());
667     }
668 
669     // Print masksToBounds if needed
670     bool layerMasksToBounds = layer->masksToBounds();
671     if (layerMasksToBounds) {
672         printIndent(indent + 1);
673         fprintf(stderr, "(masksToBounds true)\n");
674     }
675 
676     // Print opacity if needed
677     float layerOpacity = layer->opacity();
678     if (layerOpacity != 1) {
679         printIndent(indent + 1);
680         fprintf(stderr, "(opacity %hf)\n", layerOpacity);
681     }
682 
683     // Print sublayerTransform if needed
684     TransformationMatrix layerTransform = layer->sublayerTransform();
685     if (!layerTransform.isIdentity()) {
686         printIndent(indent + 1);
687         fprintf(stderr, "(sublayerTransform ");
688         printTransform(layerTransform);
689         fprintf(stderr, ")\n");
690     }
691 
692     // Print transform if needed
693     layerTransform = layer->transform();
694     if (!layerTransform.isIdentity()) {
695         printIndent(indent + 1);
696         fprintf(stderr, "(transform ");
697         printTransform(layerTransform);
698         fprintf(stderr, ")\n");
699     }
700 
701     // Print contents if needed
702     CFTypeRef layerContents = layer->contents();
703     if (layerContents) {
704         if (CFGetTypeID(layerContents) == CGImageGetTypeID()) {
705             CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents));
706             printIndent(indent + 1);
707             fprintf(stderr, "(contents (image [%d %d]))\n",
708                 CGImageGetWidth(imageContents), CGImageGetHeight(imageContents));
709         }
710     }
711 
712     // Print sublayers if needed
713     int n = layer->sublayerCount();
714     if (n > 0) {
715         printIndent(indent + 1);
716         fprintf(stderr, "(sublayers\n");
717 
718         PlatformCALayerList sublayers;
719         intern(layer)->getSublayers(sublayers);
720         ASSERT(n == sublayers.size());
721         for (int i = 0; i < n; ++i)
722             printLayer(sublayers[i].get(), indent + 2);
723 
724         printIndent(indent + 1);
725         fprintf(stderr, ")\n");
726     }
727 
728     printIndent(indent);
729     fprintf(stderr, ")\n");
730 }
731 
printTree() const732 void PlatformCALayer::printTree() const
733 {
734     // Print heading info
735     CGRect rootBounds = bounds();
736     fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n",
737         currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height);
738 
739     // Print layer tree from the root
740     printLayer(this, 0);
741 }
742 #endif // #ifndef NDEBUG
743 
744 #endif // USE(ACCELERATED_COMPOSITING)
745