Changeset 154921 in webkit


Ignore:
Timestamp:
Aug 30, 2013 5:14:41 PM (11 years ago)
Author:
Simon Fraser
Message:

Video with object-fit: cover can spill outside the box
https://bugs.webkit.org/show_bug.cgi?id=52103

Source/WebCore:

Reviewed by Dean Jackson.

object-fit on renderers which use accelerated compositing needs special
treatment.

For directly composited images, and video, GraphicsLayer needs to know
both the size of the content layer, and also a rectangle at which this
should be clipped (because, for the first time, that content layer can be
larger than the renderer's content box).

AVFoundation would always aspect-ratio fit video by default, so plumb
through MediaPlayer a way to override that when object-fit requires it.

Added a LAYER_TREE_INCLUDES_CONTENT_LAYERS enum to the layerTreeAsText()
flags so we can dump content layers for testing.

Tests: compositing/images/direct-image-object-fit.html

compositing/reflections/direct-image-object-fit-reflected.html
compositing/video/video-object-fit.html

  • page/Frame.h: New LayerTreeFlagsIncludeContentLayers flag.
  • platform/graphics/GraphicsLayer.h: New flag.
  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::shouldMaintainAspectRatio):
(WebCore::MediaPlayer::setShouldMaintainAspectRatio):

  • platform/graphics/MediaPlayer.h:
  • platform/graphics/MediaPlayerPrivate.h:

(WebCore::MediaPlayerPrivateInterface::shouldMaintainAspectRatio):
(WebCore::MediaPlayerPrivateInterface::setShouldMaintainAspectRatio):

  • platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:

(WebCore::MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation):
(WebCore::MediaPlayerPrivateAVFoundation::setShouldMaintainAspectRatio):

  • platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
  • platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:

(WebCore::MediaPlayerPrivateAVFoundationCF::updateVideoLayerGravity):
(WebCore::AVFWrapper::platformLayer):

  • platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:

(WebCore::MediaPlayerPrivateAVFoundationObjC::createVideoLayer):
(WebCore::MediaPlayerPrivateAVFoundationObjC::updateVideoLayerGravity):

  • platform/graphics/ca/GraphicsLayerCA.cpp: We need a new m_contentsClippingLayer to

clip the contents layer, which only gets created when necessary. It has to be cloned
for reflections.
(WebCore::GraphicsLayerCA::willBeDestroyed):
(WebCore::GraphicsLayerCA::setContentsRect):
(WebCore::GraphicsLayerCA::setContentsClippingRect):
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
(WebCore::GraphicsLayerCA::updateSublayerList):
(WebCore::GraphicsLayerCA::updateContentsImage):
(WebCore::GraphicsLayerCA::updateContentsMediaLayer):
(WebCore::GraphicsLayerCA::updateContentsCanvasLayer):
(WebCore::GraphicsLayerCA::updateContentsColorLayer):
(WebCore::GraphicsLayerCA::updateContentsRects):
(WebCore::GraphicsLayerCA::dumpAdditionalProperties):
(WebCore::GraphicsLayerCA::ensureCloneLayers):
(WebCore::GraphicsLayerCA::removeCloneLayers):
(WebCore::GraphicsLayerCA::fetchCloneLayers):

  • platform/graphics/ca/GraphicsLayerCA.h:
  • rendering/RenderLayerBacking.cpp: Need to push both the contentsRect and

the contentsClippingRect down to the GraphicsLayers. Most of the time they
are the same, unless object-fit makes them different.
(WebCore::RenderLayerBacking::resetContentsRect):
(WebCore::RenderLayerBacking::positionOverflowControlsLayers):
(WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):
(WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundImage):
(WebCore::RenderLayerBacking::updateImageContents):
(WebCore::RenderLayerBacking::contentsBox):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::layerTreeAsText):

  • rendering/RenderVideo.cpp:

(WebCore::RenderVideo::updatePlayer):

  • testing/Internals.cpp:

(WebCore::Internals::layerTreeAsText):

  • testing/Internals.h:
  • testing/Internals.idl:

LayoutTests:

Reviewed by Dean Jackson.

Test cases for directly composited image with object-fit, the same with
reflections, and one with video.

Tests dump content GraphicsLayers, so have platform-specific results.

  • compositing/images/direct-image-object-fit-expected.txt: Added.
  • compositing/images/direct-image-object-fit.html: Added.
  • compositing/reflections/direct-image-object-fit-reflected-expected.txt: Added.
  • compositing/reflections/direct-image-object-fit-reflected.html: Added.
  • compositing/video/video-object-fit-expected.txt: Added.
  • compositing/video/video-object-fit.html: Added.
  • media/video-object-fit-change.html: Fixed
  • platform/mac/TestExpectations: Unskip two tests.
  • platform/mac/compositing/images/direct-image-object-fit-expected.txt: Added.
  • platform/mac/compositing/reflections/direct-image-object-fit-reflected-expected.txt: Added.
  • platform/mac/compositing/video/video-object-fit-expected.txt: Added.
Location:
trunk
Files:
9 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r154920 r154921  
     12013-08-30  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Video with object-fit: cover can spill outside the box
     4        https://bugs.webkit.org/show_bug.cgi?id=52103
     5
     6        Reviewed by Dean Jackson.
     7       
     8        Test cases for directly composited image with object-fit, the same with
     9        reflections, and one with video.
     10       
     11        Tests dump content GraphicsLayers, so have platform-specific results.
     12
     13        * compositing/images/direct-image-object-fit-expected.txt: Added.
     14        * compositing/images/direct-image-object-fit.html: Added.
     15        * compositing/reflections/direct-image-object-fit-reflected-expected.txt: Added.
     16        * compositing/reflections/direct-image-object-fit-reflected.html: Added.
     17        * compositing/video/video-object-fit-expected.txt: Added.
     18        * compositing/video/video-object-fit.html: Added.
     19        * media/video-object-fit-change.html: Fixed
     20        * platform/mac/TestExpectations: Unskip two tests.
     21        * platform/mac/compositing/images/direct-image-object-fit-expected.txt: Added.
     22        * platform/mac/compositing/reflections/direct-image-object-fit-reflected-expected.txt: Added.
     23        * platform/mac/compositing/video/video-object-fit-expected.txt: Added.
     24
    1252013-08-30  Oliver Hunt  <oliver@apple.com>
    226
  • trunk/LayoutTests/media/video-object-fit-change.html

    r154858 r154921  
    1919        function init()
    2020        {
    21             setSrcByTagName("video", findMediaFile("video", "../../media/content/test"));
     21            setSrcByTagName("video", findMediaFile("video", "content/test"));
    2222
    2323            var totalCount = document.getElementsByTagName('video').length;
     
    2525            document.addEventListener("canplaythrough", function () {
    2626                if (!--count)
    27                     setTimeout(function() { changeStyle(); }, 500);
     27                    setTimeout(function() { changeStyle(); }, 250);
    2828            }, true);
    2929
     
    4444            video4.style.objectFit = 'scale-down';
    4545
    46             if (window.testRunner) {
    47                 setTimeout(function() { testRunner.notifyDone(); }, 500);
    48             }
     46        if (window.testRunner)
     47            setTimeout(function() { testRunner.notifyDone(); }, 250);
    4948        }
    5049    </script>
  • trunk/LayoutTests/platform/mac/TestExpectations

    r154908 r154921  
    5252# This test requires ogg codecs
    5353media/media-can-play-ogg.html
    54 
    55 webkit.org/b/52103 media/video-object-fit-change.html
    56 webkit.org/b/52103 media/video-object-fit.html
    5754
    5855# This test requires flac codec
  • trunk/Source/WebCore/ChangeLog

    r154915 r154921  
     12013-08-30  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Video with object-fit: cover can spill outside the box
     4        https://bugs.webkit.org/show_bug.cgi?id=52103
     5
     6        Reviewed by Dean Jackson.
     7       
     8        object-fit on renderers which use accelerated compositing needs special
     9        treatment.
     10       
     11        For directly composited images, and video, GraphicsLayer needs to know
     12        both the size of the content layer, and also a rectangle at which this
     13        should be clipped (because, for the first time, that content layer can be
     14        larger than the renderer's content box).
     15       
     16        AVFoundation would always aspect-ratio fit video by default, so plumb
     17        through MediaPlayer a way to override that when object-fit requires it.
     18       
     19        Added a LAYER_TREE_INCLUDES_CONTENT_LAYERS enum to the layerTreeAsText()
     20        flags so we can dump content layers for testing.
     21
     22        Tests: compositing/images/direct-image-object-fit.html
     23               compositing/reflections/direct-image-object-fit-reflected.html
     24               compositing/video/video-object-fit.html
     25
     26        * page/Frame.h: New LayerTreeFlagsIncludeContentLayers flag.
     27        * platform/graphics/GraphicsLayer.h: New flag.
     28        * platform/graphics/MediaPlayer.cpp:
     29        (WebCore::MediaPlayer::shouldMaintainAspectRatio):
     30        (WebCore::MediaPlayer::setShouldMaintainAspectRatio):
     31        * platform/graphics/MediaPlayer.h:
     32        * platform/graphics/MediaPlayerPrivate.h:
     33        (WebCore::MediaPlayerPrivateInterface::shouldMaintainAspectRatio):
     34        (WebCore::MediaPlayerPrivateInterface::setShouldMaintainAspectRatio):
     35        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
     36        (WebCore::MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation):
     37        (WebCore::MediaPlayerPrivateAVFoundation::setShouldMaintainAspectRatio):
     38        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
     39        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
     40        (WebCore::MediaPlayerPrivateAVFoundationCF::updateVideoLayerGravity):
     41        (WebCore::AVFWrapper::platformLayer):
     42        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h:
     43        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
     44        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
     45        (WebCore::MediaPlayerPrivateAVFoundationObjC::createVideoLayer):
     46        (WebCore::MediaPlayerPrivateAVFoundationObjC::updateVideoLayerGravity):
     47        * platform/graphics/ca/GraphicsLayerCA.cpp: We need a new m_contentsClippingLayer to
     48        clip the contents layer, which only gets created when necessary. It has to be cloned
     49        for reflections.
     50        (WebCore::GraphicsLayerCA::willBeDestroyed):
     51        (WebCore::GraphicsLayerCA::setContentsRect):
     52        (WebCore::GraphicsLayerCA::setContentsClippingRect):
     53        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
     54        (WebCore::GraphicsLayerCA::updateSublayerList):
     55        (WebCore::GraphicsLayerCA::updateContentsImage):
     56        (WebCore::GraphicsLayerCA::updateContentsMediaLayer):
     57        (WebCore::GraphicsLayerCA::updateContentsCanvasLayer):
     58        (WebCore::GraphicsLayerCA::updateContentsColorLayer):
     59        (WebCore::GraphicsLayerCA::updateContentsRects):
     60        (WebCore::GraphicsLayerCA::dumpAdditionalProperties):
     61        (WebCore::GraphicsLayerCA::ensureCloneLayers):
     62        (WebCore::GraphicsLayerCA::removeCloneLayers):
     63        (WebCore::GraphicsLayerCA::fetchCloneLayers):
     64        * platform/graphics/ca/GraphicsLayerCA.h:
     65        * rendering/RenderLayerBacking.cpp: Need to push both the contentsRect and
     66        the contentsClippingRect down to the GraphicsLayers. Most of the time they
     67        are the same, unless object-fit makes them different.
     68        (WebCore::RenderLayerBacking::resetContentsRect):
     69        (WebCore::RenderLayerBacking::positionOverflowControlsLayers):
     70        (WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):
     71        (WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundImage):
     72        (WebCore::RenderLayerBacking::updateImageContents):
     73        (WebCore::RenderLayerBacking::contentsBox):
     74        * rendering/RenderLayerCompositor.cpp:
     75        (WebCore::RenderLayerCompositor::layerTreeAsText):
     76        * rendering/RenderVideo.cpp:
     77        (WebCore::RenderVideo::updatePlayer):
     78        * testing/Internals.cpp:
     79        (WebCore::Internals::layerTreeAsText):
     80        * testing/Internals.h:
     81        * testing/Internals.idl:
     82
    1832013-08-30  Brent Fulgham  <bfulgham@apple.com>
    284
  • trunk/Source/WebCore/page/Frame.h

    r154577 r154921  
    8383        LayerTreeFlagsIncludeTileCaches = 1 << 2,
    8484        LayerTreeFlagsIncludeRepaintRects = 1 << 3,
    85         LayerTreeFlagsIncludePaintingPhases = 1 << 4
     85        LayerTreeFlagsIncludePaintingPhases = 1 << 4,
     86        LayerTreeFlagsIncludeContentLayers = 1 << 5
    8687    };
    8788    typedef unsigned LayerTreeFlags;
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.h

    r154909 r154921  
    5151    LayerTreeAsTextIncludeTileCaches = 1 << 2,
    5252    LayerTreeAsTextIncludeRepaintRects = 1 << 3,
    53     LayerTreeAsTextIncludePaintingPhases = 1 << 4
     53    LayerTreeAsTextIncludePaintingPhases = 1 << 4,
     54    LayerTreeAsTextIncludeContentLayers = 1 << 5
    5455};
    5556typedef unsigned LayerTreeAsTextBehavior;
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r154914 r154921  
    848848#endif // USE(ACCELERATED_COMPOSITING)
    849849
     850bool MediaPlayer::shouldMaintainAspectRatio() const
     851{
     852    return m_private->shouldMaintainAspectRatio();
     853}
     854
     855void MediaPlayer::setShouldMaintainAspectRatio(bool maintainAspectRatio)
     856{
     857    m_private->setShouldMaintainAspectRatio(maintainAspectRatio);
     858}
     859
    850860bool MediaPlayer::hasSingleSecurityOrigin() const
    851861{
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r154914 r154921  
    416416#endif
    417417
     418    bool shouldMaintainAspectRatio() const;
     419    void setShouldMaintainAspectRatio(bool);
     420
    418421#if PLATFORM(WIN) && USE(AVFOUNDATION)
    419422    GraphicsDeviceAdapter* graphicsDeviceAdapter() const;
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r154914 r154921  
    151151#endif
    152152
     153    virtual bool shouldMaintainAspectRatio() const { return true; }
     154    virtual void setShouldMaintainAspectRatio(bool) { }
     155
    153156    virtual bool hasSingleSecurityOrigin() const { return false; }
    154157
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp

    r154527 r154921  
    7878    , m_inbandTrackConfigurationPending(false)
    7979    , m_characteristicsChanged(false)
     80    , m_shouldMaintainAspectRatio(true)
    8081    , m_seekCount(0)
    8182{
     
    583584}
    584585
     586void MediaPlayerPrivateAVFoundation::setShouldMaintainAspectRatio(bool maintainAspectRatio)
     587{
     588    if (maintainAspectRatio == m_shouldMaintainAspectRatio)
     589        return;
     590
     591    m_shouldMaintainAspectRatio = maintainAspectRatio;
     592    updateVideoLayerGravity();
     593}
     594
    585595void MediaPlayerPrivateAVFoundation::metadataLoaded()
    586596{
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h

    r154527 r154921  
    166166    virtual void acceleratedRenderingStateChanged();
    167167#endif
     168    virtual bool shouldMaintainAspectRatio() const OVERRIDE { return m_shouldMaintainAspectRatio; }
     169    virtual void setShouldMaintainAspectRatio(bool) OVERRIDE;
     170
    168171    virtual MediaPlayer::MovieLoadType movieLoadType() const;
    169172    virtual void prepareForRendering();
     
    228231    virtual bool hasContextRenderer() const = 0;
    229232    virtual bool hasLayerRenderer() const = 0;
     233
     234    virtual void updateVideoLayerGravity() = 0;
    230235
    231236protected:
     
    309314    bool m_inbandTrackConfigurationPending;
    310315    bool m_characteristicsChanged;
     316    bool m_shouldMaintainAspectRatio;
    311317    size_t m_seekCount;
    312318};
  • trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

    r154915 r154921  
    331331    setIgnoreLoadStateChanges(false);
    332332    setDelayCallbacks(false);
     333}
     334
     335void MediaPlayerPrivateAVFoundationCF::updateVideoLayerGravity()
     336{
     337    // We should call AVCFPlayerLayerSetVideoGravity() here, but it is not yet implemented.
    333338}
    334339
     
    15781583    m_videoLayerWrapper->setAnchorPoint(FloatPoint3D());
    15791584    m_videoLayerWrapper->setNeedsLayout();
     1585    updateVideoLayerGravity();
    15801586
    15811587    return m_videoLayerWrapper->platformLayer();
  • trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h

    r154915 r154921  
    9999    virtual bool hasLayerRenderer() const;
    100100
     101    virtual void updateVideoLayerGravity() OVERRIDE;
     102
    101103    virtual void contentsNeedsDisplay();
    102104
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h

    r153706 r154921  
    149149    virtual bool hasLayerRenderer() const;
    150150
     151    virtual void updateVideoLayerGravity() OVERRIDE;
     152
    151153    virtual bool hasSingleSecurityOrigin() const;
    152154   
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

    r154775 r154921  
    9999SOFT_LINK_POINTER(AVFoundation, AVAssetImageGeneratorApertureModeCleanAperture, NSString *)
    100100SOFT_LINK_POINTER(AVFoundation, AVURLAssetReferenceRestrictionsKey, NSString *)
     101SOFT_LINK_POINTER(AVFoundation, AVLayerVideoGravityResizeAspect, NSString *)
     102SOFT_LINK_POINTER(AVFoundation, AVLayerVideoGravityResize, NSString *)
    101103
    102104SOFT_LINK_CONSTANT(CoreMedia, kCMTimeZero, CMTime)
     
    117119#define AVAssetImageGeneratorApertureModeCleanAperture getAVAssetImageGeneratorApertureModeCleanAperture()
    118120#define AVURLAssetReferenceRestrictionsKey getAVURLAssetReferenceRestrictionsKey()
     121#define AVLayerVideoGravityResizeAspect getAVLayerVideoGravityResizeAspect()
     122#define AVLayerVideoGravityResize getAVLayerVideoGravityResize()
    119123
    120124#if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP)
     
    373377        [m_videoLayer.get() setName:@"Video layer"];
    374378#endif
     379        updateVideoLayerGravity();
    375380        LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createVideoLayer(%p) - returning %p", this, m_videoLayer.get());
    376381    }
     
    986991    // FIXME - impossible to implement until rdar://8721510 is fixed.
    987992    return timeValue;
     993}
     994
     995void MediaPlayerPrivateAVFoundationObjC::updateVideoLayerGravity()
     996{
     997    if (!m_videoLayer)
     998        return;
     999
     1000    [CATransaction begin];
     1001    [CATransaction setDisableActions:YES];   
     1002    NSString* gravity = shouldMaintainAspectRatio() ? AVLayerVideoGravityResizeAspect : AVLayerVideoGravityResize;
     1003    [m_videoLayer.get() setVideoGravity:gravity];
     1004    [CATransaction commit];
    9881005}
    9891006
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r154706 r154921  
    306306    if (m_contentsLayer)
    307307        m_contentsLayer->setOwner(0);
     308
     309    if (m_contentsClippingLayer)
     310        m_contentsClippingLayer->setOwner(0);
    308311       
    309312    if (m_structuralLayer)
     
    670673
    671674    GraphicsLayer::setContentsRect(rect);
    672     noteLayerPropertyChanged(ContentsRectChanged);
     675    noteLayerPropertyChanged(ContentsRectsChanged);
     676}
     677
     678void GraphicsLayerCA::setContentsClippingRect(const IntRect& rect)
     679{
     680    if (rect == m_contentsClippingRect)
     681        return;
     682
     683    GraphicsLayer::setContentsClippingRect(rect);
     684    noteLayerPropertyChanged(ContentsRectsChanged);
    673685}
    674686
     
    12151227        repaintLayerDirtyRects();
    12161228   
    1217     if (m_uncommittedChanges & ContentsRectChanged)
    1218         updateContentsRect();
     1229    if (m_uncommittedChanges & ContentsRectsChanged) // Needs to happen before ChildrenChanged
     1230        updateContentsRects();
    12191231
    12201232    if (m_uncommittedChanges & MaskLayerChanged)
     
    12981310        // This does not cause visible rendering issues because currently contents layers are only used
    12991311        // for replaced elements that don't have children.
    1300         primaryLayerChildren.append(m_contentsLayer);
     1312        primaryLayerChildren.append(m_contentsClippingLayer ? m_contentsClippingLayer : m_contentsLayer);
    13011313    }
    13021314   
     
    17231735        }
    17241736       
    1725         updateContentsRect();
     1737        updateContentsRects();
    17261738    } else {
    17271739        // No image.
     
    17381750    // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
    17391751    setupContentsLayer(m_contentsLayer.get());
    1740     updateContentsRect();
     1752    updateContentsRects();
    17411753}
    17421754
     
    17491761    setupContentsLayer(m_contentsLayer.get());
    17501762    m_contentsLayer->setNeedsDisplay();
    1751     updateContentsRect();
     1763    updateContentsRects();
    17521764}
    17531765
     
    17591771
    17601772    setupContentsLayer(m_contentsLayer.get());
    1761     updateContentsRect();
     1773    updateContentsRects();
    17621774    ASSERT(m_contentsSolidColor.isValid());
    17631775    m_contentsLayer->setBackgroundColor(m_contentsSolidColor);
     
    17701782}
    17711783
    1772 void GraphicsLayerCA::updateContentsRect()
     1784void GraphicsLayerCA::updateContentsRects()
    17731785{
    17741786    if (!m_contentsLayer)
    17751787        return;
    17761788
    1777     FloatPoint point(m_contentsRect.x(), m_contentsRect.y());
    1778     FloatRect rect(0, 0, m_contentsRect.width(), m_contentsRect.height());
    1779 
    1780     m_contentsLayer->setPosition(point);
    1781     m_contentsLayer->setBounds(rect);
     1789    FloatPoint contentOrigin;
     1790    FloatRect contentBounds(0, 0, m_contentsRect.width(), m_contentsRect.height());
     1791
     1792    FloatPoint clippingOrigin;
     1793    FloatRect clippingBounds;
     1794   
     1795    bool gainedOrLostClippingLayer = false;
     1796    if (!m_contentsClippingRect.contains(m_contentsRect)) {
     1797        if (!m_contentsClippingLayer) {
     1798            m_contentsClippingLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
     1799            m_contentsClippingLayer->setMasksToBounds(true);
     1800            m_contentsClippingLayer->setAnchorPoint(FloatPoint());
     1801#ifndef NDEBUG
     1802            m_contentsClippingLayer->setName("Contents Clipping");
     1803#endif
     1804            m_contentsLayer->removeFromSuperlayer();
     1805            m_contentsClippingLayer->appendSublayer(m_contentsLayer.get());
     1806            gainedOrLostClippingLayer = true;
     1807        }
     1808   
     1809        clippingOrigin = m_contentsClippingRect.location();
     1810        clippingBounds.setSize(m_contentsClippingRect.size());
     1811
     1812        contentOrigin = toPoint(m_contentsRect.location() - m_contentsClippingRect.location());
     1813
     1814        m_contentsClippingLayer->setPosition(clippingOrigin);
     1815        m_contentsClippingLayer->setBounds(clippingBounds);
     1816
     1817        m_contentsLayer->setPosition(contentOrigin);
     1818        m_contentsLayer->setBounds(contentBounds);
     1819   
     1820    } else {
     1821        if (m_contentsClippingLayer) {
     1822            m_contentsLayer->removeFromSuperlayer();
     1823
     1824            m_contentsClippingLayer->removeFromSuperlayer();
     1825            m_contentsClippingLayer->setOwner(0);
     1826            m_contentsClippingLayer = nullptr;
     1827            gainedOrLostClippingLayer = true;
     1828        }
     1829
     1830        contentOrigin = m_contentsRect.location();
     1831    }
     1832   
     1833    if (gainedOrLostClippingLayer)
     1834        noteSublayersChanged();
     1835
     1836    m_contentsLayer->setPosition(contentOrigin);
     1837    m_contentsLayer->setBounds(contentBounds);
    17821838
    17831839    if (m_contentsLayerClones) {
    17841840        LayerMap::const_iterator end = m_contentsLayerClones->end();
    17851841        for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
    1786             it->value->setPosition(point);
    1787             it->value->setBounds(rect);
     1842            it->value->setPosition(contentOrigin);
     1843            it->value->setBounds(contentBounds);
     1844        }
     1845    }
     1846
     1847    if (m_contentsClippingLayerClones) {
     1848        LayerMap::const_iterator end = m_contentsClippingLayerClones->end();
     1849        for (LayerMap::const_iterator it = m_contentsClippingLayerClones->begin(); it != end; ++it) {
     1850            it->value->setPosition(clippingOrigin);
     1851            it->value->setBounds(clippingBounds);
    17881852        }
    17891853    }
     
    26612725        textStream << "(top left tile " << gridExtent.x() << ", " << gridExtent.y() << " tiles grid " << gridExtent.width() << " x " << gridExtent.height() << ")\n";
    26622726    }
     2727   
     2728    if (behavior & LayerTreeAsTextIncludeContentLayers) {
     2729        if (m_contentsClippingLayer) {
     2730            writeIndent(textStream, indent + 1);
     2731            textStream << "(contents clipping layer " << m_contentsClippingLayer->position().x() << ", " << m_contentsClippingLayer->position().y()
     2732                << " " << m_contentsClippingLayer->bounds().width() << " x " << m_contentsClippingLayer->bounds().height() << ")\n";
     2733        }
     2734
     2735        if (m_contentsLayer) {
     2736            writeIndent(textStream, indent + 1);
     2737            textStream << "(contents layer " << m_contentsLayer->position().x() << ", " << m_contentsLayer->position().y()
     2738                << " " << m_contentsLayer->bounds().width() << " x " << m_contentsLayer->bounds().height() << ")\n";
     2739        }
     2740    }
    26632741}
    26642742
     
    27962874}   
    27972875
    2798 void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel)
     2876void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer,
     2877    RefPtr<PlatformCALayer>& contentsLayer, RefPtr<PlatformCALayer>& contentsClippingLayer, CloneLevel cloneLevel)
    27992878{
    28002879    structuralLayer = 0;
     
    28092888    if (!m_contentsLayerClones && m_contentsLayer)
    28102889        m_contentsLayerClones = adoptPtr(new LayerMap);
     2890
     2891    if (!m_contentsClippingLayerClones && m_contentsClippingLayer)
     2892        m_contentsClippingLayerClones = adoptPtr(new LayerMap);
    28112893
    28122894    primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
    28132895    structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
    28142896    contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
     2897    contentsClippingLayer = findOrMakeClone(cloneID, m_contentsClippingLayer.get(), m_contentsClippingLayerClones.get(), cloneLevel);
    28152898}
    28162899
     
    28202903    m_structuralLayerClones = nullptr;
    28212904    m_contentsLayerClones = nullptr;
     2905    m_contentsClippingLayerClones = nullptr;
    28222906}
    28232907
     
    28502934    RefPtr<PlatformCALayer> structuralLayer;
    28512935    RefPtr<PlatformCALayer> contentsLayer;
    2852     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
     2936    RefPtr<PlatformCALayer> contentsClippingLayer;
     2937    ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, contentsClippingLayer, cloneLevel);
    28532938
    28542939    if (m_maskLayer) {
     
    28832968        replicaState.setBranchType(ReplicaState::ChildBranch);
    28842969    }
    2885    
    2886     if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
     2970
     2971    if (contentsClippingLayer) {
     2972        ASSERT(contentsLayer);
     2973        contentsClippingLayer->appendSublayer(contentsLayer.get());
     2974    }
     2975   
     2976    if (replicaLayer || structuralLayer || contentsLayer || contentsClippingLayer || childLayers.size() > 0) {
    28872977        if (structuralLayer) {
    28882978            // Replicas render behind the actual layer content.
     
    28922982            // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
    28932983            clonalSublayers.append(primaryLayer);
     2984        } else if (contentsClippingLayer) {
     2985            // FIXME: add the contents layer in the correct order with negative z-order children.
     2986            // This does not cause visible rendering issues because currently contents layers are only used
     2987            // for replaced elements that don't have children.
     2988            clonalSublayers.append(contentsClippingLayer);
    28942989        } else if (contentsLayer) {
    28952990            // FIXME: add the contents layer in the correct order with negative z-order children.
     
    29203015        structuralLayer->setSublayers(clonalSublayers);
    29213016
    2922         if (contentsLayer) {
     3017        if (contentsClippingLayer || contentsLayer) {
    29233018            // If we have a transform layer, then the contents layer is parented in the
    29243019            // primary layer (which is itself a child of the transform layer).
    29253020            primaryLayer->removeAllSublayers();
    2926             primaryLayer->appendSublayer(contentsLayer.get());
     3021            primaryLayer->appendSublayer(contentsClippingLayer ? contentsClippingLayer.get() : contentsLayer.get());
    29273022        }
    29283023
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

    r154470 r154921  
    106106   
    107107    virtual void setContentsRect(const IntRect&);
     108    virtual void setContentsClippingRect(const IntRect&) OVERRIDE;
    108109   
    109110    virtual void suspendAnimations(double time);
     
    315316    PassRefPtr<PlatformCALayer> findOrMakeClone(CloneID, PlatformCALayer *, LayerMap*, CloneLevel);
    316317
    317     void ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel);
     318    void ensureCloneLayers(CloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer,
     319        RefPtr<PlatformCALayer>& contentsLayer, RefPtr<PlatformCALayer>& contentsClippingLayer, CloneLevel);
    318320
    319321    bool hasCloneLayers() const { return m_layerClones; }
     
    341343    void updateContentsCanvasLayer();
    342344    void updateContentsColorLayer();
    343     void updateContentsRect();
     345    void updateContentsRects();
    344346    void updateMaskLayer();
    345347    void updateReplicatedLayers();
     
    393395        ContentsCanvasLayerChanged = 1 << 17,
    394396        ContentsColorLayerChanged = 1 << 18,
    395         ContentsRectChanged = 1 << 19,
     397        ContentsRectsChanged = 1 << 19,
    396398        MaskLayerChanged = 1 << 20,
    397399        ReplicatedLayerChanged = 1 << 21,
     
    414416    RefPtr<PlatformCALayer> m_layer; // The main layer
    415417    RefPtr<PlatformCALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer.
     418    RefPtr<PlatformCALayer> m_contentsClippingLayer; // A layer used to clip inner content
    416419    RefPtr<PlatformCALayer> m_contentsLayer; // A layer used for inner content, like image and video
    417420
     
    420423    OwnPtr<LayerMap> m_structuralLayerClones;
    421424    OwnPtr<LayerMap> m_contentsLayerClones;
     425    OwnPtr<LayerMap> m_contentsClippingLayerClones;
    422426
    423427#ifdef VISIBLE_TILE_WASH
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r154909 r154921  
    926926void RenderLayerBacking::resetContentsRect()
    927927{
    928     IntRect rect = pixelSnappedIntRect(contentsBox());
    929     m_graphicsLayer->setContentsRect(rect);
     928    m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
     929   
     930    LayoutRect contentsClippingRect;
     931    if (renderer().isBox())
     932        contentsClippingRect = toRenderBox(&renderer())->contentBoxRect();
     933
     934    contentsClippingRect.move(contentOffsetInCompostingLayer());
     935    m_graphicsLayer->setContentsClippingRect(pixelSnappedIntRect(contentsClippingRect));
     936
    930937    m_graphicsLayer->setContentsTileSize(IntSize());
    931938    m_graphicsLayer->setContentsTilePhase(IntPoint());
     
    10791086            layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
    10801087            layer->setSize(hBar->frameRect().size());
    1081             if (layer->hasContentsLayer())
    1082                 layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
     1088            if (layer->hasContentsLayer()) {
     1089                IntRect barRect = IntRect(IntPoint(), hBar->frameRect().size());
     1090                layer->setContentsRect(barRect);
     1091                layer->setContentsClippingRect(barRect);
     1092            }
    10831093        }
    10841094        layer->setDrawsContent(hBar && !layer->hasContentsLayer());
     
    10901100            layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
    10911101            layer->setSize(vBar->frameRect().size());
    1092             if (layer->hasContentsLayer())
    1093                 layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
     1102            if (layer->hasContentsLayer()) {
     1103                IntRect barRect = IntRect(IntPoint(), vBar->frameRect().size());
     1104                layer->setContentsRect(barRect);
     1105                layer->setContentsClippingRect(barRect);
     1106            }
    10941107        }
    10951108        layer->setDrawsContent(vBar && !layer->hasContentsLayer());
     
    13841397    // An unset (invalid) color will remove the solid color.
    13851398    m_graphicsLayer->setContentsToSolidColor(backgroundColor);
    1386     m_graphicsLayer->setContentsRect(backgroundBox());
     1399    IntRect contentsRect = backgroundBox();
     1400    m_graphicsLayer->setContentsRect(contentsRect);
     1401    m_graphicsLayer->setContentsClippingRect(contentsRect);
    13871402    didUpdateContentsRect = true;
    13881403}
     
    14441459    m_graphicsLayer->setContentsTilePhase(phase);
    14451460    m_graphicsLayer->setContentsRect(destRect);
     1461    m_graphicsLayer->setContentsClippingRect(destRect);
    14461462    m_graphicsLayer->setContentsToImage(image.get());
    14471463    didUpdateContentsRect = true;
     
    17261742    // This is a no-op if the layer doesn't have an inner layer for the image.
    17271743    m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
     1744
     1745    LayoutRect contentsClippingRect = imageRenderer->contentBoxRect();
     1746    contentsClippingRect.move(contentOffsetInCompostingLayer());
     1747    m_graphicsLayer->setContentsClippingRect(pixelSnappedIntRect(contentsClippingRect));
     1748
    17281749    m_graphicsLayer->setContentsToImage(image);
    17291750    bool isSimpleContainer = false;
     
    17731794        return LayoutRect();
    17741795
     1796    RenderBox& renderBox = *toRenderBox(&renderer());
    17751797    LayoutRect contentsRect;
    17761798#if ENABLE(VIDEO)
    1777     if (renderer().isVideo()) {
    1778         RenderVideo* videoRenderer = toRenderVideo(&renderer());
     1799    if (renderBox.isVideo()) {
     1800        RenderVideo* videoRenderer = toRenderVideo(&renderBox);
    17791801        contentsRect = videoRenderer->videoBox();
    17801802    } else
    17811803#endif
    1782         contentsRect = toRenderBox(&renderer())->contentBoxRect();
     1804    if (renderBox.isRenderReplaced()) {
     1805        RenderReplaced& renderReplaced = *toRenderReplaced(&renderBox);
     1806        contentsRect = renderReplaced.replacedContentRect(renderBox.intrinsicSize());
     1807    } else
     1808        contentsRect = renderBox.contentBoxRect();
    17831809
    17841810    contentsRect.move(contentOffsetInCompostingLayer());
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r154914 r154921  
    13911391    if (flags & LayerTreeFlagsIncludePaintingPhases)
    13921392        layerTreeBehavior |= LayerTreeAsTextIncludePaintingPhases;
     1393    if (flags & LayerTreeFlagsIncludeContentLayers)
     1394        layerTreeBehavior |= LayerTreeAsTextIncludeContentLayers;
    13931395
    13941396    // We skip dumping the scroll and clip layers to keep layerTreeAsText output
  • trunk/Source/WebCore/rendering/RenderVideo.cpp

    r154915 r154921  
    247247    mediaPlayer->setSize(IntSize(videoBounds.width(), videoBounds.height()));
    248248    mediaPlayer->setVisible(true);
     249    mediaPlayer->setShouldMaintainAspectRatio(style()->objectFit() != ObjectFitFill);
    249250}
    250251
  • trunk/Source/WebCore/testing/Internals.cpp

    r154877 r154921  
    16061606    if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
    16071607        layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
     1608    if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
     1609        layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
    16081610
    16091611    return document->frame()->layerTreeAsText(layerTreeFlags);
  • trunk/Source/WebCore/testing/Internals.h

    r153728 r154921  
    226226        LAYER_TREE_INCLUDES_TILE_CACHES = 2,
    227227        LAYER_TREE_INCLUDES_REPAINT_RECTS = 4,
    228         LAYER_TREE_INCLUDES_PAINTING_PHASES = 8
     228        LAYER_TREE_INCLUDES_PAINTING_PHASES = 8,
     229        LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16
    229230    };
    230231    String layerTreeAsText(Document*, unsigned flags, ExceptionCode&) const;
  • trunk/Source/WebCore/testing/Internals.idl

    r153704 r154921  
    176176    const unsigned short LAYER_TREE_INCLUDES_REPAINT_RECTS = 4;
    177177    const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 8;
     178    const unsigned short LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16;
    178179    [RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);
    179180
Note: See TracChangeset for help on using the changeset viewer.