Support "plus-lighter" in mix-blend mode
[WebKit-https.git] / Source / WebKit2 / Shared / mac / RemoteLayerTreeTransaction.mm
index d3ca5ef..1b73aae 100644 (file)
 #import "ArgumentCoders.h"
 #import "MessageDecoder.h"
 #import "MessageEncoder.h"
+#import "PlatformCAAnimationRemote.h"
 #import "PlatformCALayerRemote.h"
 #import "WebCoreArgumentCoders.h"
 #import <QuartzCore/QuartzCore.h>
+#import <WebCore/LengthFunctions.h>
 #import <WebCore/TextStream.h>
+#import <WebCore/TimingFunction.h>
 #import <wtf/text/CString.h>
 #import <wtf/text/StringBuilder.h>
 
@@ -44,6 +47,7 @@ RemoteLayerTreeTransaction::LayerCreationProperties::LayerCreationProperties()
     : layerID(0)
     , type(PlatformCALayer::LayerTypeLayer)
     , hostingContextID(0)
+    , hostingDeviceScaleFactor(1)
 {
 }
 
@@ -51,9 +55,8 @@ void RemoteLayerTreeTransaction::LayerCreationProperties::encode(IPC::ArgumentEn
 {
     encoder << layerID;
     encoder.encodeEnum(type);
-
-    if (type == PlatformCALayer::LayerTypeCustom)
-        encoder << hostingContextID;
+    encoder << hostingContextID;
+    encoder << hostingDeviceScaleFactor;
 }
 
 bool RemoteLayerTreeTransaction::LayerCreationProperties::decode(IPC::ArgumentDecoder& decoder, LayerCreationProperties& result)
@@ -64,10 +67,11 @@ bool RemoteLayerTreeTransaction::LayerCreationProperties::decode(IPC::ArgumentDe
     if (!decoder.decodeEnum(result.type))
         return false;
 
-    if (result.type == PlatformCALayer::LayerTypeCustom) {
-        if (!decoder.decode(result.hostingContextID))
-            return false;
-    }
+    if (!decoder.decode(result.hostingContextID))
+        return false;
+
+    if (!decoder.decode(result.hostingDeviceScaleFactor))
+        return false;
 
     return true;
 }
@@ -78,9 +82,11 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
     , anchorPoint(0.5, 0.5, 0)
     , contentsRect(FloatPoint(), FloatSize(1, 1))
     , maskLayerID(0)
+    , clonedLayerID(0)
     , timeOffset(0)
     , speed(1)
     , contentsScale(1)
+    , cornerRadius(0)
     , borderWidth(0)
     , opacity(1)
     , backgroundColor(Color::transparent)
@@ -89,6 +95,8 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
     , customAppearance(GraphicsLayer::NoCustomAppearance)
     , minificationFilter(PlatformCALayer::FilterType::Linear)
     , magnificationFilter(PlatformCALayer::FilterType::Linear)
+    , blendMode(BlendModeNormal)
+    , windRule(RULE_NONZERO)
     , hidden(false)
     , geometryFlipped(false)
     , doubleSided(true)
@@ -102,14 +110,19 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties(const LayerProperti
     , everChangedProperties(other.everChangedProperties)
     , name(other.name)
     , children(other.children)
+    , addedAnimations(other.addedAnimations)
+    , keyPathsOfAnimationsToRemove(other.keyPathsOfAnimationsToRemove)
     , position(other.position)
     , anchorPoint(other.anchorPoint)
-    , size(other.size)
+    , bounds(other.bounds)
     , contentsRect(other.contentsRect)
+    , shapePath(other.shapePath)
     , maskLayerID(other.maskLayerID)
+    , clonedLayerID(other.clonedLayerID)
     , timeOffset(other.timeOffset)
     , speed(other.speed)
     , contentsScale(other.contentsScale)
+    , cornerRadius(other.cornerRadius)
     , borderWidth(other.borderWidth)
     , opacity(other.opacity)
     , backgroundColor(other.backgroundColor)
@@ -118,20 +131,22 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties(const LayerProperti
     , customAppearance(other.customAppearance)
     , minificationFilter(other.minificationFilter)
     , magnificationFilter(other.magnificationFilter)
+    , blendMode(other.blendMode)
+    , windRule(other.windRule)
     , hidden(other.hidden)
     , geometryFlipped(other.geometryFlipped)
     , doubleSided(other.doubleSided)
     , masksToBounds(other.masksToBounds)
     , opaque(other.opaque)
 {
+    // FIXME: LayerProperties should reference backing store by ID, so that two layers can have the same backing store (for clones).
+    // FIXME: LayerProperties shouldn't be copyable; PlatformCALayerRemote::clone should copy the relevant properties.
+
     if (other.transform)
         transform = std::make_unique<TransformationMatrix>(*other.transform);
 
     if (other.sublayerTransform)
         sublayerTransform = std::make_unique<TransformationMatrix>(*other.sublayerTransform);
-    
-    if (other.backingStore)
-        backingStore = std::make_unique<RemoteLayerBackingStore>(*other.backingStore);
 
     if (other.filters)
         filters = std::make_unique<FilterOperations>(*other.filters);
@@ -147,11 +162,16 @@ void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& e
     if (changedProperties & ChildrenChanged)
         encoder << children;
 
+    if (changedProperties & AnimationsChanged) {
+        encoder << addedAnimations;
+        encoder << keyPathsOfAnimationsToRemove;
+    }
+
     if (changedProperties & PositionChanged)
         encoder << position;
 
-    if (changedProperties & SizeChanged)
-        encoder << size;
+    if (changedProperties & BoundsChanged)
+        encoder << bounds;
 
     if (changedProperties & BackgroundColorChanged)
         encoder << backgroundColor;
@@ -192,18 +212,36 @@ void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& e
     if (changedProperties & MaskLayerChanged)
         encoder << maskLayerID;
 
+    if (changedProperties & ClonedContentsChanged)
+        encoder << clonedLayerID;
+
     if (changedProperties & ContentsRectChanged)
         encoder << contentsRect;
 
     if (changedProperties & ContentsScaleChanged)
         encoder << contentsScale;
 
+    if (changedProperties & CornerRadiusChanged)
+        encoder << cornerRadius;
+
+    if (changedProperties & ShapeRoundedRectChanged)
+        encoder << *shapeRoundedRect;
+
+    if (changedProperties & ShapePathChanged)
+        encoder << shapePath;
+
     if (changedProperties & MinificationFilterChanged)
         encoder.encodeEnum(minificationFilter);
 
     if (changedProperties & MagnificationFilterChanged)
         encoder.encodeEnum(magnificationFilter);
 
+    if (changedProperties & BlendModeChanged)
+        encoder.encodeEnum(blendMode);
+
+    if (changedProperties & WindRuleChanged)
+        encoder.encodeEnum(windRule);
+
     if (changedProperties & SpeedChanged)
         encoder << speed;
 
@@ -211,8 +249,9 @@ void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& e
         encoder << timeOffset;
 
     if (changedProperties & BackingStoreChanged) {
-        encoder << backingStore->hasFrontBuffer();
-        if (backingStore->hasFrontBuffer())
+        bool hasFrontBuffer = backingStore && backingStore->hasFrontBuffer();
+        encoder << hasFrontBuffer;
+        if (hasFrontBuffer)
             encoder << *backingStore;
     }
 
@@ -246,13 +285,21 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
         }
     }
 
+    if (result.changedProperties & AnimationsChanged) {
+        if (!decoder.decode(result.addedAnimations))
+            return false;
+
+        if (!decoder.decode(result.keyPathsOfAnimationsToRemove))
+            return false;
+    }
+
     if (result.changedProperties & PositionChanged) {
         if (!decoder.decode(result.position))
             return false;
     }
 
-    if (result.changedProperties & SizeChanged) {
-        if (!decoder.decode(result.size))
+    if (result.changedProperties & BoundsChanged) {
+        if (!decoder.decode(result.bounds))
             return false;
     }
 
@@ -327,6 +374,11 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
             return false;
     }
 
+    if (result.changedProperties & ClonedContentsChanged) {
+        if (!decoder.decode(result.clonedLayerID))
+            return false;
+    }
+
     if (result.changedProperties & ContentsRectChanged) {
         if (!decoder.decode(result.contentsRect))
             return false;
@@ -337,6 +389,27 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
             return false;
     }
 
+    if (result.changedProperties & CornerRadiusChanged) {
+        if (!decoder.decode(result.cornerRadius))
+            return false;
+    }
+
+    if (result.changedProperties & ShapeRoundedRectChanged) {
+        FloatRoundedRect roundedRect;
+        if (!decoder.decode(roundedRect))
+            return false;
+        
+        result.shapeRoundedRect = std::make_unique<FloatRoundedRect>(roundedRect);
+    }
+
+    if (result.changedProperties & ShapePathChanged) {
+        Path path;
+        if (!decoder.decode(path))
+            return false;
+        
+        result.shapePath = WTF::move(path);
+    }
+
     if (result.changedProperties & MinificationFilterChanged) {
         if (!decoder.decodeEnum(result.minificationFilter))
             return false;
@@ -347,6 +420,16 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
             return false;
     }
 
+    if (result.changedProperties & BlendModeChanged) {
+        if (!decoder.decodeEnum(result.blendMode))
+            return false;
+    }
+
+    if (result.changedProperties & WindRuleChanged) {
+        if (!decoder.decodeEnum(result.windRule))
+            return false;
+    }
+
     if (result.changedProperties & SpeedChanged) {
         if (!decoder.decode(result.speed))
             return false;
@@ -362,19 +445,20 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
         if (!decoder.decode(hasFrontBuffer))
             return false;
         if (hasFrontBuffer) {
-            RemoteLayerBackingStore backingStore;
-            if (!decoder.decode(backingStore))
+            std::unique_ptr<RemoteLayerBackingStore> backingStore = std::make_unique<RemoteLayerBackingStore>(nullptr);
+            if (!decoder.decode(*backingStore))
                 return false;
             
-            result.backingStore = std::make_unique<RemoteLayerBackingStore>(backingStore);
-        }
+            result.backingStore = WTF::move(backingStore);
+        } else
+            result.backingStore = nullptr;
     }
 
     if (result.changedProperties & FiltersChanged) {
         std::unique_ptr<FilterOperations> filters = std::make_unique<FilterOperations>();
         if (!decoder.decode(*filters))
             return false;
-        result.filters = std::move(filters);
+        result.filters = WTF::move(filters);
     }
 
     if (result.changedProperties & EdgeAntialiasingMaskChanged) {
@@ -391,6 +475,13 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
 }
 
 RemoteLayerTreeTransaction::RemoteLayerTreeTransaction()
+    : m_pageScaleFactor(1)
+    , m_minimumScaleFactor(1)
+    , m_maximumScaleFactor(1)
+    , m_renderTreeSize(0)
+    , m_transactionID(0)
+    , m_scaleWasSetByUIProcess(false)
+    , m_allowsUserScaling(false)
 {
 }
 
@@ -403,27 +494,33 @@ void RemoteLayerTreeTransaction::encode(IPC::ArgumentEncoder& encoder) const
     encoder << m_rootLayerID;
     encoder << m_createdLayers;
 
-    encoder << m_changedLayerProperties.size();
+    encoder << static_cast<uint64_t>(m_changedLayers.size());
 
-    for (const auto& layerProperties : m_changedLayerProperties) {
-        encoder << layerProperties.key;
-        encoder << *layerProperties.value;
+    for (RefPtr<PlatformCALayerRemote> layer : m_changedLayers) {
+        encoder << layer->layerID();
+        encoder << layer->properties();
     }
     
     encoder << m_destroyedLayerIDs;
     encoder << m_videoLayerIDsPendingFullscreen;
+    encoder << m_layerIDsWithNewlyUnreachableBackingStore;
 
     encoder << m_contentsSize;
+#if PLATFORM(MAC)
+    encoder << m_scrollPosition;
+#endif
     encoder << m_pageExtendedBackgroundColor;
     encoder << m_pageScaleFactor;
     encoder << m_minimumScaleFactor;
     encoder << m_maximumScaleFactor;
 
-    encoder << m_lastVisibleContentRectUpdateID;
     encoder << m_renderTreeSize;
+    encoder << m_transactionID;
 
     encoder << m_scaleWasSetByUIProcess;
     encoder << m_allowsUserScaling;
+
+    encoder << m_callbackIDs;
 }
 
 bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLayerTreeTransaction& result)
@@ -436,11 +533,11 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
     if (!decoder.decode(result.m_createdLayers))
         return false;
 
-    int numChangedLayerProperties;
+    uint64_t numChangedLayerProperties;
     if (!decoder.decode(numChangedLayerProperties))
         return false;
 
-    for (int i = 0; i < numChangedLayerProperties; ++i) {
+    for (uint64_t i = 0; i < numChangedLayerProperties; ++i) {
         GraphicsLayer::PlatformLayerID layerID;
         if (!decoder.decode(layerID))
             return false;
@@ -449,7 +546,7 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
         if (!decoder.decode(*layerProperties))
             return false;
 
-        result.changedLayers().set(layerID, std::move(layerProperties));
+        result.changedLayerProperties().set(layerID, WTF::move(layerProperties));
     }
 
     if (!decoder.decode(result.m_destroyedLayerIDs))
@@ -463,8 +560,21 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
     if (!decoder.decode(result.m_videoLayerIDsPendingFullscreen))
         return false;
 
+    if (!decoder.decode(result.m_layerIDsWithNewlyUnreachableBackingStore))
+        return false;
+
+    for (auto& layerID : result.m_layerIDsWithNewlyUnreachableBackingStore) {
+        if (!layerID)
+            return false;
+    }
+
     if (!decoder.decode(result.m_contentsSize))
         return false;
+
+#if PLATFORM(MAC)
+    if (!decoder.decode(result.m_scrollPosition))
+        return false;
+#endif
     
     if (!decoder.decode(result.m_pageExtendedBackgroundColor))
         return false;
@@ -478,10 +588,10 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
     if (!decoder.decode(result.m_maximumScaleFactor))
         return false;
 
-    if (!decoder.decode(result.m_lastVisibleContentRectUpdateID))
+    if (!decoder.decode(result.m_renderTreeSize))
         return false;
 
-    if (!decoder.decode(result.m_renderTreeSize))
+    if (!decoder.decode(result.m_transactionID))
         return false;
 
     if (!decoder.decode(result.m_scaleWasSetByUIProcess))
@@ -490,6 +600,9 @@ bool RemoteLayerTreeTransaction::decode(IPC::ArgumentDecoder& decoder, RemoteLay
     if (!decoder.decode(result.m_allowsUserScaling))
         return false;
 
+    if (!decoder.decode(result.m_callbackIDs))
+        return false;
+
     return true;
 }
 
@@ -500,19 +613,24 @@ void RemoteLayerTreeTransaction::setRootLayerID(GraphicsLayer::PlatformLayerID r
     m_rootLayerID = rootLayerID;
 }
 
-void RemoteLayerTreeTransaction::layerPropertiesChanged(PlatformCALayerRemote* remoteLayer, RemoteLayerTreeTransaction::LayerProperties& properties)
+void RemoteLayerTreeTransaction::layerPropertiesChanged(PlatformCALayerRemote& remoteLayer)
 {
-    m_changedLayerProperties.set(remoteLayer->layerID(), std::make_unique<RemoteLayerTreeTransaction::LayerProperties>(properties));
+    m_changedLayers.append(&remoteLayer);
 }
 
 void RemoteLayerTreeTransaction::setCreatedLayers(Vector<LayerCreationProperties> createdLayers)
 {
-    m_createdLayers = std::move(createdLayers);
+    m_createdLayers = WTF::move(createdLayers);
 }
 
 void RemoteLayerTreeTransaction::setDestroyedLayerIDs(Vector<GraphicsLayer::PlatformLayerID> destroyedLayerIDs)
 {
-    m_destroyedLayerIDs = std::move(destroyedLayerIDs);
+    m_destroyedLayerIDs = WTF::move(destroyedLayerIDs);
+}
+
+void RemoteLayerTreeTransaction::setLayerIDsWithNewlyUnreachableBackingStore(Vector<GraphicsLayer::PlatformLayerID> layerIDsWithNewlyUnreachableBackingStore)
+{
+    m_layerIDsWithNewlyUnreachableBackingStore = WTF::move(layerIDsWithNewlyUnreachableBackingStore);
 }
 
 #if !defined(NDEBUG) || !LOG_DISABLED
@@ -529,12 +647,21 @@ public:
 
     RemoteLayerTreeTextStream& operator<<(const TransformationMatrix&);
     RemoteLayerTreeTextStream& operator<<(PlatformCALayer::FilterType);
+    RemoteLayerTreeTextStream& operator<<(const FloatRoundedRect&);
     RemoteLayerTreeTextStream& operator<<(FloatPoint3D);
     RemoteLayerTreeTextStream& operator<<(Color);
     RemoteLayerTreeTextStream& operator<<(FloatRect);
-    RemoteLayerTreeTextStream& operator<<(const Vector<WebCore::GraphicsLayer::PlatformLayerID>& layers);
+    RemoteLayerTreeTextStream& operator<<(const Vector<WebCore::GraphicsLayer::PlatformLayerID>&);
+    RemoteLayerTreeTextStream& operator<<(const FilterOperation&);
     RemoteLayerTreeTextStream& operator<<(const FilterOperations&);
-    RemoteLayerTreeTextStream& operator<<(const RemoteLayerBackingStore& backingStore);
+    RemoteLayerTreeTextStream& operator<<(const PlatformCAAnimationRemote::Properties&);
+    RemoteLayerTreeTextStream& operator<<(const RemoteLayerBackingStore&);
+    RemoteLayerTreeTextStream& operator<<(BlendMode);
+    RemoteLayerTreeTextStream& operator<<(PlatformCAAnimation::AnimationType);
+    RemoteLayerTreeTextStream& operator<<(PlatformCAAnimation::FillModeType);
+    RemoteLayerTreeTextStream& operator<<(PlatformCAAnimation::ValueFunctionType);
+    RemoteLayerTreeTextStream& operator<<(const TimingFunction&);
+    RemoteLayerTreeTextStream& operator<<(const PlatformCAAnimationRemote::KeyframeValue&);
 
     void increaseIndent() { ++m_indent; }
     void decreaseIndent() { --m_indent; ASSERT(m_indent >= 0); }
@@ -545,6 +672,17 @@ private:
     int m_indent;
 };
 
+template <class T>
+static void dumpProperty(RemoteLayerTreeTextStream& ts, String name, T value)
+{
+    ts << "\n";
+    ts.increaseIndent();
+    ts.writeIndent();
+    ts << "(" << name << " ";
+    ts << value << ")";
+    ts.decreaseIndent();
+}
+
 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const TransformationMatrix& transform)
 {
     RemoteLayerTreeTextStream& ts = *this;
@@ -562,6 +700,25 @@ RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const Transform
     return ts;
 }
 
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const FloatRoundedRect& roundedRect)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    ts << roundedRect.rect().x() << " " << roundedRect.rect().y() << " " << roundedRect.rect().width() << " " << roundedRect.rect().height() << "\n";
+
+    ts.increaseIndent();
+    ts.writeIndent();
+    ts << "topLeft=" << roundedRect.topLeftCorner().width() << " " << roundedRect.topLeftCorner().height() << "\n";
+    ts.writeIndent();
+    ts << "topRight=" << roundedRect.topRightCorner().width() << " " << roundedRect.topRightCorner().height() << "\n";
+    ts.writeIndent();
+    ts << "bottomLeft=" << roundedRect.bottomLeftCorner().width() << " " << roundedRect.bottomLeftCorner().height() << "\n";
+    ts.writeIndent();
+    ts << "bottomRight=" << roundedRect.bottomRightCorner().width() << " " << roundedRect.bottomRightCorner().height();
+    ts.decreaseIndent();
+
+    return ts;
+}
+
 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCALayer::FilterType filterType)
 {
     RemoteLayerTreeTextStream& ts = *this;
@@ -587,53 +744,280 @@ RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const FilterOpe
     RemoteLayerTreeTextStream& ts = *this;
     for (size_t i = 0; i < filters.size(); ++i) {
         const auto filter = filters.at(i);
-        switch (filter->type()) {
-        case FilterOperation::REFERENCE:
-            ts << "reference";
-            break;
-        case FilterOperation::GRAYSCALE:
-            ts << "grayscale";
-            break;
-        case FilterOperation::SEPIA:
-            ts << "sepia";
-            break;
-        case FilterOperation::SATURATE:
-            ts << "saturate";
-            break;
-        case FilterOperation::HUE_ROTATE:
-            ts << "hue rotate";
-            break;
-        case FilterOperation::INVERT:
-            ts << "invert";
-            break;
-        case FilterOperation::OPACITY:
-            ts << "opacity";
-            break;
-        case FilterOperation::BRIGHTNESS:
-            ts << "brightness";
-            break;
-        case FilterOperation::CONTRAST:
-            ts << "contrast";
-            break;
-        case FilterOperation::BLUR:
-            ts << "blur";
-            break;
-        case FilterOperation::DROP_SHADOW:
-            ts << "drop shadow";
-            break;
-        case FilterOperation::PASSTHROUGH:
-            ts << "passthrough";
-            break;
-        case FilterOperation::NONE:
-            ts << "none";
-            break;
-        }
-
+        if (filter)
+            ts << *filter;
+        else
+            ts << "(null)";
         if (i < filters.size() - 1)
             ts << " ";
     }
     return ts;
 }
+    
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const FilterOperation& filter)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    switch (filter.type()) {
+    case FilterOperation::REFERENCE:
+        ts << "reference";
+        break;
+    case FilterOperation::GRAYSCALE: {
+        const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
+        ts << "grayscale(" << colorMatrixFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::SEPIA: {
+        const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
+        ts << "sepia(" << colorMatrixFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::SATURATE: {
+        const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
+        ts << "saturate(" << colorMatrixFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::HUE_ROTATE: {
+        const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
+        ts << "hue-rotate(" << colorMatrixFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::INVERT: {
+        const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
+        ts << "invert(" << componentTransferFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::OPACITY: {
+        const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
+        ts << "opacity(" << componentTransferFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::BRIGHTNESS: {
+        const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
+        ts << "brightness(" << componentTransferFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::CONTRAST: {
+        const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
+        ts << "contrast(" << componentTransferFilter.amount() << ")";
+        break;
+    }
+    case FilterOperation::BLUR: {
+        const auto& blurFilter = downcast<BlurFilterOperation>(filter);
+        ts << "blur(" << floatValueForLength(blurFilter.stdDeviation(), 0) << ")";
+        break;
+    }
+    case FilterOperation::DROP_SHADOW: {
+        const auto& dropShadowFilter = downcast<DropShadowFilterOperation>(filter);
+        ts << "drop-shadow(" << dropShadowFilter.x() << " " << dropShadowFilter.y() << " " << dropShadowFilter.location() << " ";
+        ts << dropShadowFilter.color() << ")";
+        break;
+    }
+    case FilterOperation::PASSTHROUGH:
+        ts << "passthrough";
+        break;
+    case FilterOperation::DEFAULT: {
+        const auto& defaultFilter = downcast<DefaultFilterOperation>(filter);
+        ts << "default type=" << (int)defaultFilter.representedType();
+        break;
+    }
+    case FilterOperation::NONE:
+        ts << "none";
+        break;
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(BlendMode blendMode)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    switch (blendMode) {
+    case BlendModeNormal: ts << "normal"; break;
+    case BlendModeMultiply: ts << "multiply"; break;
+    case BlendModeScreen: ts << "screen"; break;
+    case BlendModeOverlay: ts << "overlay"; break;
+    case BlendModeDarken: ts << "darken"; break;
+    case BlendModeLighten: ts << "lighten"; break;
+    case BlendModeColorDodge: ts << "color-dodge"; break;
+    case BlendModeColorBurn: ts << "color-burn"; break;
+    case BlendModeHardLight: ts << "hard-light"; break;
+    case BlendModeSoftLight: ts << "soft-light"; break;
+    case BlendModeDifference: ts << "difference"; break;
+    case BlendModeExclusion: ts << "exclusion"; break;
+    case BlendModeHue: ts << "hue"; break;
+    case BlendModeSaturation: ts << "saturation"; break;
+    case BlendModeColor: ts << "color"; break;
+    case BlendModeLuminosity: ts << "luminosity"; break;
+    case BlendModePlusDarker: ts << "plus-darker"; break;
+    case BlendModePlusLighter: ts << "plus-lighter"; break;
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCAAnimation::AnimationType type)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    switch (type) {
+    case PlatformCAAnimation::Basic: ts << "basic"; break;
+    case PlatformCAAnimation::Keyframe: ts << "keyframe"; break;
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCAAnimation::FillModeType type)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    switch (type) {
+    case PlatformCAAnimation::NoFillMode: ts << "none"; break;
+    case PlatformCAAnimation::Forwards: ts << "forwards"; break;
+    case PlatformCAAnimation::Backwards: ts << "backwards"; break;
+    case PlatformCAAnimation::Both: ts << "both"; break;
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(PlatformCAAnimation::ValueFunctionType type)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    switch (type) {
+    case PlatformCAAnimation::NoValueFunction: ts << "none"; break;
+    case PlatformCAAnimation::RotateX: ts << "rotateX"; break;
+    case PlatformCAAnimation::RotateY: ts << "rotateY"; break;
+    case PlatformCAAnimation::RotateZ: ts << "rotateX"; break;
+    case PlatformCAAnimation::ScaleX: ts << "scaleX"; break;
+    case PlatformCAAnimation::ScaleY: ts << "scaleY"; break;
+    case PlatformCAAnimation::ScaleZ: ts << "scaleX"; break;
+    case PlatformCAAnimation::Scale: ts << "scale"; break;
+    case PlatformCAAnimation::TranslateX: ts << "translateX"; break;
+    case PlatformCAAnimation::TranslateY: ts << "translateY"; break;
+    case PlatformCAAnimation::TranslateZ: ts << "translateZ"; break;
+    case PlatformCAAnimation::Translate: ts << "translate"; break;
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const PlatformCAAnimationRemote::KeyframeValue& value)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+
+    switch (value.keyframeType()) {
+    case PlatformCAAnimationRemote::KeyframeValue::NumberKeyType:
+        ts << "number=" << value.numberValue();
+        break;
+    case PlatformCAAnimationRemote::KeyframeValue::ColorKeyType:
+        ts << "color=";
+        ts << value.colorValue();
+        break;
+    case PlatformCAAnimationRemote::KeyframeValue::PointKeyType:
+        ts << "point=";
+        ts << value.pointValue();
+        break;
+    case PlatformCAAnimationRemote::KeyframeValue::TransformKeyType:
+        ts << "transform=";
+        ts << value.transformValue();
+        break;
+    case PlatformCAAnimationRemote::KeyframeValue::FilterKeyType:
+        ts << "filter=";
+        if (value.filterValue())
+            ts << *value.filterValue();
+        else
+            ts << "null";
+        break;
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const TimingFunction& timingFunction)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+    switch (timingFunction.type()) {
+    case TimingFunction::LinearFunction:
+        ts << "linear";
+        break;
+    case TimingFunction::CubicBezierFunction: {
+        const CubicBezierTimingFunction& cubicBezierFunction = static_cast<const CubicBezierTimingFunction&>(timingFunction);
+        ts << "cubic-bezier(" << cubicBezierFunction.x1() << ", " << cubicBezierFunction.y1() << ", " <<  cubicBezierFunction.x2() << ", " << cubicBezierFunction.y2() << ")";
+        break;
+    }
+    case TimingFunction::StepsFunction: {
+        const StepsTimingFunction& stepsFunction = static_cast<const StepsTimingFunction&>(timingFunction);
+        ts << "steps(" << stepsFunction.numberOfSteps() << ", " << (stepsFunction.stepAtStart() ? "start" : "end") << ")";
+        break;
+    }
+    }
+    return ts;
+}
+
+RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(const PlatformCAAnimationRemote::Properties& animation)
+{
+    RemoteLayerTreeTextStream& ts = *this;
+
+    ts << "type=";
+    ts << animation.animationType;
+    ts << " keyPath=";
+    ts << animation.keyPath;
+
+    if (animation.beginTime)
+        dumpProperty(ts, "beginTime", animation.beginTime);
+
+    if (animation.duration)
+        dumpProperty(ts, "duration", animation.duration);
+
+    if (animation.timeOffset)
+        dumpProperty(ts, "timeOffset", animation.timeOffset);
+
+    dumpProperty(ts, "repeatCount", animation.repeatCount);
+
+    if (animation.speed != 1)
+        dumpProperty(ts, "speed", animation.speed);
+
+    dumpProperty(ts, "fillMode", animation.fillMode);
+    dumpProperty(ts, "valueFunction", animation.valueFunction);
+
+    if (animation.autoReverses)
+        dumpProperty(ts, "autoReverses", animation.autoReverses);
+
+    if (!animation.removedOnCompletion)
+        dumpProperty(ts, "removedOnCompletion", animation.removedOnCompletion);
+
+    if (animation.additive)
+        dumpProperty(ts, "additive", animation.additive);
+
+    if (animation.reverseTimingFunctions)
+        dumpProperty(ts, "reverseTimingFunctions", animation.reverseTimingFunctions);
+
+    if (animation.hasExplicitBeginTime)
+        dumpProperty(ts, "hasExplicitBeginTime", animation.hasExplicitBeginTime);
+
+    ts << "\n";
+    ts.increaseIndent();
+    ts.writeIndent();
+    ts << "(" << "keyframes";
+    ts.increaseIndent();
+
+    size_t maxFrames = std::max(animation.keyValues.size(), animation.keyTimes.size());
+    maxFrames = std::max(maxFrames, animation.timingFunctions.size());
+
+    for (size_t i = 0; i < maxFrames; ++i) {
+        ts << "\n";
+        ts.writeIndent();
+        ts << "(keyframe " << unsigned(i);
+        if (i < animation.keyTimes.size())
+            dumpProperty(ts, "time", animation.keyTimes[i]);
+
+        if (i < animation.timingFunctions.size() && animation.timingFunctions[i])
+            dumpProperty<const TimingFunction&>(ts, "timing function", *animation.timingFunctions[i]);
+
+        if (i < animation.keyValues.size())
+            dumpProperty(ts, "value", animation.keyValues[i]);
+
+        ts << ")";
+    }
+
+    ts.decreaseIndent();
+    ts.decreaseIndent();
+
+    return ts;
+}
 
 RemoteLayerTreeTextStream& RemoteLayerTreeTextStream::operator<<(FloatPoint3D point)
 {
@@ -687,17 +1071,6 @@ void RemoteLayerTreeTextStream::writeIndent()
         *this << "  ";
 }
 
-template <class T>
-static void dumpProperty(RemoteLayerTreeTextStream& ts, String name, T value)
-{
-    ts << "\n";
-    ts.increaseIndent();
-    ts.writeIndent();
-    ts << "(" << name << " ";
-    ts << value << ")";
-    ts.decreaseIndent();
-}
-
 static void dumpChangedLayers(RemoteLayerTreeTextStream& ts, const RemoteLayerTreeTransaction::LayerPropertiesMap& changedLayerProperties)
 {
     if (changedLayerProperties.isEmpty())
@@ -721,89 +1094,109 @@ static void dumpChangedLayers(RemoteLayerTreeTextStream& ts, const RemoteLayerTr
         ts << "(layer " << layerID;
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::NameChanged)
-            dumpProperty<String>(ts, "name", layerProperties.name);
+            dumpProperty(ts, "name", layerProperties.name);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged)
             dumpProperty<Vector<GraphicsLayer::PlatformLayerID>>(ts, "children", layerProperties.children);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::PositionChanged)
-            dumpProperty<FloatPoint3D>(ts, "position", layerProperties.position);
+            dumpProperty(ts, "position", layerProperties.position);
 
-        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SizeChanged)
-            dumpProperty<FloatSize>(ts, "size", layerProperties.size);
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BoundsChanged)
+            dumpProperty(ts, "bounds", layerProperties.bounds);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::AnchorPointChanged)
-            dumpProperty<FloatPoint3D>(ts, "anchorPoint", layerProperties.anchorPoint);
+            dumpProperty(ts, "anchorPoint", layerProperties.anchorPoint);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackgroundColorChanged)
-            dumpProperty<Color>(ts, "backgroundColor", layerProperties.backgroundColor);
+            dumpProperty(ts, "backgroundColor", layerProperties.backgroundColor);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BorderColorChanged)
-            dumpProperty<Color>(ts, "borderColor", layerProperties.borderColor);
+            dumpProperty(ts, "borderColor", layerProperties.borderColor);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged)
-            dumpProperty<float>(ts, "borderWidth", layerProperties.borderWidth);
+            dumpProperty(ts, "borderWidth", layerProperties.borderWidth);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpacityChanged)
-            dumpProperty<float>(ts, "opacity", layerProperties.opacity);
+            dumpProperty(ts, "opacity", layerProperties.opacity);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::TransformChanged)
-            dumpProperty<TransformationMatrix>(ts, "transform", layerProperties.transform ? *layerProperties.transform : TransformationMatrix());
+            dumpProperty(ts, "transform", layerProperties.transform ? *layerProperties.transform : TransformationMatrix());
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SublayerTransformChanged)
-            dumpProperty<TransformationMatrix>(ts, "sublayerTransform", layerProperties.sublayerTransform ? *layerProperties.sublayerTransform : TransformationMatrix());
+            dumpProperty(ts, "sublayerTransform", layerProperties.sublayerTransform ? *layerProperties.sublayerTransform : TransformationMatrix());
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::HiddenChanged)
-            dumpProperty<bool>(ts, "hidden", layerProperties.hidden);
+            dumpProperty(ts, "hidden", layerProperties.hidden);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::GeometryFlippedChanged)
-            dumpProperty<bool>(ts, "geometryFlipped", layerProperties.geometryFlipped);
+            dumpProperty(ts, "geometryFlipped", layerProperties.geometryFlipped);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::DoubleSidedChanged)
-            dumpProperty<bool>(ts, "doubleSided", layerProperties.doubleSided);
+            dumpProperty(ts, "doubleSided", layerProperties.doubleSided);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MasksToBoundsChanged)
-            dumpProperty<bool>(ts, "masksToBounds", layerProperties.masksToBounds);
+            dumpProperty(ts, "masksToBounds", layerProperties.masksToBounds);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpaqueChanged)
-            dumpProperty<bool>(ts, "opaque", layerProperties.opaque);
+            dumpProperty(ts, "opaque", layerProperties.opaque);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged)
-            dumpProperty<GraphicsLayer::PlatformLayerID>(ts, "maskLayer", layerProperties.maskLayerID);
+            dumpProperty(ts, "maskLayer", layerProperties.maskLayerID);
+
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ClonedContentsChanged)
+            dumpProperty(ts, "clonedLayer", layerProperties.clonedLayerID);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsRectChanged)
-            dumpProperty<FloatRect>(ts, "contentsRect", layerProperties.contentsRect);
+            dumpProperty(ts, "contentsRect", layerProperties.contentsRect);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsScaleChanged)
-            dumpProperty<float>(ts, "contentsScale", layerProperties.contentsScale);
+            dumpProperty(ts, "contentsScale", layerProperties.contentsScale);
+
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::CornerRadiusChanged)
+            dumpProperty(ts, "cornerRadius", layerProperties.cornerRadius);
+
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ShapeRoundedRectChanged)
+            dumpProperty(ts, "shapeRect", layerProperties.shapeRoundedRect ? *layerProperties.shapeRoundedRect : FloatRoundedRect());
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MinificationFilterChanged)
-            dumpProperty<PlatformCALayer::FilterType>(ts, "minificationFilter", layerProperties.minificationFilter);
+            dumpProperty(ts, "minificationFilter", layerProperties.minificationFilter);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MagnificationFilterChanged)
-            dumpProperty<PlatformCALayer::FilterType>(ts, "magnificationFilter", layerProperties.magnificationFilter);
+            dumpProperty(ts, "magnificationFilter", layerProperties.magnificationFilter);
+
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BlendModeChanged)
+            dumpProperty(ts, "blendMode", layerProperties.blendMode);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SpeedChanged)
-            dumpProperty<float>(ts, "speed", layerProperties.speed);
+            dumpProperty(ts, "speed", layerProperties.speed);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::TimeOffsetChanged)
-            dumpProperty<double>(ts, "timeOffset", layerProperties.timeOffset);
+            dumpProperty(ts, "timeOffset", layerProperties.timeOffset);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
             if (const RemoteLayerBackingStore* backingStore = layerProperties.backingStore.get())
-                dumpProperty<RemoteLayerBackingStore>(ts, "backingStore", *backingStore);
+                dumpProperty<const RemoteLayerBackingStore&>(ts, "backingStore", *backingStore);
             else
-                dumpProperty<String>(ts, "backingStore", "removed");
+                dumpProperty(ts, "backingStore", "removed");
         }
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)
-            dumpProperty<FilterOperations>(ts, "filters", layerProperties.filters ? *layerProperties.filters : FilterOperations());
+            dumpProperty(ts, "filters", layerProperties.filters ? *layerProperties.filters : FilterOperations());
+
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::AnimationsChanged) {
+            for (const auto& keyAnimationPair : layerProperties.addedAnimations)
+                dumpProperty(ts, "animation " +  keyAnimationPair.first, keyAnimationPair.second);
+
+            for (const auto& name : layerProperties.keyPathsOfAnimationsToRemove)
+                dumpProperty(ts, "removed animation", name);
+        }
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::EdgeAntialiasingMaskChanged)
-            dumpProperty<unsigned>(ts, "edgeAntialiasingMask", layerProperties.edgeAntialiasingMask);
+            dumpProperty(ts, "edgeAntialiasingMask", layerProperties.edgeAntialiasingMask);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::CustomAppearanceChanged)
-            dumpProperty<GraphicsLayer::CustomAppearance>(ts, "customAppearance", layerProperties.customAppearance);
+            dumpProperty(ts, "customAppearance", layerProperties.customAppearance);
 
         ts << ")";
 
@@ -860,12 +1253,30 @@ CString RemoteLayerTreeTransaction::description() const
             case PlatformCALayer::LayerTypeRootLayer:
                 ts << "root-layer";
                 break;
+            case PlatformCALayer::LayerTypeBackdropLayer:
+                ts << "backdrop-layer";
+                break;
             case PlatformCALayer::LayerTypeAVPlayerLayer:
-                ts << "av-player-layer";
+                ts << "av-player-layer (context-id " << createdLayer.hostingContextID << ")";
+                break;
+            case PlatformCALayer::LayerTypeWebGLLayer:
+                ts << "web-gl-layer (context-id " << createdLayer.hostingContextID << ")";
+                break;
+            case PlatformCALayer::LayerTypeShapeLayer:
+                ts << "shape-layer";
+                break;
+            case PlatformCALayer::LayerTypeScrollingLayer:
+                ts << "scrolling-layer";
                 break;
             case PlatformCALayer::LayerTypeCustom:
                 ts << "custom-layer (context-id " << createdLayer.hostingContextID << ")";
                 break;
+            case PlatformCALayer::LayerTypeLightSystemBackdropLayer:
+                ts << "light-system-backdrop-layer";
+                break;
+            case PlatformCALayer::LayerTypeDarkSystemBackdropLayer:
+                ts << "dark-system-backdrop-layer";
+                break;
             }
             ts << " " << createdLayer.layerID << ")";
         }