Unreviewed, rolling out r178518.
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / win / PlatformCALayerWin.cpp
1 /*
2  * Copyright (C) 2011, 2014 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 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 #include "PlatformCALayerWin.h"
29
30 #include "AbstractCACFLayerTreeHost.h"
31 #include "Font.h"
32 #include "GraphicsContext.h"
33 #include "PlatformCAAnimationWin.h"
34 #include "PlatformCALayerWinInternal.h"
35 #include "TileController.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
43 PassRefPtr<PlatformCALayer> PlatformCALayerWin::create(LayerType layerType, PlatformCALayerClient* owner)
44 {
45     return adoptRef(new PlatformCALayerWin(layerType, 0, owner));
46 }
47
48 PassRefPtr<PlatformCALayer> PlatformCALayerWin::create(PlatformLayer* platformLayer, PlatformCALayerClient* owner)
49 {
50     return adoptRef(new PlatformCALayerWin(LayerTypeCustom, platformLayer, owner));
51 }
52
53 static CFStringRef toCACFLayerType(PlatformCALayer::LayerType type)
54 {
55     return (type == PlatformCALayer::LayerTypeTransformLayer) ? kCACFTransformLayer : kCACFLayer;
56 }
57
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
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
78 static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer)
79 {
80     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer->platformLayer()));
81 }
82
83 static PlatformCALayerWinInternal* intern(void* layer)
84 {
85     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(static_cast<CACFLayerRef>(layer)));
86 }
87
88 PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer)
89 {
90     if (!platformLayer)
91         return 0;
92     
93     PlatformCALayerWinInternal* layerIntern = intern(platformLayer);
94     return layerIntern ? layerIntern->owner() : 0;
95 }
96
97 PlatformCALayer::RepaintRectList PlatformCALayer::collectRectsToPaint(CGContextRef, PlatformCALayer*)
98 {
99     // FIXME: We should actually collect rects to use instead of defaulting to Windows'
100     // normal drawing path.
101     PlatformCALayer::RepaintRectList dirtyRects;
102     return dirtyRects;
103 }
104
105 void PlatformCALayer::drawLayerContents(CGContextRef context, WebCore::PlatformCALayer* platformCALayer, RepaintRectList&)
106 {
107     intern(platformCALayer)->displayCallback(platformCALayer->platformLayer(), context);
108 }
109
110 CGRect PlatformCALayer::frameForLayer(const PlatformLayer* tileLayer)
111 {
112     return CACFLayerGetFrame(static_cast<CACFLayerRef>(const_cast<PlatformLayer*>(tileLayer)));
113 }
114
115 static void displayCallback(CACFLayerRef caLayer, CGContextRef context)
116 {
117     ASSERT_ARG(caLayer, CACFLayerGetUserData(caLayer));
118     intern(caLayer)->displayCallback(caLayer, context);
119 }
120
121 static void layoutSublayersProc(CACFLayerRef caLayer) 
122 {
123     PlatformCALayer* layer = PlatformCALayer::platformCALayer(caLayer);
124     if (layer && layer->owner())
125         layer->owner()->platformCALayerLayoutSublayersOfLayer(layer);
126 }
127
128 PlatformCALayerWin::PlatformCALayerWin(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner)
129     : PlatformCALayer(layer ? LayerTypeCustom : layerType, owner)
130     , m_customAppearance(GraphicsLayer::NoCustomAppearance)
131     , m_customBehavior(GraphicsLayer::NoCustomBehavior)
132 {
133     if (layer) {
134         m_layer = layer;
135         return;
136     }
137
138     m_layer = adoptCF(CACFLayerCreate(toCACFLayerType(layerType)));
139
140     // Create the PlatformCALayerWinInternal object and point to it in the userdata.
141     PlatformCALayerWinInternal* intern = new PlatformCALayerWinInternal(this);
142     CACFLayerSetUserData(m_layer.get(), intern);
143
144     // Set the display callback
145     CACFLayerSetDisplayCallback(m_layer.get(), displayCallback);
146     CACFLayerSetLayoutCallback(m_layer.get(), layoutSublayersProc);
147
148     if (usesTiledBackingLayer()) {
149         TileController* tileController = intern->createTileController(this);
150         m_customSublayers = std::make_unique<PlatformCALayerList>(tileController->containerLayers());
151     }
152 }
153
154 PlatformCALayerWin::~PlatformCALayerWin()
155 {
156     // Toss all the kids
157     removeAllSublayers();
158
159     // Get rid of the user data
160     PlatformCALayerWinInternal* layerIntern = intern(this);
161     CACFLayerSetUserData(m_layer.get(), 0);
162
163     CACFLayerRemoveFromSuperlayer(m_layer.get());
164
165     delete layerIntern;
166 }
167
168 PassRefPtr<PlatformCALayer> PlatformCALayerWin::clone(PlatformCALayerClient* owner) const
169 {
170     PlatformCALayer::LayerType type = (layerType() == PlatformCALayer::LayerTypeTransformLayer) ?
171         PlatformCALayer::LayerTypeTransformLayer : PlatformCALayer::LayerTypeLayer;
172     RefPtr<PlatformCALayer> newLayer = PlatformCALayerWin::create(type, owner);
173
174     newLayer->setPosition(position());
175     newLayer->setBounds(bounds());
176     newLayer->setAnchorPoint(anchorPoint());
177     newLayer->setTransform(transform());
178     newLayer->setSublayerTransform(sublayerTransform());
179     newLayer->setContents(contents());
180     newLayer->setMasksToBounds(masksToBounds());
181     newLayer->setDoubleSided(isDoubleSided());
182     newLayer->setOpaque(isOpaque());
183     newLayer->setBackgroundColor(backgroundColor());
184     newLayer->setContentsScale(contentsScale());
185     newLayer->copyFiltersFrom(*this);
186
187     return newLayer;
188 }
189
190 PlatformCALayer* PlatformCALayerWin::rootLayer() const
191 {
192     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
193     return host ? host->rootLayer() : nullptr;
194 }
195
196 void PlatformCALayerWin::animationStarted(const String& animationKey, CFTimeInterval beginTime)
197 {
198     // Update start time for any animation not yet started
199     CFTimeInterval cacfBeginTime = currentTimeToMediaTime(beginTime);
200
201     HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = m_animations.end();
202     for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = m_animations.begin(); it != end; ++it)
203         it->value->setActualStartTimeIfNeeded(cacfBeginTime);
204
205     if (m_owner)
206         m_owner->platformCALayerAnimationStarted(animationKey, beginTime);
207 }
208
209 void PlatformCALayerWin::animationEnded(const String& animationKey)
210 {
211     if (m_owner)
212         m_owner->platformCALayerAnimationEnded(animationKey);
213 }
214
215 void PlatformCALayerWin::setNeedsDisplayInRect(const FloatRect& dirtyRect)
216 {
217     intern(this)->setNeedsDisplayInRect(dirtyRect);
218 }
219
220 void PlatformCALayerWin::setNeedsDisplay()
221 {
222     intern(this)->setNeedsDisplay();
223 }
224
225 void PlatformCALayerWin::setNeedsCommit()
226 {
227     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
228     if (host)
229         host->layerTreeDidChange();
230 }
231
232 void PlatformCALayerWin::copyContentsFromLayer(PlatformCALayer* source)
233 {
234     if (source) {
235         RetainPtr<CFTypeRef> contents = CACFLayerGetContents(source->platformLayer());
236         CACFLayerSetContents(m_layer.get(), contents.get());
237     } else
238         CACFLayerSetContents(m_layer.get(), nullptr);
239
240     setNeedsCommit();
241 }
242
243 void PlatformCALayerWin::setNeedsLayout()
244 {
245     if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges())
246         return;
247
248     CACFLayerSetNeedsLayout(m_layer.get());
249     setNeedsCommit();
250 }
251
252 PlatformCALayer* PlatformCALayerWin::superlayer() const
253 {
254     return platformCALayer(CACFLayerGetSuperlayer(m_layer.get()));
255 }
256
257 void PlatformCALayerWin::removeFromSuperlayer()
258 {
259     CACFLayerRemoveFromSuperlayer(m_layer.get());
260     setNeedsCommit();
261 }
262
263 void PlatformCALayerWin::setSublayers(const PlatformCALayerList& list)
264 {
265     intern(this)->setSublayers(list);
266 }
267
268 void PlatformCALayerWin::removeAllSublayers()
269 {
270     intern(this)->removeAllSublayers();
271 }
272
273 void PlatformCALayerWin::appendSublayer(PlatformCALayer& layer)
274 {
275     // This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override.
276     insertSublayer(layer, intern(this)->sublayerCount());
277 }
278
279 void PlatformCALayerWin::insertSublayer(PlatformCALayer& layer, size_t index)
280 {
281     intern(this)->insertSublayer(layer, index);
282 }
283
284 void PlatformCALayerWin::replaceSublayer(PlatformCALayer& reference, PlatformCALayer& newLayer)
285 {
286     // This must not use direct calls to allow PlatformCALayerInternal to override.
287     ASSERT_ARG(reference, reference.superlayer() == this);
288
289     if (&reference == &newLayer)
290         return;
291
292     int referenceIndex = intern(this)->indexOfSublayer(&reference);
293     ASSERT(referenceIndex != -1);
294     if (referenceIndex == -1)
295         return;
296
297     reference.removeFromSuperlayer();
298
299     newLayer.removeFromSuperlayer();
300     insertSublayer(newLayer, referenceIndex);
301 }
302
303 void PlatformCALayerWin::adoptSublayers(PlatformCALayer& source)
304 {
305     PlatformCALayerList sublayers;
306     intern(&source)->getSublayers(sublayers);
307
308     // Use setSublayers() because it properly nulls out the superlayer pointers.
309     setSublayers(sublayers);
310 }
311
312 void PlatformCALayerWin::addAnimationForKey(const String& key, PlatformCAAnimation& animation)
313 {
314     // Add it to the animation list
315     m_animations.add(key, &animation);
316
317     CACFLayerAddAnimation(m_layer.get(), key.createCFString().get(), downcast<PlatformCAAnimationWin>(animation).platformAnimation());
318     setNeedsCommit();
319
320     // Tell the host about it so we can fire the start animation event
321     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
322     if (host)
323         host->addPendingAnimatedLayer(this);
324 }
325
326 void PlatformCALayerWin::removeAnimationForKey(const String& key)
327 {
328     // Remove it from the animation list
329     m_animations.remove(key);
330
331     CACFLayerRemoveAnimation(m_layer.get(), key.createCFString().get());
332
333     // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
334     // There may be other active animations on the layer and if an animation
335     // callback is fired on a layer without any animations no harm is done.
336
337     setNeedsCommit();
338 }
339
340 PassRefPtr<PlatformCAAnimation> PlatformCALayerWin::animationForKey(const String& key)
341 {
342     HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key);
343     if (it == m_animations.end())
344         return 0;
345
346     return it->value;
347 }
348
349 void PlatformCALayerWin::setMask(PlatformCALayer* layer)
350 {
351     CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0);
352     setNeedsCommit();
353 }
354
355 bool PlatformCALayerWin::isOpaque() const
356 {
357     return CACFLayerIsOpaque(m_layer.get());
358 }
359
360 void PlatformCALayerWin::setOpaque(bool value)
361 {
362     CACFLayerSetOpaque(m_layer.get(), value);
363     setNeedsCommit();
364 }
365
366 FloatRect PlatformCALayerWin::bounds() const
367 {
368     return CACFLayerGetBounds(m_layer.get());
369 }
370
371 void PlatformCALayerWin::setBounds(const FloatRect& value)
372 {
373     intern(this)->setBounds(value);
374     setNeedsLayout();
375 }
376
377 FloatPoint3D PlatformCALayerWin::position() const
378 {
379     CGPoint point = CACFLayerGetPosition(m_layer.get());
380     return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get()));
381 }
382
383 void PlatformCALayerWin::setPosition(const FloatPoint3D& value)
384 {
385     CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y()));
386     CACFLayerSetZPosition(m_layer.get(), value.z());
387     setNeedsCommit();
388 }
389
390 FloatPoint3D PlatformCALayerWin::anchorPoint() const
391 {
392     CGPoint point = CACFLayerGetAnchorPoint(m_layer.get());
393     float z = CACFLayerGetAnchorPointZ(m_layer.get());
394     return FloatPoint3D(point.x, point.y, z);
395 }
396
397 void PlatformCALayerWin::setAnchorPoint(const FloatPoint3D& value)
398 {
399     CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y()));
400     CACFLayerSetAnchorPointZ(m_layer.get(), value.z());
401     setNeedsCommit();
402 }
403
404 TransformationMatrix PlatformCALayerWin::transform() const
405 {
406     return CACFLayerGetTransform(m_layer.get());
407 }
408
409 void PlatformCALayerWin::setTransform(const TransformationMatrix& value)
410 {
411     CACFLayerSetTransform(m_layer.get(), value);
412     setNeedsCommit();
413 }
414
415 TransformationMatrix PlatformCALayerWin::sublayerTransform() const
416 {
417     return CACFLayerGetSublayerTransform(m_layer.get());
418 }
419
420 void PlatformCALayerWin::setSublayerTransform(const TransformationMatrix& value)
421 {
422     CACFLayerSetSublayerTransform(m_layer.get(), value);
423     setNeedsCommit();
424 }
425
426 void PlatformCALayerWin::setHidden(bool value)
427 {
428     CACFLayerSetHidden(m_layer.get(), value);
429     setNeedsCommit();
430 }
431
432 void PlatformCALayerWin::setGeometryFlipped(bool value)
433 {
434     CACFLayerSetGeometryFlipped(m_layer.get(), value);
435     setNeedsCommit();
436 }
437
438 bool PlatformCALayerWin::isDoubleSided() const
439 {
440     return CACFLayerIsDoubleSided(m_layer.get());
441 }
442
443 void PlatformCALayerWin::setDoubleSided(bool value)
444 {
445     CACFLayerSetDoubleSided(m_layer.get(), value);
446     setNeedsCommit();
447 }
448
449 bool PlatformCALayerWin::masksToBounds() const
450 {
451     return CACFLayerGetMasksToBounds(m_layer.get());
452 }
453
454 void PlatformCALayerWin::setMasksToBounds(bool value)
455 {
456     CACFLayerSetMasksToBounds(m_layer.get(), value);
457     setNeedsCommit();
458 }
459
460 bool PlatformCALayerWin::acceleratesDrawing() const
461 {
462     return false;
463 }
464
465 void PlatformCALayerWin::setAcceleratesDrawing(bool)
466 {
467 }
468
469 CFTypeRef PlatformCALayerWin::contents() const
470 {
471     return CACFLayerGetContents(m_layer.get());
472 }
473
474 void PlatformCALayerWin::setContents(CFTypeRef value)
475 {
476     CACFLayerSetContents(m_layer.get(), value);
477     setNeedsCommit();
478 }
479
480 void PlatformCALayerWin::setContentsRect(const FloatRect& value)
481 {
482     CACFLayerSetContentsRect(m_layer.get(), value);
483     setNeedsCommit();
484 }
485
486 void PlatformCALayerWin::setMinificationFilter(FilterType value)
487 {
488     CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value));
489 }
490
491 void PlatformCALayerWin::setMagnificationFilter(FilterType value)
492 {
493     CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value));
494     setNeedsCommit();
495 }
496
497 Color PlatformCALayerWin::backgroundColor() const
498 {
499     return CACFLayerGetBackgroundColor(m_layer.get());
500 }
501
502 void PlatformCALayerWin::setBackgroundColor(const Color& value)
503 {
504     CGFloat components[4];
505     value.getRGBA(components[0], components[1], components[2], components[3]);
506
507     RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
508     RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
509
510     CACFLayerSetBackgroundColor(m_layer.get(), color.get());
511     setNeedsCommit();
512 }
513
514 void PlatformCALayerWin::setBorderWidth(float value)
515 {
516     CACFLayerSetBorderWidth(m_layer.get(), value);
517     setNeedsCommit();
518 }
519
520 void PlatformCALayerWin::setBorderColor(const Color& value)
521 {
522     CGFloat components[4];
523     value.getRGBA(components[0], components[1], components[2], components[3]);
524
525     RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
526     RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
527
528     CACFLayerSetBorderColor(m_layer.get(), color.get());
529     setNeedsCommit();
530 }
531
532 float PlatformCALayerWin::opacity() const
533 {
534     return CACFLayerGetOpacity(m_layer.get());
535 }
536
537 void PlatformCALayerWin::setOpacity(float value)
538 {
539     CACFLayerSetOpacity(m_layer.get(), value);
540     setNeedsCommit();
541 }
542
543 void PlatformCALayerWin::setFilters(const FilterOperations&)
544 {
545 }
546
547 void PlatformCALayerWin::copyFiltersFrom(const PlatformCALayer&)
548 {
549 }
550
551 void PlatformCALayerWin::setName(const String& value)
552 {
553     CACFLayerSetName(m_layer.get(), value.createCFString().get());
554     setNeedsCommit();
555 }
556
557 void PlatformCALayerWin::setSpeed(float value)
558 {
559     CACFLayerSetSpeed(m_layer.get(), value);
560     setNeedsCommit();
561 }
562
563 void PlatformCALayerWin::setTimeOffset(CFTimeInterval value)
564 {
565     CACFLayerSetTimeOffset(m_layer.get(), value);
566     setNeedsCommit();
567 }
568
569 void PlatformCALayerWin::setEdgeAntialiasingMask(unsigned mask)
570 {
571     CACFLayerSetEdgeAntialiasingMask(m_layer.get(), mask);
572     setNeedsCommit();
573 }
574
575 float PlatformCALayerWin::contentsScale() const
576 {
577     return 1;
578 }
579
580 void PlatformCALayerWin::setContentsScale(float)
581 {
582 }
583
584 float PlatformCALayerWin::cornerRadius() const
585 {
586     return 0; // FIXME: implement.
587 }
588
589 void PlatformCALayerWin::setCornerRadius(float value)
590 {
591     // FIXME: implement.
592 }
593
594 FloatRoundedRect PlatformCALayerWin::shapeRoundedRect() const
595 {
596     // FIXME: implement.
597     return FloatRoundedRect();
598 }
599
600 void PlatformCALayerWin::setShapeRoundedRect(const FloatRoundedRect&)
601 {
602     // FIXME: implement.
603 }
604
605 #ifndef NDEBUG
606 static void printIndent(int indent)
607 {
608     for ( ; indent > 0; --indent)
609         fprintf(stderr, "  ");
610 }
611
612 static void printTransform(const CATransform3D& transform)
613 {
614     fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
615                     transform.m11, transform.m12, transform.m13, transform.m14, 
616                     transform.m21, transform.m22, transform.m23, transform.m24, 
617                     transform.m31, transform.m32, transform.m33, transform.m34, 
618                     transform.m41, transform.m42, transform.m43, transform.m44);
619 }
620
621 static void printLayer(const PlatformCALayer* layer, int indent)
622 {
623     FloatPoint3D layerPosition = layer->position();
624     FloatPoint3D layerAnchorPoint = layer->anchorPoint();
625     FloatRect layerBounds = layer->bounds();
626     printIndent(indent);
627
628     char* layerTypeName = 0;
629     switch (layer->layerType()) {
630     case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break;
631     case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break;
632     case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break;
633     case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break;
634     case PlatformCALayer::LayerTypeTiledBackingLayer: layerTypeName = "tiled-backing-layer"; break;
635     case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break;
636     case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break;
637     }
638
639     fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n",
640         layerTypeName,
641         layerPosition.x(), layerPosition.y(), layerPosition.z(), 
642         layerBounds.x(), layerBounds.y(), layerBounds.width(), layerBounds.height(),
643         layerAnchorPoint.x(), layerAnchorPoint.y(), layerAnchorPoint.z(), layer->superlayer());
644
645     // Print name if needed
646     String layerName = CACFLayerGetName(layer->platformLayer());
647     if (!layerName.isEmpty()) {
648         printIndent(indent + 1);
649         fprintf(stderr, "(name %s)\n", layerName.utf8().data());
650     }
651
652     // Print masksToBounds if needed
653     bool layerMasksToBounds = layer->masksToBounds();
654     if (layerMasksToBounds) {
655         printIndent(indent + 1);
656         fprintf(stderr, "(masksToBounds true)\n");
657     }
658
659     // Print opacity if needed
660     float layerOpacity = layer->opacity();
661     if (layerOpacity != 1) {
662         printIndent(indent + 1);
663         fprintf(stderr, "(opacity %hf)\n", layerOpacity);
664     }
665
666     // Print sublayerTransform if needed
667     TransformationMatrix layerTransform = layer->sublayerTransform();
668     if (!layerTransform.isIdentity()) {
669         printIndent(indent + 1);
670         fprintf(stderr, "(sublayerTransform ");
671         printTransform(layerTransform);
672         fprintf(stderr, ")\n");
673     }
674
675     // Print transform if needed
676     layerTransform = layer->transform();
677     if (!layerTransform.isIdentity()) {
678         printIndent(indent + 1);
679         fprintf(stderr, "(transform ");
680         printTransform(layerTransform);
681         fprintf(stderr, ")\n");
682     }
683
684     // Print contents if needed
685     CFTypeRef layerContents = layer->contents();
686     if (layerContents) {
687         if (CFGetTypeID(layerContents) == CGImageGetTypeID()) {
688             CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents));
689             printIndent(indent + 1);
690             fprintf(stderr, "(contents (image [%Iu %Iu]))\n",
691                 CGImageGetWidth(imageContents), CGImageGetHeight(imageContents));
692         }
693     }
694
695     // Print sublayers if needed
696     int n = intern(layer)->sublayerCount();
697     if (n > 0) {
698         printIndent(indent + 1);
699         fprintf(stderr, "(sublayers\n");
700
701         PlatformCALayerList sublayers;
702         intern(layer)->getSublayers(sublayers);
703         ASSERT(n == sublayers.size());
704         for (int i = 0; i < n; ++i)
705             printLayer(sublayers[i].get(), indent + 2);
706
707         printIndent(indent + 1);
708         fprintf(stderr, ")\n");
709     }
710
711     printIndent(indent);
712     fprintf(stderr, ")\n");
713 }
714
715 void PlatformCALayerWin::printTree() const
716 {
717     // Print heading info
718     CGRect rootBounds = bounds();
719     fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n", 
720         monotonicallyIncreasingTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height);
721
722     // Print layer tree from the root
723     printLayer(this, 0);
724 }
725 #endif // #ifndef NDEBUG
726
727 PassRefPtr<PlatformCALayer> PlatformCALayerWin::createCompatibleLayer(PlatformCALayer::LayerType layerType, PlatformCALayerClient* client) const
728 {
729     return PlatformCALayerWin::create(layerType, client);
730 }
731
732 TiledBacking* PlatformCALayerWin::tiledBacking()
733 {
734     if (!usesTiledBackingLayer())
735         return nullptr;
736
737     return intern(this)->tiledBacking();
738 }