<!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>[201474] 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/201474">201474</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-05-27 16:58:28 -0700 (Fri, 27 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Decrease flicker when changing video presentation mode.
https://bugs.webkit.org/show_bug.cgi?id=158148
rdar://problem/24476949

Patch by Jeremy Jones &lt;jeremyj@apple.com&gt; on 2016-05-27
Source/WebCore:

Reviewed by Jer Noble.

No new tests because there is no behavior change. This change is about the timing of
moving AVPlayerLayers between layers to prevent flicker.

1) Moving an AVPlayerLayer between CAContexts can flicker. So always keep two
AVPlayerLayers around and add and remove them from the inline and fullscreen contexts.
2) Wait to show the inline placeholder until the fullscreen video layer has been installed.
3) Wait to remove the fullscreen video layer until the placeholder has been removed.

* Modules/mediacontrols/MediaControlsHost.cpp:
(WebCore::MediaControlsHost::isVideoLayerInline): Expose isVideoLayerInline to the shadow DOM.
(WebCore::MediaControlsHost::setPreparedForInline): Expose setPreparedForInline to the shadow DOM.
* Modules/mediacontrols/MediaControlsHost.h: Add setPreparedForInline and isVideoLayerInline
* Modules/mediacontrols/MediaControlsHost.idl: Add setPreparedForInline and isVideoLayerInline
* Modules/mediacontrols/mediaControlsApple.js:
(Controller.prototype.showInlinePlaybackPlaceholderWhenSafe): Wait to show placeholder when entering fullscreen.
(Controller.prototype.handlePresentationModeChange): Wait to show placeholder, and notify when placeholder is removed.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setPreparedForInline):
(WebCore::HTMLMediaElement::waitForPreparedForInlineThen): Used to delay fullscreen cleanup until placeholder is removed.
(WebCore::HTMLMediaElement::setVideoFullscreenLayer): Add a callback so we can wait until this completes before continuing.
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::isVideoLayerInline):
(WebCore::HTMLMediaElement::waitForPreparedForInlineThen):
(WebCore::HTMLMediaElement::setVideoFullscreenLayer): Add completionHandler.
* platform/cocoa/WebVideoFullscreenModelVideoElement.h:
(WebCore::WebVideoFullscreenModelVideoElement::setVideoFullscreenLayer): Add completionHandler.
(WebCore::WebVideoFullscreenModelVideoElement::waitForPreparedForInlineThen): Added.
* platform/cocoa/WebVideoFullscreenModelVideoElement.mm:
(WebVideoFullscreenModelVideoElement::setVideoFullscreenLayer): Add completionHandler.
(WebVideoFullscreenModelVideoElement::waitForPreparedForInlineThen):
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::setVideoFullscreenLayer): Add completionHandler.
* platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayer::setVideoFullscreenLayer): Add completionHandler.
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::setVideoFullscreenLayer): Add completionHandler.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerLayer): Create two video layers.
(WebCore::MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer): Allow two video layers.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer): Add completionHandler.
(WebCore::MediaPlayerPrivateAVFoundationObjC::updateVideoLayerGravity): Allow two video layers.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::addDisplayLayer): Allow two video layers.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setVideoFullscreenLayer): Add completionHandler.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::createPreviewLayers): Allow two video layers.
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVideoFullscreenLayer): Add completionHandler.
* platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.h:
* platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.mm:
(WebCore::VideoFullscreenLayerManager::setVideoLayers): Allow two video layers.
(WebCore::VideoFullscreenLayerManager::setVideoFullscreenLayer): Add completionHandler.
(WebCore::VideoFullscreenLayerManager::setVideoFullscreenFrame): Allow two video layers.
(WebCore::VideoFullscreenLayerManager::didDestroyVideoLayer): Allow two video layers.
(WebCore::VideoFullscreenLayerManager::setVideoLayer): Deleted.
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(WebVideoFullscreenControllerContext::didSetupFullscreen): Use completionHandler.
(WebVideoFullscreenControllerContext::didExitFullscreen): Use completionHandler.

Source/WebKit2:

Reviewed by Tim Horton.

Prevent flicker by using setVideoFullscreenLayer with a completion handler to delay
enter fullscreen and cleanup fullscreen until the video layer has completely been
installed or removed.

* WebProcess/cocoa/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::didSetupFullscreen):
(WebKit::WebVideoFullscreenManager::didExitFullscreen):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediacontrolsMediaControlsHostcpp">trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediacontrolsMediaControlsHosth">trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediacontrolsMediaControlsHostidl">trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl</a></li>
<li><a href="#trunkSourceWebCoreModulesmediacontrolsmediaControlsApplejs">trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementh">trunk/Source/WebCore/html/HTMLMediaElement.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaWebVideoFullscreenModelVideoElementh">trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaWebVideoFullscreenModelVideoElementmm">trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayercpp">trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayerh">trunk/Source/WebCore/platform/graphics/MediaPlayer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayerPrivateh">trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCh">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCh">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCh">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcVideoFullscreenLayerManagerh">trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcVideoFullscreenLayerManagermm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenControllerAVKitmm">trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcesscocoaWebVideoFullscreenManagermm">trunk/Source/WebKit2/WebProcess/cocoa/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 (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/ChangeLog        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -1,3 +1,72 @@
</span><ins>+2016-05-27  Jeremy Jones  &lt;jeremyj@apple.com&gt;
+
+        Decrease flicker when changing video presentation mode.
+        https://bugs.webkit.org/show_bug.cgi?id=158148
+        rdar://problem/24476949
+
+        Reviewed by Jer Noble.
+
+        No new tests because there is no behavior change. This change is about the timing of
+        moving AVPlayerLayers between layers to prevent flicker.
+
+        1) Moving an AVPlayerLayer between CAContexts can flicker. So always keep two
+        AVPlayerLayers around and add and remove them from the inline and fullscreen contexts.
+        2) Wait to show the inline placeholder until the fullscreen video layer has been installed.
+        3) Wait to remove the fullscreen video layer until the placeholder has been removed.
+
+        * Modules/mediacontrols/MediaControlsHost.cpp:
+        (WebCore::MediaControlsHost::isVideoLayerInline): Expose isVideoLayerInline to the shadow DOM.
+        (WebCore::MediaControlsHost::setPreparedForInline): Expose setPreparedForInline to the shadow DOM.
+        * Modules/mediacontrols/MediaControlsHost.h: Add setPreparedForInline and isVideoLayerInline
+        * Modules/mediacontrols/MediaControlsHost.idl: Add setPreparedForInline and isVideoLayerInline
+        * Modules/mediacontrols/mediaControlsApple.js:
+        (Controller.prototype.showInlinePlaybackPlaceholderWhenSafe): Wait to show placeholder when entering fullscreen.
+        (Controller.prototype.handlePresentationModeChange): Wait to show placeholder, and notify when placeholder is removed.
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::setPreparedForInline):
+        (WebCore::HTMLMediaElement::waitForPreparedForInlineThen): Used to delay fullscreen cleanup until placeholder is removed.
+        (WebCore::HTMLMediaElement::setVideoFullscreenLayer): Add a callback so we can wait until this completes before continuing.
+        * html/HTMLMediaElement.h:
+        (WebCore::HTMLMediaElement::isVideoLayerInline):
+        (WebCore::HTMLMediaElement::waitForPreparedForInlineThen):
+        (WebCore::HTMLMediaElement::setVideoFullscreenLayer): Add completionHandler.
+        * platform/cocoa/WebVideoFullscreenModelVideoElement.h:
+        (WebCore::WebVideoFullscreenModelVideoElement::setVideoFullscreenLayer): Add completionHandler.
+        (WebCore::WebVideoFullscreenModelVideoElement::waitForPreparedForInlineThen): Added.
+        * platform/cocoa/WebVideoFullscreenModelVideoElement.mm:
+        (WebVideoFullscreenModelVideoElement::setVideoFullscreenLayer): Add completionHandler.
+        (WebVideoFullscreenModelVideoElement::waitForPreparedForInlineThen):
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::setVideoFullscreenLayer): Add completionHandler.
+        * platform/graphics/MediaPlayer.h:
+        (WebCore::MediaPlayer::setVideoFullscreenLayer): Add completionHandler.
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::setVideoFullscreenLayer): Add completionHandler.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerLayer): Create two video layers.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer): Allow two video layers.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer): Add completionHandler.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::updateVideoLayerGravity): Allow two video layers.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::addDisplayLayer): Allow two video layers.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setVideoFullscreenLayer): Add completionHandler.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::createPreviewLayers): Allow two video layers.
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVideoFullscreenLayer): Add completionHandler.
+        * platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.h:
+        * platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.mm:
+        (WebCore::VideoFullscreenLayerManager::setVideoLayers): Allow two video layers.
+        (WebCore::VideoFullscreenLayerManager::setVideoFullscreenLayer): Add completionHandler.
+        (WebCore::VideoFullscreenLayerManager::setVideoFullscreenFrame): Allow two video layers.
+        (WebCore::VideoFullscreenLayerManager::didDestroyVideoLayer): Allow two video layers.
+        (WebCore::VideoFullscreenLayerManager::setVideoLayer): Deleted.
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (WebVideoFullscreenControllerContext::didSetupFullscreen): Use completionHandler. 
+        (WebVideoFullscreenControllerContext::didExitFullscreen): Use completionHandler.
+
</ins><span class="cx"> 2016-05-26  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Crash in TreeScope::focusedElement
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediacontrolsMediaControlsHostcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -210,6 +210,16 @@
</span><span class="cx">     return m_mediaElement-&gt;supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenModeStandard);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MediaControlsHost::isVideoLayerInline()
+{
+    return m_mediaElement-&gt;isVideoLayerInline();
+}
+
+void MediaControlsHost::setPreparedForInline(bool value)
+{
+    m_mediaElement-&gt;setPreparedForInline(value);
+}
+
</ins><span class="cx"> bool MediaControlsHost::userGestureRequired() const
</span><span class="cx"> {
</span><span class="cx">     return !m_mediaElement-&gt;mediaSession().playbackPermitted(*m_mediaElement);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediacontrolsMediaControlsHosth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -64,7 +64,9 @@
</span><span class="cx">     void updateTextTrackContainer();
</span><span class="cx">     bool allowsInlineMediaPlayback() const;
</span><span class="cx">     bool supportsFullscreen();
</span><ins>+    bool isVideoLayerInline();
</ins><span class="cx">     bool userGestureRequired() const;
</span><ins>+    void setPreparedForInline(bool);
</ins><span class="cx"> 
</span><span class="cx">     void updateCaptionDisplaySizes();
</span><span class="cx">     void enteredFullscreen();
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediacontrolsMediaControlsHostidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -42,9 +42,11 @@
</span><span class="cx">     readonly attribute TextTrack captionMenuAutomaticItem;
</span><span class="cx">     readonly attribute DOMString captionDisplayMode;
</span><span class="cx">     void setSelectedTextTrack(TextTrack? track);
</span><ins>+    void setPreparedForInline(boolean prepared);
</ins><span class="cx">     readonly attribute HTMLElement textTrackContainer;
</span><span class="cx">     readonly attribute boolean allowsInlineMediaPlayback;
</span><span class="cx">     readonly attribute boolean supportsFullscreen;
</span><ins>+    readonly attribute boolean isVideoLayerInline;
</ins><span class="cx">     readonly attribute boolean userGestureRequired;
</span><span class="cx"> 
</span><span class="cx">     readonly attribute DOMString externalDeviceDisplayName;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediacontrolsmediaControlsApplejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -82,6 +82,7 @@
</span><span class="cx">         webkitbeginfullscreen: 'handleFullscreenChange',
</span><span class="cx">         webkitendfullscreen: 'handleFullscreenChange',
</span><span class="cx">     },
</span><ins>+    PlaceholderPollingDelay: 33,
</ins><span class="cx">     HideControlsDelay: 4 * 1000,
</span><span class="cx">     RewindAmount: 30,
</span><span class="cx">     MaximumSeekRate: 8,
</span><span class="lines">@@ -837,6 +838,16 @@
</span><span class="cx">             this.controls.pictureInPictureButton.classList.add(this.ClassNames.hidden);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    showInlinePlaybackPlaceholderWhenSafe: function() {
+        if (this.presentationMode() != 'picture-in-picture')
+            return;
+
+        if (!this.host.isVideoLayerInline)
+            this.controls.inlinePlaybackPlaceholder.classList.remove(this.ClassNames.hidden);
+        else
+            setTimeout(this.showInlinePlaybackPlaceholderWhenSafe.bind(this), this.PlaceholderPollingDelay);
+    },
+
</ins><span class="cx">     handlePresentationModeChange: function(event)
</span><span class="cx">     {
</span><span class="cx">         var presentationMode = this.presentationMode();
</span><span class="lines">@@ -854,7 +865,7 @@
</span><span class="cx">             case 'picture-in-picture':
</span><span class="cx">                 this.controls.panel.classList.add(this.ClassNames.pictureInPicture);
</span><span class="cx">                 this.controls.inlinePlaybackPlaceholder.classList.add(this.ClassNames.pictureInPicture);
</span><del>-                this.controls.inlinePlaybackPlaceholder.classList.remove(this.ClassNames.hidden);
</del><ins>+                this.showInlinePlaybackPlaceholderWhenSafe();
</ins><span class="cx"> 
</span><span class="cx">                 this.controls.inlinePlaybackPlaceholderTextTop.innerText = this.UIString('This video is playing in Picture in Picture');
</span><span class="cx">                 this.controls.inlinePlaybackPlaceholderTextTop.classList.add(this.ClassNames.pictureInPicture);
</span><span class="lines">@@ -883,6 +894,7 @@
</span><span class="cx">         this.resetHideControlsTimer();
</span><span class="cx">         if (presentationMode != 'fullscreen' &amp;&amp; this.video.paused &amp;&amp; this.controlsAreHidden())
</span><span class="cx">             this.showControls();
</span><ins>+        this.host.setPreparedForInline(presentationMode === 'inline')
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     handleFullscreenChange: function(event)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -5471,15 +5471,42 @@
</span><span class="cx">     return m_player ? m_player-&gt;platformLayer() : nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTMLMediaElement::setPreparedForInline(bool value)
+{
+    m_preparedForInline = value;
+    if (m_preparedForInline &amp;&amp; m_preparedForInlineCompletionHandler) {
+        m_preparedForInlineCompletionHandler();
+        m_preparedForInlineCompletionHandler = nullptr;
+    }
+}
+
+void HTMLMediaElement::waitForPreparedForInlineThen(std::function&lt;void()&gt; completionHandler)
+{
+    ASSERT(!m_preparedForInlineCompletionHandler);
+    if (m_preparedForInline)  {
+        completionHandler();
+        return;
+    }
+    
+    m_preparedForInlineCompletionHandler = completionHandler;
+}
+
</ins><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><span class="cx"> 
</span><del>-void HTMLMediaElement::setVideoFullscreenLayer(PlatformLayer* platformLayer)
</del><ins>+bool HTMLMediaElement::isVideoLayerInline()
</ins><span class="cx"> {
</span><ins>+    return !m_videoFullscreenLayer;
+};
+    
+void HTMLMediaElement::setVideoFullscreenLayer(PlatformLayer* platformLayer, std::function&lt;void()&gt; completionHandler)
+{
</ins><span class="cx">     m_videoFullscreenLayer = platformLayer;
</span><del>-    if (!m_player)
</del><ins>+    if (!m_player) {
+        completionHandler();
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">     
</span><del>-    m_player-&gt;setVideoFullscreenLayer(platformLayer);
</del><ins>+    m_player-&gt;setVideoFullscreenLayer(platformLayer, completionHandler);
</ins><span class="cx">     setNeedsStyleRecalc(SyntheticStyleChange);
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx">     updateTextTrackDisplay();
</span><span class="lines">@@ -5499,6 +5526,13 @@
</span><span class="cx">     if (m_player)
</span><span class="cx">         m_player-&gt;setVideoFullscreenGravity(gravity);
</span><span class="cx"> }
</span><ins>+    
+#else
+    
+bool HTMLMediaElement::isVideoLayerInline()
+{
+    return true;
+};
</ins><span class="cx"> 
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -133,8 +133,11 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT PlatformMedia platformMedia() const;
</span><span class="cx">     PlatformLayer* platformLayer() const;
</span><ins>+    bool isVideoLayerInline();
+    void setPreparedForInline(bool);
+    void waitForPreparedForInlineThen(std::function&lt;void()&gt; completionHandler = [] { });
</ins><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-    void setVideoFullscreenLayer(PlatformLayer*);
</del><ins>+    void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler = [] { });
</ins><span class="cx">     PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
</span><span class="cx">     void setVideoFullscreenFrame(FloatRect);
</span><span class="cx">     void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
</span><span class="lines">@@ -847,6 +850,8 @@
</span><span class="cx">     RefPtr&lt;Node&gt; m_nextChildNodeToConsider;
</span><span class="cx"> 
</span><span class="cx">     VideoFullscreenMode m_videoFullscreenMode;
</span><ins>+    bool m_preparedForInline;
+    std::function&lt;void()&gt; m_preparedForInlineCompletionHandler;
</ins><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><span class="cx">     RetainPtr&lt;PlatformLayer&gt; m_videoFullscreenLayer;
</span><span class="cx">     FloatRect m_videoFullscreenFrame;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaWebVideoFullscreenModelVideoElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;HTMLMediaElementEnums.h&quot;
</span><span class="cx"> #include &quot;PlatformLayer.h&quot;
</span><span class="cx"> #include &quot;WebVideoFullscreenModel.h&quot;
</span><ins>+#include &lt;functional&gt;
</ins><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -55,7 +56,8 @@
</span><span class="cx">     WEBCORE_EXPORT void setWebVideoFullscreenInterface(WebVideoFullscreenInterface*);
</span><span class="cx">     WEBCORE_EXPORT void setVideoElement(HTMLVideoElement*);
</span><span class="cx">     WEBCORE_EXPORT HTMLVideoElement* videoElement() const { return m_videoElement.get(); }
</span><del>-    WEBCORE_EXPORT void setVideoFullscreenLayer(PlatformLayer*);
</del><ins>+    WEBCORE_EXPORT void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler = [] { });
+    WEBCORE_EXPORT void waitForPreparedForInlineThen(std::function&lt;void()&gt; completionHandler = [] { });
</ins><span class="cx">     WebPlaybackSessionModelMediaElement&amp; playbackSessionModel() { return m_playbackSessionModel; }
</span><span class="cx">     
</span><span class="cx">     WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaWebVideoFullscreenModelVideoElementmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -120,10 +120,12 @@
</span><span class="cx">         m_videoFullscreenInterface-&gt;setVideoDimensions(true, m_videoElement-&gt;videoWidth(), m_videoElement-&gt;videoHeight());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebVideoFullscreenModelVideoElement::setVideoFullscreenLayer(PlatformLayer* videoLayer)
</del><ins>+void WebVideoFullscreenModelVideoElement::setVideoFullscreenLayer(PlatformLayer* videoLayer, std::function&lt;void()&gt; completionHandler)
</ins><span class="cx"> {
</span><del>-    if (m_videoFullscreenLayer == videoLayer)
</del><ins>+    if (m_videoFullscreenLayer == videoLayer) {
+        completionHandler();
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">     
</span><span class="cx">     m_videoFullscreenLayer = videoLayer;
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -133,10 +135,24 @@
</span><span class="cx"> #endif
</span><span class="cx">     [m_videoFullscreenLayer setBounds:m_videoFrame];
</span><span class="cx">     
</span><del>-    if (m_videoElement)
-        m_videoElement-&gt;setVideoFullscreenLayer(m_videoFullscreenLayer.get());
</del><ins>+    if (!m_videoElement) {
+        completionHandler();
+        return;
+    }
+
+    m_videoElement-&gt;setVideoFullscreenLayer(m_videoFullscreenLayer.get(), completionHandler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebVideoFullscreenModelVideoElement::waitForPreparedForInlineThen(std::function&lt;void()&gt; completionHandler)
+{
+    if (!m_videoElement) {
+        completionHandler();
+        return;
+    }
+
+    m_videoElement-&gt;waitForPreparedForInlineThen(completionHandler);
+}
+
</ins><span class="cx"> void WebVideoFullscreenModelVideoElement::requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode mode)
</span><span class="cx"> {
</span><span class="cx">     if (m_videoElement &amp;&amp; m_videoElement-&gt;fullscreenMode() != mode)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -660,9 +660,9 @@
</span><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-void MediaPlayer::setVideoFullscreenLayer(PlatformLayer* layer)
</del><ins>+void MediaPlayer::setVideoFullscreenLayer(PlatformLayer* layer, std::function&lt;void()&gt; completionHandler)
</ins><span class="cx"> {
</span><del>-    m_private-&gt;setVideoFullscreenLayer(layer);
</del><ins>+    m_private-&gt;setVideoFullscreenLayer(layer, completionHandler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaPlayer::setVideoFullscreenFrame(FloatRect frame)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -308,7 +308,7 @@
</span><span class="cx">     PlatformLayer* platformLayer() const;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-    void setVideoFullscreenLayer(PlatformLayer*);
</del><ins>+    void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler = [] { });
</ins><span class="cx">     void setVideoFullscreenFrame(FloatRect);
</span><span class="cx">     using MediaPlayerEnums::VideoGravity;
</span><span class="cx">     void setVideoFullscreenGravity(VideoGravity);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayerPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     virtual PlatformLayer* platformLayer() const { return 0; }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-    virtual void setVideoFullscreenLayer(PlatformLayer*) { }
</del><ins>+    virtual void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler) { completionHandler(); }
</ins><span class="cx">     virtual void setVideoFullscreenFrame(FloatRect) { }
</span><span class="cx">     virtual void setVideoFullscreenGravity(MediaPlayer::VideoGravity) { }
</span><span class="cx">     virtual void setVideoFullscreenMode(MediaPlayer::VideoFullscreenMode) { }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -172,7 +172,7 @@
</span><span class="cx">     void paintCurrentFrameInContext(GraphicsContext&amp;, const FloatRect&amp;) override;
</span><span class="cx">     PlatformLayer* platformLayer() const override;
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-    void setVideoFullscreenLayer(PlatformLayer*) override;
</del><ins>+    void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler) override;
</ins><span class="cx">     void setVideoFullscreenFrame(FloatRect) override;
</span><span class="cx">     void setVideoFullscreenGravity(MediaPlayer::VideoGravity) override;
</span><span class="cx">     void setVideoFullscreenMode(MediaPlayer::VideoFullscreenMode) override;
</span><span class="lines">@@ -329,6 +329,7 @@
</span><span class="cx">     RetainPtr&lt;AVPlayer&gt; m_avPlayer;
</span><span class="cx">     RetainPtr&lt;AVPlayerItem&gt; m_avPlayerItem;
</span><span class="cx">     RetainPtr&lt;AVPlayerLayer&gt; m_videoLayer;
</span><ins>+    RetainPtr&lt;AVPlayerLayer&gt; m_secondaryVideoLayer;
</ins><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><span class="cx">     std::unique_ptr&lt;VideoFullscreenLayerManager&gt; m_videoFullscreenLayerManager;
</span><span class="cx">     MediaPlayer::VideoGravity m_videoFullscreenGravity;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -730,17 +730,24 @@
</span><span class="cx">     m_videoLayer = adoptNS([allocAVPlayerLayerInstance() init]);
</span><span class="cx">     [m_videoLayer setPlayer:m_avPlayer.get()];
</span><span class="cx">     [m_videoLayer setBackgroundColor:cachedCGColor(Color::black)];
</span><ins>+
+    m_secondaryVideoLayer = adoptNS([allocAVPlayerLayerInstance() init]);
+    [m_secondaryVideoLayer setPlayer:m_avPlayer.get()];
+    [m_secondaryVideoLayer setBackgroundColor:cachedCGColor(Color::black)];
+
</ins><span class="cx"> #ifndef NDEBUG
</span><span class="cx">     [m_videoLayer setName:@&quot;MediaPlayerPrivate AVPlayerLayer&quot;];
</span><ins>+    [m_secondaryVideoLayer setName:@&quot;MediaPlayerPrivate AVPlayerLayer secondary&quot;];
</ins><span class="cx"> #endif
</span><span class="cx">     [m_videoLayer addObserver:m_objcObserver.get() forKeyPath:@&quot;readyForDisplay&quot; options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextAVPlayerLayer];
</span><span class="cx">     updateVideoLayerGravity();
</span><span class="cx">     [m_videoLayer setContentsScale:player()-&gt;client().mediaPlayerContentsScale()];
</span><ins>+    [m_secondaryVideoLayer setContentsScale:player()-&gt;client().mediaPlayerContentsScale()];
</ins><span class="cx">     IntSize defaultSize = snappedIntRect(player()-&gt;client().mediaPlayerContentBoxRect()).size();
</span><span class="cx">     LOG(Media, &quot;MediaPlayerPrivateAVFoundationObjC::createVideoLayer(%p) - returning %p&quot;, this, m_videoLayer.get());
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-    m_videoFullscreenLayerManager-&gt;setVideoLayer(m_videoLayer.get(), defaultSize);
</del><ins>+    m_videoFullscreenLayerManager-&gt;setVideoLayers(m_videoLayer.get(), m_secondaryVideoLayer.get(), defaultSize);
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     if ([m_videoLayer respondsToSelector:@selector(setPIPModeEnabled:)])
</span><span class="lines">@@ -748,6 +755,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> #else
</span><span class="cx">     [m_videoLayer setFrame:CGRectMake(0, 0, defaultSize.width(), defaultSize.height())];
</span><ins>+    [m_secondaryVideoLayer setFrame:CGRectMake(0, 0, defaultSize.width(), defaultSize.height())];
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -758,14 +766,16 @@
</span><span class="cx"> 
</span><span class="cx">     LOG(Media, &quot;MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer(%p) - destroying %p&quot;, this, m_videoLayer.get());
</span><span class="cx"> 
</span><del>-    [m_videoLayer.get() removeObserver:m_objcObserver.get() forKeyPath:@&quot;readyForDisplay&quot;];
-    [m_videoLayer.get() setPlayer:nil];
</del><ins>+    [m_videoLayer removeObserver:m_objcObserver.get() forKeyPath:@&quot;readyForDisplay&quot;];
+    [m_videoLayer setPlayer:nil];
+    [m_secondaryVideoLayer setPlayer:nil];
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><span class="cx">     m_videoFullscreenLayerManager-&gt;didDestroyVideoLayer();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     m_videoLayer = nil;
</span><ins>+    m_secondaryVideoLayer = nil;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MediaTime MediaPlayerPrivateAVFoundationObjC::getStartDate() const
</span><span class="lines">@@ -1183,12 +1193,14 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE))
</span><del>-void MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer(PlatformLayer* videoFullscreenLayer)
</del><ins>+void MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer(PlatformLayer* videoFullscreenLayer, std::function&lt;void()&gt; completionHandler)
</ins><span class="cx"> {
</span><del>-    if (m_videoFullscreenLayerManager-&gt;videoFullscreenLayer() == videoFullscreenLayer)
</del><ins>+    if (m_videoFullscreenLayerManager-&gt;videoFullscreenLayer() == videoFullscreenLayer) {
+        completionHandler();
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><del>-    m_videoFullscreenLayerManager-&gt;setVideoFullscreenLayer(videoFullscreenLayer);
</del><ins>+    m_videoFullscreenLayerManager-&gt;setVideoFullscreenLayer(videoFullscreenLayer, completionHandler);
</ins><span class="cx"> 
</span><span class="cx">     if (m_videoFullscreenLayerManager-&gt;videoFullscreenLayer() &amp;&amp; m_textTrackRepresentationLayer) {
</span><span class="cx">         syncTextTrackBounds();
</span><span class="lines">@@ -1872,6 +1884,7 @@
</span><span class="cx">     [CATransaction setDisableActions:YES];    
</span><span class="cx">     NSString* gravity = shouldMaintainAspectRatio() ? AVLayerVideoGravityResizeAspect : AVLayerVideoGravityResize;
</span><span class="cx">     [m_videoLayer.get() setVideoGravity:gravity];
</span><ins>+    [m_secondaryVideoLayer.get() setVideoGravity:gravity];
</ins><span class="cx">     [CATransaction commit];
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx">     void characteristicsChanged();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE)
</span><del>-    void setVideoFullscreenLayer(PlatformLayer*) override;
</del><ins>+    void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler) override;
</ins><span class="cx">     void setVideoFullscreenFrame(FloatRect) override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -770,7 +770,7 @@
</span><span class="cx">     m_player-&gt;firstVideoFrameAvailable();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE)
</span><del>-    m_videoFullscreenLayerManager-&gt;setVideoLayer(m_sampleBufferDisplayLayer.get(), snappedIntRect(m_player-&gt;client().mediaPlayerContentBoxRect()).size());
</del><ins>+    m_videoFullscreenLayerManager-&gt;setVideoLayers(m_sampleBufferDisplayLayer.get(), nil, snappedIntRect(m_player-&gt;client().mediaPlayerContentBoxRect()).size());
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -828,9 +828,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE)
</span><del>-void MediaPlayerPrivateMediaSourceAVFObjC::setVideoFullscreenLayer(PlatformLayer *videoFullscreenLayer)
</del><ins>+void MediaPlayerPrivateMediaSourceAVFObjC::setVideoFullscreenLayer(PlatformLayer *videoFullscreenLayer, std::function&lt;void()&gt; completionHandler)
</ins><span class="cx"> {
</span><del>-    m_videoFullscreenLayerManager-&gt;setVideoFullscreenLayer(videoFullscreenLayer);
</del><ins>+    m_videoFullscreenLayerManager-&gt;setVideoFullscreenLayer(videoFullscreenLayer, completionHandler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaPlayerPrivateMediaSourceAVFObjC::setVideoFullscreenFrame(FloatRect frame)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -160,7 +160,7 @@
</span><span class="cx">     void didRemoveTrack(MediaStreamTrackPrivate&amp;) override;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE)
</span><del>-    void setVideoFullscreenLayer(PlatformLayer*) override;
</del><ins>+    void setVideoFullscreenLayer(PlatformLayer*, std::function&lt;void()&gt; completionHandler) override;
</ins><span class="cx">     void setVideoFullscreenFrame(FloatRect) override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -404,7 +404,7 @@
</span><span class="cx">         m_videoBackgroundLayer.get().name = @&quot;MediaPlayerPrivateMediaStreamAVFObjC preview background layer&quot;;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE)
</span><del>-        m_videoFullscreenLayerManager-&gt;setVideoLayer(m_videoBackgroundLayer.get(), snappedIntRect(m_player-&gt;client().mediaPlayerContentBoxRect()).size());
</del><ins>+        m_videoFullscreenLayerManager-&gt;setVideoLayers(m_videoBackgroundLayer.get(), nil, snappedIntRect(m_player-&gt;client().mediaPlayerContentBoxRect()).size());
</ins><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -474,9 +474,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; ENABLE(VIDEO_PRESENTATION_MODE)
</span><del>-void MediaPlayerPrivateMediaStreamAVFObjC::setVideoFullscreenLayer(PlatformLayer *videoFullscreenLayer)
</del><ins>+void MediaPlayerPrivateMediaStreamAVFObjC::setVideoFullscreenLayer(PlatformLayer *videoFullscreenLayer, std::function&lt;void()&gt; completionHandler)
</ins><span class="cx"> {
</span><del>-    m_videoFullscreenLayerManager-&gt;setVideoFullscreenLayer(videoFullscreenLayer);
</del><ins>+    m_videoFullscreenLayerManager-&gt;setVideoFullscreenLayer(videoFullscreenLayer, completionHandler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaPlayerPrivateMediaStreamAVFObjC::setVideoFullscreenFrame(FloatRect frame)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcVideoFullscreenLayerManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.h (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.h        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.h        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;FloatRect.h&quot;
</span><span class="cx"> #include &quot;IntSize.h&quot;
</span><span class="cx"> #include &quot;PlatformLayer.h&quot;
</span><ins>+#include &lt;functional&gt;
</ins><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -43,8 +44,8 @@
</span><span class="cx">     PlatformLayer *videoInlineLayer() const { return m_videoInlineLayer.get(); }
</span><span class="cx">     PlatformLayer *videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
</span><span class="cx">     FloatRect videoFullscreenFrame() const { return m_videoFullscreenFrame; }
</span><del>-    void setVideoLayer(PlatformLayer *, IntSize contentSize);
-    void setVideoFullscreenLayer(PlatformLayer *);
</del><ins>+    void setVideoLayers(PlatformLayer *, PlatformLayer *, IntSize contentSize);
+    void setVideoFullscreenLayer(PlatformLayer *, std::function&lt;void()&gt; completionHandler);
</ins><span class="cx">     void setVideoFullscreenFrame(FloatRect);
</span><span class="cx">     void didDestroyVideoLayer();
</span><span class="cx"> 
</span><span class="lines">@@ -54,6 +55,7 @@
</span><span class="cx">     RetainPtr&lt;PlatformLayer&gt; m_videoInlineLayer;
</span><span class="cx">     RetainPtr&lt;PlatformLayer&gt; m_videoFullscreenLayer;
</span><span class="cx">     RetainPtr&lt;PlatformLayer&gt; m_videoLayer;
</span><ins>+    RetainPtr&lt;PlatformLayer&gt; m_secondaryVideoLayer;
</ins><span class="cx">     FloatRect m_videoFullscreenFrame;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcVideoFullscreenLayerManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/VideoFullscreenLayerManager.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -66,55 +66,97 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VideoFullscreenLayerManager::setVideoLayer(PlatformLayer *videoLayer, IntSize contentSize)
</del><ins>+void VideoFullscreenLayerManager::setVideoLayers(PlatformLayer *videoLayer, PlatformLayer *secondaryVideoLayer, IntSize contentSize)
</ins><span class="cx"> {
</span><span class="cx">     m_videoLayer = videoLayer;
</span><ins>+    m_secondaryVideoLayer = secondaryVideoLayer;
</ins><span class="cx"> 
</span><span class="cx">     [m_videoLayer web_disableAllActions];
</span><ins>+    [m_secondaryVideoLayer web_disableAllActions];
</ins><span class="cx">     m_videoInlineLayer = adoptNS([[WebVideoContainerLayer alloc] init]);
</span><span class="cx"> #ifndef NDEBUG
</span><span class="cx">     [m_videoInlineLayer setName:@&quot;WebVideoContainerLayer&quot;];
</span><span class="cx"> #endif
</span><span class="cx">     [m_videoInlineLayer setFrame:CGRectMake(0, 0, contentSize.width(), contentSize.height())];
</span><span class="cx">     if (m_videoFullscreenLayer) {
</span><del>-        [m_videoLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
-        [m_videoFullscreenLayer insertSublayer:m_videoLayer.get() atIndex:0];
</del><ins>+        [m_videoLayer removeFromSuperlayer];
+        PlatformLayer *activeLayer = secondaryVideoLayer ? secondaryVideoLayer : videoLayer;
+        [activeLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
+        [m_videoFullscreenLayer insertSublayer:activeLayer atIndex:0];
</ins><span class="cx">     } else {
</span><span class="cx">         [m_videoInlineLayer insertSublayer:m_videoLayer.get() atIndex:0];
</span><span class="cx">         [m_videoLayer setFrame:m_videoInlineLayer.get().bounds];
</span><ins>+        [m_secondaryVideoLayer removeFromSuperlayer];
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VideoFullscreenLayerManager::setVideoFullscreenLayer(PlatformLayer *videoFullscreenLayer)
</del><ins>+void VideoFullscreenLayerManager::setVideoFullscreenLayer(PlatformLayer *videoFullscreenLayer, std::function&lt;void()&gt; completionHandler)
</ins><span class="cx"> {
</span><del>-    if (m_videoFullscreenLayer == videoFullscreenLayer)
</del><ins>+    if (m_videoFullscreenLayer == videoFullscreenLayer) {
+        completionHandler();
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     m_videoFullscreenLayer = videoFullscreenLayer;
</span><span class="cx"> 
</span><span class="cx">     [CATransaction begin];
</span><span class="cx">     [CATransaction setDisableActions:YES];
</span><span class="cx"> 
</span><del>-    CAContext *oldContext = [m_videoLayer context];
-    CAContext *newContext = nil;
</del><ins>+    if (m_secondaryVideoLayer &amp;&amp; m_videoLayer) {
+        if (m_videoFullscreenLayer) {
+            [m_videoFullscreenLayer insertSublayer:m_secondaryVideoLayer.get() atIndex:0];
+            [m_secondaryVideoLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
+        } else if (m_videoInlineLayer) {
+            [m_videoLayer setFrame:[m_videoInlineLayer bounds]];
+            [m_videoInlineLayer insertSublayer:m_videoLayer.get() atIndex:0];
+        }
</ins><span class="cx"> 
</span><del>-    if (m_videoFullscreenLayer &amp;&amp; m_videoLayer) {
-        [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 &amp;&amp; m_videoLayer) {
-        [m_videoLayer setFrame:[m_videoInlineLayer bounds]];
-        [m_videoLayer removeFromSuperlayer];
-        [m_videoInlineLayer insertSublayer:m_videoLayer.get() atIndex:0];
-        newContext = [m_videoInlineLayer context];
-    } else if (m_videoLayer)
-        [m_videoLayer removeFromSuperlayer];
</del><ins>+        RetainPtr&lt;PlatformLayer&gt; fullscreenLayer = m_videoFullscreenLayer;
+        RetainPtr&lt;PlatformLayer&gt; videoLayer = m_videoLayer;
+        RetainPtr&lt;PlatformLayer&gt; secondaryVideoLayer = m_secondaryVideoLayer;
</ins><span class="cx"> 
</span><del>-    if (oldContext &amp;&amp; newContext &amp;&amp; oldContext != newContext) {
-        mach_port_t fencePort = [oldContext createFencePort];
-        [newContext setFencePort:fencePort];
-        mach_port_deallocate(mach_task_self(), fencePort);
</del><ins>+        [CATransaction setCompletionBlock:[completionHandler, fullscreenLayer, videoLayer, secondaryVideoLayer] {
+            [CATransaction begin];
+            [CATransaction setDisableActions:YES];
+            
+            if (fullscreenLayer)
+                [videoLayer removeFromSuperlayer];
+            else
+                [secondaryVideoLayer removeFromSuperlayer];
+
+            [CATransaction setCompletionBlock:[completionHandler] {
+                completionHandler();
+            }];
+            [CATransaction commit];
+        }];
+    } else if (m_videoLayer) {
+        if (m_videoFullscreenLayer) {
+            [m_videoFullscreenLayer insertSublayer:m_videoLayer.get() atIndex:0];
+            [m_videoLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
+        } else if (m_videoInlineLayer) {
+            [m_videoLayer setFrame:[m_videoInlineLayer bounds]];
+            [m_videoLayer removeFromSuperlayer];
+            [m_videoInlineLayer insertSublayer:m_videoLayer.get() atIndex:0];
+        } else
+            [m_videoLayer removeFromSuperlayer];
+
+        CAContext *oldContext = [m_videoFullscreenLayer context];
+        CAContext *newContext = [m_videoInlineLayer context];
+        if (oldContext &amp;&amp; newContext &amp;&amp; oldContext != newContext) {
+            mach_port_t fencePort = [oldContext createFencePort];
+            [newContext setFencePort:fencePort];
+            mach_port_deallocate(mach_task_self(), fencePort);
+        }
+
+        [CATransaction setCompletionBlock:[completionHandler] {
+            completionHandler();
+        }];
+    } else {
+        [CATransaction setCompletionBlock:[completionHandler] {
+            completionHandler();
+        }];
</ins><span class="cx">     }
</span><ins>+
</ins><span class="cx">     [CATransaction commit];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -124,17 +166,18 @@
</span><span class="cx">     if (!m_videoFullscreenLayer)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (m_videoLayer)
-        [m_videoLayer setFrame:CGRectMake(0, 0, videoFullscreenFrame.width(), videoFullscreenFrame.height())];
</del><ins>+    PlatformLayer *activeLayer = m_secondaryVideoLayer.get() ? m_secondaryVideoLayer.get() : m_videoLayer.get();
+    [activeLayer setFrame:CGRectMake(0, 0, videoFullscreenFrame.width(), videoFullscreenFrame.height())];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void VideoFullscreenLayerManager::didDestroyVideoLayer()
</span><span class="cx"> {
</span><del>-    if (m_videoFullscreenLayer)
-        [m_videoLayer removeFromSuperlayer];
</del><ins>+    [m_videoLayer removeFromSuperlayer];
+    [m_secondaryVideoLayer removeFromSuperlayer];
</ins><span class="cx"> 
</span><span class="cx">     m_videoInlineLayer = nil;
</span><span class="cx">     m_videoLayer = nil;
</span><ins>+    m_secondaryVideoLayer = nil;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenControllerAVKitmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -247,9 +247,10 @@
</span><span class="cx">     RetainPtr&lt;CALayer&gt; videoFullscreenLayer = [m_videoFullscreenView layer];
</span><span class="cx">     WebThreadRun([protectedThis, this, videoFullscreenLayer] {
</span><span class="cx">         [videoFullscreenLayer setBackgroundColor:cachedCGColor(WebCore::Color::transparent)];
</span><del>-        m_model-&gt;setVideoFullscreenLayer(videoFullscreenLayer.get());
-        dispatch_async(dispatch_get_main_queue(), [protectedThis, this] {
-            m_interface-&gt;enterFullscreen();
</del><ins>+        m_model-&gt;setVideoFullscreenLayer(videoFullscreenLayer.get(), [protectedThis, this] {
+            dispatch_async(dispatch_get_main_queue(), [protectedThis, this] {
+                m_interface-&gt;enterFullscreen();
+            });
</ins><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -259,9 +260,10 @@
</span><span class="cx">     ASSERT(isUIThread());
</span><span class="cx">     RefPtr&lt;WebVideoFullscreenControllerContext&gt; protectedThis(this);
</span><span class="cx">     WebThreadRun([protectedThis, this] {
</span><del>-        m_model-&gt;setVideoFullscreenLayer(nil);
-        dispatch_async(dispatch_get_main_queue(), [protectedThis, this] {
-            m_interface-&gt;cleanupFullscreen();
</del><ins>+        m_model-&gt;setVideoFullscreenLayer(nil, [protectedThis, this] {
+            dispatch_async(dispatch_get_main_queue(), [protectedThis, this] {
+                m_interface-&gt;cleanupFullscreen();
+            });
</ins><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebKit2/ChangeLog        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-05-27  Jeremy Jones  &lt;jeremyj@apple.com&gt;
+
+        Decrease flicker when changing video presentation mode.
+        https://bugs.webkit.org/show_bug.cgi?id=158148
+        rdar://problem/24476949
+
+        Reviewed by Tim Horton.
+
+        Prevent flicker by using setVideoFullscreenLayer with a completion handler to delay 
+        enter fullscreen and cleanup fullscreen until the video layer has completely been
+        installed or removed.
+
+        * WebProcess/cocoa/WebVideoFullscreenManager.mm:
+        (WebKit::WebVideoFullscreenManager::didSetupFullscreen):
+        (WebKit::WebVideoFullscreenManager::didExitFullscreen):
+
</ins><span class="cx"> 2016-05-27  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WorkQueue::dispatch() / RunLoop::dispatch() should not copy captured lambda variables
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcesscocoaWebVideoFullscreenManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.mm (201473 => 201474)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.mm        2016-05-27 23:42:08 UTC (rev 201473)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.mm        2016-05-27 23:58:28 UTC (rev 201474)
</span><span class="lines">@@ -369,14 +369,16 @@
</span><span class="cx">     std::tie(model, interface) = ensureModelAndInterface(contextId);
</span><span class="cx"> 
</span><span class="cx">     interface-&gt;layerHostingContext()-&gt;setRootLayer(videoLayer);
</span><del>-    model-&gt;setVideoFullscreenLayer(videoLayer);
</del><span class="cx"> 
</span><del>-    [CATransaction commit];
-
</del><span class="cx">     RefPtr&lt;WebVideoFullscreenManager&gt; strongThis(this);
</span><del>-    dispatch_async(dispatch_get_main_queue(), [strongThis, this, contextId] {
-        m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(contextId), m_page-&gt;pageID());
</del><ins>+    
+    model-&gt;setVideoFullscreenLayer(videoLayer, [strongThis, this, contextId] {
+        dispatch_async(dispatch_get_main_queue(), [strongThis, this, contextId] {
+            m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(contextId), m_page-&gt;pageID());
+        });
</ins><span class="cx">     });
</span><ins>+    
+    [CATransaction commit];
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> void WebVideoFullscreenManager::didEnterFullscreen(uint64_t contextId)
</span><span class="lines">@@ -407,17 +409,21 @@
</span><span class="cx">     RefPtr&lt;WebVideoFullscreenModelVideoElement&gt; model;
</span><span class="cx">     RefPtr&lt;WebVideoFullscreenInterfaceContext&gt; interface;
</span><span class="cx">     std::tie(model, interface) = ensureModelAndInterface(contextId);
</span><del>-
-    model-&gt;setVideoFullscreenLayer(nil);
-
</del><span class="cx">     RefPtr&lt;WebVideoFullscreenManager&gt; strongThis(this);
</span><del>-    dispatch_async(dispatch_get_main_queue(), [strongThis, contextId, interface] {
-        if (interface-&gt;layerHostingContext()) {
-            interface-&gt;layerHostingContext()-&gt;setRootLayer(nullptr);
-            interface-&gt;setLayerHostingContext(nullptr);
-        }
-        if (strongThis-&gt;m_page)
-            strongThis-&gt;m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::CleanupFullscreen(contextId), strongThis-&gt;m_page-&gt;pageID());
</del><ins>+    
+    model-&gt;waitForPreparedForInlineThen([strongThis, this, contextId, interface, model] {
+        dispatch_async(dispatch_get_main_queue(), [strongThis, this, contextId, interface, model] {
+            model-&gt;setVideoFullscreenLayer(nil, [strongThis, this, contextId, interface] {
+                dispatch_async(dispatch_get_main_queue(), [strongThis, this, contextId, interface] {
+                    if (interface-&gt;layerHostingContext()) {
+                        interface-&gt;layerHostingContext()-&gt;setRootLayer(nullptr);
+                        interface-&gt;setLayerHostingContext(nullptr);
+                    }
+                    if (strongThis-&gt;m_page)
+                        strongThis-&gt;m_page-&gt;send(Messages::WebVideoFullscreenManagerProxy::CleanupFullscreen(contextId), strongThis-&gt;m_page-&gt;pageID());
+                });
+            });
+        });
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx">     
</span></span></pre>
</div>
</div>

</body>
</html>