0846121fb0db017798754a934363f6204a3f1a9a
[WebKit-https.git] / Source / WebKit2 / Shared / mac / RemoteLayerTreeTransaction.mm
1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "RemoteLayerTreeTransaction.h"
28
29 #import "ArgumentCoders.h"
30 #import "MessageDecoder.h"
31 #import "MessageEncoder.h"
32 #import "PlatformCALayerRemote.h"
33 #import "WebCoreArgumentCoders.h"
34 #import <wtf/text/CString.h>
35 #import <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     if (changedProperties & BackgroundColorChanged)
63         encoder << backgroundColor;
64
65     if (changedProperties & AnchorPointChanged)
66         encoder << anchorPoint;
67 }
68
69 bool RemoteLayerTreeTransaction::LayerProperties::decode(CoreIPC::ArgumentDecoder& decoder, LayerProperties& result)
70 {
71     if (!decoder.decode(result.changedProperties))
72         return false;
73
74     if (result.changedProperties & NameChanged) {
75         if (!decoder.decode(result.name))
76             return false;
77     }
78
79     if (result.changedProperties & ChildrenChanged) {
80         if (!decoder.decode(result.children))
81             return false;
82
83         for (auto layerID: result.children) {
84             if (!layerID)
85                 return false;
86         }
87     }
88
89     if (result.changedProperties & PositionChanged) {
90         if (!decoder.decode(result.position))
91             return false;
92     }
93
94     if (result.changedProperties & SizeChanged) {
95         if (!decoder.decode(result.size))
96             return false;
97     }
98
99     if (result.changedProperties & BackgroundColorChanged) {
100         if (!decoder.decode(result.backgroundColor))
101             return false;
102     }
103
104     if (result.changedProperties & AnchorPointChanged) {
105         if (!decoder.decode(result.anchorPoint))
106             return false;
107     }
108
109     return true;
110 }
111
112 RemoteLayerTreeTransaction::RemoteLayerTreeTransaction()
113 {
114 }
115
116 RemoteLayerTreeTransaction::~RemoteLayerTreeTransaction()
117 {
118 }
119
120 void RemoteLayerTreeTransaction::encode(CoreIPC::ArgumentEncoder& encoder) const
121 {
122     encoder << m_rootLayerID;
123     encoder << m_changedLayerProperties;
124     encoder << m_destroyedLayerIDs;
125 }
126
127 bool RemoteLayerTreeTransaction::decode(CoreIPC::ArgumentDecoder& decoder, RemoteLayerTreeTransaction& result)
128 {
129     if (!decoder.decode(result.m_rootLayerID))
130         return false;
131     if (!result.m_rootLayerID)
132         return false;
133
134     if (!decoder.decode(result.m_changedLayerProperties))
135         return false;
136
137     if (!decoder.decode(result.m_destroyedLayerIDs))
138         return false;
139     for (LayerID layerID : result.m_destroyedLayerIDs) {
140         if (!layerID)
141             return false;
142     }
143
144     return true;
145 }
146
147 void RemoteLayerTreeTransaction::setRootLayerID(LayerID rootLayerID)
148 {
149     ASSERT_ARG(rootLayerID, rootLayerID);
150
151     m_rootLayerID = rootLayerID;
152 }
153
154 void RemoteLayerTreeTransaction::layerPropertiesChanged(PlatformCALayerRemote* remoteLayer, RemoteLayerTreeTransaction::LayerProperties& properties)
155 {
156     m_changedLayerProperties.set(remoteLayer->layerID(), properties);
157 }
158
159 void RemoteLayerTreeTransaction::setDestroyedLayerIDs(Vector<LayerID> destroyedLayerIDs)
160 {
161     m_destroyedLayerIDs = std::move(destroyedLayerIDs);
162 }
163
164 #ifndef NDEBUG
165
166 static void writeIndent(StringBuilder& builder, int indent)
167 {
168     for (int i = 0; i < indent; ++i)
169         builder.append(' ');
170 }
171
172 static void dumpChangedLayers(StringBuilder& builder, const HashMap<RemoteLayerTreeTransaction::LayerID, RemoteLayerTreeTransaction::LayerProperties>& changedLayerProperties)
173 {
174     if (changedLayerProperties.isEmpty())
175         return;
176
177     writeIndent(builder, 1);
178     builder.append("(changed-layers\n");
179
180     // Dump the layer properties sorted by layer ID.
181     Vector<RemoteLayerTreeTransaction::LayerID> layerIDs;
182     copyKeysToVector(changedLayerProperties, layerIDs);
183     std::sort(layerIDs.begin(), layerIDs.end());
184
185     for (auto layerID: layerIDs) {
186         const RemoteLayerTreeTransaction::LayerProperties& layerProperties = changedLayerProperties.get(layerID);
187
188         writeIndent(builder, 2);
189         builder.append("(layer ");
190         builder.appendNumber(layerID);
191
192         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::NameChanged) {
193             builder.append('\n');
194             writeIndent(builder, 3);
195             builder.append("(name \"");
196             builder.append(layerProperties.name);
197             builder.append("\")");
198         }
199
200         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
201             builder.append('\n');
202             writeIndent(builder, 3);
203             builder.append("(children (");
204             for (size_t i = 0; i < layerProperties.children.size(); ++i) {
205                 if (i)
206                     builder.append(' ');
207                 builder.appendNumber(layerProperties.children[i]);
208             }
209
210             builder.append(")");
211         }
212
213         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::PositionChanged) {
214             builder.append('\n');
215             writeIndent(builder, 3);
216             builder.append("(position ");
217             builder.appendNumber(layerProperties.position.x());
218             builder.append(' ');
219             builder.appendNumber(layerProperties.position.y());
220             builder.append(' ');
221             builder.appendNumber(layerProperties.position.z());
222             builder.append(')');
223         }
224
225         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::SizeChanged) {
226             builder.append('\n');
227             writeIndent(builder, 3);
228             builder.append("(size ");
229             builder.appendNumber(layerProperties.size.width());
230             builder.append(' ');
231             builder.appendNumber(layerProperties.size.height());
232             builder.append(')');
233         }
234
235         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::AnchorPointChanged) {
236             builder.append('\n');
237             writeIndent(builder, 3);
238             builder.append("(anchorPoint ");
239             builder.appendNumber(layerProperties.anchorPoint.x());
240             builder.append(' ');
241             builder.appendNumber(layerProperties.anchorPoint.y());
242             builder.append(' ');
243             builder.appendNumber(layerProperties.anchorPoint.z());
244             builder.append(')');
245         }
246
247         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackgroundColorChanged) {
248             builder.append('\n');
249             writeIndent(builder, 3);
250             builder.append("(backgroundColor ");
251             builder.append(layerProperties.backgroundColor.serialized());
252             builder.append(')');
253         }
254
255         builder.append(")\n");
256     }
257 }
258
259 void RemoteLayerTreeTransaction::dump() const
260 {
261     StringBuilder builder;
262
263     builder.append("(\n");
264
265     writeIndent(builder, 1);
266     builder.append("(root-layer ");
267     builder.appendNumber(m_rootLayerID);
268     builder.append(")\n");
269
270     dumpChangedLayers(builder, m_changedLayerProperties);
271
272     if (!m_destroyedLayerIDs.isEmpty()) {
273         writeIndent(builder, 1);
274         builder.append("(destroyed-layers ");
275         for (size_t i = 0; i < m_destroyedLayerIDs.size(); ++i) {
276             if (i)
277                 builder.append(' ');
278             builder.appendNumber(m_destroyedLayerIDs[i]);
279         }
280         builder.append(")\n");
281     }
282     builder.append(")\n");
283
284     fprintf(stderr, "%s", builder.toString().utf8().data());
285 }
286
287 #endif // NDEBUG
288
289 } // namespace WebKit