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
setNeedsDisplay(const FloatRect * dirtyRect)163 void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect)
164 {
165 intern(this)->setNeedsDisplay(dirtyRect);
166 }
167
setNeedsCommit()168 void PlatformCALayer::setNeedsCommit()
169 {
170 AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
171 if (host)
172 host->layerTreeDidChange();
173 }
174
setContentsChanged()175 void PlatformCALayer::setContentsChanged()
176 {
177 // FIXME: There is no equivalent of setContentsChanged in CACF. For now I will
178 // set contents to 0 and then back to its original value to see if that
179 // kicks CACF into redisplaying.
180 RetainPtr<CFTypeRef> contents = CACFLayerGetContents(m_layer.get());
181 CACFLayerSetContents(m_layer.get(), 0);
182 CACFLayerSetContents(m_layer.get(), contents.get());
183 setNeedsCommit();
184 }
185
setNeedsLayout()186 void PlatformCALayer::setNeedsLayout()
187 {
188 if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges())
189 return;
190
191 CACFLayerSetNeedsLayout(m_layer.get());
192 setNeedsCommit();
193 }
194
superlayer() const195 PlatformCALayer* PlatformCALayer::superlayer() const
196 {
197 return platformCALayer(CACFLayerGetSuperlayer(m_layer.get()));
198 }
199
removeFromSuperlayer()200 void PlatformCALayer::removeFromSuperlayer()
201 {
202 CACFLayerRemoveFromSuperlayer(m_layer.get());
203 setNeedsCommit();
204 }
205
setSublayers(const PlatformCALayerList & list)206 void PlatformCALayer::setSublayers(const PlatformCALayerList& list)
207 {
208 intern(this)->setSublayers(list);
209 }
210
removeAllSublayers()211 void PlatformCALayer::removeAllSublayers()
212 {
213 intern(this)->removeAllSublayers();
214 }
215
appendSublayer(PlatformCALayer * layer)216 void PlatformCALayer::appendSublayer(PlatformCALayer* layer)
217 {
218 // This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override.
219 insertSublayer(layer, sublayerCount());
220 }
221
insertSublayer(PlatformCALayer * layer,size_t index)222 void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index)
223 {
224 intern(this)->insertSublayer(layer, index);
225 }
226
replaceSublayer(PlatformCALayer * reference,PlatformCALayer * newLayer)227 void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* newLayer)
228 {
229 // This must not use direct calls to allow PlatformCALayerInternal to override.
230 ASSERT_ARG(reference, reference);
231 ASSERT_ARG(reference, reference->superlayer() == this);
232
233 if (reference == newLayer)
234 return;
235
236 int referenceIndex = intern(this)->indexOfSublayer(reference);
237 ASSERT(referenceIndex != -1);
238 if (referenceIndex == -1)
239 return;
240
241 reference->removeFromSuperlayer();
242
243 if (newLayer) {
244 newLayer->removeFromSuperlayer();
245 insertSublayer(newLayer, referenceIndex);
246 }
247 }
248
sublayerCount() const249 size_t PlatformCALayer::sublayerCount() const
250 {
251 return intern(this)->sublayerCount();
252 }
253
adoptSublayers(PlatformCALayer * source)254 void PlatformCALayer::adoptSublayers(PlatformCALayer* source)
255 {
256 PlatformCALayerList sublayers;
257 intern(source)->getSublayers(sublayers);
258
259 // Use setSublayers() because it properly nulls out the superlayer pointers.
260 setSublayers(sublayers);
261 }
262
addAnimationForKey(const String & key,PlatformCAAnimation * animation)263 void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation)
264 {
265 // Add it to the animation list
266 m_animations.add(key, animation);
267
268 RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
269 CACFLayerAddAnimation(m_layer.get(), s.get(), animation->platformAnimation());
270 setNeedsCommit();
271
272 // Tell the host about it so we can fire the start animation event
273 AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
274 if (host)
275 host->addPendingAnimatedLayer(this);
276 }
277
removeAnimationForKey(const String & key)278 void PlatformCALayer::removeAnimationForKey(const String& key)
279 {
280 // Remove it from the animation list
281 m_animations.remove(key);
282
283 RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
284 CACFLayerRemoveAnimation(m_layer.get(), s.get());
285
286 // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
287 // There may be other active animations on the layer and if an animation
288 // callback is fired on a layer without any animations no harm is done.
289
290 setNeedsCommit();
291 }
292
animationForKey(const String & key)293 PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key)
294 {
295 HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key);
296 if (it == m_animations.end())
297 return 0;
298
299 return it->second;
300 }
301
mask() const302 PlatformCALayer* PlatformCALayer::mask() const
303 {
304 return platformCALayer(CACFLayerGetMask(m_layer.get()));
305 }
306
setMask(PlatformCALayer * layer)307 void PlatformCALayer::setMask(PlatformCALayer* layer)
308 {
309 CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0);
310 setNeedsCommit();
311 }
312
isOpaque() const313 bool PlatformCALayer::isOpaque() const
314 {
315 return CACFLayerIsOpaque(m_layer.get());
316 }
317
setOpaque(bool value)318 void PlatformCALayer::setOpaque(bool value)
319 {
320 CACFLayerSetOpaque(m_layer.get(), value);
321 setNeedsCommit();
322 }
323
bounds() const324 FloatRect PlatformCALayer::bounds() const
325 {
326 return CACFLayerGetBounds(m_layer.get());
327 }
328
setBounds(const FloatRect & value)329 void PlatformCALayer::setBounds(const FloatRect& value)
330 {
331 intern(this)->setBounds(value);
332 setNeedsLayout();
333 }
334
position() const335 FloatPoint3D PlatformCALayer::position() const
336 {
337 CGPoint point = CACFLayerGetPosition(m_layer.get());
338 return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get()));
339 }
340
setPosition(const FloatPoint3D & value)341 void PlatformCALayer::setPosition(const FloatPoint3D& value)
342 {
343 CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y()));
344 CACFLayerSetZPosition(m_layer.get(), value.z());
345 setNeedsCommit();
346 }
347
anchorPoint() const348 FloatPoint3D PlatformCALayer::anchorPoint() const
349 {
350 CGPoint point = CACFLayerGetAnchorPoint(m_layer.get());
351 float z = CACFLayerGetAnchorPointZ(m_layer.get());
352 return FloatPoint3D(point.x, point.y, z);
353 }
354
setAnchorPoint(const FloatPoint3D & value)355 void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value)
356 {
357 CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y()));
358 CACFLayerSetAnchorPointZ(m_layer.get(), value.z());
359 setNeedsCommit();
360 }
361
transform() const362 TransformationMatrix PlatformCALayer::transform() const
363 {
364 return CACFLayerGetTransform(m_layer.get());
365 }
366
setTransform(const TransformationMatrix & value)367 void PlatformCALayer::setTransform(const TransformationMatrix& value)
368 {
369 CACFLayerSetTransform(m_layer.get(), value);
370 setNeedsCommit();
371 }
372
sublayerTransform() const373 TransformationMatrix PlatformCALayer::sublayerTransform() const
374 {
375 return CACFLayerGetSublayerTransform(m_layer.get());
376 }
377
setSublayerTransform(const TransformationMatrix & value)378 void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value)
379 {
380 CACFLayerSetSublayerTransform(m_layer.get(), value);
381 setNeedsCommit();
382 }
383
contentsTransform() const384 TransformationMatrix PlatformCALayer::contentsTransform() const
385 {
386 // ContentsTransform is not used
387 return TransformationMatrix();
388 }
389
setContentsTransform(const TransformationMatrix &)390 void PlatformCALayer::setContentsTransform(const TransformationMatrix&)
391 {
392 // ContentsTransform is not used
393 }
394
isHidden() const395 bool PlatformCALayer::isHidden() const
396 {
397 return CACFLayerIsHidden(m_layer.get());
398 }
399
setHidden(bool value)400 void PlatformCALayer::setHidden(bool value)
401 {
402 CACFLayerSetHidden(m_layer.get(), value);
403 setNeedsCommit();
404 }
405
isGeometryFlipped() const406 bool PlatformCALayer::isGeometryFlipped() const
407 {
408 return CACFLayerIsGeometryFlipped(m_layer.get());
409 }
410
setGeometryFlipped(bool value)411 void PlatformCALayer::setGeometryFlipped(bool value)
412 {
413 CACFLayerSetGeometryFlipped(m_layer.get(), value);
414 setNeedsCommit();
415 }
416
isDoubleSided() const417 bool PlatformCALayer::isDoubleSided() const
418 {
419 return CACFLayerIsDoubleSided(m_layer.get());
420 }
421
setDoubleSided(bool value)422 void PlatformCALayer::setDoubleSided(bool value)
423 {
424 CACFLayerSetDoubleSided(m_layer.get(), value);
425 setNeedsCommit();
426 }
427
masksToBounds() const428 bool PlatformCALayer::masksToBounds() const
429 {
430 return CACFLayerGetMasksToBounds(m_layer.get());
431 }
432
setMasksToBounds(bool value)433 void PlatformCALayer::setMasksToBounds(bool value)
434 {
435 CACFLayerSetMasksToBounds(m_layer.get(), value);
436 setNeedsCommit();
437 }
438
acceleratesDrawing() const439 bool PlatformCALayer::acceleratesDrawing() const
440 {
441 return false;
442 }
443
setAcceleratesDrawing(bool)444 void PlatformCALayer::setAcceleratesDrawing(bool)
445 {
446 }
447
contents() const448 CFTypeRef PlatformCALayer::contents() const
449 {
450 return CACFLayerGetContents(m_layer.get());
451 }
452
setContents(CFTypeRef value)453 void PlatformCALayer::setContents(CFTypeRef value)
454 {
455 CACFLayerSetContents(m_layer.get(), value);
456 setNeedsCommit();
457 }
458
contentsRect() const459 FloatRect PlatformCALayer::contentsRect() const
460 {
461 return CACFLayerGetContentsRect(m_layer.get());
462 }
463
setContentsRect(const FloatRect & value)464 void PlatformCALayer::setContentsRect(const FloatRect& value)
465 {
466 CACFLayerSetContentsRect(m_layer.get(), value);
467 setNeedsCommit();
468 }
469
setMinificationFilter(FilterType value)470 void PlatformCALayer::setMinificationFilter(FilterType value)
471 {
472 CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value));
473 }
474
setMagnificationFilter(FilterType value)475 void PlatformCALayer::setMagnificationFilter(FilterType value)
476 {
477 CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value));
478 setNeedsCommit();
479 }
480
backgroundColor() const481 Color PlatformCALayer::backgroundColor() const
482 {
483 return CACFLayerGetBackgroundColor(m_layer.get());
484 }
485
setBackgroundColor(const Color & value)486 void PlatformCALayer::setBackgroundColor(const Color& value)
487 {
488 CGFloat components[4];
489 value.getRGBA(components[0], components[1], components[2], components[3]);
490
491 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
492 RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
493
494 CACFLayerSetBackgroundColor(m_layer.get(), color.get());
495 setNeedsCommit();
496 }
497
borderWidth() const498 float PlatformCALayer::borderWidth() const
499 {
500 return CACFLayerGetBorderWidth(m_layer.get());
501 }
502
setBorderWidth(float value)503 void PlatformCALayer::setBorderWidth(float value)
504 {
505 CACFLayerSetBorderWidth(m_layer.get(), value);
506 setNeedsCommit();
507 }
508
borderColor() const509 Color PlatformCALayer::borderColor() const
510 {
511 return CACFLayerGetBorderColor(m_layer.get());
512 }
513
setBorderColor(const Color & value)514 void PlatformCALayer::setBorderColor(const Color& value)
515 {
516 CGFloat components[4];
517 value.getRGBA(components[0], components[1], components[2], components[3]);
518
519 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
520 RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
521
522 CACFLayerSetBorderColor(m_layer.get(), color.get());
523 setNeedsCommit();
524 }
525
opacity() const526 float PlatformCALayer::opacity() const
527 {
528 return CACFLayerGetOpacity(m_layer.get());
529 }
530
setOpacity(float value)531 void PlatformCALayer::setOpacity(float value)
532 {
533 CACFLayerSetOpacity(m_layer.get(), value);
534 setNeedsCommit();
535 }
536
name() const537 String PlatformCALayer::name() const
538 {
539 return CACFLayerGetName(m_layer.get());
540 }
541
setName(const String & value)542 void PlatformCALayer::setName(const String& value)
543 {
544 RetainPtr<CFStringRef> s(AdoptCF, value.createCFString());
545 CACFLayerSetName(m_layer.get(), s.get());
546 setNeedsCommit();
547 }
548
frame() const549 FloatRect PlatformCALayer::frame() const
550 {
551 return CACFLayerGetFrame(m_layer.get());
552 }
553
setFrame(const FloatRect & value)554 void PlatformCALayer::setFrame(const FloatRect& value)
555 {
556 intern(this)->setFrame(value);
557 setNeedsLayout();
558 }
559
speed() const560 float PlatformCALayer::speed() const
561 {
562 return CACFLayerGetSpeed(m_layer.get());
563 }
564
setSpeed(float value)565 void PlatformCALayer::setSpeed(float value)
566 {
567 CACFLayerSetSpeed(m_layer.get(), value);
568 setNeedsCommit();
569 }
570
timeOffset() const571 CFTimeInterval PlatformCALayer::timeOffset() const
572 {
573 return CACFLayerGetTimeOffset(m_layer.get());
574 }
575
setTimeOffset(CFTimeInterval value)576 void PlatformCALayer::setTimeOffset(CFTimeInterval value)
577 {
578 CACFLayerSetTimeOffset(m_layer.get(), value);
579 setNeedsCommit();
580 }
581
contentsScale() const582 float PlatformCALayer::contentsScale() const
583 {
584 return 1;
585 }
586
setContentsScale(float)587 void PlatformCALayer::setContentsScale(float)
588 {
589 }
590
591 #ifndef NDEBUG
printIndent(int indent)592 static void printIndent(int indent)
593 {
594 for ( ; indent > 0; --indent)
595 fprintf(stderr, " ");
596 }
597
printTransform(const CATransform3D & transform)598 static void printTransform(const CATransform3D& transform)
599 {
600 fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
601 transform.m11, transform.m12, transform.m13, transform.m14,
602 transform.m21, transform.m22, transform.m23, transform.m24,
603 transform.m31, transform.m32, transform.m33, transform.m34,
604 transform.m41, transform.m42, transform.m43, transform.m44);
605 }
606
printLayer(const PlatformCALayer * layer,int indent)607 static void printLayer(const PlatformCALayer* layer, int indent)
608 {
609 FloatPoint3D layerPosition = layer->position();
610 FloatPoint3D layerAnchorPoint = layer->anchorPoint();
611 FloatRect layerBounds = layer->bounds();
612 printIndent(indent);
613
614 char* layerTypeName = 0;
615 switch (layer->layerType()) {
616 case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break;
617 case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break;
618 case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break;
619 case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break;
620 case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break;
621 case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break;
622 }
623
624 fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n",
625 layerTypeName,
626 layerPosition.x(), layerPosition.y(), layerPosition.z(),
627 layerBounds.x(), layerBounds.y(), layerBounds.width(), layerBounds.height(),
628 layerAnchorPoint.x(), layerAnchorPoint.y(), layerAnchorPoint.z(), layer->superlayer());
629
630 // Print name if needed
631 String layerName = layer->name();
632 if (!layerName.isEmpty()) {
633 printIndent(indent + 1);
634 fprintf(stderr, "(name %s)\n", layerName.utf8().data());
635 }
636
637 // Print masksToBounds if needed
638 bool layerMasksToBounds = layer->masksToBounds();
639 if (layerMasksToBounds) {
640 printIndent(indent + 1);
641 fprintf(stderr, "(masksToBounds true)\n");
642 }
643
644 // Print opacity if needed
645 float layerOpacity = layer->opacity();
646 if (layerOpacity != 1) {
647 printIndent(indent + 1);
648 fprintf(stderr, "(opacity %hf)\n", layerOpacity);
649 }
650
651 // Print sublayerTransform if needed
652 TransformationMatrix layerTransform = layer->sublayerTransform();
653 if (!layerTransform.isIdentity()) {
654 printIndent(indent + 1);
655 fprintf(stderr, "(sublayerTransform ");
656 printTransform(layerTransform);
657 fprintf(stderr, ")\n");
658 }
659
660 // Print transform if needed
661 layerTransform = layer->transform();
662 if (!layerTransform.isIdentity()) {
663 printIndent(indent + 1);
664 fprintf(stderr, "(transform ");
665 printTransform(layerTransform);
666 fprintf(stderr, ")\n");
667 }
668
669 // Print contents if needed
670 CFTypeRef layerContents = layer->contents();
671 if (layerContents) {
672 if (CFGetTypeID(layerContents) == CGImageGetTypeID()) {
673 CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents));
674 printIndent(indent + 1);
675 fprintf(stderr, "(contents (image [%d %d]))\n",
676 CGImageGetWidth(imageContents), CGImageGetHeight(imageContents));
677 }
678 }
679
680 // Print sublayers if needed
681 int n = layer->sublayerCount();
682 if (n > 0) {
683 printIndent(indent + 1);
684 fprintf(stderr, "(sublayers\n");
685
686 PlatformCALayerList sublayers;
687 intern(layer)->getSublayers(sublayers);
688 ASSERT(n == sublayers.size());
689 for (int i = 0; i < n; ++i)
690 printLayer(sublayers[i].get(), indent + 2);
691
692 printIndent(indent + 1);
693 fprintf(stderr, ")\n");
694 }
695
696 printIndent(indent);
697 fprintf(stderr, ")\n");
698 }
699
printTree() const700 void PlatformCALayer::printTree() const
701 {
702 // Print heading info
703 CGRect rootBounds = bounds();
704 fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n",
705 currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height);
706
707 // Print layer tree from the root
708 printLayer(this, 0);
709 }
710 #endif // #ifndef NDEBUG
711
712 #endif // USE(ACCELERATED_COMPOSITING)
713