<!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>[182439] 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/182439">182439</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2015-04-06 15:02:46 -0700 (Mon, 06 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Synchronize fullscreen animation between processes.
https://bugs.webkit.org/show_bug.cgi?id=143131

Reviewed by Simon Fraser.

Source/WebCore:

Rather than attempt to synchcronize animations across the WebProcess / UIProcess boundary,
do the bounds-change animation in-process by applying a sublayer transformation to the
video layer. This gives the same visual effect as a synchronized bounds animation, but
without needing a synchronization fence. Resolve the difference between the transformation
and bounds by doing a fence-synchronized bounds change after the current animation is
scheduled to complete.

To do this calculation correctly, WebAVPlayer needs to query both the effective
videoLayerFrame and the videoLayerGravity. To that end, add getter methods for
videoLayerFrame() and videoLayerGravity().

* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::videoFullscreenGravity):
* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
(-[WebAVVideoLayer dealloc]): Cancel outstanding performSelector requests.
(-[WebAVVideoLayer setBounds:]): Add a scale transform to simulate a bonuds change.
(-[WebAVVideoLayer resolveBounds]): Reset the scale transform and set the bounds.
(WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal): Set the initial video frame bounds.
(-[WebAVPlayerController layoutSublayersOfLayer:]): Deleted.
* platform/ios/WebVideoFullscreenModel.h:
* platform/ios/WebVideoFullscreenModelVideoElement.h:
* platform/ios/WebVideoFullscreenModelVideoElement.mm:
(WebVideoFullscreenModelVideoElement::videoLayerFrame): Added; simple getter.
(WebVideoFullscreenModelVideoElement::videoLayerGravity): Ditto.

Source/WebKit2:

Support synchronize resizing by animating within the UIProcess. Since setVideoLayerFrameFenced() is now only
ever called from within a 0-duration transaction, make that the official contract of the function and wrap
the WebProcess side of that method in its own 0-duration transaction.

* Platform/spi/ios/BackBoardServicesSPI.h: Added.
* Platform/spi/ios/UIKitSPI.h:
* UIProcess/ios/WebVideoFullscreenManagerProxy.h:
* UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
(WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID): Remember the initial rect.
(WebKit::WebVideoFullscreenManagerProxy::videoLayerFrame): Added; simple getter.
(WebKit::WebVideoFullscreenManagerProxy::setVideoLayerFrame): Use a different synchronization fence primative.
    Save the cached frame value.
(WebKit::WebVideoFullscreenManagerProxy::videoLayerGravity): Added; simple getter.
(WebKit::WebVideoFullscreenManagerProxy::setVideoLayerGravity): Save the cached gravity value.
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::setVideoLayerFrameFenced): Wrap in a 0-length transaction.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementh">trunk/Source/WebCore/html/HTMLMediaElement.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenInterfaceAVKitmm">trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenModelh">trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenModelVideoElementh">trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenModelVideoElementmm">trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2PlatformspiiosUIKitSPIh">trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxyh">trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxymm">trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagermm">trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2PlatformspiiosBackBoardServicesSPIh">trunk/Source/WebKit2/Platform/spi/ios/BackBoardServicesSPI.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebCore/ChangeLog        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2015-04-06  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        Synchronize fullscreen animation between processes.
+        https://bugs.webkit.org/show_bug.cgi?id=143131
+
+        Reviewed by Simon Fraser.
+
+        Rather than attempt to synchcronize animations across the WebProcess / UIProcess boundary,
+        do the bounds-change animation in-process by applying a sublayer transformation to the
+        video layer. This gives the same visual effect as a synchronized bounds animation, but
+        without needing a synchronization fence. Resolve the difference between the transformation
+        and bounds by doing a fence-synchronized bounds change after the current animation is
+        scheduled to complete.
+
+        To do this calculation correctly, WebAVPlayer needs to query both the effective
+        videoLayerFrame and the videoLayerGravity. To that end, add getter methods for
+        videoLayerFrame() and videoLayerGravity().
+
+        * html/HTMLMediaElement.h:
+        (WebCore::HTMLMediaElement::videoFullscreenGravity):
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+        (-[WebAVVideoLayer dealloc]): Cancel outstanding performSelector requests.
+        (-[WebAVVideoLayer setBounds:]): Add a scale transform to simulate a bonuds change.
+        (-[WebAVVideoLayer resolveBounds]): Reset the scale transform and set the bounds.
+        (WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal): Set the initial video frame bounds.
+        (-[WebAVPlayerController layoutSublayersOfLayer:]): Deleted.
+        * platform/ios/WebVideoFullscreenModel.h:
+        * platform/ios/WebVideoFullscreenModelVideoElement.h:
+        * platform/ios/WebVideoFullscreenModelVideoElement.mm:
+        (WebVideoFullscreenModelVideoElement::videoLayerFrame): Added; simple getter.
+        (WebVideoFullscreenModelVideoElement::videoLayerGravity): Ditto.
+
</ins><span class="cx"> 2015-04-06  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simple line layout: RunResolver::Iterator class cleanup.
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -130,6 +130,7 @@
</span><span class="cx">     void setVideoFullscreenLayer(PlatformLayer*);
</span><span class="cx">     void setVideoFullscreenFrame(FloatRect);
</span><span class="cx">     void setVideoFullscreenGravity(MediaPlayer::VideoGravity);
</span><ins>+    MediaPlayer::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     enum DelayedActionType {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenInterfaceAVKitmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -519,20 +519,6 @@
</span><span class="cx"> {
</span><span class="cx">     return [NSSet setWithObjects:@&quot;externalPlaybackActive&quot;, nil];
</span><span class="cx"> }
</span><del>-
-- (void)layoutSublayersOfLayer:(CALayer *)layer
-{
-    CGRect layerBounds = [layer bounds];
-    if (self.delegate)
-        self.delegate-&gt;setVideoLayerFrame(CGRectMake(0, 0, CGRectGetWidth(layerBounds), CGRectGetHeight(layerBounds)));
-    
-    [CATransaction begin];
-    for (CALayer *sublayer in [layer sublayers]) {
-        [sublayer setAnchorPoint:CGPointMake(0.5, 0.5)];
-        [sublayer setPosition:CGPointMake(CGRectGetMidX(layerBounds), CGRectGetMidY(layerBounds))];
-    }
-    [CATransaction commit];
-}
</del><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @interface WebAVMediaSelectionOption : NSObject
</span><span class="lines">@@ -575,6 +561,12 @@
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)dealloc
+{
+    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resolveBounds) object:nil];
+    [super dealloc];
+}
+
</ins><span class="cx"> - (void)setPlayerController:(AVPlayerController *)playerController
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!playerController || [playerController isKindOfClass:[WebAVPlayerController class]]);
</span><span class="lines">@@ -621,27 +613,43 @@
</span><span class="cx"> {
</span><span class="cx">     [super setBounds:bounds];
</span><span class="cx"> 
</span><ins>+    [_videoSublayer setPosition:CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))];
+
</ins><span class="cx">     if (![_avPlayerController delegate] || !_avPlayerViewController)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    UIView* rootView = [[_avPlayerViewController view] window];
-    if (!rootView)
</del><ins>+    FloatRect videoFrame = [_avPlayerController delegate]-&gt;videoLayerFrame();
+    FloatRect targetFrame;
+    switch ([_avPlayerController delegate]-&gt;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];
+
+    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resolveBounds) object:nil];
+    [self performSelector:@selector(resolveBounds) withObject:nil afterDelay:[CATransaction animationDuration] + 0.1];
+}
+
+- (void)resolveBounds
+{
+    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resolveBounds) object:nil];
+    if (!_avPlayerController || ![_avPlayerController delegate])
</ins><span class="cx">         return;
</span><del>-    
</del><ins>+
</ins><span class="cx">     [CATransaction begin];
</span><del>-    NSTimeInterval animationDuration = [self animationForKey:@&quot;bounds&quot;].duration;
-    if (!animationDuration) // a duration of 0 for CA means 0.25. This is a way to approximate 0.
-        animationDuration = 0.001;
-    [CATransaction setAnimationDuration:animationDuration];
-    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
</del><ins>+    [CATransaction setAnimationDuration:0];
</ins><span class="cx"> 
</span><del>-    FloatRect rootBounds = [rootView bounds];
-    [_avPlayerController delegate]-&gt;setVideoLayerFrame(rootBounds);
</del><ins>+    [_videoSublayer setSublayerTransform:CATransform3DIdentity];
+    [_avPlayerController delegate]-&gt;setVideoLayerFrame([self bounds]);
</ins><span class="cx"> 
</span><del>-    FloatRect sourceBounds = largestRectWithAspectRatioInsideRect(CGRectGetWidth(bounds) / CGRectGetHeight(bounds), rootBounds);
-    CATransform3D transform = CATransform3DMakeScale(bounds.size.width / sourceBounds.width(), bounds.size.height / sourceBounds.height(), 1);
-    [_videoSublayer setPosition:CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))];
-    [_videoSublayer setSublayerTransform:transform];
</del><span class="cx">     [CATransaction commit];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -905,6 +913,8 @@
</span><span class="cx">     CGSize videoSize = [m_playerController contentDimensions];
</span><span class="cx">     CGRect videoRect = CGRectMake(0, 0, videoSize.width, videoSize.height);
</span><span class="cx">     [m_videoLayerContainer setVideoRect:videoRect];
</span><ins>+    if (m_videoFullscreenModel)
+        m_videoFullscreenModel-&gt;setVideoLayerFrame(videoRect);
</ins><span class="cx"> 
</span><span class="cx">     m_playerViewController = adoptNS([allocAVPlayerViewControllerInstance() initWithVideoLayer:m_videoLayerContainer.get()]);
</span><span class="cx">     [m_playerViewController setShowsPlaybackControls:NO];
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenModelh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenModel.h        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -48,8 +48,10 @@
</span><span class="cx">     virtual void endScanning() = 0;
</span><span class="cx">     virtual void requestExitFullscreen() = 0;
</span><span class="cx">     virtual void setVideoLayerFrame(FloatRect) = 0;
</span><ins>+    virtual FloatRect videoLayerFrame() const = 0;
</ins><span class="cx">     enum VideoGravity { VideoGravityResize, VideoGravityResizeAspect, VideoGravityResizeAspectFill };
</span><span class="cx">     virtual void setVideoLayerGravity(VideoGravity) = 0;
</span><ins>+    virtual VideoGravity videoLayerGravity() const = 0;
</ins><span class="cx">     virtual void selectAudioMediaOption(uint64_t index) = 0;
</span><span class="cx">     virtual void selectLegibleMediaOption(uint64_t index) = 0;
</span><span class="cx">     virtual void fullscreenModeChanged(HTMLMediaElement::VideoFullscreenMode) = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenModelVideoElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.h        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -68,7 +68,9 @@
</span><span class="cx">     WEBCORE_EXPORT virtual void endScanning() override;
</span><span class="cx">     WEBCORE_EXPORT virtual void requestExitFullscreen() override;
</span><span class="cx">     WEBCORE_EXPORT virtual void setVideoLayerFrame(FloatRect) override;
</span><del>-    WEBCORE_EXPORT virtual void setVideoLayerGravity(WebVideoFullscreenModel::VideoGravity) override;
</del><ins>+    WEBCORE_EXPORT virtual FloatRect videoLayerFrame() const override;
+    WEBCORE_EXPORT virtual void setVideoLayerGravity(VideoGravity) override;
+    WEBCORE_EXPORT virtual VideoGravity videoLayerGravity() const override;
</ins><span class="cx">     WEBCORE_EXPORT virtual void selectAudioMediaOption(uint64_t index) override;
</span><span class="cx">     WEBCORE_EXPORT virtual void selectLegibleMediaOption(uint64_t index) override;
</span><span class="cx">     WEBCORE_EXPORT virtual void fullscreenModeChanged(HTMLMediaElement::VideoFullscreenMode) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenModelVideoElementmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -288,6 +288,11 @@
</span><span class="cx">     m_videoElement-&gt;setVideoFullscreenFrame(rect);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FloatRect WebVideoFullscreenModelVideoElement::videoLayerFrame() const
+{
+    return m_videoFrame;
+}
+
</ins><span class="cx"> void WebVideoFullscreenModelVideoElement::setVideoLayerGravity(WebVideoFullscreenModel::VideoGravity gravity)
</span><span class="cx"> {
</span><span class="cx">     MediaPlayer::VideoGravity videoGravity = MediaPlayer::VideoGravityResizeAspect;
</span><span class="lines">@@ -303,6 +308,21 @@
</span><span class="cx">     m_videoElement-&gt;setVideoFullscreenGravity(videoGravity);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebVideoFullscreenModel::VideoGravity WebVideoFullscreenModelVideoElement::videoLayerGravity() const
+{
+    switch (m_videoElement-&gt;videoFullscreenGravity()) {
+    case MediaPlayer::VideoGravityResize:
+        return VideoGravityResize;
+    case MediaPlayer::VideoGravityResizeAspect:
+        return VideoGravityResizeAspect;
+    case MediaPlayer::VideoGravityResizeAspectFill:
+        return VideoGravityResizeAspectFill;
+    }
+
+    ASSERT_NOT_REACHED();
+    return VideoGravityResize;
+}
+
</ins><span class="cx"> void WebVideoFullscreenModelVideoElement::selectAudioMediaOption(uint64_t selectedAudioIndex)
</span><span class="cx"> {
</span><span class="cx">     AudioTrack* selectedAudioTrack = nullptr;
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebKit2/ChangeLog        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-04-06  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        Synchronize fullscreen animation between processes.
+        https://bugs.webkit.org/show_bug.cgi?id=143131
+
+        Reviewed by Simon Fraser.
+
+        Support synchronize resizing by animating within the UIProcess. Since setVideoLayerFrameFenced() is now only
+        ever called from within a 0-duration transaction, make that the official contract of the function and wrap
+        the WebProcess side of that method in its own 0-duration transaction.
+
+        * Platform/spi/ios/BackBoardServicesSPI.h: Added.
+        * Platform/spi/ios/UIKitSPI.h:
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.h:
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
+        (WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID): Remember the initial rect.
+        (WebKit::WebVideoFullscreenManagerProxy::videoLayerFrame): Added; simple getter.
+        (WebKit::WebVideoFullscreenManagerProxy::setVideoLayerFrame): Use a different synchronization fence primative.
+            Save the cached frame value.
+        (WebKit::WebVideoFullscreenManagerProxy::videoLayerGravity): Added; simple getter.
+        (WebKit::WebVideoFullscreenManagerProxy::setVideoLayerGravity): Save the cached gravity value.
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/ios/WebVideoFullscreenManager.mm:
+        (WebKit::WebVideoFullscreenManager::setVideoLayerFrameFenced): Wrap in a 0-length transaction.
+
</ins><span class="cx"> 2015-04-06  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WK2][iOS] Regression(r182323): ASSERTION FAILED: WebCore::SQLiteDatabaseTracker::hasTransactionInProgress() in NetworkCache::Statistics::initialize()
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformspiiosBackBoardServicesSPIh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/Platform/spi/ios/BackBoardServicesSPI.h (0 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/spi/ios/BackBoardServicesSPI.h                                (rev 0)
+++ trunk/Source/WebKit2/Platform/spi/ios/BackBoardServicesSPI.h        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#import &lt;BackBoardServices/BKSAnimationFence.h&gt;
+#import &lt;BackBoardServices/BKSAnimationFence_Private.h&gt;
+
+#else
+
+@interface BKSAnimationFenceHandle : NSObject
+- (mach_port_t)CAPort;
+@end
+
+#endif // USE(APPLE_INTERNAL_SDK)
</ins></span></pre></div>
<a id="trunkSourceWebKit2PlatformspiiosUIKitSPIh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebKit2/Platform/spi/ios/UIKitSPI.h        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -623,7 +623,10 @@
</span><span class="cx"> - (UIPanGestureRecognizer *)gestureRecognizerForInteractiveTransition:(_UINavigationInteractiveTransitionBase *)interactiveTransition WithTarget:(id)target action:(SEL)action;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><ins>+@class BKSAnimationFenceHandle;
+
</ins><span class="cx"> @interface UIWindow (Details)
</span><ins>++ (BKSAnimationFenceHandle *)_synchronizedDrawingFence;
</ins><span class="cx"> + (mach_port_t)_synchronizeDrawingAcrossProcesses;
</span><span class="cx"> @end
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.h        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -80,12 +80,16 @@
</span><span class="cx">     virtual void beginScanningBackward() override;
</span><span class="cx">     virtual void endScanning() override;
</span><span class="cx">     virtual void setVideoLayerFrame(WebCore::FloatRect) override;
</span><ins>+    virtual WebCore::FloatRect videoLayerFrame() const override;
</ins><span class="cx">     virtual void setVideoLayerGravity(WebCore::WebVideoFullscreenModel::VideoGravity) override;
</span><ins>+    virtual VideoGravity videoLayerGravity() const override;
</ins><span class="cx">     virtual void selectAudioMediaOption(uint64_t) override;
</span><span class="cx">     virtual void selectLegibleMediaOption(uint64_t) override;
</span><span class="cx"> 
</span><span class="cx">     WebPageProxy* m_page;
</span><span class="cx">     RetainPtr&lt;PlatformLayer&gt; m_layerHost;
</span><ins>+    WebCore::FloatRect m_videoLayerFrame;
+    VideoGravity m_videoLayerGravity { VideoGravityResize };
</ins><span class="cx"> };
</span><span class="cx">     
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebVideoFullscreenManagerProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> 
</span><ins>+#import &quot;BackBoardServicesSPI.h&quot;
</ins><span class="cx"> #import &quot;RemoteLayerTreeDrawingAreaProxy.h&quot;
</span><span class="cx"> #import &quot;UIKitSPI.h&quot;
</span><span class="cx"> #import &quot;WebPageProxy.h&quot;
</span><span class="lines">@@ -85,6 +86,8 @@
</span><span class="cx">         [m_layerHost setTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    m_videoLayerFrame = initialRect;
+
</ins><span class="cx">     UIView *parentView = downcast&lt;RemoteLayerTreeDrawingAreaProxy&gt;(*m_page-&gt;drawingArea()).remoteLayerTreeHost().rootLayer();
</span><span class="cx">     setupFullscreen(*m_layerHost.get(), initialRect, parentView, videoFullscreenMode, allowOptimizedFullscreen);
</span><span class="cx"> }
</span><span class="lines">@@ -209,14 +212,30 @@
</span><span class="cx">     m_page-&gt;send(Messages::WebVideoFullscreenManager::EndScanning(), m_page-&gt;pageID());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FloatRect WebVideoFullscreenManagerProxy::videoLayerFrame() const
+{
+    return m_videoLayerFrame;
+}
+
</ins><span class="cx"> void WebVideoFullscreenManagerProxy::setVideoLayerFrame(WebCore::FloatRect frame)
</span><span class="cx"> {
</span><del>-    IPC::Attachment fencePort([UIWindow _synchronizeDrawingAcrossProcesses], MACH_MSG_TYPE_MOVE_SEND);
-    m_page-&gt;send(Messages::WebVideoFullscreenManager::SetVideoLayerFrameFenced(frame, fencePort), m_page-&gt;pageID());
</del><ins>+    m_videoLayerFrame = frame;
+    @autoreleasepool {
+        BKSAnimationFenceHandle* synchronizationFence = [UIWindow _synchronizedDrawingFence];
+        mach_port_name_t fencePort = [synchronizationFence CAPort];
+
+        m_page-&gt;send(Messages::WebVideoFullscreenManager::SetVideoLayerFrameFenced(frame, IPC::Attachment(fencePort, MACH_MSG_TYPE_MOVE_SEND)), m_page-&gt;pageID());
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebCore::WebVideoFullscreenModel::VideoGravity WebVideoFullscreenManagerProxy::videoLayerGravity() const
+{
+    return m_videoLayerGravity;
+}
+
</ins><span class="cx"> void WebVideoFullscreenManagerProxy::setVideoLayerGravity(WebCore::WebVideoFullscreenModel::VideoGravity gravity)
</span><span class="cx"> {
</span><ins>+    m_videoLayerGravity = gravity;
</ins><span class="cx">     m_page-&gt;send(Messages::WebVideoFullscreenManager::SetVideoLayerGravityEnum((unsigned)gravity), m_page-&gt;pageID());
</span><span class="cx"> }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -1698,6 +1698,7 @@
</span><span class="cx">                 CD73BA47131ACC9A00EEDED2 /* WebFullScreenManagerProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD73BA45131ACC8800EEDED2 /* WebFullScreenManagerProxyMessageReceiver.cpp */; };
</span><span class="cx">                 CD73BA4E131ACDB700EEDED2 /* WebFullScreenManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD73BA48131ACD8E00EEDED2 /* WebFullScreenManagerMessageReceiver.cpp */; };
</span><span class="cx">                 CD73BA53131B645B00EEDED2 /* WebFullScreenManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD73BA37131A29FE00EEDED2 /* WebFullScreenManager.cpp */; };
</span><ins>+                CDA041F41ACE2105004A13EC /* BackBoardServicesSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA041F31ACE2105004A13EC /* BackBoardServicesSPI.h */; };
</ins><span class="cx">                 CDC382FE17211799008A2FC3 /* SecItemShimLibrary.mm in Sources */ = {isa = PBXBuildFile; fileRef = 511F8A78138B460900A95F44 /* SecItemShimLibrary.mm */; };
</span><span class="cx">                 CDC38307172117DD008A2FC3 /* CookieStorageShimLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDC382F9172116D3008A2FC3 /* CookieStorageShimLibrary.cpp */; };
</span><span class="cx">                 CDC3830817211890008A2FC3 /* WebProcessShim.dylib in Copy WebProcessShim */ = {isa = PBXBuildFile; fileRef = CDC3830617211799008A2FC3 /* WebProcessShim.dylib */; };
</span><span class="lines">@@ -3953,6 +3954,7 @@
</span><span class="cx">                 CD73BA48131ACD8E00EEDED2 /* WebFullScreenManagerMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebFullScreenManagerMessageReceiver.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD73BA49131ACD8E00EEDED2 /* WebFullScreenManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFullScreenManagerMessages.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD73BA4A131ACD8F00EEDED2 /* WebFullScreenManagerProxyMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFullScreenManagerProxyMessages.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CDA041F31ACE2105004A13EC /* BackBoardServicesSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackBoardServicesSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CDC382F717211506008A2FC3 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = /System/Library/Frameworks/CFNetwork.framework; sourceTree = &quot;&lt;absolute&gt;&quot;; };
</span><span class="cx">                 CDC382F9172116D3008A2FC3 /* CookieStorageShimLibrary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CookieStorageShimLibrary.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDC3830617211799008A2FC3 /* WebProcessShim.dylib */ = {isa = PBXFileReference; explicitFileType = &quot;compiled.mach-o.dylib&quot;; includeInIndex = 0; path = WebProcessShim.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
</span><span class="lines">@@ -7422,6 +7424,7 @@
</span><span class="cx">                 CE1A0BCB1A48E6C60054EF74 /* ios */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                CDA041F31ACE2105004A13EC /* BackBoardServicesSPI.h */,
</ins><span class="cx">                                 CE1A0BCC1A48E6C60054EF74 /* BKSProcessAssertionSPI.h */,
</span><span class="cx">                                 CE1A0BCD1A48E6C60054EF74 /* CorePDFSPI.h */,
</span><span class="cx">                                 CE1A0BCE1A48E6C60054EF74 /* DataDetectorsUISPI.h */,
</span><span class="lines">@@ -7753,6 +7756,7 @@
</span><span class="cx">                                 C58CDF2E1887609F00871536 /* InteractionInformationAtPosition.h in Headers */,
</span><span class="cx">                                 C58CDF2A1887548B00871536 /* InteractionInformationAtPosition.h in Headers */,
</span><span class="cx">                                 1A4832C81A9BC13C008B4DFE /* APIWebsiteDataRecord.h in Headers */,
</span><ins>+                                CDA041F41ACE2105004A13EC /* BackBoardServicesSPI.h in Headers */,
</ins><span class="cx">                                 1AE49A4911FFA8CE0048B464 /* JSNPMethod.h in Headers */,
</span><span class="cx">                                 1AE4987811FF7FAA0048B464 /* JSNPObject.h in Headers */,
</span><span class="cx">                                 518353DF1887128B00D9FE44 /* KeyedDecoder.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessiosWebVideoFullscreenManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm (182438 => 182439)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm        2015-04-06 21:08:26 UTC (rev 182438)
+++ trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm        2015-04-06 22:02:46 UTC (rev 182439)
</span><span class="lines">@@ -272,10 +272,13 @@
</span><span class="cx">     
</span><span class="cx"> void WebVideoFullscreenManager::setVideoLayerFrameFenced(WebCore::FloatRect bounds, IPC::Attachment fencePort)
</span><span class="cx"> {
</span><ins>+    [CATransaction begin];
+    [CATransaction setAnimationDuration:0];
</ins><span class="cx">     if (m_layerHostingContext)
</span><span class="cx">         m_layerHostingContext-&gt;setFencePort(fencePort.port());
</span><span class="cx">     setVideoLayerFrame(bounds);
</span><span class="cx">     mach_port_deallocate(mach_task_self(), fencePort.port());
</span><ins>+    [CATransaction commit];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre>
</div>
</div>

</body>
</html>