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