From 86a00b107e90c7842e602f816f888a6eae4eb585 Mon Sep 17 00:00:00 2001 From: Jer Noble Date: Fri, 20 May 2011 05:31:07 +0000 Subject: [PATCH] 2011-05-19 Jer Noble Reviewed by Maciej Stachowiak. WebKit2: Flashing when entering and exiting full screen mode https://bugs.webkit.org/show_bug.cgi?id=56957 Guard against the parameter of setAnimating() matching the ivar value it's setting, thus avoiding tearing down the renderer's layer backing. * rendering/RenderFullScreen.cpp: (RenderFullScreen::setAnimating): 2011-05-19 Jer Noble Reviewed by Maciej Stachowiak. WebKit2: Flashing when entering and exiting full screen mode https://bugs.webkit.org/show_bug.cgi?id=56957 In the WKFullscreenWindowController, when exiting accelerated compositing mode, force a repaint, and don't actually remove the animation layer until the repaint completes. Also, move back to parenting the WebView in a layer-backed view, and work around the SnowLeopard bug which causes a crash in those situations. We no longer need to do a bunch of work in finishedEnterFullScreenAnimation, because the animation layer is "hiding" all the drawing happening in the webView underneath. In the WebFullScreenManagerMac, when asked to tear down the root layer, instead remove all its children, and set its contents to a flattened image of the full screen element and its children. This helps patch over the time where everything is re-rendering and helps give the appearance of continuousness in the animation. * UIProcess/mac/WKFullScreenWindowController.mm: (-[WKFullScreenWindowController finishedEnterFullScreenAnimation:]): (-[WKFullScreenWindowController beganExitFullScreenAnimation]): (-[WKFullScreenWindowController enterAcceleratedCompositingMode:WebKit::]): (-[WKFullScreenWindowController exitAcceleratedCompositingMode]): (-[WKFullScreenWindowController exitCompositedModeRepaintCompleted]): (exitCompositedModeRepaintCompleted): (-[WKFullScreenWindowController _page]): (-[WKFullScreenWindowController _manager]): (-[WKFullScreenWindow initWithContentRect:styleMask:backing:defer:]): * WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm: (WebKit::WebFullScreenManagerMac::setRootFullScreenLayer): Canonical link: https://commits.webkit.org/76528@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@86924 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 13 +++++ Source/WebCore/rendering/RenderFullScreen.cpp | 3 ++ Source/WebKit2/ChangeLog | 32 ++++++++++++ .../mac/WKFullScreenWindowController.mm | 51 +++++++++++++------ .../FullScreen/mac/WebFullScreenManagerMac.mm | 11 +++- 5 files changed, 94 insertions(+), 16 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index cb1dcd61b8d7..51a21a326b19 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,16 @@ +2011-05-19 Jer Noble + + Reviewed by Maciej Stachowiak. + + WebKit2: Flashing when entering and exiting full screen mode + https://bugs.webkit.org/show_bug.cgi?id=56957 + + Guard against the parameter of setAnimating() matching the ivar value it's + setting, thus avoiding tearing down the renderer's layer backing. + + * rendering/RenderFullScreen.cpp: + (RenderFullScreen::setAnimating): + 2011-05-19 Julien Chaffraix Reviewed by Adam Barth. diff --git a/Source/WebCore/rendering/RenderFullScreen.cpp b/Source/WebCore/rendering/RenderFullScreen.cpp index 78cf1c164bec..6c13b767d40f 100644 --- a/Source/WebCore/rendering/RenderFullScreen.cpp +++ b/Source/WebCore/rendering/RenderFullScreen.cpp @@ -38,6 +38,9 @@ using namespace WebCore; void RenderFullScreen::setAnimating(bool animating) { + if (m_isAnimating == animating) + return; + m_isAnimating = animating; #if USE(ACCELERATED_COMPOSITING) if (layer()) { diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index 7e1d94516783..fa3dc12cfc93 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,35 @@ +2011-05-19 Jer Noble + + Reviewed by Maciej Stachowiak. + + WebKit2: Flashing when entering and exiting full screen mode + https://bugs.webkit.org/show_bug.cgi?id=56957 + + In the WKFullscreenWindowController, when exiting accelerated compositing mode, + force a repaint, and don't actually remove the animation layer until the repaint + completes. Also, move back to parenting the WebView in a layer-backed view, and + work around the SnowLeopard bug which causes a crash in those situations. We no + longer need to do a bunch of work in finishedEnterFullScreenAnimation, because + the animation layer is "hiding" all the drawing happening in the webView underneath. + + In the WebFullScreenManagerMac, when asked to tear down the root layer, instead + remove all its children, and set its contents to a flattened image of the full + screen element and its children. This helps patch over the time where everything + is re-rendering and helps give the appearance of continuousness in the animation. + + * UIProcess/mac/WKFullScreenWindowController.mm: + (-[WKFullScreenWindowController finishedEnterFullScreenAnimation:]): + (-[WKFullScreenWindowController beganExitFullScreenAnimation]): + (-[WKFullScreenWindowController enterAcceleratedCompositingMode:WebKit::]): + (-[WKFullScreenWindowController exitAcceleratedCompositingMode]): + (-[WKFullScreenWindowController exitCompositedModeRepaintCompleted]): + (exitCompositedModeRepaintCompleted): + (-[WKFullScreenWindowController _page]): + (-[WKFullScreenWindowController _manager]): + (-[WKFullScreenWindow initWithContentRect:styleMask:backing:defer:]): + * WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm: + (WebKit::WebFullScreenManagerMac::setRootFullScreenLayer): + 2011-05-19 Anders Carlsson Address a review comment by Sam Weinig. diff --git a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm index b15abacb03f1..4d7273a94558 100644 --- a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm +++ b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm @@ -46,6 +46,8 @@ using namespace WebKit; using namespace WebCore; +static void exitCompositedModeRepaintCompleted(WKErrorRef, void* context); + #if defined(BUILDING_ON_LEOPARD) @interface CATransaction(SnowLeopardConvenienceFunctions) + (void)setDisableActions:(BOOL)flag; @@ -82,6 +84,7 @@ - (void)_updatePowerAssertions; - (WKFullScreenWindow *)_fullScreenWindow; - (CFTimeInterval)_animationDuration; - (void)_swapView:(NSView*)view with:(NSView*)otherView; +- (WebPageProxy*)_page; - (WebFullScreenManagerProxy*)_manager; @end @@ -241,8 +244,6 @@ - (void)finishedEnterFullScreenAnimation:(bool)completed if (!_isEnteringFullScreen) return; _isEnteringFullScreen = NO; - - NSDisableScreenUpdates(); if (completed) { // Swap the webView placeholder into place. @@ -252,13 +253,8 @@ - (void)finishedEnterFullScreenAnimation:(bool)completed // Then insert the WebView into the full screen window NSView* contentView = [[self _fullScreenWindow] contentView]; - [contentView addSubview:_webView positioned:NSWindowBelow relativeTo:_layerHostingView.get()]; + [contentView addSubview:_webView positioned:NSWindowBelow relativeTo:nil]; [_webView setFrame:[contentView bounds]]; - - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - [[[self _fullScreenWindow] backgroundLayer] setHidden:YES]; - [CATransaction commit]; NSWindow *webWindow = [_webViewPlaceholder.get() window]; #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) @@ -271,11 +267,8 @@ - (void)finishedEnterFullScreenAnimation:(bool)completed #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) [webWindow setAnimationBehavior:animationBehavior]; #endif - [[self window] makeKeyAndOrderFront:self]; + [self _manager]->didEnterFullScreen(); } - - [self _manager]->didEnterFullScreen(); - NSEnableScreenUpdates(); } - (void)exitFullScreen @@ -305,6 +298,16 @@ - (void)beganExitFullScreenAnimation // Swap the webView back into its original position: if ([_webView window] == [self window]) { +#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) + // Work around a bug in AppKit where moving a + // layer-hosted view from a layer-backed view to a non-layer-backed view + // generates an exception. + if (![_webView wantsLayer] && [_webView layer]) { + [_webView removeFromSuperview]; + for (NSView* child in [_webView subviews]) + [[child layer] removeFromSuperlayer]; + } +#endif [self _swapView:_webViewPlaceholder.get() with:_webView]; NSWindow* webWindow = [_webView window]; #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) @@ -364,7 +367,7 @@ - (void)enterAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTr [CATransaction begin]; [CATransaction setDisableActions:YES]; WKFullScreenWindow* window = [self _fullScreenWindow]; - [[window contentView] addSubview:_layerHostingView.get() positioned:NSWindowAbove relativeTo:[window animationView]]; + [[window contentView] addSubview:_layerHostingView.get() positioned:NSWindowAbove relativeTo:nil]; // Create a root layer that will back the NSView. RetainPtr rootLayer(AdoptNS, [[CALayer alloc] init]); @@ -385,7 +388,13 @@ - (void)exitAcceleratedCompositingMode { if (!_layerHostingView) return; - + + NSDisableScreenUpdates(); + [self _page]->forceRepaint(VoidCallback::create(self, exitCompositedModeRepaintCompleted)); +} + +- (void)exitCompositedModeRepaintCompleted +{ [CATransaction begin]; [CATransaction setDisableActions:YES]; [_layerHostingView.get() removeFromSuperview]; @@ -395,6 +404,12 @@ - (void)exitAcceleratedCompositingMode [CATransaction commit]; _layerHostingView = 0; + NSEnableScreenUpdates(); +} + +static void exitCompositedModeRepaintCompleted(WKErrorRef, void* context) +{ + [(WKFullScreenWindowController*)context exitCompositedModeRepaintCompleted]; } - (WebCore::IntRect)getFullScreenRect @@ -500,9 +515,14 @@ - (void)_updatePowerAssertions } } +- (WebPageProxy*)_page +{ + return toImpl([_webView pageRef]); +} + - (WebFullScreenManagerProxy*)_manager { - WebPageProxy* webPage = toImpl([_webView pageRef]); + WebPageProxy* webPage = [self _page]; if (!webPage) return 0; return webPage->fullScreenManager(); @@ -582,6 +602,7 @@ - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backi #endif NSView* contentView = [self contentView]; + [contentView setWantsLayer:YES]; _animationView = [[NSView alloc] initWithFrame:[contentView bounds]]; CALayer* contentLayer = [[CALayer alloc] init]; diff --git a/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm index 17a803082470..9ccc19e1d3a0 100644 --- a/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm +++ b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm @@ -137,11 +137,20 @@ - (void)invalidate if (!layer) { m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); [[NSNotificationCenter defaultCenter] postNotificationName:@"WebKitLayerHostChanged" object:m_rootLayer->platformLayer() userInfo:nil]; + + Frame* frame = m_element->document()->frame(); + DragImageRef dragImage = frame ? frame->nodeImage(m_element.get()) : 0; + if (m_rootLayer) { + [CATransaction begin]; + PlatformLayer* rootPlatformLayer = m_rootLayer->platformLayer(); m_rootLayer->removeAllChildren(); + m_rootLayer->syncCompositingStateForThisLayerOnly(); m_rootLayer = nullptr; + [rootPlatformLayer setContents:dragImage.get()]; + [CATransaction commit]; } - + return; }