Unreviewed, rolling out r244627.
[WebKit-https.git] / Source / WebKit / WebProcess / WebPage / RemoteLayerTree / PlatformCALayerRemoteCustom.mm
1 /*
2  * Copyright (C) 2013 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #import "PlatformCALayerRemoteCustom.h"
28
29 #import "LayerHostingContext.h"
30 #import "RemoteLayerTreeContext.h"
31 #import "RemoteLayerTreePropertyApplier.h"
32 #import "WebProcess.h"
33 #import <AVFoundation/AVFoundation.h>
34 #import <WebCore/GraphicsLayerCA.h>
35 #import <WebCore/PlatformCALayerCocoa.h>
36 #import <WebCore/WebCoreCALayerExtras.h>
37 #import <wtf/RetainPtr.h>
38 #import <wtf/SoftLinking.h>
39
40 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
41 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVPlayerLayer)
42
43 namespace WebKit {
44 using namespace WebCore;
45
46 static NSString * const platformCALayerPointer = @"WKPlatformCALayer";
47
48 Ref<PlatformCALayerRemote> PlatformCALayerRemoteCustom::create(PlatformLayer *platformLayer, PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
49 {
50     auto layer = adoptRef(*new PlatformCALayerRemoteCustom(PlatformCALayerCocoa::layerTypeForPlatformLayer(platformLayer), platformLayer, owner, context));
51     context.layerDidEnterContext(layer.get(), layer->layerType());
52     return WTFMove(layer);
53 }
54
55 PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom(LayerType layerType, PlatformLayer * customLayer, PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
56     : PlatformCALayerRemote(layerType, owner, context)
57 {
58     switch (context.layerHostingMode()) {
59     case LayerHostingMode::InProcess:
60         m_layerHostingContext = LayerHostingContext::createForPort(WebProcess::singleton().compositingRenderServerPort());
61         break;
62 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
63     case LayerHostingMode::OutOfProcess:
64         m_layerHostingContext = LayerHostingContext::createForExternalHostingProcess();
65 #if PLATFORM(IOS_FAMILY)
66         if (layerType == LayerTypeAVPlayerLayer) {
67             float scaleFactor = context.deviceScaleFactor();
68             // Set a scale factor here to make convertRect:toLayer:nil take scale factor into account. <rdar://problem/18316542>.
69             // This scale factor is inverted in the hosting process.
70             [customLayer setTransform:CATransform3DMakeScale(scaleFactor, scaleFactor, 1)];
71         }
72 #endif
73         break;
74 #endif
75     }
76
77     m_layerHostingContext->setRootLayer(customLayer);
78     [customLayer setValue:[NSValue valueWithPointer:this] forKey:platformCALayerPointer];
79
80     m_platformLayer = customLayer;
81     [customLayer web_disableAllActions];
82
83     m_providesContents = layerType == LayerTypeContentsProvidedLayer;
84
85     properties().position = FloatPoint3D(customLayer.position.x, customLayer.position.y, customLayer.zPosition);
86     properties().anchorPoint = FloatPoint3D(customLayer.anchorPoint.x, customLayer.anchorPoint.y, customLayer.anchorPointZ);
87     properties().bounds = customLayer.bounds;
88     properties().contentsRect = customLayer.contentsRect;
89 }
90
91 PlatformCALayerRemoteCustom::~PlatformCALayerRemoteCustom()
92 {
93     [m_platformLayer setValue:nil forKey:platformCALayerPointer];
94 }
95
96 uint32_t PlatformCALayerRemoteCustom::hostingContextID()
97 {
98     return m_layerHostingContext->contextID();
99 }
100
101 Ref<WebCore::PlatformCALayer> PlatformCALayerRemoteCustom::clone(PlatformCALayerClient* owner) const
102 {
103     RetainPtr<CALayer> clonedLayer;
104     bool copyContents = true;
105
106     if (layerType() == LayerTypeAVPlayerLayer) {
107         
108         if ([platformLayer() isKindOfClass:getAVPlayerLayerClass()]) {
109             clonedLayer = adoptNS([allocAVPlayerLayerInstance() init]);
110
111             AVPlayerLayer *destinationPlayerLayer = static_cast<AVPlayerLayer *>(clonedLayer.get());
112             AVPlayerLayer *sourcePlayerLayer = static_cast<AVPlayerLayer *>(platformLayer());
113             dispatch_async(dispatch_get_main_queue(), [destinationPlayerLayer, sourcePlayerLayer] {
114                 [destinationPlayerLayer setPlayer:[sourcePlayerLayer player]];
115             });
116         } else {
117             // On iOS, the AVPlayerLayer is inside a WebVideoContainerLayer. This code needs to share logic with MediaPlayerPrivateAVFoundationObjC::createAVPlayerLayer().
118             clonedLayer = adoptNS([[CALayer alloc] init]);
119         }
120
121         copyContents = false;
122     } else if (layerType() == LayerTypeContentsProvidedLayer) {
123         clonedLayer = adoptNS([[CALayer alloc] init]);
124         // FIXME: currently copying WebGL contents breaks the original layer.
125         copyContents = false;
126     }
127
128     auto clone = adoptRef(*new PlatformCALayerRemoteCustom(layerType(), clonedLayer.get(), owner, *context()));
129     context()->layerDidEnterContext(clone.get(), clone->layerType());
130
131     updateClonedLayerProperties(clone.get(), copyContents);
132
133     clone->setClonedLayer(this);
134     return WTFMove(clone);
135 }
136
137 CFTypeRef PlatformCALayerRemoteCustom::contents() const
138 {
139     return (__bridge CFTypeRef)[m_platformLayer contents];
140 }
141
142 void PlatformCALayerRemoteCustom::setContents(CFTypeRef contents)
143 {
144     [m_platformLayer setContents:(__bridge id)contents];
145 }
146
147 void PlatformCALayerRemoteCustom::setNeedsDisplayInRect(const FloatRect& rect)
148 {
149     if (m_providesContents)
150         [m_platformLayer setNeedsDisplayInRect:rect];
151     else
152         PlatformCALayerRemote::setNeedsDisplayInRect(rect);
153 }
154
155 void PlatformCALayerRemoteCustom::setNeedsDisplay()
156 {
157     if (m_providesContents)
158         [m_platformLayer setNeedsDisplay];
159     else
160         PlatformCALayerRemote::setNeedsDisplay();
161 }
162
163 } // namespace WebKit