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 "PlatformCAAnimationRemote.h"
33#import "PlatformCALayerRemote.h"
34#import "WebCoreArgumentCoders.h"
35#import <QuartzCore/QuartzCore.h>
36#import <WebCore/LengthFunctions.h>
37#import <WebCore/TextStream.h>
38#import <WebCore/TimingFunction.h>
39#import <wtf/text/CString.h>
40#import <wtf/text/StringBuilder.h>
41
42using namespace WebCore;
43
44namespace WebKit {
45
46RemoteLayerTreeTransaction::LayerCreationProperties::LayerCreationProperties()
47    : layerID(0)
48    , type(PlatformCALayer::LayerTypeLayer)
49    , hostingContextID(0)
50{
51}
52
53void RemoteLayerTreeTransaction::LayerCreationProperties::encode(IPC::ArgumentEncoder& encoder) const
54{
55    encoder << layerID;
56    encoder.encodeEnum(type);
57    encoder << hostingContextID;
58}
59
60bool RemoteLayerTreeTransaction::LayerCreationProperties::decode(IPC::ArgumentDecoder& decoder, LayerCreationProperties& result)
61{
62    if (!decoder.decode(result.layerID))
63        return false;
64
65    if (!decoder.decodeEnum(result.type))
66        return false;
67
68    if (!decoder.decode(result.hostingContextID))
69        return false;
70
71    return true;
72}
73
74RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
75    : changedProperties(NoChange)
76    , everChangedProperties(NoChange)
77    , anchorPoint(0.5, 0.5, 0)
78    , contentsRect(FloatPoint(), FloatSize(1, 1))
79    , maskLayerID(0)
80    , clonedLayerID(0)
81    , timeOffset(0)
82    , speed(1)
83    , contentsScale(1)
84    , borderWidth(0)
85    , opacity(1)
86    , backgroundColor(Color::transparent)
87    , borderColor(Color::black)
88    , edgeAntialiasingMask(kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge)
89    , customAppearance(GraphicsLayer::NoCustomAppearance)
90    , customBehavior(GraphicsLayer::NoCustomBehavior)
91    , minificationFilter(PlatformCALayer::FilterType::Linear)
92    , magnificationFilter(PlatformCALayer::FilterType::Linear)
93    , blendMode(BlendModeNormal)
94    , hidden(false)
95    , geometryFlipped(false)
96    , doubleSided(true)
97    , masksToBounds(false)
98    , opaque(false)
99{
100}
101
102RemoteLayerTreeTransaction::LayerProperties::LayerProperties(const LayerProperties& other)
103    : changedProperties(other.changedProperties)
104    , everChangedProperties(other.everChangedProperties)
105    , name(other.name)
106    , children(other.children)
107    , addedAnimations(other.addedAnimations)
108    , keyPathsOfAnimationsToRemove(other.keyPathsOfAnimationsToRemove)
109    , position(other.position)
110    , anchorPoint(other.anchorPoint)
111    , bounds(other.bounds)
112    , contentsRect(other.contentsRect)
113    , maskLayerID(other.maskLayerID)
114    , clonedLayerID(other.clonedLayerID)
115    , timeOffset(other.timeOffset)
116    , speed(other.speed)
117    , contentsScale(other.contentsScale)
118    , borderWidth(other.borderWidth)
119    , opacity(other.opacity)
120    , backgroundColor(other.backgroundColor)
121    , borderColor(other.borderColor)
122    , edgeAntialiasingMask(other.edgeAntialiasingMask)
123    , customAppearance(other.customAppearance)
124    , customBehavior(other.customBehavior)
125    , minificationFilter(other.minificationFilter)
126    , magnificationFilter(other.magnificationFilter)
127    , blendMode(other.blendMode)
128    , hidden(other.hidden)
129    , geometryFlipped(other.geometryFlipped)
130    , doubleSided(other.doubleSided)
131    , masksToBounds(other.masksToBounds)
132    , opaque(other.opaque)
133{
134    // FIXME: LayerProperties should reference backing store by ID, so that two layers can have the same backing store (for clones).
135    // FIXME: LayerProperties shouldn't be copyable; PlatformCALayerRemote::clone should copy the relevant properties.
136
137    if (other.transform)
138        transform = std::make_unique<TransformationMatrix>(*other.transform);
139
140    if (other.sublayerTransform)
141        sublayerTransform = std::make_unique<TransformationMatrix>(*other.sublayerTransform);
142
143    if (other.filters)
144        filters = std::make_unique<FilterOperations>(*other.filters);
145}
146
147void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& encoder) const
148{
149    encoder.encodeEnum(changedProperties);
150
151    if (changedProperties & NameChanged)
152        encoder << name;
153
154    if (changedProperties & ChildrenChanged)
155        encoder << children;
156
157    if (changedProperties & AnimationsChanged) {
158        encoder << addedAnimations;
159        encoder << keyPathsOfAnimationsToRemove;
160    }
161
162    if (changedProperties & PositionChanged)
163        encoder << position;
164
165    if (changedProperties & BoundsChanged)
166        encoder << bounds;
167
168    if (changedProperties & BackgroundColorChanged)
169        encoder << backgroundColor;
170
171    if (changedProperties & AnchorPointChanged)
172        encoder << anchorPoint;
173
174    if (changedProperties & BorderWidthChanged)
175        encoder << borderWidth;
176
177    if (changedProperties & BorderColorChanged)
178        encoder << borderColor;
179
180    if (changedProperties & OpacityChanged)
181        encoder << opacity;
182
183    if (changedProperties & TransformChanged)
184        encoder << *transform;
185
186    if (changedProperties & SublayerTransformChanged)
187        encoder << *sublayerTransform;
188
189    if (changedProperties & HiddenChanged)
190        encoder << hidden;
191
192    if (changedProperties & GeometryFlippedChanged)
193        encoder << geometryFlipped;
194
195    if (changedProperties & DoubleSidedChanged)
196        encoder << doubleSided;
197
198    if (changedProperties & MasksToBoundsChanged)
199        encoder << masksToBounds;
200
201    if (changedProperties & OpaqueChanged)
202        encoder << opaque;
203
204    if (changedProperties & MaskLayerChanged)
205        encoder << maskLayerID;
206
207    if (changedProperties & ClonedContentsChanged)
208        encoder << clonedLayerID;
209
210    if (changedProperties & ContentsRectChanged)
211        encoder << contentsRect;
212
213    if (changedProperties & ContentsScaleChanged)
214        encoder << contentsScale;
215
216    if (changedProperties & MinificationFilterChanged)
217        encoder.encodeEnum(minificationFilter);
218
219    if (changedProperties & MagnificationFilterChanged)
220        encoder.encodeEnum(magnificationFilter);
221
222    if (changedProperties & BlendModeChanged)
223        encoder.encodeEnum(blendMode);
224
225    if (changedProperties & SpeedChanged)
226        encoder << speed;
227
228    if (changedProperties & TimeOffsetChanged)
229        encoder << timeOffset;
230
231    if (changedProperties & BackingStoreChanged) {
232        bool hasFrontBuffer = backingStore && backingStore->hasFrontBuffer();
233        encoder << hasFrontBuffer;
234        if (hasFrontBuffer)
235            encoder << *backingStore;
236    }
237
238    if (changedProperties & FiltersChanged)
239        encoder << *filters;
240
241    if (changedProperties & EdgeAntialiasingMaskChanged)
242        encoder << edgeAntialiasingMask;
243
244    if (changedProperties & CustomAppearanceChanged)
245        encoder.encodeEnum(customAppearance);
246
247    if (changedProperties & CustomBehaviorChanged)
248        encoder.encodeEnum(customBehavior);
249}
250
251bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& decoder, LayerProperties& result)
252{
253    if (!decoder.decodeEnum(result.changedProperties))
254        return false;
255
256    if (result.changedProperties & NameChanged) {
257        if (!decoder.decode(result.name))
258            return false;
259    }
260
261    if (result.changedProperties & ChildrenChanged) {
262        if (!decoder.decode(result.children))
263            return false;
264
265        for (auto& layerID : result.children) {
266            if (!layerID)
267                return false;
268        }
269    }
270
271    if (result.changedProperties & AnimationsChanged) {
272        if (!decoder.decode(result.addedAnimations))
273            return false;
274
275        if (!decoder.decode(result.keyPathsOfAnimationsToRemove))
276            return false;
277    }
278
279    if (result.changedProperties & PositionChanged) {
280        if (!decoder.decode(result.position))
281            return false;
282    }
283
284    if (result.changedProperties & BoundsChanged) {
285        if (!decoder.decode(result.bounds))
286            return false;
287    }
288
289    if (result.changedProperties & BackgroundColorChanged) {
290        if (!decoder.decode(result.backgroundColor))
291            return false;
292    }
293
294    if (result.changedProperties & AnchorPointChanged) {
295        if (!decoder.decode(result.anchorPoint))
296            return false;
297    }
298
299    if (result.changedProperties & BorderWidthChanged) {
300        if (!decoder.decode(result.borderWidth))
301            return false;
302    }
303
304    if (result.changedProperties & BorderColorChanged) {
305        if (!decoder.decode(result.borderColor))
306            return false;
307    }
308
309    if (result.changedProperties & OpacityChanged) {
310        if (!decoder.decode(result.opacity))
311            return false;
312    }
313
314    if (result.changedProperties & TransformChanged) {
315        TransformationMatrix transform;
316        if (!decoder.decode(transform))
317            return false;
318
319        result.transform = std::make_unique<TransformationMatrix>(transform);
320    }
321
322    if (result.changedProperties & SublayerTransformChanged) {
323        TransformationMatrix transform;
324        if (!decoder.decode(transform))
325            return false;
326
327        result.sublayerTransform = std::make_unique<TransformationMatrix>(transform);
328    }
329
330    if (result.changedProperties & HiddenChanged) {
331        if (!decoder.decode(result.hidden))
332            return false;
333    }
334
335    if (result.changedProperties & GeometryFlippedChanged) {
336        if (!decoder.decode(result.geometryFlipped))
337            return false;
338    }
339
340    if (result.changedProperties & DoubleSidedChanged) {
341        if (!decoder.decode(result.doubleSided))
342            return false;
343    }
344
345    if (result.changedProperties & MasksToBoundsChanged) {
346        if (!decoder.decode(result.masksToBounds))
347            return false;
348    }
349
350    if (result.changedProperties & OpaqueChanged) {
351        if (!decoder.decode(result.opaque))
352            return false;
353    }
354
355    if (result.changedProperties & MaskLayerChanged) {
356        if (!decoder.decode(result.maskLayerID))
357            return false;
358    }
359
360    if (result.changedProperties & ClonedContentsChanged) {
361        if (!decoder.decode(result.clonedLayerID))
362            return false;
363    }
364
365    if (result.changedProperties & ContentsRectChanged) {
366        if (!decoder.decode(result.contentsRect))
367            return false;
368    }
369
370    if (result.changedProperties & ContentsScaleChanged) {
371        if (!decoder.decode(result.contentsScale))
372            return false;
373    }
374
375    if (result.changedProperties & MinificationFilterChanged) {
376        if (!decoder.decodeEnum(result.minificationFilter))
377            return false;
378    }
379
380    if (result.changedProperties & MagnificationFilterChanged) {
381        if (!decoder.decodeEnum(result.magnificationFilter))
382            return false;
383    }
384
385    if (result.changedProperties & BlendModeChanged) {
386        if (!decoder.decodeEnum(result.blendMode))
387            return false;
388    }
389
390    if (result.changedProperties & SpeedChanged) {
391        if (!decoder.decode(result.speed))
392            return false;
393    }
394
395    if (result.changedProperties & TimeOffsetChanged) {
396        if (!decoder.decode(result.timeOffset))
397            return false;
398    }
399
400    if (result.changedProperties & BackingStoreChanged) {
401        bool hasFrontBuffer = false;
402        if (!decoder.decode(hasFrontBuffer))
403            return false;
404        if (hasFrontBuffer) {
405            std::unique_ptr<RemoteLayerBackingStore> backingStore = std::make_unique<RemoteLayerBackingStore>(nullptr);
406            if (!decoder.decode(*backingStore))
407                return false;
408
409            result.backingStore = WTF::move(backingStore);
410        } else
411            result.backingStore = nullptr;
412    }
413
414    if (result.changedProperties & FiltersChanged) {
415        std::unique_ptr<FilterOperations> filters = std::make_unique<FilterOperations>();
416        if (!decoder.decode(*filters))
417            return false;
418        result.filters = WTF::move(filters);
419    }
420
421    if (result.changedProperties & EdgeAntialiasingMaskChanged) {
422        if (!decoder.decode(result.edgeAntialiasingMask))
423            return false;
424    }
425
426    if (result.changedProperties & CustomAppearanceChanged) {
427        if (!decoder.decodeEnum(result.customAppearance))
428            return false;
429    }
430
431    if (result.changedProperties & CustomBehaviorChanged) {
432        if (!decoder.decodeEnum(result.customBehavior))
433            return false;
434    }
435
436    return true;
437}
438
439RemoteLayerTreeTransaction::RemoteLayerTreeTransaction()
440{
441}
442
443RemoteLayerTreeTransaction::~RemoteLayerTreeTransaction()
444{
445}
446
447void RemoteLayerTreeTransaction::encode(IPC::ArgumentEncoder& encoder) const
448{
449    encoder << m_rootLayerID;
450    encoder << m_createdLayers;
451
452    encoder << static_cast<uint64_t>(m_changedLayers.size());
453
454    for (RefPtr<PlatformCALayerRemote> layer : m_changedLayers) {
455        encoder << layer->layerID();
456        encoder << layer->properties();
457    }
458
459    encoder << m_destroyedLayerIDs;
460    encoder << m_videoLayerIDsPendingFullscreen;
461    encoder << m_layerIDsWithNewlyUnreachableBackingStore;
462
463    encoder << m_contentsSize;
464    encoder << m_pageExtendedBackgroundColor;
465    encoder << m_pageScaleFactor;
466    encoder << m_minimumScaleFactor;
467    encoder << m_maximumScaleFactor;
468
469    encoder << m_renderTreeSize;
470    encoder << m_transactionID;
471
472    encoder << m_scaleWasSetByUIProcess;
473    encoder << m_allowsUserScaling;
474
475    encoder << m_callbackIDs;
476}
477
478bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLayerTreeTransaction& result)
479{
480    if (!decoder.decode(result.m_rootLayerID))
481        return false;
482    if (!result.m_rootLayerID)
483        return false;
484
485    if (!decoder.decode(result.m_createdLayers))
486        return false;
487
488    uint64_t numChangedLayerProperties;
489    if (!decoder.decode(numChangedLayerProperties))
490        return false;
491
492    for (uint64_t i = 0; i < numChangedLayerProperties; ++i) {
493        GraphicsLayer::PlatformLayerID layerID;
494        if (!decoder.decode(layerID))
495            return false;
496
497        std::unique_ptr<LayerProperties> layerProperties = std::make_unique<LayerProperties>();
498        if (!decoder.decode(*layerProperties))
499            return false;
500
501        result.changedLayerProperties().set(layerID, WTF::move(layerProperties));
502    }
503
504    if (!decoder.decode(result.m_destroyedLayerIDs))
505        return false;
506
507    for (auto& layerID : result.m_destroyedLayerIDs) {
508        if (!layerID)
509            return false;
510    }
511
512    if (!decoder.decode(result.m_videoLayerIDsPendingFullscreen))
513        return false;
514
515    if (!decoder.decode(result.m_layerIDsWithNewlyUnreachableBackingStore))
516        return false;
517
518    for (auto& layerID : result.m_layerIDsWithNewlyUnreachableBackingStore) {
519        if (!layerID)
520            return false;
521    }
522
523    if (!decoder.decode(result.m_contentsSize))
524        return false;
525
526    if (!decoder.decode(result.m_pageExtendedBackgroundColor))
527        return false;
528
529    if (!decoder.decode(result.m_pageScaleFactor))
530        return false;
531
532    if (!decoder.decode(result.m_minimumScaleFactor))
533        return false;
534
535    if (!decoder.decode(result.m_maximumScaleFactor))
536        return false;
537
538    if (!decoder.decode(result.m_renderTreeSize))
539        return false;
540
541    if (!decoder.decode(result.m_transactionID))
542        return false;
543
544    if (!decoder.decode(result.m_scaleWasSetByUIProcess))
545        return false;
546
547    if (!decoder.decode(result.m_allowsUserScaling))
548        return false;
549
550    if (!decoder.decode(result.m_callbackIDs))
551        return false;
552
553    return true;
554}
555
556void RemoteLayerTreeTransaction::setRootLayerID(GraphicsLayer::PlatformLayerID rootLayerID)
557{
558    ASSERT_ARG(rootLayerID, rootLayerID);
559
560    m_rootLayerID = rootLayerID;
561}
562
563void RemoteLayerTreeTransaction::layerPropertiesChanged(PlatformCALayerRemote& remoteLayer)
564{
565    m_changedLayers.append(&remoteLayer);
566}
567
568void RemoteLayerTreeTransaction::setCreatedLayers(Vector<LayerCreationProperties> createdLayers)
569{
570    m_createdLayers = WTF::move(createdLayers);
571}
572
573void RemoteLayerTreeTransaction::setDestroyedLayerIDs(Vector<GraphicsLayer::PlatformLayerID> destroyedLayerIDs)
574{
575    m_destroyedLayerIDs = WTF::move(destroyedLayerIDs);
576}
577
578void RemoteLayerTreeTransaction::setLayerIDsWithNewlyUnreachableBackingStore(Vector<GraphicsLayer::PlatformLayerID> layerIDsWithNewlyUnreachableBackingStore)
579{
580    m_layerIDsWithNewlyUnreachableBackingStore = WTF::move(layerIDsWithNewlyUnreachableBackingStore);
581}
582
583#if !defined(NDEBUG) || !LOG_DISABLED
584
585class RemoteLayerTreeTextStream : public TextStream
586{
587public:
588    using TextStream::operator<<;
589
590    RemoteLayerTreeTextStream()
591        : m_indent(0)
592    {
593    }
594
595    RemoteLayerTreeTextStream& operator<<(const TransformationMatrix&);
596    RemoteLayerTreeTextStream& operator<<(PlatformCALayer::FilterType);
597    RemoteLayerTreeTextStream& operator<<(FloatPoint3D);
598    RemoteLayerTreeTextStream& operator<<(Color);
599    RemoteLayerTreeTextStream& operator<<(FloatRect);
600    RemoteLayerTreeTextStream& operator<<(const Vector<WebCore::GraphicsLayer::PlatformLayerID>&);
601    RemoteLayerTreeTextStream& operator<<(const FilterOperation&);
602    RemoteLayerTreeTextStream& operator<<(const FilterOperations&);
603    RemoteLayerTreeTextStream& operator<<(const PlatformCAAnimationRemote::Properties&);
604    RemoteLayerTreeTextStream& operator<<(const RemoteLayerBackingStore&);
605    RemoteLayerTreeTextStream& operator<<(BlendMode);
606    RemoteLayerTreeTextStream& operator<<(PlatformCAAnimation::AnimationType);
607    RemoteLayerTreeTextStream& operator<<(PlatformCAAnimation::FillModeType);
608    RemoteLayerTreeTextStream& operator<<(PlatformCAAnimation::ValueFunctionType);
609    RemoteLayerTreeTextStream& operator<<(const TimingFunction&);
610    RemoteLayerTreeTextStream& operator<<(const PlatformCAAnimationRemote::KeyframeValue&);
611
612    void increaseIndent() { ++m_indent; }
613    void decreaseIndent() { --m_indent; ASSERT(m_indent >= 0); }
614
615    void writeIndent();
616
617private:
618    int m_indent;
619};
620
621template <class T>
622static void dumpProperty(RemoteLayerTreeTextStream& ts, String name, T value)
623{
624    ts << "\n";
625    ts.increaseIndent();
626    ts.writeIndent();
627    ts << "(" << name << " ";
628    ts << value << ")";
629    ts.decreaseIndent();
630}
631
632RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const TransformationMatrix& transform)
633{
634    RemoteLayerTreeTextStream& ts = *this;
635    ts << "\n";
636    ts.increaseIndent();
637    ts.writeIndent();
638    ts << "[" << transform.m11() << " " << transform.m12() << " " << transform.m13() << " " << transform.m14() << "]\n";
639    ts.writeIndent();
640    ts << "[" << transform.m21() << " " << transform.m22() << " " << transform.m23() << " " << transform.m24() << "]\n";
641    ts.writeIndent();
642    ts << "[" << transform.m31() << " " << transform.m32() << " " << transform.m33() << " " << transform.m34() << "]\n";
643    ts.writeIndent();
644    ts << "[" << transform.m41() << " " << transform.m42() << " " << transform.m43() << " " << transform.m44() << "]";
645    ts.decreaseIndent();
646    return ts;
647}
648
649RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCALayer::FilterType filterType)
650{
651    RemoteLayerTreeTextStream& ts = *this;
652    switch (filterType) {
653    case PlatformCALayer::Linear:
654        ts << "linear";
655        break;
656    case PlatformCALayer::Nearest:
657        ts << "nearest";
658        break;
659    case PlatformCALayer::Trilinear:
660        ts << "trilinear";
661        break;
662    default:
663        ASSERT_NOT_REACHED();
664        break;
665    }
666    return ts;
667}
668
669RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const FilterOperations& filters)
670{
671    RemoteLayerTreeTextStream& ts = *this;
672    for (size_t i = 0; i < filters.size(); ++i) {
673        const auto filter = filters.at(i);
674        if (filter)
675            ts << *filter;
676        else
677            ts << "(null)";
678        if (i < filters.size() - 1)
679            ts << " ";
680    }
681    return ts;
682}
683
684RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const FilterOperation& filter)
685{
686    RemoteLayerTreeTextStream& ts = *this;
687    switch (filter.type()) {
688    case FilterOperation::REFERENCE:
689        ts << "reference";
690        break;
691    case FilterOperation::GRAYSCALE: {
692        const BasicColorMatrixFilterOperation& colorMatrixFilter = toBasicColorMatrixFilterOperation(filter);
693        ts << "grayscale(" << colorMatrixFilter.amount() << ")";
694        break;
695    }
696    case FilterOperation::SEPIA: {
697        const BasicColorMatrixFilterOperation& colorMatrixFilter = toBasicColorMatrixFilterOperation(filter);
698        ts << "sepia(" << colorMatrixFilter.amount() << ")";
699        break;
700    }
701    case FilterOperation::SATURATE: {
702        const BasicColorMatrixFilterOperation& colorMatrixFilter = toBasicColorMatrixFilterOperation(filter);
703        ts << "saturate(" << colorMatrixFilter.amount() << ")";
704        break;
705    }
706    case FilterOperation::HUE_ROTATE: {
707        const BasicColorMatrixFilterOperation& colorMatrixFilter = toBasicColorMatrixFilterOperation(filter);
708        ts << "hue-rotate(" << colorMatrixFilter.amount() << ")";
709        break;
710    }
711    case FilterOperation::INVERT: {
712        const BasicComponentTransferFilterOperation& componentTransferFilter = toBasicComponentTransferFilterOperation(filter);
713        ts << "invert(" << componentTransferFilter.amount() << ")";
714        break;
715    }
716    case FilterOperation::OPACITY: {
717        const BasicComponentTransferFilterOperation& componentTransferFilter = toBasicComponentTransferFilterOperation(filter);
718        ts << "opacity(" << componentTransferFilter.amount() << ")";
719        break;
720    }
721    case FilterOperation::BRIGHTNESS: {
722        const BasicComponentTransferFilterOperation& componentTransferFilter = toBasicComponentTransferFilterOperation(filter);
723        ts << "brightness(" << componentTransferFilter.amount() << ")";
724        break;
725    }
726    case FilterOperation::CONTRAST: {
727        const BasicComponentTransferFilterOperation& componentTransferFilter = toBasicComponentTransferFilterOperation(filter);
728        ts << "contrast(" << componentTransferFilter.amount() << ")";
729        break;
730    }
731    case FilterOperation::BLUR: {
732        const BlurFilterOperation& blurFilter = toBlurFilterOperation(filter);
733        ts << "blur(" << floatValueForLength(blurFilter.stdDeviation(), 0) << ")";
734        break;
735    }
736    case FilterOperation::DROP_SHADOW: {
737        const DropShadowFilterOperation& dropShadowFilter = toDropShadowFilterOperation(filter);
738        ts << "drop-shadow(" << dropShadowFilter.x() << " " << dropShadowFilter.y() << " " << dropShadowFilter.location() << " ";
739        ts << dropShadowFilter.color() << ")";
740        break;
741    }
742    case FilterOperation::PASSTHROUGH:
743        ts << "passthrough";
744        break;
745    case FilterOperation::DEFAULT: {
746        const DefaultFilterOperation& defaultFilter = toDefaultFilterOperation(filter);
747        ts << "default type=" << (int)defaultFilter.representedType();
748        break;
749    }
750    case FilterOperation::NONE:
751        ts << "none";
752        break;
753    }
754    return ts;
755}
756
757RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(BlendMode blendMode)
758{
759    RemoteLayerTreeTextStream& ts = *this;
760    switch (blendMode) {
761    case BlendModeNormal: ts << "normal"; break;
762    case BlendModeMultiply: ts << "multiply"; break;
763    case BlendModeScreen: ts << "screen"; break;
764    case BlendModeOverlay: ts << "overlay"; break;
765    case BlendModeDarken: ts << "darken"; break;
766    case BlendModeLighten: ts << "lighten"; break;
767    case BlendModeColorDodge: ts << "color-dodge"; break;
768    case BlendModeColorBurn: ts << "color-burn"; break;
769    case BlendModeHardLight: ts << "hard-light"; break;
770    case BlendModeSoftLight: ts << "soft-light"; break;
771    case BlendModeDifference: ts << "difference"; break;
772    case BlendModeExclusion: ts << "exclusion"; break;
773    case BlendModeHue: ts << "hue"; break;
774    case BlendModeSaturation: ts << "saturation"; break;
775    case BlendModeColor: ts << "color"; break;
776    case BlendModeLuminosity: ts << "luminosity"; break;
777    }
778    return ts;
779}
780
781RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCAAnimation::AnimationType type)
782{
783    RemoteLayerTreeTextStream& ts = *this;
784    switch (type) {
785    case PlatformCAAnimation::Basic: ts << "basic"; break;
786    case PlatformCAAnimation::Keyframe: ts << "keyframe"; break;
787    }
788    return ts;
789}
790
791RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCAAnimation::FillModeType type)
792{
793    RemoteLayerTreeTextStream& ts = *this;
794    switch (type) {
795    case PlatformCAAnimation::NoFillMode: ts << "none"; break;
796    case PlatformCAAnimation::Forwards: ts << "forwards"; break;
797    case PlatformCAAnimation::Backwards: ts << "backwards"; break;
798    case PlatformCAAnimation::Both: ts << "both"; break;
799    }
800    return ts;
801}
802
803RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCAAnimation::ValueFunctionType type)
804{
805    RemoteLayerTreeTextStream& ts = *this;
806    switch (type) {
807    case PlatformCAAnimation::NoValueFunction: ts << "none"; break;
808    case PlatformCAAnimation::RotateX: ts << "rotateX"; break;
809    case PlatformCAAnimation::RotateY: ts << "rotateY"; break;
810    case PlatformCAAnimation::RotateZ: ts << "rotateX"; break;
811    case PlatformCAAnimation::ScaleX: ts << "scaleX"; break;
812    case PlatformCAAnimation::ScaleY: ts << "scaleY"; break;
813    case PlatformCAAnimation::ScaleZ: ts << "scaleX"; break;
814    case PlatformCAAnimation::Scale: ts << "scale"; break;
815    case PlatformCAAnimation::TranslateX: ts << "translateX"; break;
816    case PlatformCAAnimation::TranslateY: ts << "translateY"; break;
817    case PlatformCAAnimation::TranslateZ: ts << "translateZ"; break;
818    case PlatformCAAnimation::Translate: ts << "translate"; break;
819    }
820    return ts;
821}
822
823RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const PlatformCAAnimationRemote::KeyframeValue& value)
824{
825    RemoteLayerTreeTextStream& ts = *this;
826
827    switch (value.keyframeType()) {
828    case PlatformCAAnimationRemote::KeyframeValue::NumberKeyType:
829        ts << "number=" << value.numberValue();
830        break;
831    case PlatformCAAnimationRemote::KeyframeValue::ColorKeyType:
832        ts << "color=";
833        ts << value.colorValue();
834        break;
835    case PlatformCAAnimationRemote::KeyframeValue::PointKeyType:
836        ts << "point=";
837        ts << value.pointValue();
838        break;
839    case PlatformCAAnimationRemote::KeyframeValue::TransformKeyType:
840        ts << "transform=";
841        ts << value.transformValue();
842        break;
843    case PlatformCAAnimationRemote::KeyframeValue::FilterKeyType:
844        ts << "filter=";
845        if (value.filterValue())
846            ts << *value.filterValue();
847        else
848            ts << "null";
849        break;
850    }
851    return ts;
852}
853
854RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const TimingFunction& timingFunction)
855{
856    RemoteLayerTreeTextStream& ts = *this;
857    switch (timingFunction.type()) {
858    case TimingFunction::LinearFunction:
859        ts << "linear";
860        break;
861    case TimingFunction::CubicBezierFunction: {
862        const CubicBezierTimingFunction& cubicBezierFunction = static_cast<const CubicBezierTimingFunction&>(timingFunction);
863        ts << "cubic-bezier(" << cubicBezierFunction.x1() << ", " << cubicBezierFunction.y1() << ", " <<  cubicBezierFunction.x2() << ", " << cubicBezierFunction.y2() << ")";
864        break;
865    }
866    case TimingFunction::StepsFunction: {
867        const StepsTimingFunction& stepsFunction = static_cast<const StepsTimingFunction&>(timingFunction);
868        ts << "steps(" << stepsFunction.numberOfSteps() << ", " << (stepsFunction.stepAtStart() ? "start" : "end") << ")";
869        break;
870    }
871    }
872    return ts;
873}
874
875RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const PlatformCAAnimationRemote::Properties& animation)
876{
877    RemoteLayerTreeTextStream& ts = *this;
878
879    ts << "type=";
880    ts << animation.animationType;
881    ts << " keyPath=";
882    ts << animation.keyPath;
883
884    if (animation.beginTime)
885        dumpProperty(ts, "beginTime", animation.beginTime);
886
887    if (animation.duration)
888        dumpProperty(ts, "duration", animation.duration);
889
890    if (animation.timeOffset)
891        dumpProperty(ts, "timeOffset", animation.timeOffset);
892
893    dumpProperty(ts, "repeatCount", animation.repeatCount);
894
895    if (animation.speed != 1)
896        dumpProperty(ts, "speed", animation.speed);
897
898    dumpProperty(ts, "fillMode", animation.fillMode);
899    dumpProperty(ts, "valueFunction", animation.valueFunction);
900
901    if (animation.autoReverses)
902        dumpProperty(ts, "autoReverses", animation.autoReverses);
903
904    if (!animation.removedOnCompletion)
905        dumpProperty(ts, "removedOnCompletion", animation.removedOnCompletion);
906
907    if (animation.additive)
908        dumpProperty(ts, "additive", animation.additive);
909
910    if (animation.reverseTimingFunctions)
911        dumpProperty(ts, "reverseTimingFunctions", animation.reverseTimingFunctions);
912
913    if (animation.hasExplicitBeginTime)
914        dumpProperty(ts, "hasExplicitBeginTime", animation.hasExplicitBeginTime);
915
916    ts << "\n";
917    ts.increaseIndent();
918    ts.writeIndent();
919    ts << "(" << "keyframes";
920    ts.increaseIndent();
921
922    size_t maxFrames = std::max(animation.keyValues.size(), animation.keyTimes.size());
923    maxFrames = std::max(maxFrames, animation.timingFunctions.size());
924
925    for (size_t i = 0; i < maxFrames; ++i) {
926        ts << "\n";
927        ts.writeIndent();
928        ts << "(keyframe " << unsigned(i);
929        if (i < animation.keyTimes.size())
930            dumpProperty(ts, "time", animation.keyTimes[i]);
931
932        if (i < animation.timingFunctions.size() && animation.timingFunctions[i])
933            dumpProperty<const TimingFunction&>(ts, "timing function", *animation.timingFunctions[i]);
934
935        if (i < animation.keyValues.size())
936            dumpProperty(ts, "value", animation.keyValues[i]);
937
938        ts << ")";
939    }
940
941    ts.decreaseIndent();
942    ts.decreaseIndent();
943
944    return ts;
945}
946
947RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(FloatPoint3D point)
948{
949    RemoteLayerTreeTextStream& ts = *this;
950    ts << point.x() << " " << point.y() << " " << point.z();
951    return ts;
952}
953
954RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(Color color)
955{
956    RemoteLayerTreeTextStream& ts = *this;
957    ts << color.serialized();
958    return ts;
959}
960
961RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(FloatRect rect)
962{
963    RemoteLayerTreeTextStream& ts = *this;
964    ts << rect.x() << " " << rect.y() << " " << rect.width() << " " << rect.height();
965    return ts;
966}
967
968RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const Vector<GraphicsLayer::PlatformLayerID>& layers)
969{
970    RemoteLayerTreeTextStream& ts = *this;
971
972    for (size_t i = 0; i < layers.size(); ++i) {
973        if (i)
974            ts << " ";
975        ts << layers[i];
976    }
977
978    return ts;
979}
980
981RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const RemoteLayerBackingStore& backingStore)
982{
983    RemoteLayerTreeTextStream& ts = *this;
984    ts << backingStore.size();
985    ts << " scale=" << backingStore.scale();
986    if (backingStore.isOpaque())
987        ts << " opaque";
988    if (backingStore.acceleratesDrawing())
989        ts << " accelerated";
990    return ts;
991}
992
993void RemoteLayerTreeTextStream::writeIndent()
994{
995    for (int i = 0; i < m_indent; ++i)
996        *this << "  ";
997}
998
999static void dumpChangedLayers(RemoteLayerTreeTextStream& ts, const RemoteLayerTreeTransaction::LayerPropertiesMap& changedLayerProperties)
1000{
1001    if (changedLayerProperties.isEmpty())
1002        return;
1003
1004    ts << "\n";
1005    ts.writeIndent();
1006    ts << "(changed-layers";
1007
1008    // Dump the layer properties sorted by layer ID.
1009    Vector<GraphicsLayer::PlatformLayerID> layerIDs;
1010    copyKeysToVector(changedLayerProperties, layerIDs);
1011    std::sort(layerIDs.begin(), layerIDs.end());
1012
1013    for (auto& layerID : layerIDs) {
1014        const RemoteLayerTreeTransaction::LayerProperties& layerProperties = *changedLayerProperties.get(layerID);
1015
1016        ts << "\n";
1017        ts.increaseIndent();
1018        ts.writeIndent();
1019        ts << "(layer " << layerID;
1020
1021        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::NameChanged)
1022            dumpProperty(ts, "name", layerProperties.name);
1023
1024        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged)
1025            dumpProperty<Vector<GraphicsLayer::PlatformLayerID>>(ts, "children", layerProperties.children);
1026
1027        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::PositionChanged)
1028            dumpProperty(ts, "position", layerProperties.position);
1029
1030        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BoundsChanged)
1031            dumpProperty(ts, "bounds", layerProperties.bounds);
1032
1033        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::AnchorPointChanged)
1034            dumpProperty(ts, "anchorPoint", layerProperties.anchorPoint);
1035
1036        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackgroundColorChanged)
1037            dumpProperty(ts, "backgroundColor", layerProperties.backgroundColor);
1038
1039        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BorderColorChanged)
1040            dumpProperty(ts, "borderColor", layerProperties.borderColor);
1041
1042        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged)
1043            dumpProperty(ts, "borderWidth", layerProperties.borderWidth);
1044
1045        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpacityChanged)
1046            dumpProperty(ts, "opacity", layerProperties.opacity);
1047
1048        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::TransformChanged)
1049            dumpProperty(ts, "transform", layerProperties.transform ? *layerProperties.transform : TransformationMatrix());
1050
1051        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SublayerTransformChanged)
1052            dumpProperty(ts, "sublayerTransform", layerProperties.sublayerTransform ? *layerProperties.sublayerTransform : TransformationMatrix());
1053
1054        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::HiddenChanged)
1055            dumpProperty(ts, "hidden", layerProperties.hidden);
1056
1057        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::GeometryFlippedChanged)
1058            dumpProperty(ts, "geometryFlipped", layerProperties.geometryFlipped);
1059
1060        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::DoubleSidedChanged)
1061            dumpProperty(ts, "doubleSided", layerProperties.doubleSided);
1062
1063        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MasksToBoundsChanged)
1064            dumpProperty(ts, "masksToBounds", layerProperties.masksToBounds);
1065
1066        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpaqueChanged)
1067            dumpProperty(ts, "opaque", layerProperties.opaque);
1068
1069        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged)
1070            dumpProperty(ts, "maskLayer", layerProperties.maskLayerID);
1071
1072        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ClonedContentsChanged)
1073            dumpProperty(ts, "clonedLayer", layerProperties.clonedLayerID);
1074
1075        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsRectChanged)
1076            dumpProperty(ts, "contentsRect", layerProperties.contentsRect);
1077
1078        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsScaleChanged)
1079            dumpProperty(ts, "contentsScale", layerProperties.contentsScale);
1080
1081        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MinificationFilterChanged)
1082            dumpProperty(ts, "minificationFilter", layerProperties.minificationFilter);
1083
1084        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MagnificationFilterChanged)
1085            dumpProperty(ts, "magnificationFilter", layerProperties.magnificationFilter);
1086
1087        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BlendModeChanged)
1088            dumpProperty(ts, "blendMode", layerProperties.blendMode);
1089
1090        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SpeedChanged)
1091            dumpProperty(ts, "speed", layerProperties.speed);
1092
1093        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::TimeOffsetChanged)
1094            dumpProperty(ts, "timeOffset", layerProperties.timeOffset);
1095
1096        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
1097            if (const RemoteLayerBackingStore* backingStore = layerProperties.backingStore.get())
1098                dumpProperty<const RemoteLayerBackingStore&>(ts, "backingStore", *backingStore);
1099            else
1100                dumpProperty(ts, "backingStore", "removed");
1101        }
1102
1103        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)
1104            dumpProperty(ts, "filters", layerProperties.filters ? *layerProperties.filters : FilterOperations());
1105
1106        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::AnimationsChanged) {
1107            for (const auto& keyAnimationPair : layerProperties.addedAnimations)
1108                dumpProperty(ts, "animation " +  keyAnimationPair.first, keyAnimationPair.second);
1109
1110            for (const auto& name : layerProperties.keyPathsOfAnimationsToRemove)
1111                dumpProperty(ts, "removed animation", name);
1112        }
1113
1114        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::EdgeAntialiasingMaskChanged)
1115            dumpProperty(ts, "edgeAntialiasingMask", layerProperties.edgeAntialiasingMask);
1116
1117        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::CustomAppearanceChanged)
1118            dumpProperty(ts, "customAppearance", layerProperties.customAppearance);
1119
1120        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::CustomBehaviorChanged)
1121            dumpProperty(ts, "customBehavior", layerProperties.customBehavior);
1122
1123        ts << ")";
1124
1125        ts.decreaseIndent();
1126    }
1127
1128    ts.decreaseIndent();
1129}
1130
1131void RemoteLayerTreeTransaction::dump() const
1132{
1133    fprintf(stderr, "%s", description().data());
1134}
1135
1136CString RemoteLayerTreeTransaction::description() const
1137{
1138    RemoteLayerTreeTextStream ts;
1139
1140    ts << "(\n";
1141    ts.increaseIndent();
1142    ts.writeIndent();
1143    ts << "(root-layer " << m_rootLayerID << ")";
1144
1145    if (!m_createdLayers.isEmpty()) {
1146        ts << "\n";
1147        ts.writeIndent();
1148        ts << "(created-layers";
1149        ts.increaseIndent();
1150        for (const auto& createdLayer : m_createdLayers) {
1151            ts << "\n";
1152            ts.writeIndent();
1153            ts << "(";
1154            switch (createdLayer.type) {
1155            case PlatformCALayer::LayerTypeLayer:
1156            case PlatformCALayer::LayerTypeWebLayer:
1157            case PlatformCALayer::LayerTypeSimpleLayer:
1158                ts << "layer";
1159                break;
1160            case PlatformCALayer::LayerTypeTransformLayer:
1161                ts << "transform-layer";
1162                break;
1163            case PlatformCALayer::LayerTypeWebTiledLayer:
1164                ts << "tiled-layer";
1165                break;
1166            case PlatformCALayer::LayerTypeTiledBackingLayer:
1167                ts << "tiled-backing-layer";
1168                break;
1169            case PlatformCALayer::LayerTypePageTiledBackingLayer:
1170                ts << "page-tiled-backing-layer";
1171                break;
1172            case PlatformCALayer::LayerTypeTiledBackingTileLayer:
1173                ts << "tiled-backing-tile";
1174                break;
1175            case PlatformCALayer::LayerTypeRootLayer:
1176                ts << "root-layer";
1177                break;
1178            case PlatformCALayer::LayerTypeAVPlayerLayer:
1179                ts << "av-player-layer (context-id " << createdLayer.hostingContextID << ")";
1180                break;
1181            case PlatformCALayer::LayerTypeWebGLLayer:
1182                ts << "web-gl-layer (context-id " << createdLayer.hostingContextID << ")";
1183                break;
1184            case PlatformCALayer::LayerTypeCustom:
1185                ts << "custom-layer (context-id " << createdLayer.hostingContextID << ")";
1186                break;
1187            }
1188            ts << " " << createdLayer.layerID << ")";
1189        }
1190        ts << ")";
1191        ts.decreaseIndent();
1192    }
1193
1194    dumpChangedLayers(ts, m_changedLayerProperties);
1195
1196    if (!m_destroyedLayerIDs.isEmpty())
1197        dumpProperty<Vector<GraphicsLayer::PlatformLayerID>>(ts, "destroyed-layers", m_destroyedLayerIDs);
1198
1199    ts << ")\n";
1200
1201    return ts.release().utf8();
1202}
1203
1204#endif // !defined(NDEBUG) || !LOG_DISABLED
1205
1206} // namespace WebKit
1207