Include child layers in the remote layer tree transaction
[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 #include "config.h"
27 #include "RemoteLayerTreeTransaction.h"
28
29 #include "ArgumentCoders.h"
30 #include "MessageDecoder.h"
31 #include "MessageEncoder.h"
32 #include "RemoteGraphicsLayer.h"
33 #include <wtf/text/CString.h>
34 #include <wtf/text/StringBuilder.h>
35
36 using namespace WebCore;
37
38 namespace WebKit {
39
40 RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
41     : changedProperties(NoChange)
42 {
43 }
44
45 void RemoteLayerTreeTransaction::LayerProperties::encode(CoreIPC::ArgumentEncoder& encoder) const
46 {
47     encoder << changedProperties;
48
49     if (changedProperties & NameChanged)
50         encoder << name;
51
52     if (changedProperties & ChildrenChanged)
53         encoder << children;
54 }
55
56 bool RemoteLayerTreeTransaction::LayerProperties::decode(CoreIPC::ArgumentDecoder* decoder, LayerProperties& result)
57 {
58     if (!decoder->decode(result.changedProperties))
59         return false;
60
61     if (result.changedProperties & NameChanged) {
62         if (!decoder->decode(result.name))
63             return false;
64     }
65
66     if (result.changedProperties & ChildrenChanged) {
67         if (!decoder->decode(result.children))
68             return false;
69
70         for (auto layerID: result.children) {
71             if (!layerID)
72                 return false;
73         }
74     }
75
76     return true;
77 }
78
79 RemoteLayerTreeTransaction::RemoteLayerTreeTransaction()
80 {
81 }
82
83 RemoteLayerTreeTransaction::~RemoteLayerTreeTransaction()
84 {
85 }
86
87 void RemoteLayerTreeTransaction::encode(CoreIPC::ArgumentEncoder& encoder) const
88 {
89     encoder << m_changedLayerProperties;
90 }
91
92 bool RemoteLayerTreeTransaction::decode(CoreIPC::ArgumentDecoder* decoder, RemoteLayerTreeTransaction& result)
93 {
94     if (!decoder->decode(result.m_changedLayerProperties))
95         return false;
96
97     return true;
98 }
99
100 void RemoteLayerTreeTransaction::layerPropertiesChanged(const RemoteGraphicsLayer* graphicsLayer, unsigned changedProperties)
101 {
102     LayerProperties& layerProperties = m_changedLayerProperties.add(graphicsLayer->layerID(), LayerProperties()).iterator->value;
103
104     layerProperties.changedProperties |= changedProperties;
105
106     if (changedProperties & NameChanged)
107         layerProperties.name = graphicsLayer->name();
108
109     if (changedProperties & ChildrenChanged) {
110         const Vector<GraphicsLayer*>& children = graphicsLayer->children();
111
112         ASSERT(layerProperties.children.isEmpty());
113         layerProperties.children.reserveCapacity(children.size());
114         for (size_t i = 0; i < children.size(); ++i) {
115             RemoteGraphicsLayer* childLayer = static_cast<RemoteGraphicsLayer*>(children[i]);
116             layerProperties.children.uncheckedAppend(childLayer->layerID());
117         }
118     }
119 }
120
121 #ifndef NDEBUG
122
123 static void writeIndent(StringBuilder& builder, int indent)
124 {
125     for (int i = 0; i < indent; ++i)
126         builder.append(' ');
127 }
128
129 static void dumpChangedLayers(StringBuilder& builder, const HashMap<uint64_t, RemoteLayerTreeTransaction::LayerProperties>& changedLayerProperties)
130 {
131     if (changedLayerProperties.isEmpty())
132         return;
133
134     writeIndent(builder, 1);
135     builder.append("(changed-layers\n");
136
137     // Dump the layer properties sorted by layer ID.
138     Vector<uint64_t> layerIDs;
139     copyKeysToVector(changedLayerProperties, layerIDs);
140     std::sort(layerIDs.begin(), layerIDs.end());
141
142     for (uint64_t layerID: layerIDs) {
143         const RemoteLayerTreeTransaction::LayerProperties& layerProperties = changedLayerProperties.get(layerID);
144
145         writeIndent(builder, 2);
146         builder.append("(layer ");
147         builder.appendNumber(layerID);
148
149         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::NameChanged) {
150             builder.append('\n');
151             writeIndent(builder, 3);
152             builder.append("(name \"");
153             builder.append(layerProperties.name);
154             builder.append("\")");
155         }
156
157         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
158             builder.append('\n');
159             writeIndent(builder, 3);
160             builder.append("(children (");
161             for (size_t i = 0; i < layerProperties.children.size(); ++i) {
162                 if (i != 0)
163                     builder.append(' ');
164                 builder.appendNumber(layerProperties.children[i]);
165             }
166
167             builder.append(")");
168         }
169
170         builder.append(")\n");
171     }
172 }
173
174 void RemoteLayerTreeTransaction::dump() const
175 {
176     StringBuilder builder;
177
178     builder.append("(\n");
179     dumpChangedLayers(builder, m_changedLayerProperties);
180     builder.append(")\n");
181
182     fprintf(stderr, "%s", builder.toString().utf8().data());
183 }
184
185 #endif // NDEBUG
186
187 } // namespace WebKit