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