Changeset 87102 in webkit


Ignore:
Timestamp:
May 23, 2011 3:22:27 PM (13 years ago)
Author:
jer.noble@apple.com
Message:

2011-05-20 Jeremy Noble <jer.noble@apple.com>

Reviewed by Darin Adler.

Video looks squished when animating to full screen.
https://bugs.webkit.org/show_bug.cgi?id=61220

No new tests, because DumpRenderTree does not currently "animate" the full-screen transition.

There are three issues animating video content to full screen which this patch is meant to
address:
1) The animation scales between the client sizes of the element before and after full-screen.
Because these sizes have different aspect ratios, the video appears "squished" for part of
the animation. Instead, we will animate between the content box sizes before and after full
screen which, in the case of video now and object-fit content in the future, will have the
same aspect ratio before and after full screen.
2) Now that we are animating the full-screen video element's content box, the black letterbox
bars appear above and below the video (depending on the video's aspect ratio) as soon as the
animation begins. This is extremely jarring, so set the background color to clear. The
full-screen renderer's background color will serve the same purpose (providing the letterbox
background) once the animation completes.
3) Now that the letterbox color is gone, the full screen controls can appear to float in thin
air beneath the video (again, depending on aspect ratio) during the animation, so to avoid
that effect and to make the animation consistent with the old webkitenterfullscreen()
animation, we will hide the controls during the animation by adding a new CSS pseudo class
-webkit-animating-full-screen-transition.

Added a new css pseudo-class: -webkit-animating-full-screen. During the transition animation, this
pseudo-class will be applied to the current full-screen element. Styles have been added to
fullscreenQuickTime.css to hide the video element's built-in controller during the full-screen
animation.

To accomplish this, the ivar tracking whether the full-screen animation is taking place has been moved
from the RenderFullScreen renderer, to the current full-screen Document. Because changing
isAnimatingFullScreen causes style changes, make sure to call recalcStyle on the full-screen element
after changing.

This extra transition caused assertions in HTMLFormControlElement::updateFromElementCallback. A
full-screen media control's renderer is disabled during the style recalculation when exiting full
screen. This assertion was exposed by the extra recalcStyle() issued during the exit transition, and
has been removed.

  • WebCore.exp.in:
  • css/CSSSelector.cpp: (WebCore::CSSSelector::pseudoId): Add support for new pseudo class -webkit-animate-full-screen-transition. (WebCore::nameToPseudoTypeMap): Ditto. (WebCore::CSSSelector::extractPseudoType): Ditto.
  • css/CSSSelector.h:
  • css/CSSStyleSelector.cpp: (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): Ditto.
  • css/fullscreen.css: (video:-webkit-full-screen): Set full screen video background color to clear.
  • css/fullscreenQuickTime.css: (video:-webkit-full-screen::-webkit-media-controls-panel): Set a default opacity transition. (video:-webkit-animating-full-screen::-webkit-media-controls-panel): Set the opacity to 0 and

disable the transition.

  • dom/Document.cpp: (WebCore::Document::Document): (WebCore::Document::webkitWillEnterFullScreenForElement): Call our new setAnimatingFullScreen function. (WebCore::Document::webkitDidEnterFullScreenForElement): Ditto. (WebCore::Document::webkitWillExitFullScreenForElement): Ditto. (WebCore::Document::webkitDidExitFullScreenForElement): Ditto. (WebCore::Document::isAnimatingFullScreen): Moved here from RenderFullScreen. (WebCore::Document::setAnimatingFullScreen): Ditto.
  • dom/Document.h:
  • html/HTMLFormControlElement.cpp: (WebCore::updateFromElementCallback): Use the Document's isAnimatingFullScreen function.
  • page/FrameView.cpp: (WebCore::isDocumentRunningFullScreenAnimation): Ditto.
  • rendering/RenderFullScreen.cpp:
  • rendering/RenderFullScreen.h:
  • rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Ditto. (WebCore::RenderLayerCompositor::requiresCompositingForFullScreen): Ditto.
  • rendering/style/RenderStyleConstants.h:

2011-05-20 Jer Noble <jer.noble@apple.com>

Reviewed by Darin Adler.

Video looks squished when animating to full screen.
https://bugs.webkit.org/show_bug.cgi?id=61220

Instead of scaling between the client sizes of the full-screen element before and after
entering full-screen, scale between their content boxes. The difference is that the client
sizes can have different aspect ratios, and thus the animation can end up "squishing" the
content at one end of the animation. When animating between the two content box sizes, their
aspect ratios (for the case of video) are equal, so the animation will appear to scale
smoothly between the two states without "squishing" the content.

  • WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm: (WebKit::WebFullScreenManagerMac::beginEnterFullScreenAnimation): Set the destination frame

to be the content box of the current full screen element.

(WebKit::WebFullScreenManagerMac::beginExitFullScreenAnimation): Ditto.

Location:
trunk/Source
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r87101 r87102  
     12011-05-20  Jeremy Noble  <jer.noble@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Video looks squished when animating to full screen.
     6        https://bugs.webkit.org/show_bug.cgi?id=61220
     7
     8        No new tests, because DumpRenderTree does not currently "animate" the full-screen transition.
     9
     10        There are three issues animating video content to full screen which this patch is meant to
     11        address:
     12        1) The animation scales between the client sizes of the element before and after full-screen.
     13        Because these sizes have different aspect ratios, the video appears "squished" for part of
     14        the animation. Instead, we will animate between the content box sizes before and after full
     15        screen which, in the case of video now and object-fit content in the future, will have the
     16        same aspect ratio before and after full screen.
     17        2) Now that we are animating the full-screen video element's content box, the black letterbox
     18        bars appear above and below the video (depending on the video's aspect ratio) as soon as the
     19        animation begins. This is extremely jarring, so set the background color to clear. The
     20        full-screen renderer's background color will serve the same purpose (providing the letterbox
     21        background) once the animation completes.
     22        3) Now that the letterbox color is gone, the full screen controls can appear to float in thin
     23        air beneath the video (again, depending on aspect ratio) during the animation, so to avoid
     24        that effect and to make the animation consistent with the old webkitenterfullscreen()
     25        animation, we will hide the controls during the animation by adding a new CSS pseudo class
     26        -webkit-animating-full-screen-transition.
     27
     28        Added a new css pseudo-class: -webkit-animating-full-screen.  During the transition animation, this
     29        pseudo-class will be applied to the current full-screen element.  Styles have been added to
     30        fullscreenQuickTime.css to hide the video element's built-in controller during the full-screen
     31        animation.
     32
     33        To accomplish this, the ivar tracking whether the full-screen animation is taking place has been moved
     34        from the RenderFullScreen renderer, to the current full-screen Document.  Because changing
     35        isAnimatingFullScreen causes style changes, make sure to call recalcStyle on the full-screen element
     36        after changing.
     37
     38        This extra transition caused assertions in HTMLFormControlElement::updateFromElementCallback. A
     39        full-screen media control's renderer is disabled during the style recalculation when exiting full
     40        screen. This assertion was exposed by the extra recalcStyle() issued during the exit transition, and
     41        has been removed.
     42
     43        * WebCore.exp.in:
     44        * css/CSSSelector.cpp:
     45        (WebCore::CSSSelector::pseudoId): Add support for new pseudo class -webkit-animate-full-screen-transition.
     46        (WebCore::nameToPseudoTypeMap): Ditto.
     47        (WebCore::CSSSelector::extractPseudoType): Ditto.
     48        * css/CSSSelector.h:
     49        * css/CSSStyleSelector.cpp:
     50        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): Ditto.
     51        * css/fullscreen.css:
     52        (video:-webkit-full-screen): Set full screen video background color to clear.
     53        * css/fullscreenQuickTime.css:
     54        (video:-webkit-full-screen::-webkit-media-controls-panel): Set a default opacity transition.
     55        (video:-webkit-animating-full-screen::-webkit-media-controls-panel): Set the opacity to 0 and
     56            disable the transition.
     57        * dom/Document.cpp:
     58        (WebCore::Document::Document):
     59        (WebCore::Document::webkitWillEnterFullScreenForElement): Call our new setAnimatingFullScreen function.
     60        (WebCore::Document::webkitDidEnterFullScreenForElement): Ditto.
     61        (WebCore::Document::webkitWillExitFullScreenForElement): Ditto.
     62        (WebCore::Document::webkitDidExitFullScreenForElement): Ditto.
     63        (WebCore::Document::isAnimatingFullScreen): Moved here from RenderFullScreen.
     64        (WebCore::Document::setAnimatingFullScreen): Ditto.
     65        * dom/Document.h:
     66        * html/HTMLFormControlElement.cpp:
     67        (WebCore::updateFromElementCallback): Use the Document's isAnimatingFullScreen function.
     68        * page/FrameView.cpp:
     69        (WebCore::isDocumentRunningFullScreenAnimation): Ditto.
     70        * rendering/RenderFullScreen.cpp:
     71        * rendering/RenderFullScreen.h:
     72        * rendering/RenderLayerCompositor.cpp:
     73        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Ditto.
     74        (WebCore::RenderLayerCompositor::requiresCompositingForFullScreen): Ditto.
     75        * rendering/style/RenderStyleConstants.h:
     76
    1772011-05-23  Emil A Eklund  <eae@chromium.org>
    278
  • trunk/Source/WebCore/WebCore.exp.in

    r86981 r87102  
    14801480__ZN7WebCore13GraphicsLayer6createEPNS_19GraphicsLayerClientE
    14811481__ZNK7WebCore18RenderLayerBacking20compositingLayerTypeEv
     1482__ZNK7WebCore18RenderLayerBacking11contentsBoxEv
    14821483#endif
    14831484
  • trunk/Source/WebCore/css/CSSSelector.cpp

    r85811 r87102  
    168168    case PseudoFullScreenMediaDocument:
    169169        return FULL_SCREEN_MEDIA_DOCUMENT;
     170    case PseudoAnimatingFullScreenTransition:
     171        return ANIMATING_FULL_SCREEN_TRANSITION;
    170172#endif
    171173           
     
    323325    DEFINE_STATIC_LOCAL(AtomicString, fullScreenDocument, ("-webkit-full-screen-document"));
    324326    DEFINE_STATIC_LOCAL(AtomicString, fullScreenMediaDocument, ("-webkit-full-screen-media-document"));
     327    DEFINE_STATIC_LOCAL(AtomicString, animatingFullScreenTransition, ("-webkit-animating-full-screen-transition"));
    325328#endif
    326329    DEFINE_STATIC_LOCAL(AtomicString, inRange, ("in-range"));
     
    411414        nameToPseudoType->set(fullScreenDocument.impl(), CSSSelector::PseudoFullScreenDocument);
    412415        nameToPseudoType->set(fullScreenMediaDocument.impl(), CSSSelector::PseudoFullScreenMediaDocument);
     416        nameToPseudoType->set(animatingFullScreenTransition.impl(), CSSSelector::PseudoAnimatingFullScreenTransition);
    413417#endif
    414418        nameToPseudoType->set(inRange.impl(), CSSSelector::PseudoInRange);
     
    521525    case PseudoFullScreenDocument:
    522526    case PseudoFullScreenMediaDocument:
     527    case PseudoAnimatingFullScreenTransition:
    523528#endif
    524529    case PseudoInRange:
  • trunk/Source/WebCore/css/CSSSelector.h

    r85811 r87102  
    191191            PseudoFullScreenDocument,
    192192            PseudoFullScreenMediaDocument,
     193            PseudoAnimatingFullScreenTransition,
    193194#endif
    194195            PseudoInRange,
  • trunk/Source/WebCore/css/CSSStyleSelector.cpp

    r86929 r87102  
    29052905                if (!e->document()->webkitIsFullScreen())
    29062906                    return false;
     2907                return e == e->document()->webkitCurrentFullScreenElement();
     2908            case CSSSelector::PseudoAnimatingFullScreenTransition:
    29072909                if (e != e->document()->webkitCurrentFullScreenElement())
    29082910                    return false;
    2909                 return true;
     2911                return e->document()->isAnimatingFullScreen();
    29102912            case CSSSelector::PseudoFullScreenMediaDocument:
    29112913                if (!e->document()->webkitIsFullScreen())
  • trunk/Source/WebCore/css/fullscreen.css

    r85811 r87102  
    1414
    1515video:-webkit-full-screen {
    16     background-color: black !important;
     16    background-color: transparent !important;
    1717    position: static !important;
    1818    margin: 0 !important;
  • trunk/Source/WebCore/css/fullscreenQuickTime.css

    r82053 r87102  
    5555        0  0   0 1px rgba(0, 0, 0, 0.5);
    5656    -webkit-border-radius: 8px;
     57
     58    -webkit-transition: opacity 0.3s linear;
     59}
     60
     61video:-webkit-animating-full-screen-transition::-webkit-media-controls-panel {
     62    opacity: 0 ! important;
     63    -webkit-transition: opacity 0 ! important;
    5764}
    5865
  • trunk/Source/WebCore/dom/Document.cpp

    r87022 r87102  
    416416    , m_fullScreenRenderer(0)
    417417    , m_fullScreenChangeDelayTimer(this, &Document::fullScreenChangeDelayTimerFired)
     418    , m_isAnimatingFullScreen(false)
    418419#endif
    419420    , m_loadEventDelayCount(0)
     
    48824883   
    48834884    if (m_fullScreenRenderer) {
    4884         m_fullScreenRenderer->setAnimating(true);
     4885        setAnimatingFullScreen(true);
    48854886#if USE(ACCELERATED_COMPOSITING)
    48864887        view()->updateCompositingLayers();
     
    48934894void Document::webkitDidEnterFullScreenForElement(Element*)
    48944895{
     4896    ASSERT(m_fullScreenElement);
     4897
    48954898    if (m_fullScreenRenderer) {
    48964899#if USE(ACCELERATED_COMPOSITING)
    48974900        page()->chrome()->client()->setRootFullScreenLayer(0);
    48984901#endif
    4899         m_fullScreenRenderer->setAnimating(false);
     4902        setAnimatingFullScreen(false);
    49004903#if USE(ACCELERATED_COMPOSITING)
    49014904        view()->updateCompositingLayers();
     
    49114914   
    49124915    if (m_fullScreenRenderer) {
    4913         m_fullScreenRenderer->setAnimating(true);
     4916        setAnimatingFullScreen(true);
    49144917#if USE(ACCELERATED_COMPOSITING)
    49154918        view()->updateCompositingLayers();
     
    49234926{
    49244927    m_areKeysEnabledInFullScreen = false;
     4928    setAnimatingFullScreen(false);
    49254929
    49264930    if (m_fullScreenRenderer)
     
    49354939    page()->chrome()->client()->setRootFullScreenLayer(0);
    49364940#endif
    4937     recalcStyle(Force);
     4941    scheduleForcedStyleRecalc();
    49384942   
    49394943    m_fullScreenChangeDelayTimer.startOneShot(0);
     
    50155019        fullScreenElementRemoved();
    50165020}
     5021
     5022bool Document::isAnimatingFullScreen() const
     5023{
     5024    return m_isAnimatingFullScreen;
     5025}
     5026
     5027void Document::setAnimatingFullScreen(bool flag)
     5028{
     5029    if (m_isAnimatingFullScreen == flag)
     5030        return;
     5031    m_isAnimatingFullScreen = flag;
     5032
     5033    if (m_fullScreenElement) {
     5034        m_fullScreenElement->setNeedsStyleRecalc();
     5035        scheduleStyleRecalc();
     5036    }
     5037
     5038#if USE(ACCELERATED_COMPOSITING)
     5039    if (m_fullScreenRenderer && m_fullScreenRenderer->layer()) {
     5040        m_fullScreenRenderer->layer()->contentChanged(RenderLayer::FullScreenChanged);
     5041        // Clearing the layer's backing will force the compositor to reparent
     5042        // the layer the next time layers are synchronized.
     5043        m_fullScreenRenderer->layer()->clearBacking();
     5044    }
     5045#endif
     5046}
    50175047#endif
    50185048
  • trunk/Source/WebCore/dom/Document.h

    r86838 r87102  
    10741074    void fullScreenElementRemoved();
    10751075    void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false);
     1076    bool isAnimatingFullScreen() const;
     1077    void setAnimatingFullScreen(bool);
    10761078#endif
    10771079
     
    13891391    Timer<Document> m_fullScreenChangeDelayTimer;
    13901392    Deque<RefPtr<Element> > m_fullScreenChangeEventTargetQueue;
     1393    bool m_isAnimatingFullScreen;
    13911394#endif
    13921395
  • trunk/Source/WebCore/page/FrameView.cpp

    r86632 r87102  
    597597static bool isDocumentRunningFullScreenAnimation(Document* document)
    598598{
    599     return document->webkitIsFullScreen() && document->fullScreenRenderer() && document->fullScreenRenderer()->isAnimating();
     599    return document->webkitIsFullScreen() && document->fullScreenRenderer() && document->isAnimatingFullScreen();
    600600}
    601601#endif
  • trunk/Source/WebCore/rendering/RenderFullScreen.cpp

    r86924 r87102  
    3737using namespace WebCore;
    3838
    39 void RenderFullScreen::setAnimating(bool animating)
    40 {
    41     if (m_isAnimating == animating)
    42         return;
    43 
    44     m_isAnimating = animating;
    45 #if USE(ACCELERATED_COMPOSITING)
    46     if (layer()) {
    47         layer()->contentChanged(RenderLayer::FullScreenChanged);
    48         // Clearing the layer's backing will force the compositor to reparent
    49         // the layer the next time layers are synchronized.
    50         layer()->clearBacking();
    51     }
    52 #endif
    53 }
    54 
    5539PassRefPtr<RenderStyle> RenderFullScreen::createFullScreenStyle()
    5640{
  • trunk/Source/WebCore/rendering/RenderFullScreen.h

    r75450 r87102  
    3838    virtual const char* renderName() const { return "RenderFullScreen"; }
    3939   
    40     bool isAnimating() const { return m_isAnimating; }
    41     void setAnimating(bool);
    42    
    4340    static PassRefPtr<RenderStyle> createFullScreenStyle();
    4441   
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r86632 r87102  
    885885        // the full screen layer out from under them if they're in the middle of
    886886        // animating.
    887         if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating())
     887        if (layer->renderer()->isRenderFullScreen() && m_renderView->document()->isAnimatingFullScreen())
    888888            return;
    889889#endif
     
    14151415{
    14161416#if ENABLE(FULLSCREEN_API)
    1417     return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
     1417    return renderer->isRenderFullScreen() && m_renderView->document()->isAnimatingFullScreen();
    14181418#else
    14191419    UNUSED_PARAM(renderer);
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r86929 r87102  
    7575    METER_BAR, METER_OPTIMUM, METER_SUBOPTIMAL, METER_EVEN_LESS_GOOD,
    7676    AFTER_LAST_INTERNAL_PSEUDOID,
    77     FULL_SCREEN, FULL_SCREEN_DOCUMENT, FULL_SCREEN_MEDIA_DOCUMENT,
     77    FULL_SCREEN, FULL_SCREEN_DOCUMENT, FULL_SCREEN_MEDIA_DOCUMENT, ANIMATING_FULL_SCREEN_TRANSITION,
    7878    FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
    7979    FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
  • trunk/Source/WebKit2/ChangeLog

    r87093 r87102  
     12011-05-20  Jer Noble  <jer.noble@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Video looks squished when animating to full screen.
     6        https://bugs.webkit.org/show_bug.cgi?id=61220
     7
     8        Instead of scaling between the client sizes of the full-screen element before and after
     9        entering full-screen, scale between their content boxes.  The difference is that the client
     10        sizes can have different aspect ratios, and thus the animation can end up "squishing" the
     11        content at one end of the animation.  When animating between the two content box sizes, their
     12        aspect ratios (for the case of video) are equal, so the animation will appear to scale
     13        smoothly between the two states without "squishing" the content.
     14
     15        * WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm:
     16        (WebKit::WebFullScreenManagerMac::beginEnterFullScreenAnimation): Set the destination frame
     17            to be the content box of the current full screen element.
     18        (WebKit::WebFullScreenManagerMac::beginExitFullScreenAnimation): Ditto.
     19
    1202011-05-23  Sam Weinig  <sam@webkit.org>
    221
  • trunk/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm

    r86924 r87102  
    3939#import <WebCore/GraphicsLayer.h>
    4040#import <WebCore/Page.h>
     41#import <WebCore/RenderLayer.h>
     42#import <WebCore/RenderLayerBacking.h>
     43#import <WebCore/RenderObject.h>
    4144#import <WebCore/Settings.h>
    4245#import <WebKitSystemInterface.h>
     
    196199    m_element->document()->setFullScreenRendererSize(destinationFrame.size());
    197200    m_rootLayer->syncCompositingState();
     201
     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());
    198206
    199207    // FIXME: Once we gain the ability to do native WebKit animations of generated
     
    251259    m_rootLayer->syncCompositingState();
    252260
     261    RenderLayer* layer = m_element->renderer() ? m_element->renderer()->enclosingLayer() : 0;
     262    RenderLayerBacking* backing = layer ? layer->backing() : 0;
     263    if (backing)
     264        destinationFrame.setSize(backing->contentsBox().size());
     265
    253266    // FIXME: Once we gain the ability to do native WebKit animations of generated
    254267    // content, this can change to use them.  Meanwhile, we'll have to animate the
     
    261274    // final one.
    262275    CGPoint destinationPosition = [presentationLayer position];
    263     CGRect destinationBounds = [presentationLayer bounds];
    264276    CGPoint layerAnchor = [caLayer anchorPoint];
    265277    CGPoint initialPosition = CGPointMake(
     
    267279        m_initialFrame.y() + m_initialFrame.height() * layerAnchor.y);
    268280    CATransform3D shrinkTransform = CATransform3DMakeScale(
    269         static_cast<CGFloat>(m_initialFrame.width()) / destinationBounds.size.width,
    270         static_cast<CGFloat>(m_initialFrame.height()) / destinationBounds.size.height, 1);
     281        static_cast<CGFloat>(m_initialFrame.width()) / destinationFrame.width(),
     282        static_cast<CGFloat>(m_initialFrame.height()) / destinationFrame.height(), 1);
    271283    CATransform3D shiftTransform = CATransform3DMakeTranslation(
    272284        initialPosition.x - destinationPosition.x,
Note: See TracChangeset for help on using the changeset viewer.