Changeset 87456 in webkit


Ignore:
Timestamp:
May 26, 2011 5:29:40 PM (13 years ago)
Author:
jonlee@apple.com
Message:

2011-05-26 Jon Lee <jonlee@apple.com>

Reviewed by Darin Adler.

REGRESSION (5.0.5-Jazz): Transition to full screen video animates in wrong location when scrolled (61559)
https://bugs.webkit.org/show_bug.cgi?id=61559
<rdar://problem/9496054>

The CALayer that gets animated has a position that is offset by the scroll position of the web view. To
fix this, we set the destination location based on the rect of the full screen, and add a position
animation which keeps the position of the layer centered. This prevents glitches if others
are trying to change the layer position while the animation is running.

  • WebProcess/FullScreen/mac/WebFullScreenManagerMac.h: Refactor the calculation of the CALayer windowed position into a private helper function, as well as the animation setup.
  • WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm: (WebKit::WebFullScreenManagerMac::beginEnterFullScreenAnimation): (WebKit::WebFullScreenManagerMac::beginExitFullScreenAnimation): (WebKit::WebFullScreenManagerMac::animateFullScreen): Sets up the zoom animation, and the position offset animation. (WebKit::WebFullScreenManagerMac::windowedCGTransform): Calculates the placement of the windowed layer in screen coordinates.
Location:
trunk/Source/WebKit2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r87452 r87456  
     12011-05-26  Jon Lee  <jonlee@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        REGRESSION (5.0.5-Jazz): Transition to full screen video animates in wrong location when scrolled (61559)
     6        https://bugs.webkit.org/show_bug.cgi?id=61559
     7        <rdar://problem/9496054>
     8
     9        The CALayer that gets animated has a position that is offset by the scroll position of the web view. To
     10        fix this, we set the destination location based on the rect of the full screen, and add a position
     11        animation which keeps the position of the layer centered. This prevents glitches if others
     12        are trying to change the layer position while the animation is running.
     13
     14        * WebProcess/FullScreen/mac/WebFullScreenManagerMac.h: Refactor the calculation of the CALayer windowed
     15        position into a private helper function, as well as the animation setup.
     16        * WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm:
     17        (WebKit::WebFullScreenManagerMac::beginEnterFullScreenAnimation):
     18        (WebKit::WebFullScreenManagerMac::beginExitFullScreenAnimation):
     19        (WebKit::WebFullScreenManagerMac::animateFullScreen): Sets up the zoom animation, and the position offset
     20        animation.
     21        (WebKit::WebFullScreenManagerMac::windowedCGTransform): Calculates the placement of the windowed layer
     22        in screen coordinates.
     23
    1242011-05-26  Qi Zhang  <qi.2.zhang@nokia.com>
    225
  • trunk/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h

    r86738 r87456  
    5454    virtual void beginExitFullScreenAnimation(float duration);
    5555
     56    void animateFullScreen(const CATransform3D& startTransform, const CATransform3D& endTransform, float duration, id listener);
     57    CATransform3D windowedCGTransform();
     58
    5659    OwnPtr<WebCore::GraphicsLayer> m_rootLayer;
    5760    LayerTreeContext m_layerTreeContext;
  • trunk/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm

    r87102 r87456  
    200200    m_rootLayer->syncCompositingState();
    201201
    202     RenderLayer* layer = m_element->renderer() ? m_element->renderer()->enclosingLayer() : 0;
    203     RenderLayerBacking* backing = layer ? layer->backing() : 0;
    204     if (backing)
    205         destinationFrame.setSize(backing->contentsBox().size());
    206 
    207202    // FIXME: Once we gain the ability to do native WebKit animations of generated
    208203    // content, this can change to use them.  Meanwhile, we'll have to animate the
    209     // CALayer directly:
    210     CALayer* caLayer = m_rootLayer->children().first()->platformLayer();
    211 
    212     // Create a transformation matrix that will transform the renderer layer such that
    213     // the fullscreen element appears to move from its starting position and size to its
    214     // final one.
    215     CGPoint destinationPosition = [caLayer position];
    216     CGPoint layerAnchor = [caLayer anchorPoint];
    217     CGPoint initialPosition = CGPointMake(
    218         m_initialFrame.x() + m_initialFrame.width() * layerAnchor.x,
    219         m_initialFrame.y() + m_initialFrame.height() * layerAnchor.y);
    220     CATransform3D shrinkTransform = CATransform3DMakeScale(
    221         static_cast<CGFloat>(m_initialFrame.width()) / destinationFrame.width(),
    222         static_cast<CGFloat>(m_initialFrame.height()) / destinationFrame.height(), 1);
    223     CATransform3D shiftTransform = CATransform3DMakeTranslation(
    224         initialPosition.x - destinationPosition.x,
    225         // Drawing is flipped here, and so much be the translation transformation
    226         destinationPosition.y - initialPosition.y, 0);
    227     CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, shiftTransform);
    228 
    229     // Use a CABasicAnimation here for the zoom effect. We want to be notified that the animation has
    230     // completed by way of the CAAnimation delegate.
    231     CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    232     [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:finalTransform]];
    233     [zoomAnimation setToValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]];
    234     [zoomAnimation setDelegate:m_enterFullScreenListener.get()];
    235     [zoomAnimation setDuration:duration];
    236     [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    237     [zoomAnimation setFillMode:kCAFillModeForwards];
    238 
    239     // Disable implicit animations and set the layer's transformation matrix to its final state.
    240     [CATransaction begin];
    241     [CATransaction setDisableActions:YES];
    242     [caLayer addAnimation:zoomAnimation forKey:@"zoom"];
    243     [CATransaction commit];
     204    // CALayer directly.
     205    animateFullScreen(windowedCGTransform(), CATransform3DIdentity, duration, m_enterFullScreenListener.get());
    244206}
    245207
     
    259221    m_rootLayer->syncCompositingState();
    260222
     223    // FIXME: Once we gain the ability to do native WebKit animations of generated
     224    // content, this can change to use them.  Meanwhile, we'll have to animate the
     225    // CALayer directly.
     226    CALayer* caLayer = m_rootLayer->children().first()->platformLayer();
     227    CALayer* presentationLayer = [caLayer presentationLayer] ? (CALayer*)[caLayer presentationLayer] : caLayer;
     228    animateFullScreen([presentationLayer transform], windowedCGTransform(), duration, m_exitFullScreenListener.get());
     229}
     230
     231void WebFullScreenManagerMac::animateFullScreen(const CATransform3D& startTransform, const CATransform3D& endTransform, float duration, id listener)
     232{
     233    // This is the full size of the screen.
     234    IntRect fullScreenRect = getFullScreenRect();   
     235    CALayer* caLayer = m_rootLayer->children().first()->platformLayer();
     236
     237    // This animation represents the zoom effect.
     238    CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
     239    [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:startTransform]];
     240    [zoomAnimation setToValue:[NSValue valueWithCATransform3D:endTransform]];
     241   
     242    // This animation provides a position correction to the CALayer, which might be offset based on the page's
     243    // scroll position. We animate it instead of just setting the property because others might try to
     244    // alter its position while the animation is playing.
     245    CGPoint layerAnchor = [caLayer anchorPoint];
     246    CGPoint fullScreenPosition = CGPointMake(
     247        fullScreenRect.x() + fullScreenRect.width() * layerAnchor.x,
     248        fullScreenRect.y() + fullScreenRect.height() * layerAnchor.y);
     249    CABasicAnimation* positionCorrection = [CABasicAnimation animationWithKeyPath:@"position"];
     250    [positionCorrection setFromValue:[NSValue valueWithPoint:NSPointFromCGPoint(fullScreenPosition)]];
     251    [positionCorrection setToValue:[NSValue valueWithPoint:NSPointFromCGPoint(fullScreenPosition)]];
     252   
     253    // We want to be notified that the animation has completed by way of the CAAnimation delegate.
     254    CAAnimationGroup* transitionAnimation = [CAAnimationGroup animation];
     255    [transitionAnimation setAnimations:[NSArray arrayWithObjects:zoomAnimation, positionCorrection, nil]];
     256    [transitionAnimation setDelegate:listener];
     257    [transitionAnimation setDuration:duration];
     258    [transitionAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
     259    [transitionAnimation setFillMode:kCAFillModeForwards];
     260    [transitionAnimation setRemovedOnCompletion:NO];
     261   
     262    // Disable implicit animations and set the layer's transformation matrix to its final state.
     263    [CATransaction begin];
     264    [CATransaction setDisableActions:YES];
     265    [caLayer addAnimation:transitionAnimation forKey:@"zoom"];
     266    [CATransaction commit];
     267}
     268
     269CATransform3D WebFullScreenManagerMac::windowedCGTransform()
     270{
     271    IntRect fullScreenRect = getFullScreenRect();
    261272    RenderLayer* layer = m_element->renderer() ? m_element->renderer()->enclosingLayer() : 0;
    262273    RenderLayerBacking* backing = layer ? layer->backing() : 0;
     274    IntSize fullScreenSize = fullScreenRect.size();
    263275    if (backing)
    264         destinationFrame.setSize(backing->contentsBox().size());
    265 
    266     // FIXME: Once we gain the ability to do native WebKit animations of generated
    267     // content, this can change to use them.  Meanwhile, we'll have to animate the
    268     // CALayer directly:
     276        fullScreenSize = backing->contentsBox().size();
     277
    269278    CALayer* caLayer = m_rootLayer->children().first()->platformLayer();
    270     CALayer* presentationLayer = [caLayer presentationLayer] ? (CALayer*)[caLayer presentationLayer] : caLayer;
    271279
    272280    // Create a transformation matrix that will transform the renderer layer such that
    273281    // the fullscreen element appears to move from its starting position and size to its
    274282    // final one.
    275     CGPoint destinationPosition = [presentationLayer position];
    276283    CGPoint layerAnchor = [caLayer anchorPoint];
    277     CGPoint initialPosition = CGPointMake(
     284    CGPoint fullScreenPosition = CGPointMake(
     285        fullScreenRect.x() + fullScreenRect.width() * layerAnchor.x,
     286        fullScreenRect.y() + fullScreenRect.height() * layerAnchor.y); //[presentationLayer position];
     287    CGPoint windowedPosition = CGPointMake(
    278288        m_initialFrame.x() + m_initialFrame.width() * layerAnchor.x,
    279289        m_initialFrame.y() + m_initialFrame.height() * layerAnchor.y);
    280290    CATransform3D shrinkTransform = CATransform3DMakeScale(
    281         static_cast<CGFloat>(m_initialFrame.width()) / destinationFrame.width(),
    282         static_cast<CGFloat>(m_initialFrame.height()) / destinationFrame.height(), 1);
     291        static_cast<CGFloat>(m_initialFrame.width()) / fullScreenSize.width(),
     292        static_cast<CGFloat>(m_initialFrame.height()) / fullScreenSize.height(), 1);
    283293    CATransform3D shiftTransform = CATransform3DMakeTranslation(
    284         initialPosition.x - destinationPosition.x,
     294        windowedPosition.x - fullScreenPosition.x,
    285295        // Drawing is flipped here, and so must be the translation transformation
    286         destinationPosition.y - initialPosition.y, 0);
    287     CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, shiftTransform);
    288 
    289     CATransform3D initialTransform = [presentationLayer transform];
    290 
    291     // Use a CABasicAnimation here for the zoom effect. We want to be notified that the animation has
    292     // completed by way of the CAAnimation delegate.
    293     CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    294     [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:initialTransform]];
    295     [zoomAnimation setToValue:[NSValue valueWithCATransform3D:finalTransform]];
    296     [zoomAnimation setDelegate:m_exitFullScreenListener.get()];
    297     [zoomAnimation setDuration:duration];
    298     [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    299     [zoomAnimation setFillMode:kCAFillModeForwards];
    300 
    301     // Disable implicit animations and set the layer's transformation matrix to its final state.
    302     [CATransaction begin];
    303     [CATransaction setDisableActions:YES];
    304     [caLayer addAnimation:zoomAnimation forKey:@"zoom"];
    305     [caLayer setTransform:finalTransform];
    306     [CATransaction commit];
     296        fullScreenPosition.y - windowedPosition.y, 0);
     297   
     298    return CATransform3DConcat(shrinkTransform, shiftTransform);
    307299}
    308300
Note: See TracChangeset for help on using the changeset viewer.