Title: [187044] trunk/Source
Revision
187044
Author
commit-qu...@webkit.org
Date
2015-07-20 16:27:49 -0700 (Mon, 20 Jul 2015)

Log Message

Adopt AVPlayerLayerView
https://bugs.webkit.org/show_bug.cgi?id=146862

Patch by Jeremy Jones <jere...@apple.com> on 2015-07-20
Source/WebCore:

Reviewed by Jer Noble.

The CALayerHost is replaced with WebLayerHostView to be compatible with UIView animations.
Some animation is improved in the conversion.

WebAVPlayerLayerView and WebAVPictureInPicturePlayerLayerView derive from AVKit and UIKit respectively.
Because these frameworks are loaded at runtime, these classes must be generate using objc/runtime.h to
register them from c functions at runtime. The most important part of these UIViews is that their
backing layer is a WebAVPlayerLayer.

WebCALayerHostWrapper and WebAVVideoLayer are combined into WebAVPlayerLayer to simplify the hierarchy.
WebAVPlayerLayer is a stand-in for an AVPlayerLayer.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer): -removeFromSuperlayer is redundant.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenGravity): syncTextTrackBounds on change.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenFrame):
We never want animation here, since all animation will happen in UIViews.
This is just for going into the final size after a transform based animation.

* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(WebVideoFullscreenControllerContext::didSetupFullscreen): layer -> view
(WebVideoFullscreenControllerContext::didCleanupFullscreen): layer -> view
(WebVideoFullscreenControllerContext::setUpFullscreen): layer -> view

(WebVideoFullscreenControllerContext::setVideoLayerFrame): layer -> view
Use fence port to synchronize between the UIThread and the WebThread,
the same way WebKit2 uses a fence port to synchronize between processes.

(WebVideoFullscreenControllerContext::setVideoLayerGravity):
No longer necessary to cache videoGravity at this level.

* platform/ios/WebVideoFullscreenInterfaceAVKit.h:
* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:

(-[WebAVPlayerLayer init]):
(-[WebAVPlayerLayer dealloc]):
(-[WebAVPlayerLayer playerController]):
(-[WebAVPlayerLayer setBounds:]):
(-[WebAVPlayerLayer resolveBounds]):
(-[WebAVPlayerLayer setVideoGravity:]):
(-[WebAVPlayerLayer videoGravity]):
(-[WebAVPlayerLayer videoRect]):
(+[WebAVPlayerLayer keyPathsForValuesAffectingVideoRect]):
Added class WebAVPlayerLayer, replacing WebAVVideoLayer and WebCALayerHostWrapper.

(WebAVPictureInPicturePlayerLayerView_layerClass):
(getWebAVPictureInPicturePlayerLayerViewClass):
Added runtime class WebAVPictureInPicturePlayerLayerView

(WebAVPlayerLayerView_layerClass):
(WebAVPlayerLayerView_playerController):
(WebAVPlayerLayerView_setPlayerController):
(WebAVPlayerLayerView_videoView):
(WebAVPlayerLayerView_setVideoView):
(WebAVPlayerLayerView_startRoutingVideoToPictureInPicturePlayerLayerView):
(WebAVPlayerLayerView_stopRoutingVideoToPictureInPicturePlayerLayerView):
(WebAVPlayerLayerView_pictureInPicturePlayerLayerView):
(getWebAVPlayerLayerViewClass):
Added runtime class WebAVPlayerLayerView

(WebVideoFullscreenInterfaceAVKit::setVideoDimensions):
Dimensions are also stored in WebAVPlayerLayer so it can make decisions about
animating the video layer.

(WebVideoFullscreenInterfaceAVKit::setExternalPlayback):
(WebVideoFullscreenInterfaceAVKit::enterFullscreen):
(WebVideoFullscreenInterfaceAVKit::didStopPictureInPicture):
(WebVideoFullscreenInterfaceAVKit::cleanupFullscreen):
Straightforward layer to view conversion.

(WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline):
Set view frame using the view hierarchy instead of assuming it is directly in a window.

(WebVideoFullscreenInterfaceAVKit::exitFullscreen):
Set view frame using the view hierarchy instead of assuming it is directly in a window.
dispatch_async before calling didExitFullscreen() to allows CATransactions to complete.

(WebVideoFullscreenInterfaceAVKit::setupFullscreen):
Set view frame using the view hierarchy instead of assuming it is directly in a window.
dispatch_async before calling didSetupFullscreen() to allows CATransactions to complete.

(-[WebCALayerHostWrapper dealloc]): Deleted.
(-[WebCALayerHostWrapper setVideoSublayer:]): Deleted.
(-[WebCALayerHostWrapper videoSublayer]): Deleted.
(-[WebCALayerHostWrapper setBounds:]): Deleted.
(-[WebCALayerHostWrapper resolveBounds]): Deleted.
Class WebCALayerHostWrapper deleted. Functionality rolled into WebAVPlayerLayer.

(+[WebAVVideoLayer videoLayer]): Deleted.
(-[WebAVVideoLayer init]): Deleted.
(-[WebAVVideoLayer setPlayerViewController:]): Deleted.
(-[WebAVVideoLayer setVideoSublayer:]): Deleted.
(-[WebAVVideoLayer setBounds:]): Deleted.
(-[WebAVVideoLayer setVideoLayerGravity:]): Deleted.
(-[WebAVVideoLayer videoLayerGravity]): Deleted.
(-[WebAVVideoLayer enterPIPModeRedirectingVideoToLayer:]): Deleted.
(-[WebAVVideoLayer leavePIPMode]): Deleted.
Class WebAVVideoLayer deleted. Functionality rolled into WebAVPlayerLayer.

* platform/ios/WebVideoFullscreenModel.h:
* platform/ios/WebVideoFullscreenModelVideoElement.h:
* platform/ios/WebVideoFullscreenModelVideoElement.mm:
No need to store frame and gravity in the model. It is stored in the UI where it is used.

(WebVideoFullscreenModelVideoElement::videoLayerFrame): Deleted.
(WebVideoFullscreenModelVideoElement::videoLayerGravity): Deleted.
* platform/spi/cocoa/AVKitSPI.h: Add AVPlayerLayerView.

Source/WebKit2:

Reviewed by Simon Fraser.

The CALayerHost is replaced with WebLayerHostView to be compatible with UIView animations.
videoLayerFrame and videoLayerGravity no longer need to be stored because they are stored
where they are used in the interface. Some animation is improved in the conversion.

* UIProcess/ios/WebVideoFullscreenManagerProxy.h:
* UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
(+[WebLayerHostView layerClass]): Add class WebLayerHostView.
(-[WebLayerHostView contextID]):
(-[WebLayerHostView setContextID:]):
(-[WebLayerHostView layerHost]):
(WebKit::WebVideoFullscreenManagerProxy::invalidate): layer -> view
(WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID):
Apply the hostingDeviceScaleFactor transform to -sublayerTransform instead of to
-transform. This more directly inverts the tranform WebProcess and allows -transform
to be used for animation in the UIProcess. This is important because UIView's actions
animate -transform, but not -sublayerTrasform.

(WebKit::WebVideoFullscreenManagerProxy::didCleanupFullscreen): layer -> view
(WebKit::WebVideoFullscreenModelContext::setVideoLayerFrame): Deleted.
(WebKit::WebVideoFullscreenModelContext::videoLayerFrame): Deleted.
(WebKit::WebVideoFullscreenModelContext::setVideoLayerGravity): Deleted.
(WebKit::WebVideoFullscreenModelContext::videoLayerGravity): Deleted.
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::enterVideoFullscreenForVideoElement):
Set initial video layer frame to fix start point of animation.

(WebKit::WebVideoFullscreenManager::didSetupFullscreen):
dispatch_async allows the CATransaction to complete before continuing with the animation.
This prevents a flash during animation.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (187043 => 187044)


--- trunk/Source/WebCore/ChangeLog	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/ChangeLog	2015-07-20 23:27:49 UTC (rev 187044)
@@ -1,3 +1,117 @@
+2015-07-20  Jeremy Jones  <jere...@apple.com>
+
+        Adopt AVPlayerLayerView
+        https://bugs.webkit.org/show_bug.cgi?id=146862
+
+        Reviewed by Jer Noble.
+
+        The CALayerHost is replaced with WebLayerHostView to be compatible with UIView animations.
+        Some animation is improved in the conversion.
+
+        WebAVPlayerLayerView and WebAVPictureInPicturePlayerLayerView derive from AVKit and UIKit respectively.
+        Because these frameworks are loaded at runtime, these classes must be generate using objc/runtime.h to
+        register them from c functions at runtime. The most important part of these UIViews is that their
+        backing layer is a WebAVPlayerLayer.
+
+        WebCALayerHostWrapper and WebAVVideoLayer are combined into WebAVPlayerLayer to simplify the hierarchy.
+        WebAVPlayerLayer is a stand-in for an AVPlayerLayer.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer): -removeFromSuperlayer is redundant.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenGravity): syncTextTrackBounds on change.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenFrame):
+        We never want animation here, since all animation will happen in UIViews. 
+        This is just for going into the final size after a transform based animation.
+
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (WebVideoFullscreenControllerContext::didSetupFullscreen): layer -> view
+        (WebVideoFullscreenControllerContext::didCleanupFullscreen): layer -> view
+        (WebVideoFullscreenControllerContext::setUpFullscreen): layer -> view
+
+        (WebVideoFullscreenControllerContext::setVideoLayerFrame): layer -> view
+        Use fence port to synchronize between the UIThread and the WebThread,
+        the same way WebKit2 uses a fence port to synchronize between processes.
+
+        (WebVideoFullscreenControllerContext::setVideoLayerGravity):
+        No longer necessary to cache videoGravity at this level.
+
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.h:
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+
+        (-[WebAVPlayerLayer init]):
+        (-[WebAVPlayerLayer dealloc]):
+        (-[WebAVPlayerLayer playerController]):
+        (-[WebAVPlayerLayer setBounds:]):
+        (-[WebAVPlayerLayer resolveBounds]):
+        (-[WebAVPlayerLayer setVideoGravity:]):
+        (-[WebAVPlayerLayer videoGravity]):
+        (-[WebAVPlayerLayer videoRect]):
+        (+[WebAVPlayerLayer keyPathsForValuesAffectingVideoRect]):
+        Added class WebAVPlayerLayer, replacing WebAVVideoLayer and WebCALayerHostWrapper.
+
+        (WebAVPictureInPicturePlayerLayerView_layerClass):
+        (getWebAVPictureInPicturePlayerLayerViewClass):
+        Added runtime class WebAVPictureInPicturePlayerLayerView
+
+        (WebAVPlayerLayerView_layerClass):
+        (WebAVPlayerLayerView_playerController):
+        (WebAVPlayerLayerView_setPlayerController):
+        (WebAVPlayerLayerView_videoView):
+        (WebAVPlayerLayerView_setVideoView):
+        (WebAVPlayerLayerView_startRoutingVideoToPictureInPicturePlayerLayerView):
+        (WebAVPlayerLayerView_stopRoutingVideoToPictureInPicturePlayerLayerView):
+        (WebAVPlayerLayerView_pictureInPicturePlayerLayerView):
+        (getWebAVPlayerLayerViewClass):
+        Added runtime class WebAVPlayerLayerView
+
+        (WebVideoFullscreenInterfaceAVKit::setVideoDimensions):
+        Dimensions are also stored in WebAVPlayerLayer so it can make decisions about
+        animating the video layer.
+
+        (WebVideoFullscreenInterfaceAVKit::setExternalPlayback):
+        (WebVideoFullscreenInterfaceAVKit::enterFullscreen): 
+        (WebVideoFullscreenInterfaceAVKit::didStopPictureInPicture):
+        (WebVideoFullscreenInterfaceAVKit::cleanupFullscreen):
+        Straightforward layer to view conversion.
+
+        (WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline):
+        Set view frame using the view hierarchy instead of assuming it is directly in a window.
+
+        (WebVideoFullscreenInterfaceAVKit::exitFullscreen):
+        Set view frame using the view hierarchy instead of assuming it is directly in a window.
+        dispatch_async before calling didExitFullscreen() to allows CATransactions to complete.
+
+        (WebVideoFullscreenInterfaceAVKit::setupFullscreen):
+        Set view frame using the view hierarchy instead of assuming it is directly in a window.
+        dispatch_async before calling didSetupFullscreen() to allows CATransactions to complete.
+
+        (-[WebCALayerHostWrapper dealloc]): Deleted.
+        (-[WebCALayerHostWrapper setVideoSublayer:]): Deleted.
+        (-[WebCALayerHostWrapper videoSublayer]): Deleted.
+        (-[WebCALayerHostWrapper setBounds:]): Deleted.
+        (-[WebCALayerHostWrapper resolveBounds]): Deleted.
+        Class WebCALayerHostWrapper deleted. Functionality rolled into WebAVPlayerLayer.
+
+        (+[WebAVVideoLayer videoLayer]): Deleted.
+        (-[WebAVVideoLayer init]): Deleted.
+        (-[WebAVVideoLayer setPlayerViewController:]): Deleted.
+        (-[WebAVVideoLayer setVideoSublayer:]): Deleted.
+        (-[WebAVVideoLayer setBounds:]): Deleted.
+        (-[WebAVVideoLayer setVideoLayerGravity:]): Deleted.
+        (-[WebAVVideoLayer videoLayerGravity]): Deleted.
+        (-[WebAVVideoLayer enterPIPModeRedirectingVideoToLayer:]): Deleted.
+        (-[WebAVVideoLayer leavePIPMode]): Deleted.
+        Class WebAVVideoLayer deleted. Functionality rolled into WebAVPlayerLayer.
+
+        * platform/ios/WebVideoFullscreenModel.h:
+        * platform/ios/WebVideoFullscreenModelVideoElement.h:
+        * platform/ios/WebVideoFullscreenModelVideoElement.mm:
+        No need to store frame and gravity in the model. It is stored in the UI where it is used.
+
+        (WebVideoFullscreenModelVideoElement::videoLayerFrame): Deleted.
+        (WebVideoFullscreenModelVideoElement::videoLayerGravity): Deleted.
+        * platform/spi/cocoa/AVKitSPI.h: Add AVPlayerLayerView.
+
 2015-07-20  Anders Carlsson  <ander...@apple.com>
 
         Add PLATFORM #ifdefs for Mac SPI headers

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (187043 => 187044)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2015-07-20 23:27:49 UTC (rev 187044)
@@ -1124,9 +1124,8 @@
     CAContext *newContext = nil;
     
     if (m_videoFullscreenLayer && m_videoLayer) {
-        [m_videoLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
-        [m_videoLayer removeFromSuperlayer];
         [m_videoFullscreenLayer insertSublayer:m_videoLayer.get() atIndex:0];
+        [m_videoLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
         newContext = [m_videoFullscreenLayer context];
     } else if (m_videoInlineLayer && m_videoLayer) {
         [m_videoLayer setFrame:[m_videoInlineLayer bounds]];
@@ -1158,11 +1157,7 @@
         return;
 
     if (m_videoLayer) {
-        [m_videoLayer setStyle:nil]; // This enables actions, i.e. implicit animations.
-        [CATransaction begin];
         [m_videoLayer setFrame:CGRectMake(0, 0, frame.width(), frame.height())];
-        [CATransaction commit];
-        [m_videoLayer web_disableAllActions];
     }
     syncTextTrackBounds();
 }
@@ -1182,8 +1177,12 @@
         videoGravity = AVLayerVideoGravityResizeAspectFill;
     else
         ASSERT_NOT_REACHED();
+    
+    if ([m_videoLayer videoGravity] == videoGravity)
+        return;
 
     [m_videoLayer setVideoGravity:videoGravity];
+    syncTextTrackBounds();
 }
 
 void MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenMode(MediaPlayer::VideoFullscreenMode mode)

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (187043 => 187044)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2015-07-20 23:27:49 UTC (rev 187044)
@@ -30,6 +30,8 @@
 #import "WebVideoFullscreenControllerAVKit.h"
 
 #import "Logging.h"
+#import "QuartzCoreSPI.h"
+#import "SoftLinking.h"
 #import "TimeRanges.h"
 #import "WebVideoFullscreenInterfaceAVKit.h"
 #import "WebVideoFullscreenModelVideoElement.h"
@@ -37,6 +39,9 @@
 #import <WebCore/HTMLVideoElement.h>
 #import <WebCore/WebCoreThreadRun.h>
 
+SOFT_LINK_FRAMEWORK(UIKit)
+SOFT_LINK_CLASS(UIKit, UIView)
+
 using namespace WebCore;
 
 #if __IPHONE_OS_VERSION_MIN_REQUIRED <= 80200 || !HAVE(AVKIT)
@@ -129,9 +134,7 @@
     virtual void endScanning() override;
     virtual void requestExitFullscreen() override;
     virtual void setVideoLayerFrame(FloatRect) override;
-    virtual FloatRect videoLayerFrame() const override { return m_frame; }
     virtual void setVideoLayerGravity(WebVideoFullscreenModel::VideoGravity) override;
-    virtual VideoGravity videoLayerGravity() const override { return m_gravity; }
     virtual void selectAudioMediaOption(uint64_t index) override;
     virtual void selectLegibleMediaOption(uint64_t index) override;
     virtual void fullscreenModeChanged(HTMLMediaElementEnums::VideoFullscreenMode) override;
@@ -139,10 +142,8 @@
     RefPtr<WebVideoFullscreenInterfaceAVKit> m_interface;
     RefPtr<WebVideoFullscreenModelVideoElement> m_model;
     RefPtr<HTMLVideoElement> m_videoElement;
-    RetainPtr<PlatformLayer> m_videoFullscreenLayer;
+    RetainPtr<UIView> m_videoFullscreenView;
     RetainPtr<WebVideoFullscreenController> m_controller;
-    FloatRect m_frame;
-    VideoGravity m_gravity;
 };
 
 #pragma mark WebVideoFullscreenChangeObserver
@@ -151,8 +152,9 @@
 {
     ASSERT(isUIThread());
     RefPtr<WebVideoFullscreenControllerContext> strongThis(this);
-    WebThreadRun([strongThis, this] {
-        m_model->setVideoFullscreenLayer(m_videoFullscreenLayer.get());
+    RetainPtr<CALayer> videoFullscreenLayer = [m_videoFullscreenView layer];
+    WebThreadRun([strongThis, this, videoFullscreenLayer] {
+        m_model->setVideoFullscreenLayer(videoFullscreenLayer.get());
         dispatch_async(dispatch_get_main_queue(), [strongThis, this] {
             m_interface->enterFullscreen();
         });
@@ -177,6 +179,7 @@
     m_interface->setWebVideoFullscreenModel(nullptr);
     m_interface->setWebVideoFullscreenChangeObserver(nullptr);
     m_interface = nullptr;
+    m_videoFullscreenView = nil;
     
     RefPtr<WebVideoFullscreenControllerContext> strongThis(this);
     WebThreadRun([strongThis, this] {
@@ -185,7 +188,6 @@
         m_model->setVideoElement(nullptr);
         m_model = nullptr;
         m_videoElement = nullptr;
-        m_videoFullscreenLayer = nil;
         
         [m_controller didFinishFullscreen:this];
     });
@@ -450,18 +452,25 @@
 void WebVideoFullscreenControllerContext::setVideoLayerFrame(FloatRect frame)
 {
     ASSERT(isUIThread());
-    m_frame = frame;
     RefPtr<WebVideoFullscreenControllerContext> strongThis(this);
-    WebThreadRun([strongThis, this, frame] {
+    RetainPtr<CALayer> videoFullscreenLayer = [m_videoFullscreenView layer];
+
+    mach_port_name_t fencePort = [[videoFullscreenLayer context] createFencePort];
+    
+    WebThreadRun([strongThis, this, frame, fencePort, videoFullscreenLayer] {
+        [CATransaction begin];
+        [CATransaction setAnimationDuration:0];
         if (m_model)
             m_model->setVideoLayerFrame(frame);
+        [[videoFullscreenLayer context] setFencePort:fencePort];
+        mach_port_deallocate(mach_task_self(), fencePort);
+        [CATransaction commit];
     });
 }
 
 void WebVideoFullscreenControllerContext::setVideoLayerGravity(WebVideoFullscreenModel::VideoGravity videoGravity)
 {
     ASSERT(isUIThread());
-    m_gravity = videoGravity;
     RefPtr<WebVideoFullscreenControllerContext> strongThis(this);
     WebThreadRun([strongThis, this, videoGravity] {
         if (m_model)
@@ -510,19 +519,19 @@
     m_interface = WebVideoFullscreenInterfaceAVKit::create();
     m_interface->setWebVideoFullscreenChangeObserver(this);
     m_interface->setWebVideoFullscreenModel(this);
+    m_videoFullscreenView = adoptNS([[getUIViewClass() alloc] init]);
     
     RefPtr<WebVideoFullscreenControllerContext> strongThis(this);
     WebThreadRun([strongThis, this, viewRef, mode] {
         m_model = WebVideoFullscreenModelVideoElement::create();
         m_model->setWebVideoFullscreenInterface(this);
         m_model->setVideoElement(m_videoElement.get());
-        m_videoFullscreenLayer = [CALayer layer];
         
         bool allowsPictureInPicture = m_videoElement->mediaSession().allowsPictureInPicture(*m_videoElement.get());
         IntRect videoElementClientRect = m_videoElement->clientRect();
         
         dispatch_async(dispatch_get_main_queue(), [strongThis, this, videoElementClientRect, viewRef, mode, allowsPictureInPicture] {
-            m_interface->setupFullscreen(*m_videoFullscreenLayer.get(), videoElementClientRect, viewRef.get(), mode, allowsPictureInPicture);
+            m_interface->setupFullscreen(*m_videoFullscreenView.get(), videoElementClientRect, viewRef.get(), mode, allowsPictureInPicture);
         });
     });
 }

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h (187043 => 187044)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h	2015-07-20 23:27:49 UTC (rev 187044)
@@ -45,8 +45,8 @@
 OBJC_CLASS UIWindow;
 OBJC_CLASS UIView;
 OBJC_CLASS CALayer;
-OBJC_CLASS WebAVVideoLayer;
-OBJC_CLASS WebCALayerHostWrapper;
+OBJC_CLASS WebAVPlayerLayerView;
+OBJC_CLASS WebAVPlayerLayer;
 
 namespace WTF {
 class String;
@@ -91,7 +91,7 @@
     WEBCORE_EXPORT virtual void setLegibleMediaSelectionOptions(const Vector<WTF::String>& options, uint64_t selectedIndex) override;
     WEBCORE_EXPORT virtual void setExternalPlayback(bool enabled, ExternalPlaybackTargetType, WTF::String localizedDeviceName) override;
     
-    WEBCORE_EXPORT virtual void setupFullscreen(PlatformLayer&, const IntRect& initialRect, UIView *, HTMLMediaElementEnums::VideoFullscreenMode, bool allowsPictureInPicturePlayback);
+    WEBCORE_EXPORT virtual void setupFullscreen(UIView&, const IntRect& initialRect, UIView *, HTMLMediaElementEnums::VideoFullscreenMode, bool allowsPictureInPicturePlayback);
     WEBCORE_EXPORT virtual void enterFullscreen();
     WEBCORE_EXPORT virtual void exitFullscreen(const IntRect& finalRect);
     WEBCORE_EXPORT virtual void cleanupFullscreen();
@@ -133,9 +133,6 @@
 
     RetainPtr<WebAVPlayerController> m_playerController;
     RetainPtr<AVPlayerViewController> m_playerViewController;
-    RetainPtr<CALayer> m_videoLayer;
-    RetainPtr<WebAVVideoLayer> m_videoLayerContainer;
-    RetainPtr<WebCALayerHostWrapper> m_layerHostWrapper;
     WebVideoFullscreenModel* m_videoFullscreenModel { nullptr };
     WebVideoFullscreenChangeObserver* m_fullscreenChangeObserver { nullptr };
 
@@ -144,6 +141,7 @@
     RetainPtr<UIViewController> m_viewController;
     RetainPtr<UIView> m_parentView;
     RetainPtr<UIWindow> m_parentWindow;
+    RetainPtr<WebAVPlayerLayerView> m_playerLayerView;
     HTMLMediaElementEnums::VideoFullscreenMode m_mode { HTMLMediaElementEnums::VideoFullscreenModeNone };
     std::function<void(bool)> m_prepareToInlineCallback;
     bool m_allowsPictureInPicturePlayback { false };

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm (187043 => 187044)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm	2015-07-20 23:27:49 UTC (rev 187044)
@@ -39,6 +39,8 @@
 #import "WebVideoFullscreenModel.h"
 #import <AVFoundation/AVTime.h>
 #import <UIKit/UIKit.h>
+#import <objc/message.h>
+#import <objc/runtime.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/text/CString.h>
 #import <wtf/text/WTFString.h>
@@ -50,11 +52,16 @@
 
 SOFT_LINK_FRAMEWORK(AVFoundation)
 SOFT_LINK_CLASS(AVFoundation, AVPlayerLayer)
+SOFT_LINK_CONSTANT(AVFoundation, AVLayerVideoGravityResize, NSString *)
+SOFT_LINK_CONSTANT(AVFoundation, AVLayerVideoGravityResizeAspect, NSString *)
+SOFT_LINK_CONSTANT(AVFoundation, AVLayerVideoGravityResizeAspectFill, NSString *)
 
 SOFT_LINK_FRAMEWORK(AVKit)
 SOFT_LINK_CLASS(AVKit, AVPlayerController)
 SOFT_LINK_CLASS(AVKit, AVPlayerViewController)
 SOFT_LINK_CLASS(AVKit, AVValueTiming)
+SOFT_LINK_CLASS(AVKit, AVPlayerLayerView)
+SOFT_LINK_CLASS(AVKit, AVPictureInPicturePlayerLayerView)
 
 SOFT_LINK_FRAMEWORK(UIKit)
 SOFT_LINK_CLASS(UIKit, UIApplication)
@@ -74,13 +81,12 @@
 
 @class WebAVMediaSelectionOption;
 
-@interface WebAVPlayerController : NSObject <AVPlayerViewControllerDelegate>
-{
+@interface WebAVPlayerController : NSObject <AVPlayerViewControllerDelegate> {
     WebAVMediaSelectionOption *_currentAudioMediaSelectionOption;
     WebAVMediaSelectionOption *_currentLegibleMediaSelectionOption;
 }
 
--(void)resetState;
+- (void)resetState;
 
 @property (retain) AVPlayerController* playerControllerProxy;
 @property (assign) WebVideoFullscreenModel* delegate;
@@ -150,7 +156,8 @@
     [super dealloc];
 }
 
--(void)resetState {
+- (void)resetState
+{
     self.contentDuration = 0;
     self.maxTime = 0;
     self.contentDurationWithinEndTimes = 0;
@@ -181,7 +188,8 @@
     self.currentLegibleMediaSelectionOption = nil;
 }
 
-- (AVPlayer*) player {
+- (AVPlayer *) player
+{
     return nil;
 }
 
@@ -568,25 +576,52 @@
 @implementation WebAVMediaSelectionOption
 @end
 
-
-@interface WebCALayerHostWrapper : CALayer
-@property (assign) WebVideoFullscreenModel* model;
+@interface WebAVPlayerLayer : CALayer
+@property (nonatomic, retain) NSString *videoGravity;
+@property (nonatomic, getter=isReadyForDisplay) BOOL readyForDisplay;
+@property (nonatomic, retain) AVPlayerController *playerController;
+@property (nonatomic, retain) CALayer *videoSublayer;
+@property (nonatomic, copy, nullable) NSDictionary *pixelBufferAttributes;
+@property CGSize videoDimensions;
+@property CGRect modelVideoLayerFrame;
 @end
 
-@implementation WebCALayerHostWrapper {
+@implementation WebAVPlayerLayer {
+    RetainPtr<WebAVPlayerController> _avPlayerController;
     RetainPtr<CALayer> _videoSublayer;
+    RetainPtr<NSString> _videoGravity;
 }
 
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        [self setMasksToBounds:YES];
+        _videoGravity = getAVLayerVideoGravityResizeAspect();
+    }
+    return self;
+}
+
 - (void)dealloc
 {
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resolveBounds) object:nil];
     [super dealloc];
 }
 
-- (void)setVideoSublayer:(CALayer*)videoSublayer
+- (AVPlayerController *)playerController
 {
+    return (AVPlayerController *)_avPlayerController.get();
+}
+
+- (void)setPlayerController:(AVPlayerController *)playerController
+{
+    ASSERT(!playerController || [playerController isKindOfClass:[WebAVPlayerController class]]);
+    _avPlayerController = (WebAVPlayerController *)playerController;
+}
+
+- (void)setVideoSublayer:(CALayer *)videoSublayer
+{
     _videoSublayer = videoSublayer;
-    [self addSublayer:videoSublayer];
 }
 
 - (CALayer*)videoSublayer
@@ -598,152 +633,239 @@
 {
     if (CGRectEqualToRect(bounds, self.bounds))
         return;
-
+    
     [super setBounds:bounds];
+    
+    if ([_videoSublayer superlayer] != self)
+        return;
 
     [_videoSublayer setPosition:CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))];
-
-    if (!self.model)
+    
+    if (![_avPlayerController delegate])
         return;
 
-    FloatRect videoFrame = self.model->videoLayerFrame();
-    FloatRect targetFrame;
-    switch (self.model->videoLayerGravity()) {
-    case WebCore::WebVideoFullscreenModel::VideoGravityResize:
-        targetFrame = bounds;
-        break;
-    case WebCore::WebVideoFullscreenModel::VideoGravityResizeAspect:
-        targetFrame = largestRectWithAspectRatioInsideRect(videoFrame.size().aspectRatio(), bounds);
-        break;
-    case WebCore::WebVideoFullscreenModel::VideoGravityResizeAspectFill:
-        targetFrame = smallestRectWithAspectRatioAroundRect(videoFrame.size().aspectRatio(), bounds);
-        break;
-    }
-    CATransform3D transform = CATransform3DMakeScale(targetFrame.width() / videoFrame.width(), targetFrame.height() / videoFrame.height(), 1);
-    [_videoSublayer setSublayerTransform:transform];
+    FloatRect sourceVideoFrame;
+    FloatRect targetVideoFrame;
+    float videoAspectRatio = self.videoDimensions.width / self.videoDimensions.height;
+    
+    if ([getAVLayerVideoGravityResize() isEqualToString:self.videoGravity]) {
+        sourceVideoFrame = self.modelVideoLayerFrame;
+        targetVideoFrame = self.bounds;
+    } else if ([getAVLayerVideoGravityResizeAspect() isEqualToString:self.videoGravity]) {
+        sourceVideoFrame = largestRectWithAspectRatioInsideRect(videoAspectRatio, self.modelVideoLayerFrame);
+        targetVideoFrame = largestRectWithAspectRatioInsideRect(videoAspectRatio, self.bounds);
+    } else if ([getAVLayerVideoGravityResizeAspectFill() isEqualToString:self.videoGravity]) {
+        sourceVideoFrame = smallestRectWithAspectRatioAroundRect(videoAspectRatio, self.modelVideoLayerFrame);
+        self.modelVideoLayerFrame = CGRectMake(0, 0, sourceVideoFrame.width(), sourceVideoFrame.height());
+        [_avPlayerController delegate]->setVideoLayerFrame(self.modelVideoLayerFrame);
+        targetVideoFrame = smallestRectWithAspectRatioAroundRect(videoAspectRatio, self.bounds);
+    } else
+        ASSERT_NOT_REACHED();
 
+    UIView *view = [_videoSublayer delegate];
+    CGAffineTransform transform = CGAffineTransformMakeScale(targetVideoFrame.width() / sourceVideoFrame.width(), targetVideoFrame.height() / sourceVideoFrame.height());
+    [view setTransform:transform];
+    
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resolveBounds) object:nil];
-    [self performSelector:@selector(resolveBounds) withObject:nil afterDelay:[CATransaction animationDuration] + 0.1];
+    
+    if (!CGAffineTransformEqualToTransform(CGAffineTransformIdentity, transform))
+        [self performSelector:@selector(resolveBounds) withObject:nil afterDelay:[CATransaction animationDuration] + 0.1];
 }
 
 - (void)resolveBounds
 {
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resolveBounds) object:nil];
-    if (!self.model)
+    if (![_avPlayerController delegate])
         return;
-
+    
+    if ([_videoSublayer superlayer] != self)
+        return;
+    
     [CATransaction begin];
     [CATransaction setAnimationDuration:0];
-
-    [_videoSublayer setSublayerTransform:CATransform3DIdentity];
-    self.model->setVideoLayerFrame([self bounds]);
     
+    [(UIView *)[_videoSublayer delegate] setTransform:CGAffineTransformIdentity];
+    self.modelVideoLayerFrame = [self bounds];
+    [_avPlayerController delegate]->setVideoLayerFrame(self.modelVideoLayerFrame);
+    
     [CATransaction commit];
 }
+
+- (void)setVideoGravity:(NSString *)videoGravity
+{
+    _videoGravity = videoGravity;
+    
+    if (![_avPlayerController delegate])
+        return;
+
+    WebCore::WebVideoFullscreenModel::VideoGravity gravity = WebCore::WebVideoFullscreenModel::VideoGravityResizeAspect;
+    if (videoGravity == getAVLayerVideoGravityResize())
+        gravity = WebCore::WebVideoFullscreenModel::VideoGravityResize;
+    if (videoGravity == getAVLayerVideoGravityResizeAspect())
+        gravity = WebCore::WebVideoFullscreenModel::VideoGravityResizeAspect;
+    else if (videoGravity == getAVLayerVideoGravityResizeAspectFill())
+        gravity = WebCore::WebVideoFullscreenModel::VideoGravityResizeAspectFill;
+    else
+        ASSERT_NOT_REACHED();
+    
+    [_avPlayerController delegate]->setVideoLayerGravity(gravity);
+}
+
+- (NSString *)videoGravity
+{
+    return _videoGravity.get();
+}
+
+- (CGRect)videoRect
+{
+    float videoAspectRatio = self.videoDimensions.width / self.videoDimensions.height;
+    
+    if ([getAVLayerVideoGravityResizeAspect() isEqualToString:self.videoGravity])
+        return largestRectWithAspectRatioInsideRect(videoAspectRatio, self.bounds);
+    if ([getAVLayerVideoGravityResizeAspectFill() isEqualToString:self.videoGravity])
+        return smallestRectWithAspectRatioAroundRect(videoAspectRatio, self.bounds);
+
+    return self.bounds;
+}
+
++ (NSSet *)keyPathsForValuesAffectingVideoRect
+{
+    return [NSSet setWithObjects:@"videoDimensions", @"videoGravity", nil];
+}
+
 @end
 
-@interface WebAVVideoLayer : CALayer <AVVideoLayer>
-+(WebAVVideoLayer *)videoLayer;
-@property (nonatomic) AVVideoLayerGravity videoLayerGravity;
-@property (nonatomic, getter = isReadyForDisplay) BOOL readyForDisplay;
-@property (nonatomic) CGRect videoRect;
-- (void)setPlayerViewController:(AVPlayerViewController *)playerViewController;
-- (void)setPlayerController:(AVPlayerController *)playerController;
-@property (nonatomic, retain) CALayer* videoSublayer;
+@interface WebAVPictureInPicturePlayerLayerView : AVPictureInPicturePlayerLayerView
 @end
 
-@implementation WebAVVideoLayer
+static CALayer* WebAVPictureInPicturePlayerLayerView_layerClass(id, SEL)
 {
-    RetainPtr<WebAVPlayerController> _avPlayerController;
-    RetainPtr<AVPlayerViewController> _avPlayerViewController;
-    RetainPtr<CALayer> _videoSublayer;
-    AVVideoLayerGravity _videoLayerGravity;
+    return [WebAVPlayerLayer class];
 }
 
-+(WebAVVideoLayer *)videoLayer
+static Class getWebAVPictureInPicturePlayerLayerViewClass()
 {
-    return [[[WebAVVideoLayer alloc] init] autorelease];
+    static Class theClass = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        theClass = objc_allocateClassPair(getAVPictureInPicturePlayerLayerViewClass(), "WebAVPictureInPicturePlayerLayerView", 0);
+        objc_registerClassPair(theClass);
+        Class metaClass = objc_getMetaClass("WebAVPictureInPicturePlayerLayerView");
+        class_addMethod(metaClass, @selector(layerClass), (IMP)WebAVPictureInPicturePlayerLayerView_layerClass, "@@:");
+    });
+    
+    return theClass;
 }
 
-- (instancetype)init
+@interface WebAVPlayerLayerView : AVPlayerLayerView
+@property (retain) UIView* videoView;
+@end
+
+static CALayer* WebAVPlayerLayerView_layerClass(id, SEL)
 {
-    self = [super init];
-    if (self) {
-        [self setMasksToBounds:YES];
-        [self setVideoLayerGravity:AVVideoLayerGravityResizeAspect];
-    }
-    return self;
+    return [WebAVPlayerLayer class];
 }
 
-- (void)setPlayerController:(AVPlayerController *)playerController
+static AVPlayerController* WebAVPlayerLayerView_playerController(id aSelf, SEL)
 {
-    ASSERT(!playerController || [playerController isKindOfClass:[WebAVPlayerController class]]);
-    _avPlayerController = (WebAVPlayerController *)playerController;
+    AVPlayerLayerView *playerLayer = aSelf;
+    WebAVPlayerLayer *webAVPlayerLayer = (WebAVPlayerLayer *)[playerLayer playerLayer];
+    return [webAVPlayerLayer playerController];
 }
 
-- (void)setPlayerViewController:(AVPlayerViewController *)playerViewController
+static void WebAVPlayerLayerView_setPlayerController(id aSelf, SEL, AVPlayerController *playerController)
 {
-    _avPlayerViewController = playerViewController;
+    AVPlayerLayerView *playerLayerView = aSelf;
+    WebAVPlayerLayer *webAVPlayerLayer = (WebAVPlayerLayer *)[playerLayerView playerLayer];
+    [webAVPlayerLayer setPlayerController: playerController];
 }
 
-- (void)setVideoSublayer:(CALayer *)videoSublayer
+static UIView* WebAVPlayerLayerView_videoView(id aSelf, SEL)
 {
-    _videoSublayer = videoSublayer;
-    [self addSublayer:videoSublayer];
+    AVPlayerLayerView *playerLayer = aSelf;
+    WebAVPlayerLayer *webAVPlayerLayer = (WebAVPlayerLayer *)[playerLayer playerLayer];
+    CALayer* videoLayer = [webAVPlayerLayer videoSublayer];
+    if (!videoLayer)
+        return nil;
+    ASSERT([[videoLayer delegate] isKindOfClass:getUIViewClass()]);
+    return (UIView *)[videoLayer delegate];
 }
 
-- (CALayer*)videoSublayer
+static void WebAVPlayerLayerView_setVideoView(id aSelf, SEL, UIView *videoView)
 {
-    return _videoSublayer.get();
+    AVPlayerLayerView *playerLayerView = aSelf;
+    WebAVPlayerLayer *webAVPlayerLayer = (WebAVPlayerLayer *)[playerLayerView playerLayer];
+    [webAVPlayerLayer setVideoSublayer:[videoView layer]];
 }
 
-- (void)setBounds:(CGRect)bounds
+static void WebAVPlayerLayerView_startRoutingVideoToPictureInPicturePlayerLayerView(id aSelf, SEL)
 {
-    [super setBounds:bounds];
+    WebAVPlayerLayerView *playerLayerView = aSelf;
+    AVPictureInPicturePlayerLayerView *pipView = [playerLayerView pictureInPicturePlayerLayerView];
 
-    if ([_videoSublayer superlayer] == self) {
-        [_videoSublayer setPosition:CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))];
-        [_videoSublayer setBounds:bounds];
-    }
+    WebAVPlayerLayer *playerLayer = (WebAVPlayerLayer *)[playerLayerView playerLayer];
+    WebAVPlayerLayer *pipPlayerLayer = (WebAVPlayerLayer *)[pipView playerLayer];
+    [playerLayer setVideoGravity:getAVLayerVideoGravityResizeAspect()];
+    [pipPlayerLayer setVideoSublayer:playerLayer.videoSublayer];
+    [pipPlayerLayer setVideoDimensions:playerLayer.videoDimensions];
+    [pipPlayerLayer setVideoGravity:playerLayer.videoGravity];
+    [pipPlayerLayer setModelVideoLayerFrame:playerLayer.modelVideoLayerFrame];
+    [pipPlayerLayer setPlayerController:playerLayer.playerController];
+    [pipView addSubview:playerLayerView.videoView];
 }
 
-- (void)setVideoLayerGravity:(AVVideoLayerGravity)videoLayerGravity
+static void WebAVPlayerLayerView_stopRoutingVideoToPictureInPicturePlayerLayerView(id aSelf, SEL)
 {
-    _videoLayerGravity = videoLayerGravity;
-    
-    if (![_avPlayerController delegate])
-        return;
-
-    WebCore::WebVideoFullscreenModel::VideoGravity gravity = WebCore::WebVideoFullscreenModel::VideoGravityResizeAspect;
-    if (videoLayerGravity == AVVideoLayerGravityResize)
-        gravity = WebCore::WebVideoFullscreenModel::VideoGravityResize;
-    if (videoLayerGravity == AVVideoLayerGravityResizeAspect)
-        gravity = WebCore::WebVideoFullscreenModel::VideoGravityResizeAspect;
-    else if (videoLayerGravity == AVVideoLayerGravityResizeAspectFill)
-        gravity = WebCore::WebVideoFullscreenModel::VideoGravityResizeAspectFill;
-    else
-        ASSERT_NOT_REACHED();
-    
-    [_avPlayerController delegate]->setVideoLayerGravity(gravity);
+    WebAVPlayerLayerView *playerLayerView = aSelf;
+    [playerLayerView addSubview:playerLayerView.videoView];
 }
 
-- (AVVideoLayerGravity)videoLayerGravity
+static AVPictureInPicturePlayerLayerView *WebAVPlayerLayerView_pictureInPicturePlayerLayerView(id aSelf, SEL)
 {
-    return _videoLayerGravity;
+    WebAVPlayerLayerView *playerLayerView = aSelf;
+    WebAVPictureInPicturePlayerLayerView *pipView = [playerLayerView valueForKey:@"_pictureInPicturePlayerLayerView"];
+    if (!pipView) {
+        pipView = [[getWebAVPictureInPicturePlayerLayerViewClass() alloc] initWithFrame:CGRectZero];
+        [playerLayerView setValue:pipView forKey:@"_pictureInPicturePlayerLayerView"];
+    }
+    return pipView;
 }
 
-- (void)enterPIPModeRedirectingVideoToLayer:(CALayer *)layer
+static void WebAVPlayerLayerView_dealloc(id aSelf, SEL)
 {
-    [_videoSublayer removeFromSuperlayer];
-    [layer addSublayer:_videoSublayer.get()];
+    WebAVPlayerLayerView *playerLayerView = aSelf;
+    RetainPtr<WebAVPictureInPicturePlayerLayerView> pipView = adoptNS([playerLayerView valueForKey:@"_pictureInPicturePlayerLayerView"]);
+    [playerLayerView setValue:nil forKey:@"_pictureInPicturePlayerLayerView"];
+    objc_super superClass { playerLayerView, getAVPlayerLayerViewClass() };
+    auto super_dealloc = reinterpret_cast<void(*)(objc_super*, SEL)>(objc_msgSendSuper);
+    super_dealloc(&superClass, @selector(dealloc));
 }
 
-- (void)leavePIPMode
+#pragma mark - Methods
+
+static Class getWebAVPlayerLayerViewClass()
 {
-    [_videoSublayer removeFromSuperlayer];
-    [self addSublayer:_videoSublayer.get()];
+    static Class theClass = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        theClass = objc_allocateClassPair(getAVPlayerLayerViewClass(), "WebAVPlayerLayerView", 0);
+        class_addMethod(theClass, @selector(dealloc), (IMP)WebAVPlayerLayerView_dealloc, "v@:");
+        class_addMethod(theClass, @selector(setPlayerController:), (IMP)WebAVPlayerLayerView_setPlayerController, "v@:@");
+        class_addMethod(theClass, @selector(playerController), (IMP)WebAVPlayerLayerView_playerController, "@@:");
+        class_addMethod(theClass, @selector(setVideoView:), (IMP)WebAVPlayerLayerView_setVideoView, "v@:@");
+        class_addMethod(theClass, @selector(videoView), (IMP)WebAVPlayerLayerView_videoView, "@@:");
+        class_addMethod(theClass, @selector(startRoutingVideoToPictureInPicturePlayerLayerView), (IMP)WebAVPlayerLayerView_startRoutingVideoToPictureInPicturePlayerLayerView, "v@:");
+        class_addMethod(theClass, @selector(stopRoutingVideoToPictureInPicturePlayerLayerView), (IMP)WebAVPlayerLayerView_stopRoutingVideoToPictureInPicturePlayerLayerView, "v@:");
+        class_addMethod(theClass, @selector(pictureInPicturePlayerLayerView), (IMP)WebAVPlayerLayerView_pictureInPicturePlayerLayerView, "@@:");
+        
+        class_addIvar(theClass, "_pictureInPicturePlayerLayerView", sizeof(WebAVPictureInPicturePlayerLayerView *), log2(sizeof(WebAVPictureInPicturePlayerLayerView *)), "@");
+        
+        objc_registerClassPair(theClass);
+        Class metaClass = objc_getMetaClass("WebAVPlayerLayerView");
+        class_addMethod(metaClass, @selector(layerClass), (IMP)WebAVPlayerLayerView_layerClass, "@@:");
+    });
+    return theClass;
 }
-@end
 
 WebVideoFullscreenInterfaceAVKit::WebVideoFullscreenInterfaceAVKit()
     : m_playerController(adoptNS([[WebAVPlayerController alloc] init]))
@@ -826,6 +948,9 @@
 
 void WebVideoFullscreenInterfaceAVKit::setVideoDimensions(bool hasVideo, float width, float height)
 {
+    WebAVPlayerLayer *playerLayer = (WebAVPlayerLayer *)[m_playerLayerView playerLayer];
+
+    [playerLayer setVideoDimensions:CGSizeMake(width, height)];
     [m_playerController setHasEnabledVideo:hasVideo];
     [m_playerController setContentDimensions:CGSizeMake(width, height)];
 }
@@ -890,18 +1015,18 @@
     playerController.externalPlaybackAirPlayDeviceLocalizedName = localizedDeviceName;
     playerController.externalPlaybackType = externalPlaybackType;
     playerController.externalPlaybackActive = enabled;
-    [m_videoLayerContainer.get() setHidden:enabled];
+    [m_playerLayerView setHidden:enabled];
 }
 
 @interface UIWindow ()
--(BOOL)_isHostedInAnotherProcess;
+- (BOOL)_isHostedInAnotherProcess;
 @end
 
 @interface UIViewController ()
 @property (nonatomic, assign, setter=_setIgnoreAppSupportedOrientations:) BOOL _ignoreAppSupportedOrientations;
 @end
 
-void WebVideoFullscreenInterfaceAVKit::setupFullscreen(PlatformLayer& videoLayer, const WebCore::IntRect& initialRect, UIView* parentView, HTMLMediaElementEnums::VideoFullscreenMode mode, bool allowsPictureInPicturePlayback)
+void WebVideoFullscreenInterfaceAVKit::setupFullscreen(UIView& videoView, const WebCore::IntRect& initialRect, UIView* parentView, HTMLMediaElementEnums::VideoFullscreenMode mode, bool allowsPictureInPicturePlayback)
 {
     ASSERT(mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
     LOG(Fullscreen, "WebVideoFullscreenInterfaceAVKit::setupFullscreen(%p)", this);
@@ -910,7 +1035,6 @@
 
     [CATransaction begin];
     [CATransaction setDisableActions:YES];
-    m_videoLayer = &videoLayer;
     m_mode = mode;
     m_parentView = parentView;
     m_parentWindow = parentView.window;
@@ -925,51 +1049,46 @@
         [m_window makeKeyAndVisible];
     }
 
-    [m_videoLayer removeFromSuperlayer];
+    m_playerLayerView = adoptNS([[getWebAVPlayerLayerViewClass() alloc] init]);
+    [m_playerLayerView setHidden:[m_playerController isExternalPlaybackActive]];
+    [m_playerLayerView setBackgroundColor:[getUIColorClass() clearColor]];
+    
+    [m_playerLayerView setVideoView:&videoView];
+    [m_playerLayerView addSubview:&videoView];
 
-    m_layerHostWrapper = adoptNS([[WebCALayerHostWrapper alloc] init]);
-    [m_layerHostWrapper setModel:m_videoFullscreenModel];
-    [m_layerHostWrapper setVideoSublayer:m_videoLayer.get()];
+    WebAVPlayerLayer *playerLayer = (WebAVPlayerLayer *)[m_playerLayerView playerLayer];
 
-    m_videoLayerContainer = [WebAVVideoLayer videoLayer];
-    [m_videoLayerContainer setHidden:[m_playerController isExternalPlaybackActive]];
-    [m_videoLayerContainer setVideoSublayer:m_layerHostWrapper.get()];
+    [playerLayer setModelVideoLayerFrame:CGRectMake(0, 0, initialRect.width(), initialRect.height())];
+    [playerLayer setVideoDimensions:[m_playerController contentDimensions]];
 
-    CGSize videoSize = [m_playerController contentDimensions];
-    CGRect videoRect = CGRectMake(0, 0, videoSize.width, videoSize.height);
-    [m_videoLayerContainer setVideoRect:videoRect];
-    if (m_videoFullscreenModel)
-        m_videoFullscreenModel->setVideoLayerFrame(videoRect);
+    m_playerViewController = adoptNS([allocAVPlayerViewControllerInstance() initWithPlayerLayerView:m_playerLayerView.get()]);
 
-    // This method has been deprecated so ignore the warning until we port our code to the new API.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    m_playerViewController = adoptNS([allocAVPlayerViewControllerInstance() initWithVideoLayer:m_videoLayerContainer.get()]);
-#pragma clang diagnostic pop
-
     [m_playerViewController setShowsPlaybackControls:NO];
     [m_playerViewController setPlayerController:(AVPlayerController *)m_playerController.get()];
     [m_playerViewController setDelegate:m_playerController.get()];
     [m_playerViewController setAllowsPictureInPicturePlayback:m_allowsPictureInPicturePlayback];
 
-    [m_videoLayerContainer setPlayerViewController:m_playerViewController.get()];
-
     if (m_viewController) {
         [m_viewController addChildViewController:m_playerViewController.get()];
         [[m_viewController view] addSubview:[m_playerViewController view]];
     } else
-        [parentView.window addSubview:[m_playerViewController view]];
+        [parentView addSubview:[m_playerViewController view]];
 
-    [m_playerViewController view].frame = [parentView convertRect:initialRect toView:nil];
+    [m_playerViewController view].frame = [parentView convertRect:initialRect toView:[m_playerViewController view].superview];
 
     [[m_playerViewController view] setBackgroundColor:[getUIColorClass() clearColor]];
+    [[m_playerViewController view] setAutoresizingMask:(UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin)];
+
     [[m_playerViewController view] setNeedsLayout];
     [[m_playerViewController view] layoutIfNeeded];
 
     [CATransaction commit];
 
-    if (m_fullscreenChangeObserver)
-        m_fullscreenChangeObserver->didSetupFullscreen();
+    RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
+    dispatch_async(dispatch_get_main_queue(), [strongThis, this] {
+        if (m_fullscreenChangeObserver)
+            m_fullscreenChangeObserver->didSetupFullscreen();
+    });
 }
 
 void WebVideoFullscreenInterfaceAVKit::enterFullscreen()
@@ -980,7 +1099,7 @@
     m_exitRequested = false;
     m_enterRequested = true;
 
-    [m_videoLayerContainer setBackgroundColor:[[getUIColorClass() blackColor] CGColor]];
+    [m_playerLayerView setBackgroundColor:[getUIColorClass() blackColor]];
     if (mode() == HTMLMediaElementEnums::VideoFullscreenModePictureInPicture)
         enterPictureInPicture();
     else if (mode() == HTMLMediaElementEnums::VideoFullscreenModeStandard)
@@ -1024,13 +1143,12 @@
     
     LOG(Fullscreen, "WebVideoFullscreenInterfaceAVKit::exitFullscreen(%p)", this);
     [m_playerViewController setShowsPlaybackControls:NO];
-    if (m_viewController)
-        [m_playerViewController view].frame = [m_parentView convertRect:finalRect toView:nil];
-    else
-        [m_playerViewController view].frame = finalRect;
+    
+    [m_playerViewController view].frame = [m_parentView convertRect:finalRect toView:[m_playerViewController view].superview];
 
-    if ([m_videoLayerContainer videoLayerGravity] != AVVideoLayerGravityResizeAspect)
-        [m_videoLayerContainer setVideoLayerGravity:AVVideoLayerGravityResizeAspect];
+    WebAVPlayerLayer *playerLayer = (WebAVPlayerLayer *)[m_playerLayerView playerLayer];
+    if ([playerLayer videoGravity] != getAVLayerVideoGravityResizeAspect())
+        [playerLayer setVideoGravity:getAVLayerVideoGravityResizeAspect()];
     [[m_playerViewController view] layoutIfNeeded];
 
     if (isMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture)) {
@@ -1049,22 +1167,24 @@
 
             [CATransaction begin];
             [CATransaction setDisableActions:YES];
-            [m_videoLayerContainer setBackgroundColor:[[getUIColorClass() clearColor] CGColor]];
+            [m_playerLayerView setBackgroundColor:[getUIColorClass() clearColor]];
             [[m_playerViewController view] setBackgroundColor:[getUIColorClass() clearColor]];
             [CATransaction commit];
 
-            if (m_fullscreenChangeObserver)
-                m_fullscreenChangeObserver->didExitFullscreen();
+            dispatch_async(dispatch_get_main_queue(), ^{
+                if (m_fullscreenChangeObserver)
+                    m_fullscreenChangeObserver->didExitFullscreen();
+            });
         }];
     };
 }
 
 @interface UIApplication ()
--(void)_setStatusBarOrientation:(UIInterfaceOrientation)o;
+- (void)_setStatusBarOrientation:(UIInterfaceOrientation)o;
 @end
 
 @interface UIWindow ()
--(UIInterfaceOrientation)interfaceOrientation;
+- (UIInterfaceOrientation)interfaceOrientation;
 @end
 
 void WebVideoFullscreenInterfaceAVKit::cleanupFullscreen()
@@ -1092,16 +1212,10 @@
     if (m_viewController)
         [m_playerViewController removeFromParentViewController];
     
-    [m_videoLayer removeFromSuperlayer];
-    [m_videoLayerContainer removeFromSuperlayer];
-    [m_videoLayerContainer setPlayerViewController:nil];
+    [m_playerLayerView removeFromSuperview];
     [[m_viewController view] removeFromSuperview];
 
-    [m_layerHostWrapper setModel:nullptr];
-
-    m_layerHostWrapper = nil;
-    m_videoLayer = nil;
-    m_videoLayerContainer = nil;
+    m_playerLayerView = nil;
     m_playerViewController = nil;
     m_playerController = nil;
     m_viewController = nil;
@@ -1147,7 +1261,7 @@
     LOG(Fullscreen, "WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline(%p) - visible(%s)", this, boolString(visible));
     if (m_prepareToInlineCallback) {
         
-        [m_playerViewController view].frame = [m_parentView convertRect:inlineRect toView:nil];
+        [m_playerViewController view].frame = [m_parentView convertRect:inlineRect toView:[m_playerViewController view].superview];
 
         std::function<void(bool)> callback = WTF::move(m_prepareToInlineCallback);
         callback(visible);
@@ -1218,7 +1332,7 @@
 
     m_exitCompleted = true;
 
-    [m_videoLayerContainer setBackgroundColor:[[getUIColorClass() clearColor] CGColor]];
+    [m_playerLayerView setBackgroundColor:[getUIColorClass() clearColor]];
     [[m_playerViewController view] setBackgroundColor:[getUIColorClass() clearColor]];
 
     clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h (187043 => 187044)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h	2015-07-20 23:27:49 UTC (rev 187044)
@@ -48,10 +48,8 @@
     virtual void endScanning() = 0;
     virtual void requestExitFullscreen() = 0;
     virtual void setVideoLayerFrame(FloatRect) = 0;
-    virtual FloatRect videoLayerFrame() const = 0;
     enum VideoGravity { VideoGravityResize, VideoGravityResizeAspect, VideoGravityResizeAspectFill };
     virtual void setVideoLayerGravity(VideoGravity) = 0;
-    virtual VideoGravity videoLayerGravity() const = 0;
     virtual void selectAudioMediaOption(uint64_t index) = 0;
     virtual void selectLegibleMediaOption(uint64_t index) = 0;
     virtual void fullscreenModeChanged(HTMLMediaElementEnums::VideoFullscreenMode) = 0;

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h (187043 => 187044)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h	2015-07-20 23:27:49 UTC (rev 187044)
@@ -72,9 +72,7 @@
     WEBCORE_EXPORT virtual void endScanning() override;
     WEBCORE_EXPORT virtual void requestExitFullscreen() override;
     WEBCORE_EXPORT virtual void setVideoLayerFrame(FloatRect) override;
-    WEBCORE_EXPORT virtual FloatRect videoLayerFrame() const override;
     WEBCORE_EXPORT virtual void setVideoLayerGravity(VideoGravity) override;
-    WEBCORE_EXPORT virtual VideoGravity videoLayerGravity() const override;
     WEBCORE_EXPORT virtual void selectAudioMediaOption(uint64_t index) override;
     WEBCORE_EXPORT virtual void selectLegibleMediaOption(uint64_t index) override;
     WEBCORE_EXPORT virtual void fullscreenModeChanged(HTMLMediaElementEnums::VideoFullscreenMode) override;

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm (187043 => 187044)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm	2015-07-20 23:27:49 UTC (rev 187044)
@@ -254,11 +254,6 @@
         m_videoElement->setVideoFullscreenFrame(rect);
 }
 
-FloatRect WebVideoFullscreenModelVideoElement::videoLayerFrame() const
-{
-    return m_videoFrame;
-}
-
 void WebVideoFullscreenModelVideoElement::setVideoLayerGravity(WebVideoFullscreenModel::VideoGravity gravity)
 {
     MediaPlayer::VideoGravity videoGravity = MediaPlayer::VideoGravityResizeAspect;
@@ -274,21 +269,6 @@
     m_videoElement->setVideoFullscreenGravity(videoGravity);
 }
 
-WebVideoFullscreenModel::VideoGravity WebVideoFullscreenModelVideoElement::videoLayerGravity() const
-{
-    switch (m_videoElement->videoFullscreenGravity()) {
-    case MediaPlayer::VideoGravityResize:
-        return VideoGravityResize;
-    case MediaPlayer::VideoGravityResizeAspect:
-        return VideoGravityResizeAspect;
-    case MediaPlayer::VideoGravityResizeAspectFill:
-        return VideoGravityResizeAspectFill;
-    }
-
-    ASSERT_NOT_REACHED();
-    return VideoGravityResize;
-}
-
 void WebVideoFullscreenModelVideoElement::selectAudioMediaOption(uint64_t selectedAudioIndex)
 {
     AudioTrack* selectedAudioTrack = nullptr;

Modified: trunk/Source/WebCore/platform/spi/cocoa/AVKitSPI.h (187043 => 187044)


--- trunk/Source/WebCore/platform/spi/cocoa/AVKitSPI.h	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/spi/cocoa/AVKitSPI.h	2015-07-20 23:27:49 UTC (rev 187044)
@@ -34,9 +34,12 @@
 #if USE(APPLE_INTERNAL_SDK)
 
 #import <AVKit/AVPlayerController.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-property-no-attribute"
+#import <AVKit/AVPlayerLayerView.h>
+#pragma clang diagnostic pop
 #import <AVKit/AVPlayerViewController_Private.h>
 #import <AVKit/AVPlayerViewController_WebKitOnly.h>
-#import <AVKit/AVVideoLayer.h>
 
 #else
 
@@ -58,19 +61,19 @@
 @property (NS_NONATOMIC_IOSONLY, readonly) AVPlayerControllerStatus status;
 @end
 
-@protocol AVVideoLayer
-typedef NS_ENUM(NSInteger, AVVideoLayerGravity) {
-    AVVideoLayerGravityInvalid = 0,
-    AVVideoLayerGravityResizeAspect = 1,
-    AVVideoLayerGravityResizeAspectFill = 2,
-    AVVideoLayerGravityResize = 3,
-};
-- (void)setPlayerController:(AVPlayerController *)playerController;
-@property (nonatomic) AVVideoLayerGravity videoLayerGravity;
-@property (nonatomic) CGRect videoRect;
-@property (nonatomic, readonly, getter=isReadyForDisplay) BOOL readyForDisplay;
+@class AVPlayerLayer;
+
+@interface AVPictureInPicturePlayerLayerView : UIView
+@property (nonatomic, readonly) AVPlayerLayer *playerLayer;
 @end
 
+@interface AVPlayerLayerView : UIView
+@property (nonatomic, readonly) AVPlayerLayer *playerLayer;
+@property (nonatomic, readonly) AVPictureInPicturePlayerLayerView *pictureInPicturePlayerLayerView;
+- (void)startRoutingVideoToPictureInPicturePlayerLayerView;
+- (void)stopRoutingVideoToPictureInPicturePlayerLayerView;
+@end
+
 @protocol AVPlayerViewControllerDelegate <NSObject>
 @optional
 typedef NS_ENUM(NSInteger, AVPlayerViewControllerExitFullScreenReason) {
@@ -85,15 +88,15 @@
 @end
 
 @interface AVPlayerViewController (Details)
-- (instancetype)initWithVideoLayer:(CALayer <AVVideoLayer> *)videoLayer;
+- (instancetype)initWithPlayerLayerView:(AVPlayerLayerView *)playerLayerView;
 - (void)enterFullScreenAnimated:(BOOL)animated completionHandler:(void (^)(BOOL success, NSError *))completionHandler;
 - (void)exitFullScreenAnimated:(BOOL)animated completionHandler:(void (^)(BOOL success, NSError *))completionHandler;
 
 - (BOOL)isPictureInPicturePossible;
 - (void)startPictureInPicture;
 - (void)stopPictureInPicture;
-- (void)setAllowsPictureInPicturePlayback:(BOOL)allow;
 
+@property (nonatomic) BOOL allowsPictureInPicturePlayback;
 @property (nonatomic, strong) AVPlayerController *playerController;
 @property (nonatomic, weak) id <AVPlayerViewControllerDelegate> delegate;
 @end

Modified: trunk/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h (187043 => 187044)


--- trunk/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h	2015-07-20 23:27:49 UTC (rev 187044)
@@ -32,6 +32,7 @@
 #include <QuartzCore/CARenderServer.h>
 
 #ifdef __OBJC__
+#import <QuartzCore/CALayerHost.h>
 #import <QuartzCore/CALayerPrivate.h>
 
 // FIXME: As a workaround for <rdar://problem/18985152>, we conditionally enclose the following
@@ -134,6 +135,12 @@
 + (void)addCommitHandler:(void(^)(void))block forPhase:(CATransactionPhase)phase;
 @end
 #endif
+
+@interface CALayerHost : CALayer
+@property uint32_t contextId;
+@property BOOL inheritsSecurity;
+@end
+
 #endif // __OBJC__
 
 #endif

Modified: trunk/Source/WebKit2/ChangeLog (187043 => 187044)


--- trunk/Source/WebKit2/ChangeLog	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebKit2/ChangeLog	2015-07-20 23:27:49 UTC (rev 187044)
@@ -1,3 +1,40 @@
+2015-07-20  Jeremy Jones  <jere...@apple.com>
+
+        Adopt AVPlayerLayerView
+        https://bugs.webkit.org/show_bug.cgi?id=146862
+
+        Reviewed by Simon Fraser.
+
+        The CALayerHost is replaced with WebLayerHostView to be compatible with UIView animations.
+        videoLayerFrame and videoLayerGravity no longer need to be stored because they are stored
+        where they are used in the interface. Some animation is improved in the conversion.
+
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.h:
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
+        (+[WebLayerHostView layerClass]): Add class WebLayerHostView.
+        (-[WebLayerHostView contextID]):
+        (-[WebLayerHostView setContextID:]):
+        (-[WebLayerHostView layerHost]):
+        (WebKit::WebVideoFullscreenManagerProxy::invalidate): layer -> view
+        (WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID):
+        Apply the hostingDeviceScaleFactor transform to -sublayerTransform instead of to
+        -transform. This more directly inverts the tranform WebProcess and allows -transform
+        to be used for animation in the UIProcess. This is important because UIView's actions
+        animate -transform, but not -sublayerTrasform.
+
+        (WebKit::WebVideoFullscreenManagerProxy::didCleanupFullscreen): layer -> view
+        (WebKit::WebVideoFullscreenModelContext::setVideoLayerFrame): Deleted.
+        (WebKit::WebVideoFullscreenModelContext::videoLayerFrame): Deleted.
+        (WebKit::WebVideoFullscreenModelContext::setVideoLayerGravity): Deleted.
+        (WebKit::WebVideoFullscreenModelContext::videoLayerGravity): Deleted.
+        * WebProcess/ios/WebVideoFullscreenManager.mm:
+        (WebKit::WebVideoFullscreenManager::enterVideoFullscreenForVideoElement):
+        Set initial video layer frame to fix start point of animation.
+
+        (WebKit::WebVideoFullscreenManager::didSetupFullscreen):
+        dispatch_async allows the CATransaction to complete before continuing with the animation.
+        This prevents a flash during animation.
+
 2015-07-20  Tim Horton  <timothy_hor...@apple.com>
 
         REGRESSION (r174287): Flash of black when opening a new web view or navigating to a new page

Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h (187043 => 187044)


--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h	2015-07-20 23:27:49 UTC (rev 187044)
@@ -53,11 +53,9 @@
 
     void invalidate() { m_manager = nullptr; }
 
-    PlatformLayer* layerHost() const { return m_layerHost.get(); }
-    void setLayerHost(RetainPtr<PlatformLayer>&& layerHost) { m_layerHost = WTF::move(layerHost); }
+    UIView *layerHostView() const { return m_layerHostView.get(); }
+    void setLayerHostView(RetainPtr<UIView>&& layerHostView) { m_layerHostView = WTF::move(layerHostView); }
 
-    void setInitialVideoLayerFrame(WebCore::FloatRect frame) { m_videoLayerFrame = frame; }
-
 private:
     WebVideoFullscreenModelContext(WebVideoFullscreenManagerProxy& manager, uint64_t contextId)
         : m_manager(&manager)
@@ -78,9 +76,7 @@
     virtual void endScanning() override;
     virtual void requestExitFullscreen() override;
     virtual void setVideoLayerFrame(WebCore::FloatRect) override;
-    virtual WebCore::FloatRect videoLayerFrame() const override;
     virtual void setVideoLayerGravity(VideoGravity) override;
-    virtual VideoGravity videoLayerGravity() const override;
     virtual void selectAudioMediaOption(uint64_t) override;
     virtual void selectLegibleMediaOption(uint64_t) override;
     virtual void fullscreenModeChanged(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) override;
@@ -94,9 +90,7 @@
 
     WebVideoFullscreenManagerProxy* m_manager;
     uint64_t m_contextId;
-    RetainPtr<PlatformLayer> m_layerHost;
-    WebCore::FloatRect m_videoLayerFrame;
-    VideoGravity m_videoLayerGravity { VideoGravityResize };
+    RetainPtr<UIView *> m_layerHostView;
 };
 
 class WebVideoFullscreenManagerProxy : public RefCounted<WebVideoFullscreenManagerProxy>, private IPC::MessageReceiver {

Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm (187043 => 187044)


--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm	2015-07-20 23:27:49 UTC (rev 187044)
@@ -35,9 +35,34 @@
 #import "WebVideoFullscreenManagerMessages.h"
 #import "WebVideoFullscreenManagerProxyMessages.h"
 #import <QuartzCore/CoreAnimation.h>
+#import <WebCore/QuartzCoreSPI.h>
 #import <WebCore/TimeRanges.h>
 #import <WebKitSystemInterface.h>
 
+@interface WebLayerHostView : UIView
+@property (nonatomic, assign) uint32_t contextID;
+@end
+
+@implementation WebLayerHostView
+
++ (Class)layerClass {
+    return [CALayerHost class];
+}
+
+- (uint32_t)contextID {
+    return [[self layerHost] contextId];
+}
+
+- (void)setContextID:(uint32_t)contextID {
+    [[self layerHost] setContextId:contextID];
+}
+
+- (CALayerHost *)layerHost {
+    return (CALayerHost *)[self layer];
+}
+
+@end
+
 using namespace WebCore;
 
 namespace WebKit {
@@ -139,28 +164,16 @@
 
 void WebVideoFullscreenModelContext::setVideoLayerFrame(WebCore::FloatRect frame)
 {
-    m_videoLayerFrame = frame;
     if (m_manager)
         m_manager->setVideoLayerFrame(m_contextId, frame);
 }
 
-WebCore::FloatRect WebVideoFullscreenModelContext::videoLayerFrame() const
-{
-    return m_videoLayerFrame;
-}
-
 void WebVideoFullscreenModelContext::setVideoLayerGravity(WebCore::WebVideoFullscreenModel::VideoGravity gravity)
 {
-    m_videoLayerGravity = gravity;
     if (m_manager)
         m_manager->setVideoLayerGravity(m_contextId, gravity);
 }
 
-WebCore::WebVideoFullscreenModel::VideoGravity WebVideoFullscreenModelContext::videoLayerGravity() const
-{
-    return m_videoLayerGravity;
-}
-
 void WebVideoFullscreenModelContext::selectAudioMediaOption(uint64_t optionId)
 {
     if (m_manager)
@@ -240,8 +253,8 @@
         std::tie(model, interface) = tuple;
 
         interface->invalidate();
-        [model->layerHost() removeFromSuperlayer];
-        model->setLayerHost(nullptr);
+        [model->layerHostView() removeFromSuperview];
+        model->setLayerHostView(nullptr);
     }
 
     m_contextMap.clear();
@@ -310,16 +323,17 @@
 
     std::tie(model, interface) = ensureModelAndInterface(contextId);
 
-    model->setInitialVideoLayerFrame(initialRect);
-    model->setLayerHost(WKMakeRenderLayer(videoLayerID));
+    RetainPtr<WebLayerHostView> view = adoptNS([[WebLayerHostView alloc] init]);
+    [view setContextID:videoLayerID];
+    model->setLayerHostView(view);
     if (hostingDeviceScaleFactor != 1) {
         // Invert the scale transform added in the WebProcess to fix <rdar://problem/18316542>.
         float inverseScale = 1 / hostingDeviceScaleFactor;
-        [model->layerHost() setTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
+        [[model->layerHostView() layer] setSublayerTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
     }
 
     UIView *parentView = downcast<RemoteLayerTreeDrawingAreaProxy>(*m_page->drawingArea()).remoteLayerTreeHost().rootLayer();
-    interface->setupFullscreen(*model->layerHost(), initialRect, parentView, videoFullscreenMode, allowsPictureInPicture);
+    interface->setupFullscreen(*model->layerHostView(), initialRect, parentView, videoFullscreenMode, allowsPictureInPicture);
 }
 
 void WebVideoFullscreenManagerProxy::resetMediaState(uint64_t contextId)
@@ -502,8 +516,8 @@
     auto& model = ensureModel(contextId);
 
     [CATransaction flush];
-    [model.layerHost() removeFromSuperlayer];
-    model.setLayerHost(nullptr);
+    [model.layerHostView() removeFromSuperview];
+    model.setLayerHostView(nullptr);
     m_page->send(Messages::WebVideoFullscreenManager::DidCleanupFullscreen(contextId), m_page->pageID());
 
     m_contextMap.remove(contextId);

Modified: trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm (187043 => 187044)


--- trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm	2015-07-20 23:26:04 UTC (rev 187043)
+++ trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm	2015-07-20 23:27:49 UTC (rev 187044)
@@ -232,9 +232,13 @@
     RefPtr<WebVideoFullscreenInterfaceContext> interface;
     std::tie(model, interface) = ensureModelAndInterface(contextId);
 
+    FloatRect clientRect = clientRectForElement(&videoElement);
+    FloatRect videoLayerFrame = FloatRect(0, 0, clientRect.width(), clientRect.height());
+    
     interface->setTargetIsFullscreen(true);
     interface->setFullscreenMode(mode);
     model->setVideoElement(&videoElement);
+    model->setVideoLayerFrame(videoLayerFrame);
 
     if (interface->isAnimating())
         return;
@@ -428,7 +432,10 @@
 
     [CATransaction commit];
 
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(contextId), m_page->pageID());
+    RefPtr<WebVideoFullscreenManager> strongThis(this);
+    dispatch_async(dispatch_get_main_queue(), [strongThis, this, contextId] {
+        m_page->send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(contextId), m_page->pageID());
+    });
 }
     
 void WebVideoFullscreenManager::didEnterFullscreen(uint64_t contextId)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to