Message decoding functions should take a MessageDecoder reference
[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 "WebCoreArgumentCoders.h"
34 #include <wtf/text/CString.h>
35 #include <wtf/text/StringBuilder.h>
36
37 using namespace WebCore;
38
39 namespace WebKit {
40
41 RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
42     : changedProperties(NoChange)
43 {
44 }
45
46 void RemoteLayerTreeTransaction::LayerProperties::encode(CoreIPC::ArgumentEncoder& encoder) const
47 {
48     encoder << changedProperties;
49
50     if (changedProperties & NameChanged)
51         encoder << name;
52
53     if (changedProperties & ChildrenChanged)
54         encoder << children;
55
56     if (changedProperties & PositionChanged)
57         encoder << position;
58
59     if (changedProperties & SizeChanged)
60         encoder << size;
61 }
62
63 bool RemoteLayerTreeTransaction::LayerProperties::decode(CoreIPC::ArgumentDecoder& decoder, LayerProperties& result)
64 {
65     if (!decoder.decode(result.changedProperties))
66         return false;
67
68     if (result.changedProperties & NameChanged) {
69         if (!decoder.decode(result.name))
70             return false;
71     }
72
73     if (result.changedProperties & ChildrenChanged) {
74         if (!decoder.decode(result.children))
75             return false;
76
77         for (auto layerID: result.children) {
78             if (!layerID)
79                 return false;
80         }
81     }
82
83     if (result.changedProperties & PositionChanged) {
84         if (!decoder.decode(result.position))
85             return false;
86     }
87
88     if (result.changedProperties & SizeChanged) {
89         if (!decoder.decode(result.size))
90             return false;
91     }
92     return true;
93 }
94
95 RemoteLayerTreeTransaction::RemoteLayerTreeTransaction()
96 {
97 }
98
99 RemoteLayerTreeTransaction::~RemoteLayerTreeTransaction()
100 {
101 }
102
103 void RemoteLayerTreeTransaction::encode(CoreIPC::ArgumentEncoder& encoder) const
104 {
105     encoder << m_rootLayerID;
106     encoder << m_changedLayerProperties;
107     encoder << m_destroyedLayerIDs;
108 }
109
110 bool RemoteLayerTreeTransaction::decode(CoreIPC::ArgumentDecoder& decoder, RemoteLayerTreeTransaction& result)
111 {
112     if (!decoder.decode(result.m_rootLayerID))
113         return false;
114     if (!result.m_rootLayerID)
115         return false;
116
117     if (!decoder.decode(result.m_changedLayerProperties))
118         return false;
119
120     if (!decoder.decode(result.m_destroyedLayerIDs))
121         return false;
122     for (uint64_t layerID: result.m_destroyedLayerIDs) {
123         if (!layerID)
124             return false;
125     }
126
127     return true;
128 }
129
130 void RemoteLayerTreeTransaction::setRootLayerID(uint64_t rootLayerID)
131 {
132     ASSERT_ARG(rootLayerID, rootLayerID);
133
134     m_rootLayerID = rootLayerID;
135 }
136
137 void RemoteLayerTreeTransaction::layerPropertiesChanged(const RemoteGraphicsLayer* graphicsLayer, unsigned changedProperties)
138 {
139     LayerProperties& layerProperties = m_changedLayerProperties.add(graphicsLayer->layerID(), LayerProperties()).iterator->value;
140
141     layerProperties.changedProperties |= changedProperties;
142
143     if (changedProperties & NameChanged)
144         layerProperties.name = graphicsLayer->name();
145
146     if (changedProperties & ChildrenChanged) {
147         const Vector<GraphicsLayer*>& children = graphicsLayer->children();
148
149         ASSERT(layerProperties.children.isEmpty());
150         layerProperties.children.reserveCapacity(children.size());
151         for (size_t i = 0; i < children.size(); ++i) {
152             RemoteGraphicsLayer* childLayer = static_cast<RemoteGraphicsLayer*>(children[i]);
153             layerProperties.children.uncheckedAppend(childLayer->layerID());
154         }
155     }
156
157     if (changedProperties & PositionChanged)
158         layerProperties.position = graphicsLayer->position();
159
160     if (changedProperties & SizeChanged)
161         layerProperties.size = graphicsLayer->size();
162 }
163
164 void RemoteLayerTreeTransaction::setDestroyedLayerIDs(Vector<uint64_t> destroyedLayerIDs)
165 {
166     m_destroyedLayerIDs = std::move(destroyedLayerIDs);
167 }
168
169 #ifndef NDEBUG
170
171 static void writeIndent(StringBuilder& builder, int indent)
172 {
173     for (int i = 0; i < indent; ++i)
174         builder.append(' ');
175 }
176
177 static void dumpChangedLayers(StringBuilder& builder, const HashMap<uint64_t, RemoteLayerTreeTransaction::LayerProperties>& changedLayerProperties)
178 {
179     if (changedLayerProperties.isEmpty())
180         return;
181
182     writeIndent(builder, 1);
183     builder.append("(changed-layers\n");
184
185     // Dump the layer properties sorted by layer ID.
186     Vector<uint64_t> layerIDs;
187     copyKeysToVector(changedLayerProperties, layerIDs);
188     std::sort(layerIDs.begin(), layerIDs.end());
189
190     for (uint64_t layerID: layerIDs) {
191         const RemoteLayerTreeTransaction::LayerProperties& layerProperties = changedLayerProperties.get(layerID);
192
193         writeIndent(builder, 2);
194         builder.append("(layer ");
195         builder.appendNumber(layerID);
196
197         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::NameChanged) {
198             builder.append('\n');
199             writeIndent(builder, 3);
200             builder.append("(name \"");
201             builder.append(layerProperties.name);
202             builder.append("\")");
203         }
204
205         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
206             builder.append('\n');
207             writeIndent(builder, 3);
208             builder.append("(children (");
209             for (size_t i = 0; i < layerProperties.children.size(); ++i) {
210                 if (i)
211                     builder.append(' ');
212                 builder.appendNumber(layerProperties.children[i]);
213             }
214
215             builder.append(")");
216         }
217
218         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::PositionChanged) {
219             builder.append('\n');
220             writeIndent(builder, 3);
221             builder.append("(position ");
222             builder.append(String::number(layerProperties.position.x()));
223             builder.append(" ");
224             builder.append(String::number(layerProperties.position.y()));
225             builder.append(')');
226         }
227
228         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SizeChanged) {
229             builder.append('\n');
230             writeIndent(builder, 3);
231             builder.append("(size ");
232             builder.append(String::number(layerProperties.size.width()));
233             builder.append(" ");
234             builder.append(String::number(layerProperties.size.height()));
235             builder.append(')');
236         }
237
238         builder.append(")\n");
239     }
240 }
241
242 void RemoteLayerTreeTransaction::dump() const
243 {
244     StringBuilder builder;
245
246     builder.append("(\n");
247
248     writeIndent(builder, 1);
249     builder.append("(root-layer ");
250     builder.appendNumber(m_rootLayerID);
251     builder.append(")\n");
252
253     dumpChangedLayers(builder, m_changedLayerProperties);
254
255     if (!m_destroyedLayerIDs.isEmpty()) {
256         writeIndent(builder, 1);
257         builder.append("(destroyed-layers ");
258         for (size_t i = 0; i < m_destroyedLayerIDs.size(); ++i) {
259             if (i)
260                 builder.append(' ');
261             builder.appendNumber(m_destroyedLayerIDs[i]);
262         }
263         builder.append(")\n");
264     }
265     builder.append(")\n");
266
267     fprintf(stderr, "%s", builder.toString().utf8().data());
268 }
269
270 #endif // NDEBUG
271
272 } // namespace WebKit