Apply overhang shadow and linen to UI-side layers
[WebKit-https.git] / Source / WebKit2 / Shared / mac / RemoteLayerTreeTransaction.mm
1 /*
2  * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "RemoteLayerTreeTransaction.h"
28
29 #import "ArgumentCoders.h"
30 #import "MessageDecoder.h"
31 #import "MessageEncoder.h"
32 #import "PlatformCALayerRemote.h"
33 #import "WebCoreArgumentCoders.h"
34 #import <WebCore/TextStream.h>
35 #import <wtf/text/CString.h>
36 #import <wtf/text/StringBuilder.h>
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
42 RemoteLayerTreeTransaction::LayerCreationProperties::LayerCreationProperties()
43 {
44 }
45
46 void RemoteLayerTreeTransaction::LayerCreationProperties::encode(CoreIPC::ArgumentEncoder& encoder) const
47 {
48     encoder << layerID;
49     encoder.encodeEnum(type);
50
51     if (type == PlatformCALayer::LayerTypeCustom)
52         encoder << hostingContextID;
53 }
54
55 bool RemoteLayerTreeTransaction::LayerCreationProperties::decode(CoreIPC::ArgumentDecoder& decoder, LayerCreationProperties& result)
56 {
57     if (!decoder.decode(result.layerID))
58         return false;
59
60     if (!decoder.decodeEnum(result.type))
61         return false;
62
63     if (result.type == PlatformCALayer::LayerTypeCustom) {
64         if (!decoder.decode(result.hostingContextID))
65             return false;
66     }
67
68     return true;
69 }
70
71 RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
72     : changedProperties(NoChange)
73     , everChangedProperties(NoChange)
74 {
75 }
76
77 void RemoteLayerTreeTransaction::LayerProperties::encode(CoreIPC::ArgumentEncoder& encoder) const
78 {
79     encoder.encodeEnum(changedProperties);
80
81     if (changedProperties & NameChanged)
82         encoder << name;
83
84     if (changedProperties & ChildrenChanged)
85         encoder << children;
86
87     if (changedProperties & PositionChanged)
88         encoder << position;
89
90     if (changedProperties & SizeChanged)
91         encoder << size;
92
93     if (changedProperties & BackgroundColorChanged)
94         encoder << backgroundColor;
95
96     if (changedProperties & AnchorPointChanged)
97         encoder << anchorPoint;
98
99     if (changedProperties & BorderWidthChanged)
100         encoder << borderWidth;
101
102     if (changedProperties & BorderColorChanged)
103         encoder << borderColor;
104
105     if (changedProperties & OpacityChanged)
106         encoder << opacity;
107
108     if (changedProperties & TransformChanged)
109         encoder << transform;
110
111     if (changedProperties & SublayerTransformChanged)
112         encoder << sublayerTransform;
113
114     if (changedProperties & HiddenChanged)
115         encoder << hidden;
116
117     if (changedProperties & GeometryFlippedChanged)
118         encoder << geometryFlipped;
119
120     if (changedProperties & DoubleSidedChanged)
121         encoder << doubleSided;
122
123     if (changedProperties & MasksToBoundsChanged)
124         encoder << masksToBounds;
125
126     if (changedProperties & OpaqueChanged)
127         encoder << opaque;
128
129     if (changedProperties & MaskLayerChanged)
130         encoder << maskLayerID;
131
132     if (changedProperties & ContentsRectChanged)
133         encoder << contentsRect;
134
135     if (changedProperties & ContentsScaleChanged)
136         encoder << contentsScale;
137
138     if (changedProperties & MinificationFilterChanged)
139         encoder.encodeEnum(minificationFilter);
140
141     if (changedProperties & MagnificationFilterChanged)
142         encoder.encodeEnum(magnificationFilter);
143
144     if (changedProperties & SpeedChanged)
145         encoder << speed;
146
147     if (changedProperties & TimeOffsetChanged)
148         encoder << timeOffset;
149
150     if (changedProperties & BackingStoreChanged)
151         encoder << backingStore;
152
153     if (changedProperties & FiltersChanged)
154         encoder << filters;
155
156     if (changedProperties & EdgeAntialiasingMaskChanged)
157         encoder << edgeAntialiasingMask;
158
159     if (changedProperties & CustomAppearanceChanged)
160         encoder.encodeEnum(customAppearance);
161 }
162
163 bool RemoteLayerTreeTransaction::LayerProperties::decode(CoreIPC::ArgumentDecoder& decoder, LayerProperties& result)
164 {
165     if (!decoder.decodeEnum(result.changedProperties))
166         return false;
167
168     if (result.changedProperties & NameChanged) {
169         if (!decoder.decode(result.name))
170             return false;
171     }
172
173     if (result.changedProperties & ChildrenChanged) {
174         if (!decoder.decode(result.children))
175             return false;
176
177         for (auto layerID : result.children) {
178             if (!layerID)
179                 return false;
180         }
181     }
182
183     if (result.changedProperties & PositionChanged) {
184         if (!decoder.decode(result.position))
185             return false;
186     }
187
188     if (result.changedProperties & SizeChanged) {
189         if (!decoder.decode(result.size))
190             return false;
191     }
192
193     if (result.changedProperties & BackgroundColorChanged) {
194         if (!decoder.decode(result.backgroundColor))
195             return false;
196     }
197
198     if (result.changedProperties & AnchorPointChanged) {
199         if (!decoder.decode(result.anchorPoint))
200             return false;
201     }
202
203     if (result.changedProperties & BorderWidthChanged) {
204         if (!decoder.decode(result.borderWidth))
205             return false;
206     }
207
208     if (result.changedProperties & BorderColorChanged) {
209         if (!decoder.decode(result.borderColor))
210             return false;
211     }
212
213     if (result.changedProperties & OpacityChanged) {
214         if (!decoder.decode(result.opacity))
215             return false;
216     }
217
218     if (result.changedProperties & TransformChanged) {
219         if (!decoder.decode(result.transform))
220             return false;
221     }
222
223     if (result.changedProperties & SublayerTransformChanged) {
224         if (!decoder.decode(result.sublayerTransform))
225             return false;
226     }
227
228     if (result.changedProperties & HiddenChanged) {
229         if (!decoder.decode(result.hidden))
230             return false;
231     }
232
233     if (result.changedProperties & GeometryFlippedChanged) {
234         if (!decoder.decode(result.geometryFlipped))
235             return false;
236     }
237
238     if (result.changedProperties & DoubleSidedChanged) {
239         if (!decoder.decode(result.doubleSided))
240             return false;
241     }
242
243     if (result.changedProperties & MasksToBoundsChanged) {
244         if (!decoder.decode(result.masksToBounds))
245             return false;
246     }
247
248     if (result.changedProperties & OpaqueChanged) {
249         if (!decoder.decode(result.opaque))
250             return false;
251     }
252
253     if (result.changedProperties & MaskLayerChanged) {
254         if (!decoder.decode(result.maskLayerID))
255             return false;
256     }
257
258     if (result.changedProperties & ContentsRectChanged) {
259         if (!decoder.decode(result.contentsRect))
260             return false;
261     }
262
263     if (result.changedProperties & ContentsScaleChanged) {
264         if (!decoder.decode(result.contentsScale))
265             return false;
266     }
267
268     if (result.changedProperties & MinificationFilterChanged) {
269         if (!decoder.decodeEnum(result.minificationFilter))
270             return false;
271     }
272
273     if (result.changedProperties & MagnificationFilterChanged) {
274         if (!decoder.decodeEnum(result.magnificationFilter))
275             return false;
276     }
277
278     if (result.changedProperties & SpeedChanged) {
279         if (!decoder.decode(result.speed))
280             return false;
281     }
282
283     if (result.changedProperties & TimeOffsetChanged) {
284         if (!decoder.decode(result.timeOffset))
285             return false;
286     }
287
288     if (result.changedProperties & BackingStoreChanged) {
289         if (!decoder.decode(result.backingStore))
290             return false;
291     }
292
293     if (result.changedProperties & FiltersChanged) {
294         if (!decoder.decode(result.filters))
295             return false;
296     }
297
298     if (result.changedProperties & EdgeAntialiasingMaskChanged) {
299         if (!decoder.decode(result.edgeAntialiasingMask))
300             return false;
301     }
302
303     if (result.changedProperties & CustomAppearanceChanged) {
304         if (!decoder.decodeEnum(result.customAppearance))
305             return false;
306     }
307
308     return true;
309 }
310
311 RemoteLayerTreeTransaction::RemoteLayerTreeTransaction()
312 {
313 }
314
315 RemoteLayerTreeTransaction::~RemoteLayerTreeTransaction()
316 {
317 }
318
319 void RemoteLayerTreeTransaction::encode(CoreIPC::ArgumentEncoder& encoder) const
320 {
321     encoder << m_rootLayerID;
322     encoder << m_createdLayers;
323     encoder << m_changedLayerProperties;
324     encoder << m_destroyedLayerIDs;
325 }
326
327 bool RemoteLayerTreeTransaction::decode(CoreIPC::ArgumentDecoder& decoder, RemoteLayerTreeTransaction& result)
328 {
329     if (!decoder.decode(result.m_rootLayerID))
330         return false;
331     if (!result.m_rootLayerID)
332         return false;
333
334     if (!decoder.decode(result.m_createdLayers))
335         return false;
336
337     if (!decoder.decode(result.m_changedLayerProperties))
338         return false;
339
340     if (!decoder.decode(result.m_destroyedLayerIDs))
341         return false;
342     for (LayerID layerID : result.m_destroyedLayerIDs) {
343         if (!layerID)
344             return false;
345     }
346
347     return true;
348 }
349
350 void RemoteLayerTreeTransaction::setRootLayerID(LayerID rootLayerID)
351 {
352     ASSERT_ARG(rootLayerID, rootLayerID);
353
354     m_rootLayerID = rootLayerID;
355 }
356
357 void RemoteLayerTreeTransaction::layerPropertiesChanged(PlatformCALayerRemote* remoteLayer, RemoteLayerTreeTransaction::LayerProperties& properties)
358 {
359     m_changedLayerProperties.set(remoteLayer->layerID(), properties);
360 }
361
362 void RemoteLayerTreeTransaction::setCreatedLayers(Vector<LayerCreationProperties> createdLayers)
363 {
364     m_createdLayers = std::move(createdLayers);
365 }
366
367 void RemoteLayerTreeTransaction::setDestroyedLayerIDs(Vector<LayerID> destroyedLayerIDs)
368 {
369     m_destroyedLayerIDs = std::move(destroyedLayerIDs);
370 }
371
372 #if !defined(NDEBUG) || !LOG_DISABLED
373
374 class RemoteLayerTreeTextStream : public TextStream
375 {
376 public:
377     using TextStream::operator<<;
378
379     RemoteLayerTreeTextStream()
380         : m_indent(0)
381     {
382     }
383
384     RemoteLayerTreeTextStream& operator<<(const TransformationMatrix&);
385     RemoteLayerTreeTextStream& operator<<(PlatformCALayer::FilterType);
386     RemoteLayerTreeTextStream& operator<<(FloatPoint3D);
387     RemoteLayerTreeTextStream& operator<<(Color);
388     RemoteLayerTreeTextStream& operator<<(FloatRect);
389     RemoteLayerTreeTextStream& operator<<(const Vector<RemoteLayerTreeTransaction::LayerID>& layers);
390     RemoteLayerTreeTextStream& operator<<(const FilterOperations&);
391
392     void increaseIndent() { ++m_indent; }
393     void decreaseIndent() { --m_indent; ASSERT(m_indent >= 0); }
394
395     void writeIndent();
396
397 private:
398     int m_indent;
399 };
400
401 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const TransformationMatrix& transform)
402 {
403     RemoteLayerTreeTextStream& ts = *this;
404     ts << "\n";
405     ts.increaseIndent();
406     ts.writeIndent();
407     ts << "[" << transform.m11() << " " << transform.m12() << " " << transform.m13() << " " << transform.m14() << "]\n";
408     ts.writeIndent();
409     ts << "[" << transform.m21() << " " << transform.m22() << " " << transform.m23() << " " << transform.m24() << "]\n";
410     ts.writeIndent();
411     ts << "[" << transform.m31() << " " << transform.m32() << " " << transform.m33() << " " << transform.m34() << "]\n";
412     ts.writeIndent();
413     ts << "[" << transform.m41() << " " << transform.m42() << " " << transform.m43() << " " << transform.m44() << "]";
414     ts.decreaseIndent();
415     return ts;
416 }
417
418 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCALayer::FilterType filterType)
419 {
420     RemoteLayerTreeTextStream& ts = *this;
421     switch (filterType) {
422     case PlatformCALayer::Linear:
423         ts << "linear";
424         break;
425     case PlatformCALayer::Nearest:
426         ts << "nearest";
427         break;
428     case PlatformCALayer::Trilinear:
429         ts << "trilinear";
430         break;
431     default:
432         ASSERT_NOT_REACHED();
433         break;
434     }
435     return ts;
436 }
437
438 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const FilterOperations& filters)
439 {
440     RemoteLayerTreeTextStream& ts = *this;
441     for (size_t i = 0; i < filters.size(); ++i) {
442         const auto filter = filters.at(i);
443         switch (filter->type()) {
444         case FilterOperation::REFERENCE:
445             ts << "reference";
446             break;
447         case FilterOperation::GRAYSCALE:
448             ts << "grayscale";
449             break;
450         case FilterOperation::SEPIA:
451             ts << "sepia";
452             break;
453         case FilterOperation::SATURATE:
454             ts << "saturate";
455             break;
456         case FilterOperation::HUE_ROTATE:
457             ts << "hue rotate";
458             break;
459         case FilterOperation::INVERT:
460             ts << "invert";
461             break;
462         case FilterOperation::OPACITY:
463             ts << "opacity";
464             break;
465         case FilterOperation::BRIGHTNESS:
466             ts << "brightness";
467             break;
468         case FilterOperation::CONTRAST:
469             ts << "contrast";
470             break;
471         case FilterOperation::BLUR:
472             ts << "blur";
473             break;
474         case FilterOperation::DROP_SHADOW:
475             ts << "drop shadow";
476             break;
477 #if ENABLE(CSS_SHADERS)
478         case FilterOperation::CUSTOM:
479             ts << "custom";
480             break;
481         case FilterOperation::VALIDATED_CUSTOM:
482             ts << "custom (validated)";
483             break;
484 #endif
485         case FilterOperation::PASSTHROUGH:
486             ts << "passthrough";
487             break;
488         case FilterOperation::NONE:
489             ts << "none";
490             break;
491         }
492
493         if (i < filters.size() - 1)
494             ts << " ";
495     }
496     return ts;
497 }
498
499 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(FloatPoint3D point)
500 {
501     RemoteLayerTreeTextStream& ts = *this;
502     ts << point.x() << " " << point.y() << " " << point.z();
503     return ts;
504 }
505
506 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(Color color)
507 {
508     RemoteLayerTreeTextStream& ts = *this;
509     ts << color.serialized();
510     return ts;
511 }
512
513 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(FloatRect rect)
514 {
515     RemoteLayerTreeTextStream& ts = *this;
516     ts << rect.x() << " " << rect.y() << " " << rect.width() << " " << rect.height();
517     return ts;
518 }
519
520 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const Vector<RemoteLayerTreeTransaction::LayerID>& layers)
521 {
522     RemoteLayerTreeTextStream& ts = *this;
523
524     for (size_t i = 0; i < layers.size(); ++i) {
525         if (i)
526             ts << " ";
527         ts << layers[i];
528     }
529
530     return ts;
531 }
532
533 void RemoteLayerTreeTextStream::writeIndent()
534 {
535     for (int i = 0; i < m_indent; ++i)
536         *this << "  ";
537 }
538
539 template <class T>
540 static void dumpProperty(RemoteLayerTreeTextStream& ts, String name, T value)
541 {
542     ts << "\n";
543     ts.increaseIndent();
544     ts.writeIndent();
545     ts << "(" << name << " ";
546     ts << value << ")";
547     ts.decreaseIndent();
548 }
549
550 static void dumpChangedLayers(RemoteLayerTreeTextStream& ts, const HashMap<RemoteLayerTreeTransaction::LayerID, RemoteLayerTreeTransaction::LayerProperties>& changedLayerProperties)
551 {
552     if (changedLayerProperties.isEmpty())
553         return;
554
555     ts << "\n";
556     ts.writeIndent();
557     ts << "(changed-layers";
558
559     // Dump the layer properties sorted by layer ID.
560     Vector<RemoteLayerTreeTransaction::LayerID> layerIDs;
561     copyKeysToVector(changedLayerProperties, layerIDs);
562     std::sort(layerIDs.begin(), layerIDs.end());
563
564     for (auto layerID : layerIDs) {
565         const RemoteLayerTreeTransaction::LayerProperties& layerProperties = changedLayerProperties.get(layerID);
566
567         ts << "\n";
568         ts.increaseIndent();
569         ts.writeIndent();
570         ts << "(layer " << layerID;
571
572         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::NameChanged)
573             dumpProperty<String>(ts, "name", layerProperties.name);
574
575         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged)
576             dumpProperty<Vector<RemoteLayerTreeTransaction::LayerID>>(ts, "children", layerProperties.children);
577
578         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::PositionChanged)
579             dumpProperty<FloatPoint3D>(ts, "position", layerProperties.position);
580
581         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SizeChanged)
582             dumpProperty<FloatSize>(ts, "size", layerProperties.size);
583
584         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::AnchorPointChanged)
585             dumpProperty<FloatPoint3D>(ts, "anchorPoint", layerProperties.anchorPoint);
586
587         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackgroundColorChanged)
588             dumpProperty<Color>(ts, "backgroundColor", layerProperties.backgroundColor);
589
590         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BorderColorChanged)
591             dumpProperty<Color>(ts, "borderColor", layerProperties.borderColor);
592
593         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged)
594             dumpProperty<float>(ts, "borderWidth", layerProperties.borderWidth);
595
596         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpacityChanged)
597             dumpProperty<float>(ts, "opacity", layerProperties.opacity);
598
599         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::TransformChanged)
600             dumpProperty<TransformationMatrix>(ts, "transform", layerProperties.transform);
601
602         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SublayerTransformChanged)
603             dumpProperty<TransformationMatrix>(ts, "sublayerTransform", layerProperties.sublayerTransform);
604
605         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::HiddenChanged)
606             dumpProperty<bool>(ts, "hidden", layerProperties.hidden);
607
608         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::GeometryFlippedChanged)
609             dumpProperty<bool>(ts, "geometryFlipped", layerProperties.geometryFlipped);
610
611         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::DoubleSidedChanged)
612             dumpProperty<bool>(ts, "doubleSided", layerProperties.doubleSided);
613
614         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MasksToBoundsChanged)
615             dumpProperty<bool>(ts, "masksToBounds", layerProperties.masksToBounds);
616
617         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpaqueChanged)
618             dumpProperty<bool>(ts, "opaque", layerProperties.opaque);
619
620         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged)
621             dumpProperty<RemoteLayerTreeTransaction::LayerID>(ts, "maskLayer", layerProperties.maskLayerID);
622
623         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsRectChanged)
624             dumpProperty<FloatRect>(ts, "contentsRect", layerProperties.contentsRect);
625
626         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsScaleChanged)
627             dumpProperty<float>(ts, "contentsScale", layerProperties.contentsScale);
628
629         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MinificationFilterChanged)
630             dumpProperty<PlatformCALayer::FilterType>(ts, "minificationFilter", layerProperties.minificationFilter);
631
632         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MagnificationFilterChanged)
633             dumpProperty<PlatformCALayer::FilterType>(ts, "magnificationFilter", layerProperties.magnificationFilter);
634
635         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SpeedChanged)
636             dumpProperty<float>(ts, "speed", layerProperties.speed);
637
638         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::TimeOffsetChanged)
639             dumpProperty<double>(ts, "timeOffset", layerProperties.timeOffset);
640
641         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged)
642             dumpProperty<IntSize>(ts, "backingStore", layerProperties.backingStore.size());
643
644         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)
645             dumpProperty<FilterOperations>(ts, "filters", layerProperties.filters);
646
647         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::EdgeAntialiasingMaskChanged)
648             dumpProperty<unsigned>(ts, "edgeAntialiasingMask", layerProperties.edgeAntialiasingMask);
649
650         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::CustomAppearanceChanged)
651             dumpProperty<GraphicsLayer::CustomAppearance>(ts, "customAppearance", layerProperties.customAppearance);
652
653         ts << ")";
654
655         ts.decreaseIndent();
656     }
657
658     ts.decreaseIndent();
659 }
660
661 void RemoteLayerTreeTransaction::dump() const
662 {
663     fprintf(stderr, "%s", description().data());
664 }
665
666 CString RemoteLayerTreeTransaction::description() const
667 {
668     RemoteLayerTreeTextStream ts;
669
670     ts << "(\n";
671     ts.increaseIndent();
672     ts.writeIndent();
673     ts << "(root-layer " << m_rootLayerID << ")";
674
675     if (!m_createdLayers.isEmpty()) {
676         ts << "\n";
677         ts.writeIndent();
678         ts << "(created-layers";
679         ts.increaseIndent();
680         for (const auto& createdLayer : m_createdLayers) {
681             ts << "\n";
682             ts.writeIndent();
683             ts << "(";
684             switch (createdLayer.type) {
685             case PlatformCALayer::LayerTypeLayer:
686             case PlatformCALayer::LayerTypeWebLayer:
687             case PlatformCALayer::LayerTypeSimpleLayer:
688                 ts << "layer";
689                 break;
690             case PlatformCALayer::LayerTypeTransformLayer:
691                 ts << "transform-layer";
692                 break;
693             case PlatformCALayer::LayerTypeWebTiledLayer:
694                 ts << "tiled-layer";
695                 break;
696             case PlatformCALayer::LayerTypeTiledBackingLayer:
697                 ts << "tiled-backing-layer";
698                 break;
699             case PlatformCALayer::LayerTypePageTiledBackingLayer:
700                 ts << "page-tiled-backing-layer";
701                 break;
702             case PlatformCALayer::LayerTypeTiledBackingTileLayer:
703                 ts << "tiled-backing-tile";
704                 break;
705             case PlatformCALayer::LayerTypeRootLayer:
706                 ts << "root-layer";
707                 break;
708             case PlatformCALayer::LayerTypeAVPlayerLayer:
709                 ts << "av-player-layer";
710                 break;
711             case PlatformCALayer::LayerTypeCustom:
712                 ts << "custom-layer (context-id " << createdLayer.hostingContextID << ")";
713                 break;
714             }
715             ts << " " << createdLayer.layerID << ")";
716         }
717         ts << ")";
718         ts.decreaseIndent();
719     }
720
721     dumpChangedLayers(ts, m_changedLayerProperties);
722
723     if (!m_destroyedLayerIDs.isEmpty())
724         dumpProperty<Vector<RemoteLayerTreeTransaction::LayerID>>(ts, "destroyed-layers", m_destroyedLayerIDs);
725
726     ts << ")\n";
727
728     return ts.release().utf8();
729 }
730
731 #endif // !defined(NDEBUG) || !LOG_DISABLED
732
733 } // namespace WebKit