<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[170083] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/170083">170083</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-06-17 16:33:16 -0700 (Tue, 17 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Improve enter and exit fullscreen transition by using two step transition.
https://bugs.webkit.org/show_bug.cgi?id=133706

Patch by Jeremy Jones &lt;jeremyj@apple.com&gt; on 2014-06-17
Reviewed by Simon Fraser.

Source/WebCore:
setupFullscreen, creates the fullscreen views ready to receive the video layer.
Once they are in place, didSetupFullscreen will move the video layer into the
new view hierarchy and initiate enterFullscreen to animate.

Reverse process for exit fullscreen.

* WebCore.exp.in: Add exports.
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(-[WebVideoFullscreenController enterFullscreen:]):
Refactor into didSetupFullscreen.
(-[WebVideoFullscreenController didSetupFullscreen]):
Move the video layer once fullscreen is ready to receive it.
(-[WebVideoFullscreenController didExitFullscreen]):
Move the video layer back into we the web page, and initiate cleanup.
(-[WebVideoFullscreenController didCleanupFullscreen]):
Refactord cleanup from didExitFullscreen.
* platform/ios/WebVideoFullscreenInterfaceAVKit.h: Add delcarations.
* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
(WebVideoFullscreenInterfaceAVKit::setupFullscreen):
Refactored from enterFullscreen. Builds views ready to receive video layer.
(WebVideoFullscreenInterfaceAVKit::enterFullscreen):
Animates into fullscreen.
(WebVideoFullscreenInterfaceAVKit::exitFullscreen):
Animates from fullscreen. Cleanup is refactored into cleanupFullscreen()
(WebVideoFullscreenInterfaceAVKit::cleanupFullscreen):
Refactored from exitFullscreen(), removes views.

Source/WebKit2:
Add setupFullscreen()/didSetupFullscreen() and cleanupFullscreen()/didCleanupFullscreen()
to the proxies. And refactor enter/exit fullscreen to do some of the work in setup/cleanup.

* UIProcess/ios/WebVideoFullscreenManagerProxy.h:
Add four methods mentioned above.
* UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in:
Add Setup/Cleanup functions.
* UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
(WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID): does what enterFullscreen used to do.
(WebKit::WebVideoFullscreenManagerProxy::didCleanupFullscreen): forward IPC.
(WebKit::WebVideoFullscreenManagerProxy::didSetupFullscreen): forward IPC.
(WebKit::WebVideoFullscreenManagerProxy::enterFullscreenWithID): changed to enterFullscreen
* WebProcess/ios/WebVideoFullscreenManager.h: Add didSetup/didCleanup
* WebProcess/ios/WebVideoFullscreenManager.messages.in: Add didSetup/didCleanup
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::enterFullscreenForNode): refactored,
some implementation moves to didSetupFullscreen.
(WebKit::WebVideoFullscreenManager::didSetupFullscreen):
Moves the video layer over to the hosted layer, and initiates fullscreen.
(WebKit::WebVideoFullscreenManager::didExitFullscreen): refactored,
some implementation moves to didCleanupFullscreen, and initiates cleanup.
(WebKit::WebVideoFullscreenManager::didCleanupFullscreen):
Final cleanup refactored from didExitFullscreen()</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenControllerAVKitmm">trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenInterfaceAVKith">trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenInterfaceAVKitmm">trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxyh">trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxymessagesin">trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxymm">trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagerh">trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagermessagesin">trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagermm">trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebCore/ChangeLog        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2014-06-17  Jeremy Jones  &lt;jeremyj@apple.com&gt;
+
+        Improve enter and exit fullscreen transition by using two step transition.
+        https://bugs.webkit.org/show_bug.cgi?id=133706
+
+        Reviewed by Simon Fraser.
+
+        setupFullscreen, creates the fullscreen views ready to receive the video layer.
+        Once they are in place, didSetupFullscreen will move the video layer into the 
+        new view hierarchy and initiate enterFullscreen to animate.
+
+        Reverse process for exit fullscreen.
+
+        * WebCore.exp.in: Add exports.
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (-[WebVideoFullscreenController enterFullscreen:]):
+        Refactor into didSetupFullscreen.
+        (-[WebVideoFullscreenController didSetupFullscreen]):
+        Move the video layer once fullscreen is ready to receive it.
+        (-[WebVideoFullscreenController didExitFullscreen]):
+        Move the video layer back into we the web page, and initiate cleanup.
+        (-[WebVideoFullscreenController didCleanupFullscreen]):
+        Refactord cleanup from didExitFullscreen.
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.h: Add delcarations.
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+        (WebVideoFullscreenInterfaceAVKit::setupFullscreen):
+        Refactored from enterFullscreen. Builds views ready to receive video layer.
+        (WebVideoFullscreenInterfaceAVKit::enterFullscreen):
+        Animates into fullscreen.
+        (WebVideoFullscreenInterfaceAVKit::exitFullscreen):
+        Animates from fullscreen. Cleanup is refactored into cleanupFullscreen()
+        (WebVideoFullscreenInterfaceAVKit::cleanupFullscreen):
+        Refactored from exitFullscreen(), removes views.
+
</ins><span class="cx"> 2014-06-17  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove unnecessary Structure flags from generated bindings
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -3400,7 +3400,9 @@
</span><span class="cx"> __ZN7WebCore32WebVideoFullscreenInterfaceAVKit11setDurationEd
</span><span class="cx"> __ZN7WebCore32WebVideoFullscreenInterfaceAVKit14exitFullscreenENS_7IntRectE
</span><span class="cx"> __ZN7WebCore32WebVideoFullscreenInterfaceAVKit14setCurrentTimeEdd
</span><del>-__ZN7WebCore32WebVideoFullscreenInterfaceAVKit15enterFullscreenER7CALayerNS_7IntRectE
</del><ins>+__ZN7WebCore32WebVideoFullscreenInterfaceAVKit15enterFullscreenEv
+__ZN7WebCore32WebVideoFullscreenInterfaceAVKit15setupFullscreenER7CALayerNS_7IntRectE
+__ZN7WebCore32WebVideoFullscreenInterfaceAVKit17cleanupFullscreenEv
</ins><span class="cx"> __ZN7WebCore32WebVideoFullscreenInterfaceAVKit17setSeekableRangesERKNS_10TimeRangesE
</span><span class="cx"> __ZN7WebCore32WebVideoFullscreenInterfaceAVKit18setVideoDimensionsEbff
</span><span class="cx"> __ZN7WebCore32WebVideoFullscreenInterfaceAVKit19setExternalPlaybackEbNS_27WebVideoFullscreenInterface26ExternalPlaybackTargetTypeEN3WTF6StringE
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenControllerAVKitmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -63,16 +63,20 @@
</span><span class="cx"> #else
</span><span class="cx"> 
</span><span class="cx"> @interface WebVideoFullscreenController (FullscreenObservation)
</span><ins>+- (void)didSetupFullscreen;
</ins><span class="cx"> - (void)didEnterFullscreen;
</span><span class="cx"> - (void)didExitFullscreen;
</span><ins>+- (void)didCleanupFullscreen;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> class WebVideoFullscreenControllerChangeObserver : public WebVideoFullscreenChangeObserver {
</span><span class="cx">     WebVideoFullscreenController* _target;
</span><span class="cx"> public:
</span><span class="cx">     void setTarget(WebVideoFullscreenController* target) { _target = target; }
</span><ins>+    virtual void didSetupFullscreen() override { [_target didSetupFullscreen]; }
</ins><span class="cx">     virtual void didEnterFullscreen() override { [_target didEnterFullscreen]; }
</span><span class="cx">     virtual void didExitFullscreen() override { [_target didExitFullscreen]; }
</span><ins>+    virtual void didCleanupFullscreen() override { [_target didCleanupFullscreen]; }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> @implementation WebVideoFullscreenController
</span><span class="lines">@@ -115,15 +119,14 @@
</span><span class="cx">     [self retain]; // Balanced by -release in didExitFullscreen:
</span><span class="cx">     
</span><span class="cx">     UNUSED_PARAM(screen);
</span><del>-    _videoFullscreenLayer = [CALayer layer];
</del><span class="cx">     _interface = adoptRef(new WebVideoFullscreenInterfaceAVKit);
</span><span class="cx">     _interface-&gt;setWebVideoFullscreenChangeObserver(&amp;_changeObserver);
</span><span class="cx">     _model = adoptRef(new WebVideoFullscreenModelMediaElement);
</span><span class="cx">     _model-&gt;setWebVideoFullscreenInterface(_interface.get());
</span><span class="cx">     _interface-&gt;setWebVideoFullscreenModel(_model.get());
</span><span class="cx">     _model-&gt;setMediaElement(_mediaElement.get());
</span><del>-    _model-&gt;setVideoFullscreenLayer(_videoFullscreenLayer.get());
-    _interface-&gt;enterFullscreen(*_videoFullscreenLayer.get(), _mediaElement-&gt;screenRect());
</del><ins>+    _videoFullscreenLayer = [CALayer layer];
+    _interface-&gt;setupFullscreen(*_videoFullscreenLayer.get(), _mediaElement-&gt;screenRect());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)exitFullscreen
</span><span class="lines">@@ -137,6 +140,12 @@
</span><span class="cx">         _interface-&gt;requestHideAndExitFullscreen();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)didSetupFullscreen
+{
+    _model-&gt;setVideoFullscreenLayer(_videoFullscreenLayer.get());
+    _interface-&gt;enterFullscreen();
+}
+
</ins><span class="cx"> - (void)didEnterFullscreen
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -144,9 +153,17 @@
</span><span class="cx"> - (void)didExitFullscreen
</span><span class="cx"> {
</span><span class="cx">     WebThreadRun(^{
</span><ins>+        _model-&gt;setVideoFullscreenLayer(nil);
+        _interface-&gt;cleanupFullscreen();
+    });
+}
+
+- (void)didCleanupFullscreen
+{
+    WebThreadRun(^{
</ins><span class="cx">         _interface-&gt;setWebVideoFullscreenModel(nullptr);
</span><span class="cx">         _model-&gt;setWebVideoFullscreenInterface(nullptr);
</span><del>-        _model-&gt;setVideoFullscreenLayer(nullptr);
</del><ins>+        _model-&gt;setVideoFullscreenLayer(nil);
</ins><span class="cx">         _model-&gt;setMediaElement(nullptr);
</span><span class="cx">         _interface-&gt;setWebVideoFullscreenChangeObserver(nullptr);
</span><span class="cx">         _model = nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenInterfaceAVKith"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -49,8 +49,10 @@
</span><span class="cx"> class WebVideoFullscreenChangeObserver {
</span><span class="cx"> public:
</span><span class="cx">     virtual ~WebVideoFullscreenChangeObserver() { };
</span><ins>+    virtual void didSetupFullscreen() = 0;
</ins><span class="cx">     virtual void didEnterFullscreen() = 0;
</span><span class="cx">     virtual void didExitFullscreen() = 0;
</span><ins>+    virtual void didCleanupFullscreen() = 0;
</ins><span class="cx"> };
</span><span class="cx">     
</span><span class="cx"> class WebVideoFullscreenInterfaceAVKit
</span><span class="lines">@@ -85,8 +87,10 @@
</span><span class="cx">     virtual void setLegibleMediaSelectionOptions(const Vector&lt;String&gt;&amp; options, uint64_t selectedIndex) override;
</span><span class="cx">     virtual void setExternalPlayback(bool enabled, ExternalPlaybackTargetType, String localizedDeviceName) override;
</span><span class="cx"> 
</span><del>-    virtual void enterFullscreen(PlatformLayer&amp;, WebCore::IntRect initialRect);
</del><ins>+    virtual void setupFullscreen(PlatformLayer&amp;, WebCore::IntRect initialRect);
+    virtual void enterFullscreen();
</ins><span class="cx">     virtual void exitFullscreen(WebCore::IntRect finalRect);
</span><ins>+    virtual void cleanupFullscreen();
</ins><span class="cx">     virtual void invalidate();
</span><span class="cx">     virtual void requestHideAndExitFullscreen();
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenInterfaceAVKitmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -688,7 +688,7 @@
</span><span class="cx">     [m_videoLayerContainer.get() setHidden:enabled];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebVideoFullscreenInterfaceAVKit::enterFullscreen(PlatformLayer&amp; videoLayer, WebCore::IntRect initialRect)
</del><ins>+void WebVideoFullscreenInterfaceAVKit::setupFullscreen(PlatformLayer&amp; videoLayer, WebCore::IntRect initialRect)
</ins><span class="cx"> {
</span><span class="cx">     __block RefPtr&lt;WebVideoFullscreenInterfaceAVKit&gt; protect(this);
</span><span class="cx">     
</span><span class="lines">@@ -710,6 +710,7 @@
</span><span class="cx">         [m_videoLayerContainer setVideoRect:videoRect];
</span><span class="cx"> 
</span><span class="cx">         m_playerViewController = adoptNS([[classAVPlayerViewController alloc] initWithVideoLayer:m_videoLayerContainer.get()]);
</span><ins>+        [m_playerViewController setShowsPlaybackControls:NO];
</ins><span class="cx">         [m_playerViewController setPlayerController:(AVPlayerController *)playerController()];
</span><span class="cx">         [m_playerViewController setDelegate:playerController()];
</span><span class="cx">         [m_videoLayerContainer setPlayerViewController:m_playerViewController.get()];
</span><span class="lines">@@ -727,46 +728,45 @@
</span><span class="cx">         [m_playerViewController didMoveToParentViewController:m_viewController.get()];
</span><span class="cx">         [[m_playerViewController view] layoutIfNeeded];
</span><span class="cx"> 
</span><del>-        __block RefPtr&lt;WebVideoFullscreenInterfaceAVKit&gt; protect2(this);
-
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [m_playerViewController enterFullScreenWithCompletionHandler:^(BOOL, NSError*){
-                if (m_fullscreenChangeObserver)
-                    m_fullscreenChangeObserver-&gt;didEnterFullscreen();
-                protect2.clear();
-            }];
-        });
-
</del><span class="cx">         [CATransaction commit];
</span><del>-
</del><ins>+        
+        if (m_fullscreenChangeObserver)
+            m_fullscreenChangeObserver-&gt;didSetupFullscreen();
+        
</ins><span class="cx">         protect.clear();
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebVideoFullscreenInterfaceAVKit::enterFullscreen()
+{
+    __block RefPtr&lt;WebVideoFullscreenInterfaceAVKit&gt; protect(this);
+    
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [m_playerViewController enterFullScreenWithCompletionHandler:^(BOOL, NSError*)
+        {
+            [m_playerViewController setShowsPlaybackControls:YES];
+            if (m_fullscreenChangeObserver)
+                m_fullscreenChangeObserver-&gt;didEnterFullscreen();
+            protect.clear();
+        }];
+    });
+}
+
</ins><span class="cx"> void WebVideoFullscreenInterfaceAVKit::exitFullscreen(WebCore::IntRect finalRect)
</span><span class="cx"> {
</span><span class="cx">     __block RefPtr&lt;WebVideoFullscreenInterfaceAVKit&gt; protect(this);
</span><del>-
</del><ins>+    
</ins><span class="cx">     m_playerController.clear();
</span><span class="cx">     
</span><span class="cx">     dispatch_async(dispatch_get_main_queue(), ^{
</span><ins>+        [m_playerViewController setShowsPlaybackControls:NO];
</ins><span class="cx">         [m_playerViewController view].frame = finalRect;
</span><span class="cx">         if ([m_videoLayerContainer videoLayerGravity] != AVVideoLayerGravityResizeAspect)
</span><span class="cx">             [m_videoLayerContainer setVideoLayerGravity:AVVideoLayerGravityResizeAspect];
</span><del>-        [m_playerViewController exitFullScreenWithCompletionHandler:^(BOOL, NSError*){
-            [m_window setHidden:YES];
-            [m_window setRootViewController:nil];
-            [m_playerViewController setDelegate:nil];
-            [m_playerViewController setPlayerController:nil];
-            m_playerViewController = nil;
-            m_viewController = nil;
-            m_window = nil;
-            [m_videoLayer removeFromSuperlayer];
-            m_videoLayer = nil;
-            [m_videoLayerContainer removeFromSuperlayer];
-            [m_videoLayerContainer setPlayerViewController:nil];
-            m_videoLayerContainer = nil;
-
</del><ins>+        [[m_playerViewController view] layoutIfNeeded];
+        [m_playerViewController exitFullScreenWithCompletionHandler:^(BOOL, NSError*)
+        {
+            [[m_playerViewController view] setBackgroundColor:[classUIColor clearColor]];
</ins><span class="cx">             if (m_fullscreenChangeObserver)
</span><span class="cx">                 m_fullscreenChangeObserver-&gt;didExitFullscreen();
</span><span class="cx">             protect.clear();
</span><span class="lines">@@ -774,6 +774,30 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebVideoFullscreenInterfaceAVKit::cleanupFullscreen()
+{
+    __block RefPtr&lt;WebVideoFullscreenInterfaceAVKit&gt; protect(this);
+    
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [m_window setHidden:YES];
+        [m_window setRootViewController:nil];
+        [m_playerViewController setDelegate:nil];
+        [m_playerViewController setPlayerController:nil];
+        m_playerViewController = nil;
+        m_viewController = nil;
+        m_window = nil;
+        [m_videoLayer removeFromSuperlayer];
+        m_videoLayer = nil;
+        [m_videoLayerContainer removeFromSuperlayer];
+        [m_videoLayerContainer setPlayerViewController:nil];
+        m_videoLayerContainer = nil;
+        
+        if (m_fullscreenChangeObserver)
+            m_fullscreenChangeObserver-&gt;didCleanupFullscreen();
+        protect.clear();
+    });
+}
+
</ins><span class="cx"> void WebVideoFullscreenInterfaceAVKit::invalidate()
</span><span class="cx"> {
</span><span class="cx">     m_playerController.clear();
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/ChangeLog        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2014-06-17  Jeremy Jones  &lt;jeremyj@apple.com&gt;
+
+        Improve enter and exit fullscreen transition by using two step transition.
+        https://bugs.webkit.org/show_bug.cgi?id=133706
+
+        Reviewed by Simon Fraser.
+
+        Add setupFullscreen()/didSetupFullscreen() and cleanupFullscreen()/didCleanupFullscreen()
+        to the proxies. And refactor enter/exit fullscreen to do some of the work in setup/cleanup.
+
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.h:
+        Add four methods mentioned above.
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in:
+        Add Setup/Cleanup functions.
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
+        (WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID): does what enterFullscreen used to do.
+        (WebKit::WebVideoFullscreenManagerProxy::didCleanupFullscreen): forward IPC.
+        (WebKit::WebVideoFullscreenManagerProxy::didSetupFullscreen): forward IPC.
+        (WebKit::WebVideoFullscreenManagerProxy::enterFullscreenWithID): changed to enterFullscreen
+        * WebProcess/ios/WebVideoFullscreenManager.h: Add didSetup/didCleanup
+        * WebProcess/ios/WebVideoFullscreenManager.messages.in: Add didSetup/didCleanup
+        * WebProcess/ios/WebVideoFullscreenManager.mm: 
+        (WebKit::WebVideoFullscreenManager::enterFullscreenForNode): refactored,
+        some implementation moves to didSetupFullscreen.
+        (WebKit::WebVideoFullscreenManager::didSetupFullscreen):
+        Moves the video layer over to the hosted layer, and initiates fullscreen.
+        (WebKit::WebVideoFullscreenManager::didExitFullscreen): refactored,
+        some implementation moves to didCleanupFullscreen, and initiates cleanup.
+        (WebKit::WebVideoFullscreenManager::didCleanupFullscreen):
+        Final cleanup refactored from didExitFullscreen()
+
</ins><span class="cx"> 2014-06-17  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] enable background audio in WK2
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -55,13 +55,15 @@
</span><span class="cx">     virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&amp;) override;
</span><span class="cx"> 
</span><span class="cx">     // Translate to FullscreenInterface
</span><del>-    void enterFullscreenWithID(uint32_t, WebCore::IntRect initialRect);
</del><ins>+    void setupFullscreenWithID(uint32_t, WebCore::IntRect initialRect);
</ins><span class="cx">     void setSeekableRangesVector(Vector&lt;std::pair&lt;double, double&gt;&gt;&amp;);
</span><span class="cx">     void setExternalPlaybackProperties(bool enabled, uint32_t targetType, String localizedDeviceName);
</span><span class="cx">     
</span><span class="cx">     // Fullscreen Observer
</span><ins>+    virtual void didSetupFullscreen() override;
+    virtual void didEnterFullscreen() override;
</ins><span class="cx">     virtual void didExitFullscreen() override;
</span><del>-    virtual void didEnterFullscreen() override;
</del><ins>+    virtual void didCleanupFullscreen() override;
</ins><span class="cx">     
</span><span class="cx">     // FullscreenModel
</span><span class="cx">     virtual void play() override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -30,7 +30,9 @@
</span><span class="cx">     SetExternalPlaybackProperties(bool enabled, uint32_t targetType, String localizedDeviceName);
</span><span class="cx">     SetDuration(double duration)
</span><span class="cx">     SetRate(bool isPlaying, double rate)
</span><del>-    EnterFullscreenWithID(uint32_t videoLayerID, WebCore::IntRect initialRect)
</del><ins>+    SetupFullscreenWithID(uint32_t videoLayerID, WebCore::IntRect initialRect)
+    EnterFullscreen()
</ins><span class="cx">     ExitFullscreen(WebCore::IntRect finalRect)
</span><ins>+    CleanupFullscreen()
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -71,11 +71,11 @@
</span><span class="cx">     m_layerHost.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebVideoFullscreenManagerProxy::enterFullscreenWithID(uint32_t videoLayerID, WebCore::IntRect initialRect)
</del><ins>+void WebVideoFullscreenManagerProxy::setupFullscreenWithID(uint32_t videoLayerID, WebCore::IntRect initialRect)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(videoLayerID);
</span><span class="cx">     m_layerHost = WKMakeRenderLayer(videoLayerID);
</span><del>-    enterFullscreen(*m_layerHost.get(), initialRect);
</del><ins>+    setupFullscreen(*m_layerHost.get(), initialRect);
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> void WebVideoFullscreenManagerProxy::setSeekableRangesVector(Vector&lt;std::pair&lt;double, double&gt;&gt;&amp; ranges)
</span><span class="lines">@@ -112,7 +112,17 @@
</span><span class="cx">     [m_layerHost removeFromSuperlayer];
</span><span class="cx">     m_layerHost.clear();
</span><span class="cx"> }
</span><ins>+    
+void WebVideoFullscreenManagerProxy::didCleanupFullscreen()
+{
+    m_page-&gt;send(Messages::WebVideoFullscreenManager::DidCleanupFullscreen(), m_page-&gt;pageID());
+}
</ins><span class="cx"> 
</span><ins>+void WebVideoFullscreenManagerProxy::didSetupFullscreen()
+{
+    m_page-&gt;send(Messages::WebVideoFullscreenManager::DidSetupFullscreen(), m_page-&gt;pageID());
+}
+
</ins><span class="cx"> void WebVideoFullscreenManagerProxy::didEnterFullscreen()
</span><span class="cx"> {
</span><span class="cx">     m_page-&gt;send(Messages::WebVideoFullscreenManager::DidEnterFullscreen(), m_page-&gt;pageID());
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.h (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.h        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.h        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -76,8 +76,10 @@
</span><span class="cx">     virtual void setExternalPlayback(bool enabled, WebVideoFullscreenInterface::ExternalPlaybackTargetType, String localizedDeviceName) override;
</span><span class="cx"> 
</span><span class="cx">     // additional incoming
</span><ins>+    virtual void didSetupFullscreen();
</ins><span class="cx">     virtual void didEnterFullscreen();
</span><span class="cx">     virtual void didExitFullscreen();
</span><ins>+    virtual void didCleanupFullscreen();
</ins><span class="cx">     virtual void setVideoLayerGravityEnum(unsigned);
</span><span class="cx">     
</span><span class="cx">     WebPage* m_page;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagermessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.messages.in (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.messages.in        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.messages.in        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -33,8 +33,10 @@
</span><span class="cx">     BeginScanningBackward()
</span><span class="cx">     EndScanning()
</span><span class="cx">     RequestExitFullscreen()
</span><ins>+    DidSetupFullscreen()
</ins><span class="cx">     DidExitFullscreen()
</span><span class="cx">     DidEnterFullscreen()
</span><ins>+    DidCleanupFullscreen()
</ins><span class="cx">     SetVideoLayerFrame(WebCore::FloatRect bounds)
</span><span class="cx">     SetVideoLayerGravityEnum(unsigned gravity)
</span><span class="cx">     SelectAudioMediaOption(uint64_t index)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm (170082 => 170083)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm        2014-06-17 23:05:48 UTC (rev 170082)
+++ trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm        2014-06-17 23:33:16 UTC (rev 170083)
</span><span class="lines">@@ -22,28 +22,28 @@
</span><span class="cx">  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><del>-#include &quot;config.h&quot;
-#include &quot;WebVideoFullscreenManager.h&quot;
</del><ins>+#import &quot;config.h&quot;
+#import &quot;WebVideoFullscreenManager.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> 
</span><del>-#include &quot;WebCoreArgumentCoders.h&quot;
-#include &quot;WebPage.h&quot;
-#include &quot;WebProcess.h&quot;
-#include &quot;WebVideoFullscreenManagerMessages.h&quot;
-#include &quot;WebVideoFullscreenManagerProxyMessages.h&quot;
-#include &lt;QuartzCore/CoreAnimation.h&gt;
-#include &lt;WebCore/Event.h&gt;
-#include &lt;WebCore/EventNames.h&gt;
-#include &lt;WebCore/FrameView.h&gt;
-#include &lt;WebCore/HTMLVideoElement.h&gt;
-#include &lt;WebCore/PlatformCALayer.h&gt;
-#include &lt;WebCore/RenderLayer.h&gt;
-#include &lt;WebCore/RenderLayerBacking.h&gt;
-#include &lt;WebCore/RenderView.h&gt;
-#include &lt;WebCore/Settings.h&gt;
-#include &lt;WebCore/TimeRanges.h&gt;
-#include &lt;WebCore/WebCoreThreadRun.h&gt;
</del><ins>+#import &quot;WebCoreArgumentCoders.h&quot;
+#import &quot;WebPage.h&quot;
+#import &quot;WebProcess.h&quot;
+#import &quot;WebVideoFullscreenManagerMessages.h&quot;
+#import &quot;WebVideoFullscreenManagerProxyMessages.h&quot;
+#import &lt;QuartzCore/CoreAnimation.h&gt;
+#import &lt;WebCore/Event.h&gt;
+#import &lt;WebCore/EventNames.h&gt;
+#import &lt;WebCore/FrameView.h&gt;
+#import &lt;WebCore/HTMLVideoElement.h&gt;
+#import &lt;WebCore/PlatformCALayer.h&gt;
+#import &lt;WebCore/RenderLayer.h&gt;
+#import &lt;WebCore/RenderLayerBacking.h&gt;
+#import &lt;WebCore/RenderView.h&gt;
+#import &lt;WebCore/Settings.h&gt;
+#import &lt;WebCore/TimeRanges.h&gt;
+#import &lt;WebCore/WebCoreThreadRun.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="lines">@@ -94,15 +94,9 @@
</span><span class="cx">     m_isAnimating = true;
</span><span class="cx">     setMediaElement(toHTMLMediaElement(node));
</span><span class="cx"> 
</span><del>-    PlatformLayer* videoLayer = [CALayer layer];
-#ifndef NDEBUG
-    [videoLayer setName:@&quot;Web video fullscreen manager layer&quot;];
-#endif
</del><span class="cx">     m_layerHostingContext = LayerHostingContext::createForExternalHostingProcess();
</span><del>-    m_layerHostingContext-&gt;setRootLayer(videoLayer);
-    setVideoFullscreenLayer(videoLayer);
-
-    m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreenWithID(m_layerHostingContext-&gt;contextID(), screenRectForNode(node)), m_page-&gt;pageID());
</del><ins>+    
+    m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::SetupFullscreenWithID(m_layerHostingContext-&gt;contextID(), screenRectForNode(node)), m_page-&gt;pageID());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebVideoFullscreenManager::exitFullscreenForNode(Node* node)
</span><span class="lines">@@ -165,7 +159,19 @@
</span><span class="cx"> {
</span><span class="cx">     m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::SetExternalPlaybackProperties(enabled, static_cast&lt;uint32_t&gt;(targetType), localizedDeviceName), m_page-&gt;pageID());
</span><span class="cx"> }
</span><del>-
</del><ins>+    
+void WebVideoFullscreenManager::didSetupFullscreen()
+{
+    PlatformLayer* videoLayer = [CALayer layer];
+#ifndef NDEBUG
+    [videoLayer setName:@&quot;Web video fullscreen manager layer&quot;];
+#endif
+    
+    m_layerHostingContext-&gt;setRootLayer(videoLayer);
+    setVideoFullscreenLayer(videoLayer);
+    m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(), m_page-&gt;pageID());
+}
+    
</ins><span class="cx"> void WebVideoFullscreenManager::didEnterFullscreen()
</span><span class="cx"> {
</span><span class="cx">     m_isAnimating = false;
</span><span class="lines">@@ -184,13 +190,22 @@
</span><span class="cx"> 
</span><span class="cx"> void WebVideoFullscreenManager::didExitFullscreen()
</span><span class="cx"> {
</span><ins>+    setVideoFullscreenLayer(nil);
+    __block RefPtr&lt;WebVideoFullscreenModelMediaElement&gt; protect(this);
+
+    dispatch_async(dispatch_get_main_queue(), ^{
+        m_layerHostingContext-&gt;setRootLayer(nullptr);
+        m_layerHostingContext = nullptr;
+        m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::CleanupFullscreen(), m_page-&gt;pageID());
+        protect.clear();
+    });
+}
+    
+void WebVideoFullscreenManager::didCleanupFullscreen()
+{
</ins><span class="cx">     m_isAnimating = false;
</span><span class="cx">     m_isFullscreen = false;
</span><del>-
-    m_layerHostingContext-&gt;setRootLayer(nullptr);
-    m_layerHostingContext = nullptr;
-    setVideoFullscreenLayer(nullptr);
-
</del><ins>+    
</ins><span class="cx">     setMediaElement(nullptr);
</span><span class="cx"> 
</span><span class="cx">     if (!m_targetIsFullscreen)
</span></span></pre>
</div>
</div>

</body>
</html>