Changeset 194706 in webkit


Ignore:
Timestamp:
Jan 7, 2016 11:40:46 AM (8 years ago)
Author:
Chris Dumez
Message:

Directly-composited animated GIFs never resume once scrolled offscreen
https://bugs.webkit.org/show_bug.cgi?id=152817
<rdar://problem/19982020>

Reviewed by Daniel Bates.

Source/WebCore:

Directly-composited animated GIFs would never resume once scrolled
offscreen. This is because calling repaint() in this case would not
cause BitmapImage::draw() to be called and the animation would thus
not be resumed. To address the problem,
repaintForPausedImageAnimationsIfNeeded() now calls
RenderBoxModelObject::contentChanged(ImageChanged) in addition to
repaint() to make sure the animation actually gets resumed, even in
the directly-composited animated GIF case.

Test: fast/images/composited-animated-gif-outside-viewport.html

  • platform/graphics/BitmapImage.h:

Make currentFrame() public so it can be exposed via Internals for the
purpose of testing.

  • rendering/RenderElement.cpp:

(WebCore::RenderElement::repaintForPausedImageAnimationsIfNeeded):
Call RenderBoxModelObject::contentChanged(ImageChanged) in addition to
calling repaint() to make sure the animation actually gets resumed in
the directly-composited animated GIFs case.

  • testing/Internals.cpp:

(WebCore::Internals::imageFrameIndex):

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

Expose new "unsigned long imageFrameIndex(Element)" operation on
Internals so layout tests can better check if an image is actually
animating. Previously, we would rely on the output of
internals.hasPausedImageAnimations(Element) but this is not sufficient
to cover this bug as our rendering code believed it has resumed the
animations but the GIF was not actually animating due to it being
directly-composited.

LayoutTests:

Add a layout test to check that directly-composited animated GIFs are
properly suspended / resumed based on visibility inside the viewport.

  • fast/images/composited-animated-gif-outside-viewport-expected.txt: Added.
  • fast/images/composited-animated-gif-outside-viewport.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r194704 r194706  
     12016-01-07  Chris Dumez  <cdumez@apple.com>
     2
     3        Directly-composited animated GIFs never resume once scrolled offscreen
     4        https://bugs.webkit.org/show_bug.cgi?id=152817
     5        <rdar://problem/19982020>
     6
     7        Reviewed by Daniel Bates.
     8
     9        Add a layout test to check that directly-composited animated GIFs are
     10        properly suspended / resumed based on visibility inside the viewport.
     11
     12        * fast/images/composited-animated-gif-outside-viewport-expected.txt: Added.
     13        * fast/images/composited-animated-gif-outside-viewport.html: Added.
     14
    1152016-01-06  Joseph Pecoraro  <pecoraro@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r194697 r194706  
     12016-01-07  Chris Dumez  <cdumez@apple.com>
     2
     3        Directly-composited animated GIFs never resume once scrolled offscreen
     4        https://bugs.webkit.org/show_bug.cgi?id=152817
     5        <rdar://problem/19982020>
     6
     7        Reviewed by Daniel Bates.
     8
     9        Directly-composited animated GIFs would never resume once scrolled
     10        offscreen. This is because calling repaint() in this case would not
     11        cause BitmapImage::draw() to be called and the animation would thus
     12        not be resumed. To address the problem,
     13        repaintForPausedImageAnimationsIfNeeded() now calls
     14        RenderBoxModelObject::contentChanged(ImageChanged) in addition to
     15        repaint() to make sure the animation actually gets resumed, even in
     16        the directly-composited animated GIF case.
     17
     18        Test: fast/images/composited-animated-gif-outside-viewport.html
     19
     20        * platform/graphics/BitmapImage.h:
     21        Make currentFrame() public so it can be exposed via Internals for the
     22        purpose of testing.
     23
     24        * rendering/RenderElement.cpp:
     25        (WebCore::RenderElement::repaintForPausedImageAnimationsIfNeeded):
     26        Call RenderBoxModelObject::contentChanged(ImageChanged) in addition to
     27        calling repaint() to make sure the animation actually gets resumed in
     28        the directly-composited animated GIFs case.
     29
     30        * testing/Internals.cpp:
     31        (WebCore::Internals::imageFrameIndex):
     32        * testing/Internals.h:
     33        * testing/Internals.idl:
     34        Expose new "unsigned long imageFrameIndex(Element)" operation on
     35        Internals so layout tests can better check if an image is actually
     36        animating. Previously, we would rely on the output of
     37        internals.hasPausedImageAnimations(Element) but this is not sufficient
     38        to cover this bug as our rendering code believed it has resumed the
     39        animations but the GIF was not actually animating due to it being
     40        directly-composited.
     41
    1422016-01-07  Michael Catanzaro  <mcatanzaro@igalia.com>
    243
  • trunk/Source/WebCore/platform/graphics/BitmapImage.h

    r192140 r194706  
    184184    bool allowSubsampling() const { return m_allowSubsampling; }
    185185    void setAllowSubsampling(bool allowSubsampling) { m_allowSubsampling = allowSubsampling; }
     186
     187    size_t currentFrame() const { return m_currentFrame; }
    186188   
    187189private:
     
    211213#endif
    212214
    213     size_t currentFrame() const { return m_currentFrame; }
    214215    size_t frameCount();
    215216
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r194645 r194706  
    15181518    if (!shouldRepaintForImageAnimation(*this, visibleRect))
    15191519        return false;
     1520
    15201521    repaint();
     1522
     1523    // For directly-composited animated GIFs it does not suffice to call repaint() to resume animation. We need to mark the image as changed.
     1524    if (is<RenderBoxModelObject>(*this))
     1525        downcast<RenderBoxModelObject>(*this).contentChanged(ImageChanged);
     1526
    15211527    return true;
    15221528}
  • trunk/Source/WebCore/testing/Internals.cpp

    r194672 r194706  
    3333#include "ApplicationCacheStorage.h"
    3434#include "BackForwardController.h"
     35#include "BitmapImage.h"
    3536#include "CachedImage.h"
    3637#include "CachedResourceLoader.h"
     
    589590}
    590591
     592size_t Internals::imageFrameIndex(Element* element, ExceptionCode& ec)
     593{
     594    if (!is<HTMLImageElement>(element)) {
     595        ec = TypeError;
     596        return 0;
     597    }
     598
     599    auto* cachedImage = downcast<HTMLImageElement>(*element).cachedImage();
     600    if (!cachedImage)
     601        return 0;
     602
     603    auto* image = cachedImage->image();
     604    return is<BitmapImage>(image) ? downcast<BitmapImage>(*image).currentFrame() : 0;
     605}
     606
    591607void Internals::clearPageCache()
    592608{
  • trunk/Source/WebCore/testing/Internals.h

    r194117 r194706  
    105105    unsigned memoryCacheSize() const;
    106106
     107    size_t imageFrameIndex(Element*, ExceptionCode&);
     108
    107109    void clearPageCache();
    108110    unsigned pageCacheSize() const;
  • trunk/Source/WebCore/testing/Internals.idl

    r194117 r194706  
    206206    [RaisesException] boolean isPageBoxVisible(long pageNumber);
    207207
     208    [RaisesException] unsigned long imageFrameIndex(Element element);
     209
    208210    readonly attribute InternalSettings settings;
    209211    readonly attribute unsigned long workerThreadCount;
Note: See TracChangeset for help on using the changeset viewer.