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 "RemoteLayerTreeDrawingAreaProxy.h" 30#import "RemoteLayerTreePropertyApplier.h" 31#import "RemoteLayerTreeTransaction.h" 32#import "ShareableBitmap.h" 33#import "WebPageProxy.h" 34#import "WebProcessProxy.h" 35#import <QuartzCore/QuartzCore.h> 36#import <WebCore/PlatformLayer.h> 37#import <WebCore/WebActionDisablingCALayerDelegate.h> 38#import <WebKitSystemInterface.h> 39 40#if PLATFORM(IOS) 41#import <UIKit/UIView.h> 42#endif 43 44using namespace WebCore; 45 46namespace WebKit { 47 48RemoteLayerTreeHost::RemoteLayerTreeHost(RemoteLayerTreeDrawingAreaProxy& drawingArea) 49 : m_drawingArea(drawingArea) 50 , m_rootLayer(nullptr) 51 , m_isDebugLayerTreeHost(false) 52{ 53} 54 55RemoteLayerTreeHost::~RemoteLayerTreeHost() 56{ 57 clearLayers(); 58} 59 60bool RemoteLayerTreeHost::updateLayerTree(const RemoteLayerTreeTransaction& transaction, float indicatorScaleFactor) 61{ 62 for (const auto& createdLayer : transaction.createdLayers()) { 63 const RemoteLayerTreeTransaction::LayerProperties* properties = transaction.changedLayerProperties().get(createdLayer.layerID); 64 createLayer(createdLayer, properties); 65 } 66 67 bool rootLayerChanged = false; 68 LayerOrView *rootLayer = getLayer(transaction.rootLayerID()); 69 if (m_rootLayer != rootLayer) { 70 m_rootLayer = rootLayer; 71 rootLayerChanged = true; 72 } 73 74 typedef std::pair<GraphicsLayer::PlatformLayerID, GraphicsLayer::PlatformLayerID> LayerIDPair; 75 Vector<LayerIDPair> clonesToUpdate; 76 77 for (auto& changedLayer : transaction.changedLayerProperties()) { 78 auto layerID = changedLayer.key; 79 const RemoteLayerTreeTransaction::LayerProperties& properties = *changedLayer.value; 80 81 LayerOrView *layer = getLayer(layerID); 82 ASSERT(layer); 83 84 RemoteLayerTreePropertyApplier::RelatedLayerMap relatedLayers; 85 if (properties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) { 86 for (auto& child : properties.children) 87 relatedLayers.set(child, getLayer(child)); 88 } 89 90 if (properties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged && properties.maskLayerID) 91 relatedLayers.set(properties.maskLayerID, getLayer(properties.maskLayerID)); 92 93 if (properties.changedProperties & RemoteLayerTreeTransaction::ClonedContentsChanged && properties.clonedLayerID) 94 clonesToUpdate.append(LayerIDPair(layerID, properties.clonedLayerID)); 95 96 if (m_isDebugLayerTreeHost) { 97 RemoteLayerTreePropertyApplier::applyProperties(layer, this, properties, relatedLayers); 98 99 if (properties.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged) 100 asLayer(layer).borderWidth = properties.borderWidth / indicatorScaleFactor; 101 asLayer(layer).masksToBounds = false; 102 } else 103 RemoteLayerTreePropertyApplier::applyProperties(layer, this, properties, relatedLayers); 104 } 105 106 for (const auto& layerPair : clonesToUpdate) { 107 LayerOrView *layer = getLayer(layerPair.first); 108 LayerOrView *clonedLayer = getLayer(layerPair.second); 109 asLayer(layer).contents = asLayer(clonedLayer).contents; 110 } 111 112 for (auto& destroyedLayer : transaction.destroyedLayers()) 113 layerWillBeRemoved(destroyedLayer); 114 115 // Drop the contents of any layers which were unparented; the Web process will re-send 116 // the backing store in the commit that reparents them. 117 for (auto& newlyUnreachableLayerID : transaction.layerIDsWithNewlyUnreachableBackingStore()) 118 asLayer(getLayer(newlyUnreachableLayerID)).contents = nullptr; 119 120 return rootLayerChanged; 121} 122 123LayerOrView *RemoteLayerTreeHost::getLayer(GraphicsLayer::PlatformLayerID layerID) const 124{ 125 if (!layerID) 126 return nil; 127 128 return m_layers.get(layerID).get(); 129} 130 131void RemoteLayerTreeHost::layerWillBeRemoved(WebCore::GraphicsLayer::PlatformLayerID layerID) 132{ 133 m_animationDelegates.remove(layerID); 134 m_layers.remove(layerID); 135} 136 137void RemoteLayerTreeHost::animationDidStart(WebCore::GraphicsLayer::PlatformLayerID layerID, CAAnimation *animation, double startTime) 138{ 139 CALayer *layer = asLayer(getLayer(layerID)); 140 if (!layer) 141 return; 142 143 String animationKey; 144 for (NSString *key in [layer animationKeys]) { 145 if ([layer animationForKey:key] == animation) { 146 animationKey = key; 147 break; 148 } 149 } 150 151 if (!animationKey.isEmpty()) 152 m_drawingArea.acceleratedAnimationDidStart(layerID, animationKey, startTime); 153} 154 155void RemoteLayerTreeHost::clearLayers() 156{ 157 for (auto& idLayer : m_layers) { 158 m_animationDelegates.remove(idLayer.key); 159#if PLATFORM(IOS) 160 [idLayer.value.get() removeFromSuperview]; 161#else 162 [asLayer(idLayer.value.get()) removeFromSuperlayer]; 163#endif 164 } 165 166 m_layers.clear(); 167 168 if (m_rootLayer) 169 m_rootLayer = nullptr; 170} 171 172static NSString* const WKLayerIDPropertyKey = @"WKLayerID"; 173 174void RemoteLayerTreeHost::setLayerID(CALayer *layer, WebCore::GraphicsLayer::PlatformLayerID layerID) 175{ 176 [layer setValue:[NSNumber numberWithUnsignedLongLong:layerID] forKey:WKLayerIDPropertyKey]; 177} 178 179WebCore::GraphicsLayer::PlatformLayerID RemoteLayerTreeHost::layerID(CALayer* layer) 180{ 181 return [[layer valueForKey:WKLayerIDPropertyKey] unsignedLongLongValue]; 182} 183 184#if !PLATFORM(IOS) 185LayerOrView *RemoteLayerTreeHost::createLayer(const RemoteLayerTreeTransaction::LayerCreationProperties& properties, const RemoteLayerTreeTransaction::LayerProperties*) 186{ 187 RetainPtr<CALayer>& layer = m_layers.add(properties.layerID, nullptr).iterator->value; 188 189 ASSERT(!layer); 190 191 switch (properties.type) { 192 case PlatformCALayer::LayerTypeLayer: 193 case PlatformCALayer::LayerTypeWebLayer: 194 case PlatformCALayer::LayerTypeRootLayer: 195 case PlatformCALayer::LayerTypeSimpleLayer: 196 case PlatformCALayer::LayerTypeTiledBackingLayer: 197 case PlatformCALayer::LayerTypePageTiledBackingLayer: 198 case PlatformCALayer::LayerTypeTiledBackingTileLayer: 199 layer = adoptNS([[CALayer alloc] init]); 200 break; 201 case PlatformCALayer::LayerTypeTransformLayer: 202 layer = adoptNS([[CATransformLayer alloc] init]); 203 break; 204 case PlatformCALayer::LayerTypeCustom: 205 case PlatformCALayer::LayerTypeAVPlayerLayer: 206 case PlatformCALayer::LayerTypeWebGLLayer: 207 if (!m_isDebugLayerTreeHost) 208 layer = WKMakeRenderLayer(properties.hostingContextID); 209 else 210 layer = adoptNS([[CALayer alloc] init]); 211 break; 212 default: 213 ASSERT_NOT_REACHED(); 214 } 215 216 [layer setDelegate:[WebActionDisablingCALayerDelegate shared]]; 217 setLayerID(layer.get(), properties.layerID); 218 219 return layer.get(); 220} 221#endif 222 223void RemoteLayerTreeHost::detachRootLayer() 224{ 225#if PLATFORM(IOS) 226 [m_rootLayer removeFromSuperview]; 227#else 228 [asLayer(m_rootLayer) removeFromSuperlayer]; 229#endif 230 m_rootLayer = nullptr; 231} 232 233} // namespace WebKit 234