Remote tile layers shouldn't be UIViews
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Nov 2018 09:12:03 +0000 (09:12 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Nov 2018 09:12:03 +0000 (09:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191953

Reviewed by Tim Horton.

They don't need any UIView functionality, nor do they ever have UIView descendants.
We can use lighter weight objects.

* Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.h:
* Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.mm:
(WebKit::RemoteLayerTreePropertyApplier::applyProperties):
(WebKit::RemoteLayerTreePropertyApplier::updateChildren):

Factor to a function shared between platforms.
Support having both views and plain layers in the same tree.
Assert that all siblings are of the same type and that we don't attempt to add views to layers.

(WebKit::RemoteLayerTreePropertyApplier::applyPropertiesToUIView):
* UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::makeNode):

Use new plain layer on Mac too.

* UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
* UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm:
(-[WKPlainRemoteLayer description]):

Add a CALayer subclass so we can have a description, similar to WKCompositingView and pals.

(WebKit::RemoteLayerTreeNode::createWithPlainLayer):
(WebKit::RemoteLayerTreeNode::detachFromParent):

Support having null view.

(WebKit::RemoteLayerTreeNode::appendLayerDescription):

Helper for layer descriptions.

* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm:
(WebKit::RemoteLayerTreeHost::makeNode):

Construct plain layers for tiles.

* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(-[WKCompositingView description]):
(-[WKUIRemoteView description]):
(-[WKBackdropView description]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238547 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.h
Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.mm
Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm
Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h
Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm

index 3a2fe4b..197fb25 100644 (file)
@@ -1,3 +1,53 @@
+2018-11-27  Antti Koivisto  <antti@apple.com>
+
+        Remote tile layers shouldn't be UIViews
+        https://bugs.webkit.org/show_bug.cgi?id=191953
+
+        Reviewed by Tim Horton.
+
+        They don't need any UIView functionality, nor do they ever have UIView descendants.
+        We can use lighter weight objects.
+
+        * Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.h:
+        * Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.mm:
+        (WebKit::RemoteLayerTreePropertyApplier::applyProperties):
+        (WebKit::RemoteLayerTreePropertyApplier::updateChildren):
+
+        Factor to a function shared between platforms.
+        Support having both views and plain layers in the same tree.
+        Assert that all siblings are of the same type and that we don't attempt to add views to layers.
+
+        (WebKit::RemoteLayerTreePropertyApplier::applyPropertiesToUIView):
+        * UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm:
+        (WebKit::RemoteLayerTreeHost::makeNode):
+
+        Use new plain layer on Mac too.
+
+        * UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
+        * UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm:
+        (-[WKPlainRemoteLayer description]):
+
+        Add a CALayer subclass so we can have a description, similar to WKCompositingView and pals.
+
+        (WebKit::RemoteLayerTreeNode::createWithPlainLayer):
+        (WebKit::RemoteLayerTreeNode::detachFromParent):
+
+        Support having null view.
+
+        (WebKit::RemoteLayerTreeNode::appendLayerDescription):
+
+        Helper for layer descriptions.
+
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm:
+        (WebKit::RemoteLayerTreeHost::makeNode):
+
+        Construct plain layers for tiles.
+
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
+        (-[WKCompositingView description]):
+        (-[WKUIRemoteView description]):
+        (-[WKBackdropView description]):
+
 2018-11-27  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         Remove "using namespace WebCore" under Source/WebKit/WebProcess/InjectedBundle/API
index 6584a90..761b48c 100644 (file)
@@ -40,6 +40,7 @@ public:
     static void applyPropertiesToLayer(CALayer *, RemoteLayerTreeHost*, const RemoteLayerTreeTransaction::LayerProperties&, RemoteLayerBackingStore::LayerContentsType);
 
 private:
+    static void updateChildren(RemoteLayerTreeNode&, const RemoteLayerTreeTransaction::LayerProperties&, const RelatedLayerMap&);
 #if PLATFORM(IOS_FAMILY)
     static void applyPropertiesToUIView(UIView *, const RemoteLayerTreeTransaction::LayerProperties&, const RelatedLayerMap&);
 #endif
index 202c591..9e97483 100644 (file)
@@ -261,20 +261,11 @@ void RemoteLayerTreePropertyApplier::applyProperties(RemoteLayerTreeNode& node,
     CALayer *layer = node.layer();
 
     applyPropertiesToLayer(layer, layerTreeHost, properties, layerContentsType);
+    updateChildren(node, properties, relatedLayers);
 
 #if PLATFORM(IOS_FAMILY)
     applyPropertiesToUIView(node.uiView(), properties, relatedLayers);
 #else
-    if (properties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
-        RetainPtr<NSMutableArray> children = adoptNS([[NSMutableArray alloc] initWithCapacity:properties.children.size()]);
-        for (auto& child : properties.children) {
-            ASSERT(relatedLayers.contains(child));
-            [children addObject:relatedLayers.get(child)->layer()];
-        }
-
-        layer.sublayers = children.get();
-    }
-
     if (properties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged) {
         if (!properties.maskLayerID)
             layer.mask = nullptr;
@@ -289,25 +280,58 @@ void RemoteLayerTreePropertyApplier::applyProperties(RemoteLayerTreeNode& node,
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-#if PLATFORM(IOS_FAMILY)
-void RemoteLayerTreePropertyApplier::applyPropertiesToUIView(UIView *view, const RemoteLayerTreeTransaction::LayerProperties& properties, const RelatedLayerMap& relatedLayers)
+void RemoteLayerTreePropertyApplier::updateChildren(RemoteLayerTreeNode& node, const RemoteLayerTreeTransaction::LayerProperties& properties, const RelatedLayerMap& relatedLayers)
 {
-    if (properties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
-        RetainPtr<NSMutableArray> children = adoptNS([[NSMutableArray alloc] initWithCapacity:properties.children.size()]);
-        for (auto& child : properties.children) {
-            ASSERT(relatedLayers.contains(child));
-            [children addObject:relatedLayers.get(child)->uiView()];
-        }
+    if (!properties.changedProperties.contains(RemoteLayerTreeTransaction::ChildrenChanged))
+        return;
+
+#if PLATFORM(IOS_FAMILY)
+    auto hasViewChildren = [&] {
+        if (node.uiView() && [[node.uiView() subviews] count])
+            return true;
+        return !properties.children.isEmpty() && relatedLayers.get(properties.children.first())->uiView();
+    };
 
+    auto contentView = [&] {
         if (properties.customAppearance == GraphicsLayer::CustomAppearance::LightBackdrop || properties.customAppearance == GraphicsLayer::CustomAppearance::DarkBackdrop) {
             // This is a UIBackdropView, which should have children attached to
             // its content view, not directly on its layers.
-            [[(_UIBackdropView*)view contentView] _web_setSubviews:children.get()];
-        } else
-            [view _web_setSubviews:children.get()];
+            return [(_UIBackdropView *)node.uiView() contentView];
+        }
+        return node.uiView();
+    };
+
+    if (hasViewChildren()) {
+        ASSERT(node.uiView());
+
+        RetainPtr<NSMutableArray> subviews = adoptNS([[NSMutableArray alloc] initWithCapacity:properties.children.size()]);
+        for (auto& child : properties.children) {
+            auto* childNode = relatedLayers.get(child);
+            ASSERT(childNode->uiView());
+            [subviews addObject:childNode->uiView()];
+        }
+
+        [contentView() _web_setSubviews:subviews.get()];
+        return;
     }
+#endif
 
-    if (properties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged) {
+    RetainPtr<NSMutableArray> sublayers = adoptNS([[NSMutableArray alloc] initWithCapacity:properties.children.size()]);
+    for (auto& child : properties.children) {
+        auto* childNode = relatedLayers.get(child);
+#if PLATFORM(IOS_FAMILY)
+        ASSERT(!childNode->uiView());
+#endif
+        [sublayers addObject:childNode->layer()];
+    }
+
+    node.layer().sublayers = sublayers.get();
+}
+
+#if PLATFORM(IOS_FAMILY)
+void RemoteLayerTreePropertyApplier::applyPropertiesToUIView(UIView *view, const RemoteLayerTreeTransaction::LayerProperties& properties, const RelatedLayerMap& relatedLayers)
+{
+    if (properties.changedProperties.contains(RemoteLayerTreeTransaction::MaskLayerChanged)) {
         CALayer *maskOwnerLayer = view.layer;
 
         if (properties.customAppearance == GraphicsLayer::CustomAppearance::LightBackdrop || properties.customAppearance == GraphicsLayer::CustomAppearance::DarkBackdrop) {
@@ -330,7 +354,6 @@ void RemoteLayerTreePropertyApplier::applyPropertiesToUIView(UIView *view, const
 
     if (properties.changedProperties.containsAny({ RemoteLayerTreeTransaction::ContentsHiddenChanged, RemoteLayerTreeTransaction::UserInteractionEnabledChanged }))
         view.userInteractionEnabled = !properties.contentsHidden && properties.userInteractionEnabled;
-
 }
 #endif
 
index 3f0830a..bc023e9 100644 (file)
@@ -272,7 +272,7 @@ std::unique_ptr<RemoteLayerTreeNode> RemoteLayerTreeHost::makeNode(const RemoteL
     case PlatformCALayer::LayerTypeTiledBackingTileLayer:
     case PlatformCALayer::LayerTypeScrollingLayer:
     case PlatformCALayer::LayerTypeEditableImageLayer:
-        return makeAdoptingLayer([[CALayer alloc] init]);
+        return RemoteLayerTreeNode::createWithPlainLayer(properties.layerID);
 
     case PlatformCALayer::LayerTypeTransformLayer:
         return makeAdoptingLayer([[CATransformLayer alloc] init]);
@@ -284,13 +284,13 @@ std::unique_ptr<RemoteLayerTreeNode> RemoteLayerTreeHost::makeNode(const RemoteL
         return makeAdoptingLayer([[CABackdropLayer alloc] init]);
 #else
         ASSERT_NOT_REACHED();
-        return makeAdoptingLayer([[CALayer alloc] init]);
+        return RemoteLayerTreeNode::createWithPlainLayer(properties.layerID);
 #endif
     case PlatformCALayer::LayerTypeCustom:
     case PlatformCALayer::LayerTypeAVPlayerLayer:
     case PlatformCALayer::LayerTypeContentsProvidedLayer:
         if (m_isDebugLayerTreeHost)
-            return makeAdoptingLayer([[CALayer alloc] init]);
+            return RemoteLayerTreeNode::createWithPlainLayer(properties.layerID);
         return makeWithLayer([CALayer _web_renderLayerWithContextID:properties.hostingContextID]);
 
     case PlatformCALayer::LayerTypeShapeLayer:
index f25141c..88d52b1 100644 (file)
@@ -42,9 +42,10 @@ public:
 #if PLATFORM(IOS_FAMILY)
     RemoteLayerTreeNode(WebCore::GraphicsLayer::PlatformLayerID, RetainPtr<UIView>);
 #endif
-
     ~RemoteLayerTreeNode();
 
+    static std::unique_ptr<RemoteLayerTreeNode> createWithPlainLayer(WebCore::GraphicsLayer::PlatformLayerID);
+
     CALayer *layer() const { return m_layer.get(); }
 #if PLATFORM(IOS_FAMILY)
     UIView *uiView() const { return m_uiView.get(); }
@@ -52,7 +53,8 @@ public:
 
     void detachFromParent();
 
-    static WebCore::GraphicsLayer::PlatformLayerID layerID(CALayer*);
+    static WebCore::GraphicsLayer::PlatformLayerID layerID(CALayer *);
+    static NSString *appendLayerDescription(NSString *description, CALayer *);
 
 private:
     void setLayerID(WebCore::GraphicsLayer::PlatformLayerID);
index 141ac5a..79ebe2d 100644 (file)
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "config.h"
-#include "RemoteLayerTreeNode.h"
+#import "config.h"
+#import "RemoteLayerTreeNode.h"
 
+#import <QuartzCore/CALayer.h>
 #import <WebCore/WebActionDisablingCALayerDelegate.h>
 
+#if PLATFORM(IOS_FAMILY)
+#import <UIKit/UIView.h>
+#endif
+
+@interface WKPlainRemoteLayer : CALayer
+@end
+
+@implementation WKPlainRemoteLayer
+- (NSString *)description
+{
+    return WebKit::RemoteLayerTreeNode::appendLayerDescription(super.description, self);
+}
+@end
+
 namespace WebKit {
 
 RemoteLayerTreeNode::RemoteLayerTreeNode(WebCore::GraphicsLayer::PlatformLayerID layerID, RetainPtr<CALayer> layer)
@@ -48,25 +63,39 @@ RemoteLayerTreeNode::RemoteLayerTreeNode(WebCore::GraphicsLayer::PlatformLayerID
 
 RemoteLayerTreeNode::~RemoteLayerTreeNode() = default;
 
+std::unique_ptr<RemoteLayerTreeNode> RemoteLayerTreeNode::createWithPlainLayer(WebCore::GraphicsLayer::PlatformLayerID layerID)
+{
+    RetainPtr<CALayer> layer = adoptNS([[WKPlainRemoteLayer alloc] init]);
+    return std::make_unique<RemoteLayerTreeNode>(layerID, WTFMove(layer));
+}
+
 void RemoteLayerTreeNode::detachFromParent()
 {
 #if PLATFORM(IOS_FAMILY)
-    [uiView() removeFromSuperview];
-#else
-    [layer() removeFromSuperlayer];
+    if (auto view = uiView()) {
+        [view removeFromSuperview];
+        return;
+    }
 #endif
+    [layer() removeFromSuperlayer];
 }
 
-static NSStringconst WKLayerIDPropertyKey = @"WKLayerID";
+static NSString *const WKLayerIDPropertyKey = @"WKLayerID";
 
 void RemoteLayerTreeNode::setLayerID(WebCore::GraphicsLayer::PlatformLayerID layerID)
 {
     [layer() setValue:@(layerID) forKey:WKLayerIDPropertyKey];
 }
 
-WebCore::GraphicsLayer::PlatformLayerID RemoteLayerTreeNode::layerID(CALayerlayer)
+WebCore::GraphicsLayer::PlatformLayerID RemoteLayerTreeNode::layerID(CALayer *layer)
 {
     return [[layer valueForKey:WKLayerIDPropertyKey] unsignedLongLongValue];
 }
 
+NSString *RemoteLayerTreeNode::appendLayerDescription(NSString *description, CALayer *layer)
+{
+    NSString *layerDescription = [NSString stringWithFormat:@" layerID = %llu \"%@\"", WebKit::RemoteLayerTreeNode::layerID(layer), layer.name ? layer.name : @""];
+    return [description stringByAppendingString:layerDescription];
+}
+
 }
index b7e4e4e..efde315 100644 (file)
@@ -75,9 +75,11 @@ std::unique_ptr<RemoteLayerTreeNode> RemoteLayerTreeHost::makeNode(const RemoteL
     case PlatformCALayer::LayerTypeSimpleLayer:
     case PlatformCALayer::LayerTypeTiledBackingLayer:
     case PlatformCALayer::LayerTypePageTiledBackingLayer:
-    case PlatformCALayer::LayerTypeTiledBackingTileLayer:
         return makeAdoptingView([[WKCompositingView alloc] init]);
 
+    case PlatformCALayer::LayerTypeTiledBackingTileLayer:
+        return RemoteLayerTreeNode::createWithPlainLayer(properties.layerID);
+
     case PlatformCALayer::LayerTypeBackdropLayer:
         return makeAdoptingView([[WKSimpleBackdropView alloc] init]);
 
index a2620da..2f359b0 100644 (file)
@@ -91,9 +91,7 @@
 
 - (NSString *)description
 {
-    NSString *viewDescription = [super description];
-    NSString *webKitDetails = [NSString stringWithFormat:@" layerID = %llu \"%@\"", WebKit::RemoteLayerTreeNode::layerID(self.layer), self.layer.name ? self.layer.name : @""];
-    return [viewDescription stringByAppendingString:webKitDetails];
+    return WebKit::RemoteLayerTreeNode::appendLayerDescription(super.description, self.layer);
 }
 
 @end
 
 - (NSString *)description
 {
-    NSString *viewDescription = [super description];
-    NSString *webKitDetails = [NSString stringWithFormat:@" layerID = %llu \"%@\"", WebKit::RemoteLayerTreeNode::layerID(self.layer), self.layer.name ? self.layer.name : @""];
-    return [viewDescription stringByAppendingString:webKitDetails];
+    return WebKit::RemoteLayerTreeNode::appendLayerDescription(super.description, self.layer);
 }
 
 @end
 
 - (NSString *)description
 {
-    NSString *viewDescription = [super description];
-    NSString *webKitDetails = [NSString stringWithFormat:@" layerID = %llu \"%@\"", WebKit::RemoteLayerTreeNode::layerID(self.layer), self.layer.name ? self.layer.name : @""];
-    return [viewDescription stringByAppendingString:webKitDetails];
+    return WebKit::RemoteLayerTreeNode::appendLayerDescription(super.description, self.layer);
 }
 
 @end