diff options
author | Steve Block <steveblock@google.com> | 2011-05-25 19:08:45 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-06-08 13:51:31 +0100 |
commit | 2bde8e466a4451c7319e3a072d118917957d6554 (patch) | |
tree | 28f4a1b869a513e565c7760d0e6a06e7cf1fe95a /Source/WebKit2/WebProcess/FullScreen/mac | |
parent | 6939c99b71d9372d14a0c74a772108052e8c48c8 (diff) | |
download | external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.zip external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.gz external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.bz2 |
Merge WebKit at r82507: Initial merge by git
Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e
Diffstat (limited to 'Source/WebKit2/WebProcess/FullScreen/mac')
-rw-r--r-- | Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h | 67 | ||||
-rw-r--r-- | Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm | 277 |
2 files changed, 344 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h new file mode 100644 index 0000000..e247eb5 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebFullScreenManagerMac_h +#define WebFullScreenManagerMac_h + +#if ENABLE(FULLSCREEN_API) + +#import "LayerTreeContext.h" +#import "WebFullScreenManager.h" + +#import <WebCore/IntRect.h> +#import <wtf/RetainPtr.h> + +typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef; +OBJC_CLASS WebFullScreenManagerAnimationListener; + +namespace WebKit { + +class WebFullScreenManagerMac : public WebFullScreenManager { +public: + static PassRefPtr<WebFullScreenManagerMac> create(WebPage*); + + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*); + +private: + WebFullScreenManagerMac(WebPage*); + virtual ~WebFullScreenManagerMac(); + + virtual void beginEnterFullScreenAnimation(float duration); + virtual void beginExitFullScreenAnimation(float duration); + + OwnPtr<WebCore::GraphicsLayer> m_rootLayer; + WebCore::GraphicsLayer* m_fullScreenRootLayer; + LayerTreeContext m_layerTreeContext; + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; + RetainPtr<id> m_enterFullScreenListener; + RetainPtr<id> m_exitFullScreenListener; +}; + +} + +#endif // ENABLE(FULLSCREEN_API) + +#endif // WebFullScreenManagerMac_h diff --git a/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm new file mode 100644 index 0000000..66243c5 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#import "config.h" +#import "WebFullScreenManagerMac.h" + +#if ENABLE(FULLSCREEN_API) + +#import "Connection.h" +#import "LayerTreeContext.h" +#import "MessageID.h" +#import "WebFullScreenManagerProxyMessages.h" +#import "WebPage.h" +#import "WebProcess.h" +#import <QuartzCore/QuartzCore.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/GraphicsLayer.h> +#import <WebCore/Page.h> +#import <WebCore/Settings.h> +#import <WebKitSystemInterface.h> + +using namespace WebCore; + +typedef void (WebKit::WebFullScreenManager::*AnimationBeganFunction)(); +typedef void (WebKit::WebFullScreenManager::*AnimationFinishedFunction)(bool); + +#if defined(BUILDING_ON_LEOPARD) +@interface CATransaction(SnowLeopardConvenienceFunctions) ++ (void)setDisableActions:(BOOL)flag; +@end + +@implementation CATransaction(SnowLeopardConvenienceFunctions) ++ (void)setDisableActions:(BOOL)flag +{ + [self setValue:[NSNumber numberWithBool:flag] forKey:kCATransactionDisableActions]; +} +@end +#endif + +@interface WebFullScreenManagerAnimationListener : NSObject { + WebKit::WebFullScreenManager* _manager; + AnimationBeganFunction _began; + AnimationFinishedFunction _finished; +} +- (id)initWithManager:(WebKit::WebFullScreenManager*)manager began:(AnimationBeganFunction)began finished:(AnimationFinishedFunction)finished; +- (void)animationDidStart:(CAAnimation *)anim; +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; +- (void)invalidate; +@end + +@implementation WebFullScreenManagerAnimationListener +- (id)initWithManager:(WebKit::WebFullScreenManager*)manager began:(AnimationBeganFunction)began finished:(AnimationFinishedFunction)finished +{ + self = [super init]; + if (!self) + return nil; + + _manager = manager; + _began = began; + _finished = finished; + return self; +} + +- (void)animationDidStart:(CAAnimation *)anim +{ + if (_manager && _began) + (_manager->*_began)(); +} + +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag +{ + if (_manager && _finished) + (_manager->*_finished)(flag); +} + +- (void)invalidate +{ + _manager = 0; + _began = 0; + _finished = 0; +} +@end + +namespace WebKit { + +PassRefPtr<WebFullScreenManager> WebFullScreenManager::create(WebPage* page) +{ + return WebFullScreenManagerMac::create(page); +} + +PassRefPtr<WebFullScreenManagerMac> WebFullScreenManagerMac::create(WebPage* page) +{ + return adoptRef(new WebFullScreenManagerMac(page)); +} + +WebFullScreenManagerMac::WebFullScreenManagerMac(WebPage* page) + : WebFullScreenManager(page) +{ + m_enterFullScreenListener.adoptNS([[WebFullScreenManagerAnimationListener alloc] initWithManager:this began:&WebFullScreenManagerMac::beganEnterFullScreenAnimation finished:&WebFullScreenManagerMac::finishedEnterFullScreenAnimation]); + m_exitFullScreenListener.adoptNS([[WebFullScreenManagerAnimationListener alloc] initWithManager:this began:&WebFullScreenManagerMac::beganExitFullScreenAnimation finished:&WebFullScreenManagerMac::finishedExitFullScreenAnimation]); +} + +WebFullScreenManagerMac::~WebFullScreenManagerMac() +{ + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + [m_enterFullScreenListener.get() invalidate]; + [m_exitFullScreenListener.get() invalidate]; +} + +void WebFullScreenManagerMac::setRootFullScreenLayer(WebCore::GraphicsLayer* layer) +{ + if (m_fullScreenRootLayer == layer) + return; + m_fullScreenRootLayer = layer; + + if (!m_fullScreenRootLayer) { + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + if (m_rootLayer) { + m_rootLayer->removeAllChildren(); + m_rootLayer = 0; + } + return; + } + + if (!m_rootLayer) { + mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); + m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort); + + m_rootLayer = GraphicsLayer::create(NULL); +#ifndef NDEBUG + m_rootLayer->setName("Full screen root layer"); +#endif + m_rootLayer->setDrawsContent(false); + m_rootLayer->setSize(getFullScreenRect().size()); + + [m_rootLayer->platformLayer() setGeometryFlipped:YES]; + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer->platformLayer()); + m_layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); + m_page->send(Messages::WebFullScreenManagerProxy::EnterAcceleratedCompositingMode(m_layerTreeContext)); + } + + m_rootLayer->removeAllChildren(); + + if (m_fullScreenRootLayer) + m_rootLayer->addChild(m_fullScreenRootLayer); + + m_rootLayer->syncCompositingStateForThisLayerOnly(); + m_page->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); +} + +void WebFullScreenManagerMac::beginEnterFullScreenAnimation(float duration) +{ + ASSERT(m_element); + ASSERT(m_fullScreenRootLayer); + + IntRect destinationFrame = getFullScreenRect(); + m_element->document()->setFullScreenRendererSize(destinationFrame.size()); + m_rootLayer->syncCompositingStateForThisLayerOnly(); + m_page->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); + + // FIXME: Once we gain the ability to do native WebKit animations of generated + // content, this can change to use them. Meanwhile, we'll have to animate the + // CALayer directly: + CALayer* caLayer = m_fullScreenRootLayer->platformLayer(); + + // Create a transformation matrix that will transform the renderer layer such that + // the fullscreen element appears to move from its starting position and size to its + // final one. + CGPoint destinationPosition = [caLayer position]; + CGPoint layerAnchor = [caLayer anchorPoint]; + CGPoint initialPosition = CGPointMake( + m_initialFrame.x() + m_initialFrame.width() * layerAnchor.x, + m_initialFrame.y() + m_initialFrame.height() * layerAnchor.y); + CATransform3D shrinkTransform = CATransform3DMakeScale( + static_cast<CGFloat>(m_initialFrame.width()) / destinationFrame.width(), + static_cast<CGFloat>(m_initialFrame.height()) / destinationFrame.height(), 1); + CATransform3D shiftTransform = CATransform3DMakeTranslation( + initialPosition.x - destinationPosition.x, + // Drawing is flipped here, and so much be the translation transformation + destinationPosition.y - initialPosition.y, 0); + CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, shiftTransform); + + // Use a CABasicAnimation here for the zoom effect. We want to be notified that the animation has + // completed by way of the CAAnimation delegate. + CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; + [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:finalTransform]]; + [zoomAnimation setToValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]]; + [zoomAnimation setDelegate:m_enterFullScreenListener.get()]; + [zoomAnimation setDuration:duration]; + [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [zoomAnimation setFillMode:kCAFillModeForwards]; + + // Disable implicit animations and set the layer's transformation matrix to its final state. + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [caLayer addAnimation:zoomAnimation forKey:@"zoom"]; + [CATransaction commit]; +} + +void WebFullScreenManagerMac::beginExitFullScreenAnimation(float duration) +{ + ASSERT(m_element); + ASSERT(m_fullScreenRootLayer); + + IntRect destinationFrame = getFullScreenRect(); + m_element->document()->setFullScreenRendererSize(destinationFrame.size()); + m_rootLayer->syncCompositingStateForThisLayerOnly(); + m_page->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); + + // FIXME: Once we gain the ability to do native WebKit animations of generated + // content, this can change to use them. Meanwhile, we'll have to animate the + // CALayer directly: + CALayer* caLayer = m_fullScreenRootLayer->platformLayer(); + + // Create a transformation matrix that will transform the renderer layer such that + // the fullscreen element appears to move from its starting position and size to its + // final one. + CGPoint destinationPosition = [(CALayer*)[caLayer presentationLayer] position]; + CGRect destinationBounds = NSRectToCGRect([[caLayer presentationLayer] bounds]); + CGPoint layerAnchor = [caLayer anchorPoint]; + CGPoint initialPosition = CGPointMake( + m_initialFrame.x() + m_initialFrame.width() * layerAnchor.x, + m_initialFrame.y() + m_initialFrame.height() * layerAnchor.y); + CATransform3D shrinkTransform = CATransform3DMakeScale( + static_cast<CGFloat>(m_initialFrame.width()) / destinationBounds.size.width, + static_cast<CGFloat>(m_initialFrame.height()) / destinationBounds.size.height, 1); + CATransform3D shiftTransform = CATransform3DMakeTranslation( + initialPosition.x - destinationPosition.x, + // Drawing is flipped here, and so must be the translation transformation + destinationPosition.y - initialPosition.y, 0); + CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, shiftTransform); + + CATransform3D initialTransform = [(CALayer*)[caLayer presentationLayer] transform]; + + // Use a CABasicAnimation here for the zoom effect. We want to be notified that the animation has + // completed by way of the CAAnimation delegate. + CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; + [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:initialTransform]]; + [zoomAnimation setToValue:[NSValue valueWithCATransform3D:finalTransform]]; + [zoomAnimation setDelegate:m_exitFullScreenListener.get()]; + [zoomAnimation setDuration:duration]; + [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [zoomAnimation setFillMode:kCAFillModeForwards]; + + // Disable implicit animations and set the layer's transformation matrix to its final state. + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [caLayer addAnimation:zoomAnimation forKey:@"zoom"]; + [caLayer setTransform:finalTransform]; + [CATransaction commit]; +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) |