[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebKit / UIProcess / RemoteLayerTree / ios / RemoteLayerTreeHostIOS.mm
1 /*
2  * Copyright (C) 2014 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 #if PLATFORM(IOS_FAMILY)
30
31 #import "EditableImageController.h"
32 #import "RemoteLayerTreeDrawingAreaProxy.h"
33 #import "RemoteLayerTreeViews.h"
34 #import "UIKitSPI.h"
35 #import "WKDrawingView.h"
36 #import "WebPageProxy.h"
37 #import <UIKit/UIScrollView.h>
38 #import <pal/spi/cocoa/QuartzCoreSPI.h>
39 #import <wtf/SoftLinking.h>
40
41 namespace WebKit {
42 using namespace WebCore;
43
44 static RetainPtr<UIView> createRemoteView(pid_t pid, uint32_t contextID)
45 {
46 #if USE(UIREMOTEVIEW_CONTEXT_HOSTING)
47     // FIXME: Remove this respondsToSelector check when possible.
48     static BOOL canUseUIRemoteView;
49     static std::once_flag initializeCanUseUIRemoteView;
50     std::call_once(initializeCanUseUIRemoteView, [] {
51         canUseUIRemoteView = [_UIRemoteView instancesRespondToSelector:@selector(initWithFrame:pid:contextID:)];
52     });
53     if (canUseUIRemoteView)
54         return adoptNS([[WKUIRemoteView alloc] initWithFrame:CGRectZero pid:pid contextID:contextID]);
55 #else
56     UNUSED_PARAM(pid);
57 #endif
58     return adoptNS([[WKRemoteView alloc] initWithFrame:CGRectZero contextID:contextID]);
59 }
60
61 std::unique_ptr<RemoteLayerTreeNode> RemoteLayerTreeHost::makeNode(const RemoteLayerTreeTransaction::LayerCreationProperties& properties)
62 {
63     auto makeWithView = [&] (RetainPtr<UIView> view) {
64         return makeUnique<RemoteLayerTreeNode>(properties.layerID, WTFMove(view));
65     };
66     auto makeAdoptingView = [&] (UIView* view) {
67         return makeWithView(adoptNS(view));
68     };
69
70     switch (properties.type) {
71     case PlatformCALayer::LayerTypeLayer:
72     case PlatformCALayer::LayerTypeWebLayer:
73     case PlatformCALayer::LayerTypeRootLayer:
74     case PlatformCALayer::LayerTypeSimpleLayer:
75     case PlatformCALayer::LayerTypeTiledBackingLayer:
76     case PlatformCALayer::LayerTypePageTiledBackingLayer:
77         return makeAdoptingView([[WKCompositingView alloc] init]);
78
79     case PlatformCALayer::LayerTypeTiledBackingTileLayer:
80         return RemoteLayerTreeNode::createWithPlainLayer(properties.layerID);
81
82     case PlatformCALayer::LayerTypeBackdropLayer:
83         return makeAdoptingView([[WKSimpleBackdropView alloc] init]);
84
85     case PlatformCALayer::LayerTypeLightSystemBackdropLayer:
86         return makeAdoptingView([[WKBackdropView alloc] initWithFrame:CGRectZero privateStyle:_UIBackdropViewStyle_Light]);
87
88     case PlatformCALayer::LayerTypeDarkSystemBackdropLayer:
89         return makeAdoptingView([[WKBackdropView alloc] initWithFrame:CGRectZero privateStyle:_UIBackdropViewStyle_Dark]);
90
91     case PlatformCALayer::LayerTypeTransformLayer:
92         return makeAdoptingView([[WKTransformView alloc] init]);
93
94     case PlatformCALayer::LayerTypeCustom:
95     case PlatformCALayer::LayerTypeAVPlayerLayer:
96     case PlatformCALayer::LayerTypeContentsProvidedLayer:
97         if (!m_isDebugLayerTreeHost) {
98             auto view = createRemoteView(m_drawingArea->page().processIdentifier(), properties.hostingContextID);
99             if (properties.type == PlatformCALayer::LayerTypeAVPlayerLayer) {
100                 // Invert the scale transform added in the WebProcess to fix <rdar://problem/18316542>.
101                 float inverseScale = 1 / properties.hostingDeviceScaleFactor;
102                 [[view layer] setTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
103             }
104             return makeWithView(WTFMove(view));
105         }
106         return makeAdoptingView([[WKCompositingView alloc] init]);
107
108     case PlatformCALayer::LayerTypeShapeLayer:
109         return makeAdoptingView([[WKShapeView alloc] init]);
110
111     case PlatformCALayer::LayerTypeScrollContainerLayer:
112         if (!m_isDebugLayerTreeHost)
113             return makeAdoptingView([[WKChildScrollView alloc] init]);
114         // The debug indicator parents views under layers, which can cause crashes with UIScrollView.
115         return makeAdoptingView([[UIView alloc] init]);
116
117     case PlatformCALayer::LayerTypeEditableImageLayer:
118         return makeWithView(createEmbeddedView(properties));
119
120     default:
121         ASSERT_NOT_REACHED();
122         return nullptr;
123     }
124 }
125
126 RetainPtr<WKEmbeddedView> RemoteLayerTreeHost::createEmbeddedView(const RemoteLayerTreeTransaction::LayerCreationProperties& properties)
127 {
128     if (m_isDebugLayerTreeHost)
129         return adoptNS([[UIView alloc] init]);
130
131     auto result = m_embeddedViews.ensure(properties.embeddedViewID, [&]() -> RetainPtr<UIView> {
132         switch (properties.type) {
133 #if HAVE(PENCILKIT)
134         case PlatformCALayer::LayerTypeEditableImageLayer: {
135             auto editableImage = m_drawingArea->page().editableImageController().editableImage(properties.embeddedViewID);
136             return editableImage ? editableImage->drawingView : nil;
137         }
138 #endif
139         default:
140             return adoptNS([[UIView alloc] init]);
141         }
142     });
143     auto view = result.iterator->value;
144     if (!result.isNewEntry)
145         m_layerToEmbeddedViewMap.remove(RemoteLayerTreeNode::layerID([view layer]));
146     m_layerToEmbeddedViewMap.set(properties.layerID, properties.embeddedViewID);
147     return view;
148 }
149
150 } // namespace WebKit
151
152 #endif // PLATFORM(IOS_FAMILY)