a1cba05482f4f7d282b2a9b004cd758cf5dbdfda
[WebKit-https.git] / Source / WebKit2 / UIProcess / mac / RemoteLayerTreeHost.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 "RemoteLayerTreeHost.h"
28
29 #import "RemoteLayerTreeHostMessages.h"
30 #import "RemoteLayerTreeTransaction.h"
31 #import "ShareableBitmap.h"
32 #import "WebPageProxy.h"
33 #import "WebProcessProxy.h"
34 #import <WebCore/PlatformCAFilters.h>
35 #import <WebCore/PlatformLayer.h>
36 #import <WebKitSystemInterface.h>
37
38 #import <QuartzCore/QuartzCore.h>
39
40 using namespace WebCore;
41
42 static NSDictionary *nullActionsDictionary()
43 {
44     NSNull* nullValue = [NSNull null];
45     return @{
46         @"anchorPoint" : nullValue,
47         @"anchorPointZ" : nullValue,
48         @"bounds" : nullValue,
49         @"contents" : nullValue,
50         @"contentsRect" : nullValue,
51         @"opacity" : nullValue,
52         @"position" : nullValue,
53         @"shadowColor" : nullValue,
54         @"sublayerTransform" : nullValue,
55         @"sublayers" : nullValue,
56         @"transform" : nullValue,
57         @"zPosition" : nullValue };
58 }
59
60 namespace WebKit {
61
62 RemoteLayerTreeHost::RemoteLayerTreeHost(WebPageProxy* webPageProxy)
63     : m_webPageProxy(webPageProxy)
64     , m_rootLayer(nullptr)
65 {
66     m_webPageProxy->process()->addMessageReceiver(Messages::RemoteLayerTreeHost::messageReceiverName(), m_webPageProxy->pageID(), this);
67 }
68
69 RemoteLayerTreeHost::~RemoteLayerTreeHost()
70 {
71     m_webPageProxy->process()->removeMessageReceiver(Messages::RemoteLayerTreeHost::messageReceiverName(), m_webPageProxy->pageID());
72 }
73
74 static RetainPtr<CGColorRef> cgColorFromColor(Color color)
75 {
76     CGFloat components[4];
77     color.getRGBA(components[0], components[1], components[2], components[3]);
78
79     RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
80     RetainPtr<CGColorRef> cgColor = adoptCF(CGColorCreate(colorSpace.get(), components));
81     return cgColor;
82 }
83
84 static NSString *toCAFilterType(PlatformCALayer::FilterType type)
85 {
86     switch (type) {
87     case PlatformCALayer::Linear:
88         return kCAFilterLinear;
89     case PlatformCALayer::Nearest:
90         return kCAFilterNearest;
91     case PlatformCALayer::Trilinear:
92         return kCAFilterTrilinear;
93     };
94
95     ASSERT_NOT_REACHED();
96     return 0;
97 }
98
99
100 void RemoteLayerTreeHost::commit(const RemoteLayerTreeTransaction& transaction)
101 {
102 #if !defined(NDEBUG)
103     transaction.dump();
104 #endif
105
106     for (auto createdLayer : transaction.createdLayers())
107         createLayer(createdLayer);
108
109     CALayer *rootLayer = getLayer(transaction.rootLayerID());
110     if (m_rootLayer != rootLayer) {
111         m_rootLayer = rootLayer;
112         m_webPageProxy->setAcceleratedCompositingRootLayer(m_rootLayer);
113     }
114
115     for (auto changedLayer : transaction.changedLayers()) {
116         RemoteLayerTreeTransaction::LayerID layerID = changedLayer.key;
117         const auto& properties = changedLayer.value;
118
119         CALayer *layer = getLayer(layerID);
120         ASSERT(layer);
121
122         if (properties.changedProperties & RemoteLayerTreeTransaction::NameChanged)
123             layer.name = properties.name;
124
125         if (properties.changedProperties & RemoteLayerTreeTransaction::PositionChanged) {
126             layer.position = CGPointMake(properties.position.x(), properties.position.y());
127             layer.zPosition = properties.position.z();
128         }
129
130         if (properties.changedProperties & RemoteLayerTreeTransaction::AnchorPointChanged) {
131             layer.anchorPoint = CGPointMake(properties.anchorPoint.x(), properties.anchorPoint.y());
132             layer.anchorPointZ = properties.anchorPoint.z();
133         }
134
135         if (properties.changedProperties & RemoteLayerTreeTransaction::SizeChanged)
136             layer.bounds = FloatRect(FloatPoint(), properties.size);
137
138         if (properties.changedProperties & RemoteLayerTreeTransaction::BackgroundColorChanged)
139             layer.backgroundColor = cgColorFromColor(properties.backgroundColor).get();
140
141         if (properties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
142             RetainPtr<NSMutableArray> children = adoptNS([[NSMutableArray alloc] initWithCapacity:properties.children.size()]);
143             for (auto child : properties.children)
144                 [children addObject:getLayer(child)];
145             layer.sublayers = children.get();
146         }
147
148         if (properties.changedProperties & RemoteLayerTreeTransaction::BorderColorChanged)
149             layer.borderColor = cgColorFromColor(properties.borderColor).get();
150
151         if (properties.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged)
152             layer.borderWidth = properties.borderWidth;
153
154         if (properties.changedProperties & RemoteLayerTreeTransaction::OpacityChanged)
155             layer.opacity = properties.opacity;
156
157         if (properties.changedProperties & RemoteLayerTreeTransaction::TransformChanged)
158             layer.transform = properties.transform;
159
160         if (properties.changedProperties & RemoteLayerTreeTransaction::SublayerTransformChanged)
161             layer.sublayerTransform = properties.sublayerTransform;
162
163         if (properties.changedProperties & RemoteLayerTreeTransaction::HiddenChanged)
164             layer.hidden = properties.hidden;
165
166         if (properties.changedProperties & RemoteLayerTreeTransaction::GeometryFlippedChanged)
167             layer.geometryFlipped = properties.geometryFlipped;
168
169         if (properties.changedProperties & RemoteLayerTreeTransaction::DoubleSidedChanged)
170             layer.doubleSided = properties.doubleSided;
171
172         if (properties.changedProperties & RemoteLayerTreeTransaction::MasksToBoundsChanged)
173             layer.masksToBounds = properties.masksToBounds;
174
175         if (properties.changedProperties & RemoteLayerTreeTransaction::OpaqueChanged)
176             layer.opaque = properties.opaque;
177
178         if (properties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged) {
179             CALayer *maskLayer = getLayer(properties.maskLayer);
180             ASSERT(!maskLayer.superlayer);
181             if (!maskLayer.superlayer)
182                 layer.mask = maskLayer;
183         }
184
185         if (properties.changedProperties & RemoteLayerTreeTransaction::ContentsRectChanged)
186             layer.contentsRect = properties.contentsRect;
187
188         if (properties.changedProperties & RemoteLayerTreeTransaction::ContentsScaleChanged)
189             layer.contentsScale = properties.contentsScale;
190
191         if (properties.changedProperties & RemoteLayerTreeTransaction::MinificationFilterChanged)
192             layer.minificationFilter = toCAFilterType(properties.minificationFilter);
193
194         if (properties.changedProperties & RemoteLayerTreeTransaction::MagnificationFilterChanged)
195             layer.magnificationFilter = toCAFilterType(properties.magnificationFilter);
196
197         if (properties.changedProperties & RemoteLayerTreeTransaction::SpeedChanged)
198             layer.speed = properties.speed;
199
200         if (properties.changedProperties & RemoteLayerTreeTransaction::TimeOffsetChanged)
201             layer.timeOffset = properties.timeOffset;
202
203         if (properties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
204             if (properties.backingStore.acceleratesDrawing())
205                 layer.contents = (id)properties.backingStore.surface().get();
206             else
207                 layer.contents = (id)properties.backingStore.image().get();
208         }
209
210         if (properties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)
211             PlatformCAFilters::setFiltersOnLayer(layer, properties.filters);
212
213         if (properties.changedProperties & RemoteLayerTreeTransaction::EdgeAntialiasingMaskChanged)
214             layer.edgeAntialiasingMask = properties.edgeAntialiasingMask;
215     }
216
217     for (auto destroyedLayer : transaction.destroyedLayers())
218         m_layers.remove(destroyedLayer);
219 }
220
221 CALayer *RemoteLayerTreeHost::getLayer(RemoteLayerTreeTransaction::LayerID layerID)
222 {
223     return m_layers.get(layerID).get();
224 }
225
226 CALayer *RemoteLayerTreeHost::createLayer(RemoteLayerTreeTransaction::LayerCreationProperties properties)
227 {
228     RetainPtr<CALayer>& layer = m_layers.add(properties.layerID, nullptr).iterator->value;
229
230     ASSERT(!layer);
231
232     switch (properties.type) {
233     case PlatformCALayer::LayerTypeLayer:
234     case PlatformCALayer::LayerTypeWebLayer:
235     case PlatformCALayer::LayerTypeRootLayer:
236     case PlatformCALayer::LayerTypeSimpleLayer:
237     case PlatformCALayer::LayerTypeTiledBackingLayer:
238     case PlatformCALayer::LayerTypePageTiledBackingLayer:
239     case PlatformCALayer::LayerTypeTiledBackingTileLayer:
240         layer = adoptNS([[CALayer alloc] init]);
241         break;
242     case PlatformCALayer::LayerTypeTransformLayer:
243         layer = adoptNS([[CATransformLayer alloc] init]);
244         break;
245     case PlatformCALayer::LayerTypeCustom:
246         layer = WKMakeRenderLayer(properties.hostingContextID);
247         break;
248     default:
249         ASSERT_NOT_REACHED();
250     }
251
252     [layer setStyle:@{ @"actions" : nullActionsDictionary() }];
253
254     return layer.get();
255 }
256
257 } // namespace WebKit