[UI-side compositing] Support reflections on custom layers like video
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Jul 2014 23:44:58 +0000 (23:44 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Jul 2014 23:44:58 +0000 (23:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134701

Reviewed by Tim Horton.

Source/WebCore:

Add a LayerTypeWebGLLayer layer type, and support casting to PlatformCALayerRemoteCustom.

* WebCore.exp.in: Export PlatformCALayerMac::layerTypeForPlatformLayer(CALayer*), and sort.
* platform/graphics/ca/PlatformCALayer.h:
(WebCore::PlatformCALayer::isPlatformCALayerRemoteCustom):
* platform/graphics/ca/mac/PlatformCALayerMac.h:
* platform/graphics/ca/mac/PlatformCALayerMac.mm:
(PlatformCALayerMac::layerTypeForPlatformLayer):
(PlatformCALayerMac::PlatformCALayerMac):
(PlatformCALayerMac::commonInit):

Source/WebKit2:

For video reflections, we have to support cloning of PlatformCALayerRemoteCustom
in the web process. Do so by implementing PlatformCALayerRemoteCustom::clone(),
which does the right gyrations to get AVPlayerLayers cloned, then makes a
new PlatformCALayerRemoteCustom to wrap the new layer. This ends up getting
its own context hosting ID, allowing the clone to show in the UI process.

Attempt to do the same for WebGL, but turn it off because it breaks.

* Shared/mac/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::drawInContext):
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::encode): Unconditionally encode/decode
the hostingContextID. It will be 0 for most layers.
(WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::decode):
(WebKit::RemoteLayerTreeTransaction::description):
* UIProcess/ios/RemoteLayerTreeHostIOS.mm:
(WebKit::RemoteLayerTreeHost::createLayer):
* UIProcess/mac/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::createLayer):
* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(WebKit::PlatformCALayerRemote::create): Creation with a custom PlatformLayer* always
creates a PlatformCALayerRemoteCustom.
(WebKit::PlatformCALayerRemote::clone): Factor some code.
(WebKit::PlatformCALayerRemote::updateClonedLayerProperties):
(WebKit::PlatformCALayerRemote::recursiveBuildTransaction):
* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
* WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.h:
* WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.mm:
(WebKit::PlatformCALayerRemoteCustom::create):
(WebKit::PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom):
(WebKit::PlatformCALayerRemoteCustom::clone): Clone by making an instance of the
correct type of platform layer when possible, then wrapping a PlatformCALayerRemoteCustom
around it.
(WebKit::PlatformCALayerRemoteCustom::contents):
(WebKit::PlatformCALayerRemoteCustom::setContents):
* WebProcess/WebPage/mac/RemoteLayerTreeContext.mm:
(WebKit::RemoteLayerTreeContext::layerWasCreated):
(WebKit::RemoteLayerTreeContext::layerWillBeDestroyed):

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/platform/graphics/ca/PlatformCALayer.h
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm
Source/WebKit2/UIProcess/ios/RemoteLayerTreeHostIOS.mm
Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.h
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.mm
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.mm

index c6f3ef5..735ca79 100644 (file)
@@ -1,5 +1,23 @@
 2014-07-07  Simon Fraser  <simon.fraser@apple.com>
 
+        [UI-side compositing] Support reflections on custom layers like video
+        https://bugs.webkit.org/show_bug.cgi?id=134701
+
+        Reviewed by Tim Horton.
+
+        Add a LayerTypeWebGLLayer layer type, and support casting to PlatformCALayerRemoteCustom.
+
+        * WebCore.exp.in: Export PlatformCALayerMac::layerTypeForPlatformLayer(CALayer*), and sort.
+        * platform/graphics/ca/PlatformCALayer.h:
+        (WebCore::PlatformCALayer::isPlatformCALayerRemoteCustom):
+        * platform/graphics/ca/mac/PlatformCALayerMac.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm:
+        (PlatformCALayerMac::layerTypeForPlatformLayer):
+        (PlatformCALayerMac::PlatformCALayerMac):
+        (PlatformCALayerMac::commonInit):
+
+2014-07-07  Simon Fraser  <simon.fraser@apple.com>
+
         [UI-side compositing] Crash when starting a filter transition on a reflected layer
         https://bugs.webkit.org/show_bug.cgi?id=134694
 
index 91b0424..c6a9fe7 100644 (file)
@@ -158,14 +158,18 @@ __ZN7WebCore11HistoryItem12setURLStringERKN3WTF6StringE
 __ZN7WebCore11HistoryItem12setViewStateEP11objc_object
 __ZN7WebCore11HistoryItem14addRedirectURLERKN3WTF6StringE
 __ZN7WebCore11HistoryItem14setScrollPointERKNS_8IntPointE
+__ZN7WebCore11HistoryItem14setStateObjectEN3WTF10PassRefPtrINS_21SerializedScriptValueEEE
 __ZN7WebCore11HistoryItem15setIsTargetItemEb
 __ZN7WebCore11HistoryItem15setRedirectURLsENSt3__110unique_ptrIN3WTF6VectorINS3_6StringELm0ENS3_15CrashOnOverflowEEENS1_14default_deleteIS7_EEEE
 __ZN7WebCore11HistoryItem16setDocumentStateERKN3WTF6VectorINS1_6StringELm0ENS1_15CrashOnOverflowEEE
 __ZN7WebCore11HistoryItem17setAlternateTitleERKN3WTF6StringE
+__ZN7WebCore11HistoryItem18setFormContentTypeERKN3WTF6StringE
+__ZN7WebCore11HistoryItem18setPageScaleFactorEf
 __ZN7WebCore11HistoryItem20setOriginalURLStringERKN3WTF6StringE
 __ZN7WebCore11HistoryItem20setTransientPropertyERKN3WTF6StringEP11objc_object
 __ZN7WebCore11HistoryItem8formDataEv
 __ZN7WebCore11HistoryItem8setTitleERKN3WTF6StringE
+__ZN7WebCore11HistoryItem9setTargetERKN3WTF6StringE
 __ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_
 __ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_S4_
 __ZN7WebCore11HistoryItemC1ERKNS_3URLERKN3WTF6StringES7_S7_
@@ -595,10 +599,6 @@ __ZN7WebCore15GraphicsLayerCA7setSizeERKNS_9FloatSizeE
 __ZN7WebCore15GraphicsLayerCA8addChildEPNS_13GraphicsLayerE
 __ZN7WebCore15GraphicsLayerCAC2ERNS_19GraphicsLayerClientE
 __ZN7WebCore15GraphicsLayerCAD2Ev
-__ZN7WebCore11HistoryItem14setStateObjectEN3WTF10PassRefPtrINS_21SerializedScriptValueEEE
-__ZN7WebCore11HistoryItem18setFormContentTypeERKN3WTF6StringE
-__ZN7WebCore11HistoryItem18setPageScaleFactorEf
-__ZN7WebCore11HistoryItem9setTargetERKN3WTF6StringE
 __ZN7WebCore15HitTestLocation12rectForPointERKNS_11LayoutPointEjjjj
 __ZN7WebCore15HitTestLocationC1ERKNS_10FloatPointE
 __ZN7WebCore15HitTestLocationD1Ev
@@ -774,6 +774,7 @@ __ZN7WebCore17userVisibleStringEP5NSURL
 __ZN7WebCore18DOMWindowExtensionC1EPNS_5FrameERNS_15DOMWrapperWorldE
 __ZN7WebCore18PlatformCALayerMac18setGeometryFlippedEb
 __ZN7WebCore18PlatformCALayerMac22filtersCanBeCompositedERKNS_16FilterOperationsE
+__ZN7WebCore18PlatformCALayerMac25layerTypeForPlatformLayerEP7CALayer
 __ZN7WebCore18PlatformPasteboard10uniqueNameEv
 __ZN7WebCore18PlatformPasteboard13bufferForTypeERKN3WTF6StringE
 __ZN7WebCore18PlatformPasteboard13stringForTypeERKN3WTF6StringE
@@ -1300,8 +1301,8 @@ __ZN7WebCore8Document8iconURLsEi
 __ZN7WebCore8FormData10appendBlobERKNS_3URLE
 __ZN7WebCore8FormData10appendDataEPKvm
 __ZN7WebCore8FormData15appendFileRangeERKN3WTF6StringExxdb
-__ZN7WebCore8FormData6createEv
 __ZN7WebCore8FormData6createEPKvm
+__ZN7WebCore8FormData6createEv
 __ZN7WebCore8FormDataD1Ev
 __ZN7WebCore8Gradient12addColorStopEfRKNS_5ColorE
 __ZN7WebCore8GradientC1ERKNS_10FloatPointES3_
index 8e874e1..dbfbf83 100644 (file)
@@ -75,6 +75,7 @@ public:
         LayerTypeTiledBackingTileLayer,
         LayerTypeRootLayer,
         LayerTypeAVPlayerLayer,
+        LayerTypeWebGLLayer,
         LayerTypeCustom
     };
     enum FilterType { Linear, Nearest, Trilinear };
@@ -87,6 +88,7 @@ public:
 
     virtual bool isPlatformCALayerMac() const { return false; }
     virtual bool isPlatformCALayerRemote() const { return false; }
+    virtual bool isPlatformCALayerRemoteCustom() const { return false; }
 
     // This function passes the layer as a void* rather than a PlatformLayer because PlatformLayer
     // is defined differently for Obj C and C++. This allows callers from both languages.
index fa2931c..bab1f23 100644 (file)
@@ -40,6 +40,8 @@ public:
     // is defined differently for Obj C and C++. This allows callers from both languages.
     static PassRefPtr<PlatformCALayer> create(void* platformLayer, PlatformCALayerClient*);
 
+    static LayerType layerTypeForPlatformLayer(PlatformLayer*);
+
     ~PlatformCALayerMac();
 
     virtual void setOwner(PlatformCALayerClient*) override;
index 21213ab..9e8ce83 100644 (file)
@@ -42,6 +42,7 @@
 #import "WebActionDisablingCALayerDelegate.h"
 #import "WebCoreCALayerExtras.h"
 #import "WebLayer.h"
+#import "WebGLLayer.h"
 #import "WebTiledBackingLayer.h"
 #import <objc/objc-auto.h>
 #import <objc/runtime.h>
@@ -175,6 +176,17 @@ static NSString *toCAFilterType(PlatformCALayer::FilterType type)
     }
 }
 
+PlatformCALayer::LayerType PlatformCALayerMac::layerTypeForPlatformLayer(PlatformLayer* layer)
+{
+    if ([layer isKindOfClass:getAVPlayerLayerClass()])
+        return LayerTypeAVPlayerLayer;
+
+    if ([layer isKindOfClass:[WebGLLayer class]])
+        return LayerTypeWebGLLayer;
+
+    return LayerTypeCustom;
+}
+
 PlatformCALayerMac::PlatformCALayerMac(LayerType layerType, PlatformCALayerClient* owner)
     : PlatformCALayer(layerType, owner)
     , m_customAppearance(GraphicsLayer::NoCustomAppearance)
@@ -206,6 +218,10 @@ PlatformCALayerMac::PlatformCALayerMac(LayerType layerType, PlatformCALayerClien
     case LayerTypeAVPlayerLayer:
         layerClass = getAVPlayerLayerClass();
         break;
+    case LayerTypeWebGLLayer:
+        // We don't create PlatformCALayerMacs wrapped around WebGLLayers.
+        ASSERT_NOT_REACHED();
+        break;
     case LayerTypeCustom:
         break;
     }
@@ -217,7 +233,7 @@ PlatformCALayerMac::PlatformCALayerMac(LayerType layerType, PlatformCALayerClien
 }
 
 PlatformCALayerMac::PlatformCALayerMac(PlatformLayer* layer, PlatformCALayerClient* owner)
-    : PlatformCALayer([layer isKindOfClass:getAVPlayerLayerClass()] ? LayerTypeAVPlayerLayer : LayerTypeCustom, owner)
+    : PlatformCALayer(layerTypeForPlatformLayer(layer), owner)
     , m_customAppearance(GraphicsLayer::NoCustomAppearance)
     , m_customBehavior(GraphicsLayer::NoCustomBehavior)
 {
@@ -232,7 +248,7 @@ void PlatformCALayerMac::commonInit()
     [m_layer setValue:[NSValue valueWithPointer:this] forKey:platformCALayerPointer];
     
     // Clear all the implicit animations on the CALayer
-    if (m_layerType == LayerTypeAVPlayerLayer || m_layerType == LayerTypeCustom)
+    if (m_layerType == LayerTypeAVPlayerLayer || m_layerType == LayerTypeWebGLLayer || m_layerType == LayerTypeCustom)
         [m_layer web_disableAllActions];
     else
         [m_layer setDelegate:[WebActionDisablingCALayerDelegate shared]];
index 46cdc73..ab6d4a8 100644 (file)
@@ -1,5 +1,51 @@
 2014-07-07  Simon Fraser  <simon.fraser@apple.com>
 
+        [UI-side compositing] Support reflections on custom layers like video
+        https://bugs.webkit.org/show_bug.cgi?id=134701
+
+        Reviewed by Tim Horton.
+        
+        For video reflections, we have to support cloning of PlatformCALayerRemoteCustom
+        in the web process. Do so by implementing PlatformCALayerRemoteCustom::clone(),
+        which does the right gyrations to get AVPlayerLayers cloned, then makes a
+        new PlatformCALayerRemoteCustom to wrap the new layer. This ends up getting
+        its own context hosting ID, allowing the clone to show in the UI process.
+        
+        Attempt to do the same for WebGL, but turn it off because it breaks.
+
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        (WebKit::RemoteLayerBackingStore::drawInContext):
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::encode): Unconditionally encode/decode
+        the hostingContextID. It will be 0 for most layers.
+        (WebKit::RemoteLayerTreeTransaction::LayerCreationProperties::decode):
+        (WebKit::RemoteLayerTreeTransaction::description):
+        * UIProcess/ios/RemoteLayerTreeHostIOS.mm:
+        (WebKit::RemoteLayerTreeHost::createLayer):
+        * UIProcess/mac/RemoteLayerTreeHost.mm:
+        (WebKit::RemoteLayerTreeHost::createLayer):
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (WebKit::PlatformCALayerRemote::create): Creation with a custom PlatformLayer* always
+        creates a PlatformCALayerRemoteCustom.
+        (WebKit::PlatformCALayerRemote::clone): Factor some code.
+        (WebKit::PlatformCALayerRemote::updateClonedLayerProperties):
+        (WebKit::PlatformCALayerRemote::recursiveBuildTransaction):
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        * WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.h:
+        * WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.mm:
+        (WebKit::PlatformCALayerRemoteCustom::create):
+        (WebKit::PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom):
+        (WebKit::PlatformCALayerRemoteCustom::clone): Clone by making an instance of the 
+        correct type of platform layer when possible, then wrapping a PlatformCALayerRemoteCustom
+        around it.
+        (WebKit::PlatformCALayerRemoteCustom::contents):
+        (WebKit::PlatformCALayerRemoteCustom::setContents):
+        * WebProcess/WebPage/mac/RemoteLayerTreeContext.mm:
+        (WebKit::RemoteLayerTreeContext::layerWasCreated):
+        (WebKit::RemoteLayerTreeContext::layerWillBeDestroyed):
+
+2014-07-07  Simon Fraser  <simon.fraser@apple.com>
+
         [UI-side compositing] Crash when starting a filter transition on a reflected layer
         https://bugs.webkit.org/show_bug.cgi?id=134694
 
index 0f0f766..5faa0fd 100644 (file)
@@ -337,6 +337,7 @@ void RemoteLayerBackingStore::drawInContext(GraphicsContext& context, CGImageRef
     case PlatformCALayer::LayerTypePageTiledBackingLayer:
     case PlatformCALayer::LayerTypeRootLayer:
     case PlatformCALayer::LayerTypeAVPlayerLayer:
+    case PlatformCALayer::LayerTypeWebGLLayer:
     case PlatformCALayer::LayerTypeCustom:
         ASSERT_NOT_REACHED();
         break;
index 3f9da8f..d4a764e 100644 (file)
@@ -54,9 +54,7 @@ void RemoteLayerTreeTransaction::LayerCreationProperties::encode(IPC::ArgumentEn
 {
     encoder << layerID;
     encoder.encodeEnum(type);
-
-    if (type == PlatformCALayer::LayerTypeCustom)
-        encoder << hostingContextID;
+    encoder << hostingContextID;
 }
 
 bool RemoteLayerTreeTransaction::LayerCreationProperties::decode(IPC::ArgumentDecoder& decoder, LayerCreationProperties& result)
@@ -67,10 +65,8 @@ bool RemoteLayerTreeTransaction::LayerCreationProperties::decode(IPC::ArgumentDe
     if (!decoder.decodeEnum(result.type))
         return false;
 
-    if (result.type == PlatformCALayer::LayerTypeCustom) {
-        if (!decoder.decode(result.hostingContextID))
-            return false;
-    }
+    if (!decoder.decode(result.hostingContextID))
+        return false;
 
     return true;
 }
@@ -1180,7 +1176,10 @@ CString RemoteLayerTreeTransaction::description() const
                 ts << "root-layer";
                 break;
             case PlatformCALayer::LayerTypeAVPlayerLayer:
-                ts << "av-player-layer";
+                ts << "av-player-layer (context-id " << createdLayer.hostingContextID << ")";
+                break;
+            case PlatformCALayer::LayerTypeWebGLLayer:
+                ts << "web-gl-layer (context-id " << createdLayer.hostingContextID << ")";
                 break;
             case PlatformCALayer::LayerTypeCustom:
                 ts << "custom-layer (context-id " << createdLayer.hostingContextID << ")";
index 981e45f..5f4a411 100644 (file)
@@ -152,6 +152,8 @@ LayerOrView *RemoteLayerTreeHost::createLayer(const RemoteLayerTreeTransaction::
         view = adoptNS([[WKTransformView alloc] init]);
         break;
     case PlatformCALayer::LayerTypeCustom:
+    case PlatformCALayer::LayerTypeAVPlayerLayer:
+    case PlatformCALayer::LayerTypeWebGLLayer:
         if (!m_isDebugLayerTreeHost)
             view = adoptNS([[WKRemoteView alloc] initWithFrame:CGRectZero contextID:properties.hostingContextID]);
         else
index 30625fe..dba6a3f 100644 (file)
@@ -202,6 +202,8 @@ LayerOrView *RemoteLayerTreeHost::createLayer(const RemoteLayerTreeTransaction::
         layer = adoptNS([[CATransformLayer alloc] init]);
         break;
     case PlatformCALayer::LayerTypeCustom:
+    case PlatformCALayer::LayerTypeAVPlayerLayer:
+    case PlatformCALayer::LayerTypeWebGLLayer:
         if (!m_isDebugLayerTreeHost)
             layer = WKMakeRenderLayer(properties.hostingContextID);
         else
index 62c2528..304c191 100644 (file)
@@ -61,11 +61,7 @@ PassRefPtr<PlatformCALayerRemote> PlatformCALayerRemote::create(LayerType layerT
 
 PassRefPtr<PlatformCALayerRemote> PlatformCALayerRemote::create(PlatformLayer *platformLayer, PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
 {
-    RefPtr<PlatformCALayerRemote> layer = adoptRef(new PlatformCALayerRemoteCustom(static_cast<PlatformLayer*>(platformLayer), owner, context));
-
-    context.layerWasCreated(*layer, LayerTypeCustom);
-
-    return layer.release();
+    return PlatformCALayerRemoteCustom::create(platformLayer, owner, context);
 }
 
 PassRefPtr<PlatformCALayerRemote> PlatformCALayerRemote::create(const PlatformCALayerRemote& other, WebCore::PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
@@ -97,31 +93,11 @@ PlatformCALayerRemote::PlatformCALayerRemote(const PlatformCALayerRemote& other,
 {
 }
 
-PassRefPtr<PlatformCALayer> PlatformCALayerRemote::clone(PlatformCALayerClient* client) const
+PassRefPtr<PlatformCALayer> PlatformCALayerRemote::clone(PlatformCALayerClient* owner) const
 {
-    RefPtr<PlatformCALayerRemote> clone = PlatformCALayerRemote::create(*this, client, *m_context);
+    RefPtr<PlatformCALayerRemote> clone = PlatformCALayerRemote::create(*this, owner, *m_context);
 
-    clone->setPosition(position());
-    clone->setBounds(bounds());
-    clone->setAnchorPoint(anchorPoint());
-
-    if (m_properties.transform)
-        clone->setTransform(*m_properties.transform);
-
-    if (m_properties.sublayerTransform)
-        clone->setSublayerTransform(*m_properties.sublayerTransform);
-
-    clone->setContents(contents());
-    clone->setMasksToBounds(masksToBounds());
-    clone->setDoubleSided(isDoubleSided());
-    clone->setOpaque(isOpaque());
-    clone->setBackgroundColor(backgroundColor());
-    clone->setContentsScale(contentsScale());
-#if ENABLE(CSS_FILTERS)
-    if (m_properties.filters)
-        clone->copyFiltersFrom(this);
-#endif
-    clone->updateCustomAppearance(customAppearance());
+    updateClonedLayerProperties(*clone);
 
     clone->setClonedLayer(this);
     return clone.release();
@@ -136,6 +112,33 @@ PlatformCALayerRemote::~PlatformCALayerRemote()
         m_context->layerWillBeDestroyed(*this);
 }
 
+void PlatformCALayerRemote::updateClonedLayerProperties(PlatformCALayerRemote& clone, bool copyContents) const
+{
+    clone.setPosition(position());
+    clone.setBounds(bounds());
+    clone.setAnchorPoint(anchorPoint());
+
+    if (m_properties.transform)
+        clone.setTransform(*m_properties.transform);
+
+    if (m_properties.sublayerTransform)
+        clone.setSublayerTransform(*m_properties.sublayerTransform);
+
+    if (copyContents)
+        clone.setContents(contents());
+
+    clone.setMasksToBounds(masksToBounds());
+    clone.setDoubleSided(isDoubleSided());
+    clone.setOpaque(isOpaque());
+    clone.setBackgroundColor(backgroundColor());
+    clone.setContentsScale(contentsScale());
+#if ENABLE(CSS_FILTERS)
+    if (m_properties.filters)
+        clone.copyFiltersFrom(this);
+#endif
+    clone.updateCustomAppearance(customAppearance());
+}
+
 void PlatformCALayerRemote::recursiveBuildTransaction(RemoteLayerTreeContext& context, RemoteLayerTreeTransaction& transaction)
 {
     ASSERT(!m_properties.backingStore || owner());
@@ -156,7 +159,7 @@ void PlatformCALayerRemote::recursiveBuildTransaction(RemoteLayerTreeContext& co
                 m_properties.children.append(layer->layerID());
         }
 
-        if (m_layerType == LayerTypeCustom) {
+        if (isPlatformCALayerRemoteCustom()) {
             RemoteLayerTreePropertyApplier::applyProperties(platformLayer(), nullptr, m_properties, RemoteLayerTreePropertyApplier::RelatedLayerMap());
             didCommit();
             return;
index aedfad1..86f6fcb 100644 (file)
@@ -171,6 +171,8 @@ protected:
     PlatformCALayerRemote(WebCore::PlatformCALayer::LayerType, WebCore::PlatformCALayerClient* owner, RemoteLayerTreeContext& context);
     PlatformCALayerRemote(const PlatformCALayerRemote&, WebCore::PlatformCALayerClient*, RemoteLayerTreeContext&);
 
+    void updateClonedLayerProperties(PlatformCALayerRemote& clone, bool copyContents = true) const;
+
 private:
     virtual bool isPlatformCALayerRemote() const override { return true; }
     void ensureBackingStore();
index d706097..e6dd22d 100644 (file)
@@ -32,9 +32,12 @@ namespace WebKit {
 
 class LayerHostingContext;
 
+// PlatformCALayerRemoteCustom is used for CALayers that live in the web process and are hosted into the UI process via remote context.
 class PlatformCALayerRemoteCustom final : public PlatformCALayerRemote {
     friend class PlatformCALayerRemote;
 public:
+    static PassRefPtr<PlatformCALayerRemote> create(PlatformLayer *, WebCore::PlatformCALayerClient*, RemoteLayerTreeContext&);
+
     virtual ~PlatformCALayerRemoteCustom();
 
     virtual PlatformLayer* platformLayer() const override { return m_platformLayer.get(); }
@@ -44,13 +47,22 @@ public:
     virtual void setNeedsDisplay(const WebCore::FloatRect* dirtyRect = 0) override;
 
 private:
-    PlatformCALayerRemoteCustom(PlatformLayer*, WebCore::PlatformCALayerClient* owner, RemoteLayerTreeContext&);
+    PlatformCALayerRemoteCustom(WebCore::PlatformCALayer::LayerType, PlatformLayer *, WebCore::PlatformCALayerClient* owner, RemoteLayerTreeContext&);
+
+    virtual PassRefPtr<WebCore::PlatformCALayer> clone(WebCore::PlatformCALayerClient* owner) const override;
+
+    virtual bool isPlatformCALayerRemoteCustom() const { return true; }
+
+    virtual CFTypeRef contents() const override;
+    virtual void setContents(CFTypeRef) override;
 
     std::unique_ptr<LayerHostingContext> m_layerHostingContext;
     RetainPtr<PlatformLayer> m_platformLayer;
     bool m_providesContents;
 };
 
+PLATFORM_CALAYER_TYPE_CASTS(PlatformCALayerRemoteCustom, isPlatformCALayerRemote())
+
 } // namespace WebKit
 
 #endif // PlatformCALayerRemoteCustom_h
index 80b3e32..c0cb922 100644 (file)
 #import "RemoteLayerTreeContext.h"
 #import "RemoteLayerTreePropertyApplier.h"
 #import "WebProcess.h"
+#import <AVFoundation/AVFoundation.h>
 #import <WebCore/GraphicsLayerCA.h>
 #import <WebCore/PlatformCALayerMac.h>
 #import <WebCore/SoftLinking.h>
 #import <WebCore/WebCoreCALayerExtras.h>
 #import <wtf/RetainPtr.h>
 
+SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
+SOFT_LINK_CLASS(AVFoundation, AVPlayerLayer)
+
 using namespace WebCore;
 
 namespace WebKit {
 
 static NSString * const platformCALayerPointer = @"WKPlatformCALayer";
-PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom(PlatformLayer* customLayer, PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
-    : PlatformCALayerRemote(LayerTypeCustom, owner, context)
+
+PassRefPtr<PlatformCALayerRemote> PlatformCALayerRemoteCustom::create(PlatformLayer *platformLayer, PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
+{
+    RefPtr<PlatformCALayerRemote> layer = adoptRef(new PlatformCALayerRemoteCustom(PlatformCALayerMac::layerTypeForPlatformLayer(platformLayer), platformLayer, owner, context));
+    context.layerWasCreated(*layer, layer->layerType());
+
+    return layer.release();
+}
+
+PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom(LayerType layerType, PlatformLayer * customLayer, PlatformCALayerClient* owner, RemoteLayerTreeContext& context)
+    : PlatformCALayerRemote(layerType, owner, context)
 {
     switch (context.layerHostingMode()) {
     case LayerHostingMode::InProcess:
@@ -61,7 +74,7 @@ PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom(PlatformLayer* customLa
     m_platformLayer = customLayer;
     [customLayer web_disableAllActions];
 
-    m_providesContents = [customLayer isKindOfClass:NSClassFromString(@"WebGLLayer")];
+    m_providesContents = layerType == LayerTypeWebGLLayer;
 
     properties().position = FloatPoint3D(customLayer.position.x, customLayer.position.y, customLayer.zPosition);
     properties().anchorPoint = FloatPoint3D(customLayer.anchorPoint.x, customLayer.anchorPoint.y, customLayer.anchorPointZ);
@@ -79,6 +92,45 @@ uint32_t PlatformCALayerRemoteCustom::hostingContextID()
     return m_layerHostingContext->contextID();
 }
 
+PassRefPtr<WebCore::PlatformCALayer> PlatformCALayerRemoteCustom::clone(PlatformCALayerClient* owner) const
+{
+    RetainPtr<CALayer *> clonedLayer;
+    bool copyContents = true;
+
+    if (layerType() == LayerTypeAVPlayerLayer) {
+        clonedLayer = adoptNS([[getAVPlayerLayerClass() alloc] init]);
+
+        AVPlayerLayer* destinationPlayerLayer = static_cast<AVPlayerLayer *>(clonedLayer.get());
+        AVPlayerLayer* sourcePlayerLayer = static_cast<AVPlayerLayer *>(platformLayer());
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [destinationPlayerLayer setPlayer:[sourcePlayerLayer player]];
+        });
+        copyContents = false;
+    } else if (layerType() == LayerTypeWebGLLayer) {
+        clonedLayer = adoptNS([[CALayer alloc] init]);
+        // FIXME: currently copying WebGL contents breaks the original layer.
+        copyContents = false;
+    }
+
+    RefPtr<PlatformCALayerRemote> clone = adoptRef(new PlatformCALayerRemoteCustom(layerType(), clonedLayer.get(), owner, *context()));
+    context()->layerWasCreated(*clone, clone->layerType());
+
+    updateClonedLayerProperties(*clone, copyContents);
+
+    clone->setClonedLayer(this);
+    return clone.release();
+}
+
+CFTypeRef PlatformCALayerRemoteCustom::contents() const
+{
+    return [m_platformLayer contents];
+}
+
+void PlatformCALayerRemoteCustom::setContents(CFTypeRef contents)
+{
+    [m_platformLayer setContents:(id)contents];
+}
+
 void PlatformCALayerRemoteCustom::setNeedsDisplay(const FloatRect* rect)
 {
     if (m_providesContents) {
index 988fc3a..ebd3ff2 100644 (file)
@@ -61,7 +61,7 @@ void RemoteLayerTreeContext::layerWasCreated(PlatformCALayerRemote& layer, Platf
     creationProperties.layerID = layerID;
     creationProperties.type = type;
 
-    if (type == PlatformCALayer::LayerTypeCustom)
+    if (layer.isPlatformCALayerRemoteCustom())
         creationProperties.hostingContextID = layer.hostingContextID();
 
     m_createdLayers.append(creationProperties);
@@ -70,6 +70,7 @@ void RemoteLayerTreeContext::layerWasCreated(PlatformCALayerRemote& layer, Platf
 
 void RemoteLayerTreeContext::layerWillBeDestroyed(PlatformCALayerRemote& layer)
 {
+    ASSERT(layer.layerID());
     GraphicsLayer::PlatformLayerID layerID = layer.layerID();
 
     m_liveLayers.remove(layerID);