Title: [171286] trunk/Source
Revision
171286
Author
[email protected]
Date
2014-07-20 19:30:24 -0700 (Sun, 20 Jul 2014)

Log Message

Decrease flicker when enter and exit fullscreen.
https://bugs.webkit.org/show_bug.cgi?id=134919

Patch by Jeremy Jones <[email protected]> on 2014-07-20
Reviewed by Simon Fraser.

Source/WebCore:
Put AVPlayerLayer in a container layer so moving it between inline and fullscreen
is as easy as adding and removing it from a containter layer; no need to do a layout.

Make sure fullscreen layers are transparent before moving moving the AVPlayerLayer
between inline and fullscreen so you don't briefly see the empty fullscreen layers.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::platformLayer): remove fullscreen special case.
(WebCore::HTMLMediaElement::setVideoFullscreenLayer): no need to recalc style
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: add inline container layer
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
add WebVideoContainerLayer to contain AVPlayerLayer and keep layout correct.
(-[WebVideoContainerLayer setBounds:]): forward setbounds to set child frame.
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerLayer): create the video container layer
(WebCore::MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer): destroy the video container layer
(WebCore::MediaPlayerPrivateAVFoundationObjC::platformLayer): use container layer instead of video layer
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer): use transactions to prevent unwanted animation.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenFrame): ditto
* platform/graphics/ca/mac/PlatformCALayerMac.mm:
(PlatformCALayerMac::layerTypeForPlatformLayer): WebVideoContainerLayer is a kind of AVPlayerLayer
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(-[WebVideoFullscreenController didCleanupFullscreen]): remove video fullscreen layer first
* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
(WebVideoFullscreenInterfaceAVKit::setupFullscreen): make background transparent during transition.
   dispatch_async to allow CATransaction to complete before calling didSetupFullscreen()

Source/WebKit2:
Change the sequence of tear down and use transparency to prevent flicker when entering and exiting fullscreen.

* UIProcess/ios/WebVideoFullscreenManagerProxy.mm: wait to remove layerHost until didCleanupFullscreen
(WebKit::WebVideoFullscreenManagerProxy::didExitFullscreen): removed from here
(WebKit::WebVideoFullscreenManagerProxy::didCleanupFullscreen): added here
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::didSetupFullscreen): use transparent background during transition

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (171285 => 171286)


--- trunk/Source/WebCore/ChangeLog	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/ChangeLog	2014-07-21 02:30:24 UTC (rev 171286)
@@ -1,3 +1,36 @@
+2014-07-20  Jeremy Jones  <[email protected]>
+
+        Decrease flicker when enter and exit fullscreen.
+        https://bugs.webkit.org/show_bug.cgi?id=134919
+
+        Reviewed by Simon Fraser.
+
+        Put AVPlayerLayer in a container layer so moving it between inline and fullscreen
+        is as easy as adding and removing it from a containter layer; no need to do a layout.
+
+        Make sure fullscreen layers are transparent before moving moving the AVPlayerLayer
+        between inline and fullscreen so you don't briefly see the empty fullscreen layers.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::platformLayer): remove fullscreen special case.
+        (WebCore::HTMLMediaElement::setVideoFullscreenLayer): no need to recalc style
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: add inline container layer
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: 
+        add WebVideoContainerLayer to contain AVPlayerLayer and keep layout correct.
+        (-[WebVideoContainerLayer setBounds:]): forward setbounds to set child frame.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerLayer): create the video container layer
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer): destroy the video container layer
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::platformLayer): use container layer instead of video layer
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer): use transactions to prevent unwanted animation.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenFrame): ditto
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm:
+        (PlatformCALayerMac::layerTypeForPlatformLayer): WebVideoContainerLayer is a kind of AVPlayerLayer
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (-[WebVideoFullscreenController didCleanupFullscreen]): remove video fullscreen layer first
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+        (WebVideoFullscreenInterfaceAVKit::setupFullscreen): make background transparent during transition.
+           dispatch_async to allow CATransaction to complete before calling didSetupFullscreen()
+
 2014-07-20  Ryuan Choi  <[email protected]>
 
         Move ExceptionCodeDescription.h into the files that actually need it

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (171285 => 171286)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2014-07-21 02:30:24 UTC (rev 171286)
@@ -4946,10 +4946,6 @@
 
 PlatformLayer* HTMLMediaElement::platformLayer() const
 {
-#if PLATFORM(IOS)
-    if (m_videoFullscreenLayer)
-        return nullptr;
-#endif
     return m_player ? m_player->platformLayer() : nullptr;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (171285 => 171286)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2014-07-21 02:30:24 UTC (rev 171286)
@@ -271,6 +271,7 @@
     RetainPtr<AVPlayer> m_avPlayer;
     RetainPtr<AVPlayerItem> m_avPlayerItem;
     RetainPtr<AVPlayerLayer> m_videoLayer;
+    RetainPtr<PlatformLayer> m_videoInlineLayer;
 #if PLATFORM(IOS)
     RetainPtr<PlatformLayer> m_videoFullscreenLayer;
     FloatRect m_videoFullscreenFrame;

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2014-07-21 02:30:24 UTC (rev 171286)
@@ -86,6 +86,19 @@
 #import <VideoToolbox/VideoToolbox.h>
 #endif
 
+@interface WebVideoContainerLayer : CALayer
+@end
+
+@implementation WebVideoContainerLayer
+
+- (void)setBounds:(CGRect)bounds
+{
+    [super setBounds:bounds];
+    for (CALayer* layer in self.sublayers)
+        layer.frame = bounds;
+}
+@end
+
 #if ENABLE(AVF_CAPTIONS)
 // Note: This must be defined before our SOFT_LINK macros:
 @class AVMediaSelectionOption;
@@ -573,21 +586,26 @@
     m_videoLayer = adoptNS([[AVPlayerLayer alloc] init]);
     [m_videoLayer setPlayer:m_avPlayer.get()];
     [m_videoLayer setBackgroundColor:cachedCGColor(Color::black, ColorSpaceDeviceRGB)];
+    m_videoInlineLayer = adoptNS([[WebVideoContainerLayer alloc] init]);
 #ifndef NDEBUG
     [m_videoLayer setName:@"MediaPlayerPrivate AVPlayerLayer"];
 #endif
     [m_videoLayer addObserver:m_objcObserver.get() forKeyPath:@"readyForDisplay" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextAVPlayerLayer];
     updateVideoLayerGravity();
     IntSize defaultSize = player()->mediaPlayerClient() ? player()->mediaPlayerClient()->mediaPlayerContentBoxRect().pixelSnappedSize() : IntSize();
-    [m_videoLayer setFrame:CGRectMake(0, 0, defaultSize.width(), defaultSize.height())];
+    [m_videoInlineLayer setFrame:CGRectMake(0, 0, defaultSize.width(), defaultSize.height())];
     LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createVideoLayer(%p) - returning %p", this, m_videoLayer.get());
 
 #if PLATFORM(IOS)
     if (m_videoFullscreenLayer) {
-        [m_videoLayer setFrame:CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height())];
+        [m_videoLayer setFrame:[m_videoFullscreenLayer bounds]];
         [m_videoFullscreenLayer insertSublayer:m_videoLayer.get() atIndex:0];
+    } else
+#endif
+    {
+        [m_videoInlineLayer insertSublayer:m_videoLayer.get() atIndex:0];
+        [m_videoLayer setFrame:m_videoInlineLayer.get().bounds];
     }
-#endif
 }
 
 void MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer()
@@ -605,7 +623,8 @@
         [m_videoLayer removeFromSuperlayer];
 #endif
 
-    m_videoLayer = 0;
+    m_videoLayer = nil;
+    m_videoInlineLayer = nil;
 }
 
 bool MediaPlayerPrivateAVFoundationObjC::hasAvailableVideoFrame() const
@@ -936,7 +955,7 @@
 
 PlatformLayer* MediaPlayerPrivateAVFoundationObjC::platformLayer() const
 {
-    return m_haveBeenAskedToCreateLayer ? m_videoLayer.get() : nullptr;
+    return m_haveBeenAskedToCreateLayer ? m_videoInlineLayer.get() : nullptr;
 }
 
 #if PLATFORM(IOS)
@@ -945,17 +964,24 @@
     if (m_videoFullscreenLayer == videoFullscreenLayer)
         return;
 
-    if (m_videoFullscreenLayer)
-       [m_videoLayer removeFromSuperlayer];
-
     m_videoFullscreenLayer = videoFullscreenLayer;
 
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+
     if (m_videoFullscreenLayer && m_videoLayer) {
-        CGRect frame = CGRectMake(0, 0, m_videoFullscreenFrame.width(), m_videoFullscreenFrame.height());
-        [m_videoLayer setFrame:frame];
+        [m_videoLayer setFrame:[m_videoFullscreenLayer bounds]];
+        [m_videoLayer removeFromSuperlayer];
         [m_videoFullscreenLayer insertSublayer:m_videoLayer.get() atIndex:0];
-    }
+    } else if (m_videoInlineLayer && m_videoLayer) {
+        [m_videoLayer setFrame:[m_videoInlineLayer bounds]];
+        [m_videoLayer removeFromSuperlayer];
+        [m_videoInlineLayer insertSublayer:m_videoLayer.get() atIndex:0];
+    } else if (m_videoLayer)
+        [m_videoLayer removeFromSuperlayer];
 
+    [CATransaction commit];
+
     if (m_videoFullscreenLayer && m_textTrackRepresentationLayer) {
         syncTextTrackBounds();
         [m_videoFullscreenLayer addSublayer:m_textTrackRepresentationLayer.get()];
@@ -971,9 +997,12 @@
     if (!m_videoFullscreenLayer)
         return;
 
-    if (m_videoLayer)
+    if (m_videoLayer) {
+        [CATransaction begin];
+        [CATransaction setDisableActions:YES];
         [m_videoLayer setFrame:CGRectMake(0, 0, frame.width(), frame.height())];
-
+        [CATransaction commit];
+    }
     syncTextTrackBounds();
 }
 

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm (171285 => 171286)


--- trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2014-07-21 02:30:24 UTC (rev 171286)
@@ -178,7 +178,7 @@
 
 PlatformCALayer::LayerType PlatformCALayerMac::layerTypeForPlatformLayer(PlatformLayer* layer)
 {
-    if ([layer isKindOfClass:getAVPlayerLayerClass()])
+    if ([layer isKindOfClass:getAVPlayerLayerClass()] || [layer isKindOfClass:objc_getClass("WebVideoContainerLayer")])
         return LayerTypeAVPlayerLayer;
 
     if ([layer isKindOfClass:[WebGLLayer class]])

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (171285 => 171286)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2014-07-21 02:30:24 UTC (rev 171286)
@@ -161,9 +161,9 @@
 - (void)didCleanupFullscreen
 {
     WebThreadRun(^{
+        _model->setVideoFullscreenLayer(nil);
         _interface->setWebVideoFullscreenModel(nullptr);
         _model->setWebVideoFullscreenInterface(nullptr);
-        _model->setVideoFullscreenLayer(nil);
         _model->setMediaElement(nullptr);
         _interface->setWebVideoFullscreenChangeObserver(nullptr);
         _model = nullptr;

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm (171285 => 171286)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm	2014-07-21 02:30:24 UTC (rev 171286)
@@ -774,15 +774,18 @@
         [m_viewController addChildViewController:m_playerViewController.get()];
         [[m_viewController view] addSubview:[m_playerViewController view]];
         [m_playerViewController view].frame = initialRect;
+        [[m_playerViewController view] setBackgroundColor:[getUIColorClass() clearColor]];
         [m_playerViewController didMoveToParentViewController:m_viewController.get()];
         [[m_playerViewController view] layoutIfNeeded];
 
         [CATransaction commit];
-        
-        if (m_fullscreenChangeObserver)
-            m_fullscreenChangeObserver->didSetupFullscreen();
-        
-        protect.clear();
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (m_fullscreenChangeObserver)
+                m_fullscreenChangeObserver->didSetupFullscreen();
+            
+            protect.clear();
+        });
     });
 }
 

Modified: trunk/Source/WebKit2/ChangeLog (171285 => 171286)


--- trunk/Source/WebKit2/ChangeLog	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebKit2/ChangeLog	2014-07-21 02:30:24 UTC (rev 171286)
@@ -1,3 +1,18 @@
+2014-07-20  Jeremy Jones  <[email protected]>
+
+        Decrease flicker when enter and exit fullscreen.
+        https://bugs.webkit.org/show_bug.cgi?id=134919
+
+        Reviewed by Simon Fraser.
+
+        Change the sequence of tear down and use transparency to prevent flicker when entering and exiting fullscreen.
+
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.mm: wait to remove layerHost until didCleanupFullscreen
+        (WebKit::WebVideoFullscreenManagerProxy::didExitFullscreen): removed from here
+        (WebKit::WebVideoFullscreenManagerProxy::didCleanupFullscreen): added here
+        * WebProcess/ios/WebVideoFullscreenManager.mm:
+        (WebKit::WebVideoFullscreenManager::didSetupFullscreen): use transparent background during transition
+
 2014-07-20  Dan Bernstein  <[email protected]>
 
         <rdar://problem/17739526> REGRESSION (r171057): Crash in WebPage::getPositionInformation()

Modified: trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm (171285 => 171286)


--- trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm	2014-07-21 02:30:24 UTC (rev 171286)
@@ -109,12 +109,12 @@
 void WebVideoFullscreenManagerProxy::didExitFullscreen()
 {
     m_page->send(Messages::WebVideoFullscreenManager::DidExitFullscreen(), m_page->pageID());
-    [m_layerHost removeFromSuperlayer];
-    m_layerHost.clear();
 }
     
 void WebVideoFullscreenManagerProxy::didCleanupFullscreen()
 {
+    [m_layerHost removeFromSuperlayer];
+    m_layerHost.clear();
     m_page->send(Messages::WebVideoFullscreenManager::DidCleanupFullscreen(), m_page->pageID());
 }
 

Modified: trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm (171285 => 171286)


--- trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm	2014-07-21 02:19:48 UTC (rev 171285)
+++ trunk/Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm	2014-07-21 02:30:24 UTC (rev 171286)
@@ -33,6 +33,7 @@
 #import "WebVideoFullscreenManagerMessages.h"
 #import "WebVideoFullscreenManagerProxyMessages.h"
 #import <QuartzCore/CoreAnimation.h>
+#import <WebCore/Color.h>
 #import <WebCore/Event.h>
 #import <WebCore/EventNames.h>
 #import <WebCore/FrameView.h>
@@ -166,9 +167,13 @@
 #ifndef NDEBUG
     [videoLayer setName:@"Web video fullscreen manager layer"];
 #endif
-    
+
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+    [videoLayer setBackgroundColor:cachedCGColor(WebCore::Color::transparent, WebCore::ColorSpaceDeviceRGB)];
     m_layerHostingContext->setRootLayer(videoLayer);
     setVideoFullscreenLayer(videoLayer);
+    [CATransaction commit];
     m_page->send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(), m_page->pageID());
 }
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to