Changeset 61341 in webkit


Ignore:
Timestamp:
Jun 17, 2010 12:50:36 PM (14 years ago)
Author:
senorblanco@chromium.org
Message:

2010-06-17 Stephen White <senorblanco@chromium.org>

Reviewed by David Levin.

Fix for slow multiple animated resize issue.
https://bugs.webkit.org/show_bug.cgi?id=38233

The timer-based resize quality approach implemented in
http://trac.webkit.org/changeset/34210 is a good idea, but doesn't
scale to multiple images with animated resizes. This fix unifies all
outstanding resize timers into a single timer, and removes the "use
last quality" check (which doesn't work when images are overlapping).
It also refactors the copy of this code implemented in
RenderBoxModelObject in http://trac.webkit.org/changeset/53949.

This improves Safari performance for the following IE9 platform demos on my C2D MacPro (10.5):
http://ie.microsoft.com/testdrive/Performance/01FlyingImages/Default.html (4->60fps)
http://ie.microsoft.com/testdrive/Performance/10FlickrExplorer/Default.html (3->16fps)
http://ie.microsoft.com/testdrive/Performance/11BrowserFlip/Default.html (9->60fps)

  • rendering/RenderBoxModelObject.cpp: (WebCore::ImageQualityController::ImageQualityController): Unify all timers into a single timer, rename RenderBoxModelScaleObserver to ImageQualityController, and remove the resize quality "stickness", since it doesn't work with multiple outstanding resizes. (WebCore::ImageQualityController::objectDestroyed): gImages global is now m_lastPaintTimeMap member. (WebCore::ImageQualityController::highQualityRepaintTimerFired): Function made non-static; repaint all pending resizes (not just one). (WebCore::ImageQualityController::restartTimer): Added function to restart timer at 1.05x threshold. (WebCore::imageQualityController): Static function to return singleton. (WebCore::ImageQualityController::shouldPaintAtLowQuality): Use m_lastPaintTimeMap, not gImages global. Implement new timer algorithm. Remove resize "stickiness". (WebCore::RenderBoxModelObject::shouldPaintAtLowQuality): Implement shouldPaintAtLowQuality, which pulls out "this" and passes the call to the ImageQualityController. (WebCore::RenderBoxModelObject::~RenderBoxModelObject): Call ImageQualityController singleton's objectDestroyed() instead of old static function. (WebCore::RenderBoxModelObject::paintFillLayerExtended): Modify shouldPaintAtLowQuality() call to match new class name and function signature.
  • rendering/RenderBoxModelObject.h: Expose shouldPaintAtLowQuality as a member function.
  • rendering/RenderImage.cpp: (WebCore::RenderImage::~RenderImage): No need to call objectDestroyed() here anymore, since the RenderBoxModelObject destructor will do this for us. (WebCore::RenderImage::paintIntoRect): Rip out RenderImageScaleObserver, and call RenderBoxModelObject::shouldPaintAtLowQuality() instead.

2010-06-17 Stephen White <senorblanco@chromium.org>

Reviewed by David Levin.

Temporarily modify test_expectations.txt to add tests broken by
https://bugs.webkit.org/show_bug.cgi?id=38233

  • platform/chromium/test_expectations.txt:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r61340 r61341  
     12010-06-17  Stephen White  <senorblanco@chromium.org>
     2
     3        Reviewed by David Levin.
     4
     5        Temporarily modify test_expectations.txt to add tests broken by
     6        https://bugs.webkit.org/show_bug.cgi?id=38233
     7
     8        * platform/chromium/test_expectations.txt:
     9
    1102010-06-17  Rob Buis  <rwlbuis@gmail.com>
    211
  • trunk/LayoutTests/platform/chromium/test_expectations.txt

    r61337 r61341  
    29182918// needs new baseline, transferring over from downstream.
    29192919BUG46674 : fast/js/missing-title-end-tag-js.html = FAIL
     2920
     2921// The following need to be rebaselined due to change of resize algorithm in
     2922// https://bugs.webkit.org/show_bug.cgi?id=38233
     2923
     2924BUG_SENORBLANCO WIN LINUX : css2.1/t090501-c414-flt-03-b-g.html = IMAGE
     2925BUG_SENORBLANCO WIN LINUX : css2.1/t090501-c5525-flt-l-00-b-g.html = IMAGE
     2926BUG_SENORBLANCO WIN LINUX : css2.1/t090501-c5525-flt-r-00-b-g.html = IMAGE
     2927BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize01.html = IMAGE
     2928BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize02.html = IMAGE
     2929BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize04.html = IMAGE
     2930BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize05.html = IMAGE
     2931BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize06.html = IMAGE
     2932BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize07.html = IMAGE
     2933BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize08.html = IMAGE
     2934BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize09.html = IMAGE
     2935BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize10.html = IMAGE
     2936BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize11.html = IMAGE
     2937BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize12.html = IMAGE
     2938BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize13.html = IMAGE
     2939BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize14.html = IMAGE
     2940BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize15.html = IMAGE
     2941BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize16.html = IMAGE
     2942BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize17.html = IMAGE
     2943BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize18.html = IMAGE
     2944BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize19.html = IMAGE
     2945BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize20.html = IMAGE
     2946BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize21.html = IMAGE
     2947BUG_SENORBLANCO WIN LINUX : fast/backgrounds/size/backgroundSize22.html = IMAGE
     2948BUG_SENORBLANCO WIN LINUX : fast/block/positioning/replaced-inside-fixed-top-bottom.html = IMAGE
     2949BUG_SENORBLANCO WIN LINUX : fast/css/value-list-out-of-bounds-crash.html = IMAGE
     2950BUG_SENORBLANCO WIN LINUX : fast/events/pointer-events-2.html = IMAGE
     2951BUG_SENORBLANCO WIN LINUX : fast/forms/input-type-change.html = IMAGE
     2952BUG_SENORBLANCO WIN LINUX : fast/replaced/absolute-image-sizing.html = IMAGE
     2953BUG_SENORBLANCO WIN LINUX : fast/replaced/image-sizing.html = IMAGE
     2954BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug101674.html = IMAGE
     2955BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug11026.html = IMAGE
     2956BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug1188.html = IMAGE
     2957BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug1296.html = IMAGE
     2958BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug1430.html = IMAGE
     2959BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug14929.html = IMAGE
     2960BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug15544.html = IMAGE
     2961BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug2981-2.html = IMAGE
     2962BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug4093.html = IMAGE
     2963BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug4284.html = IMAGE
     2964BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug4427.html = IMAGE
     2965BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug56563.html = IMAGE
     2966BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug625.html = IMAGE
     2967BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug6404.html = IMAGE
     2968BUG_SENORBLANCO WIN LINUX : tables/mozilla/bugs/bug97383.html = IMAGE
     2969BUG_SENORBLANCO WIN LINUX : tables/mozilla/core/bloomberg.html = IMAGE
     2970BUG_SENORBLANCO WIN LINUX : tables/mozilla/core/col_widths_auto_autoFix.html = IMAGE
     2971BUG_SENORBLANCO WIN LINUX : tables/mozilla/core/misc.html = IMAGE
     2972BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tbody_valign_baseline.html = IMAGE
     2973BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tbody_valign_bottom.html = IMAGE
     2974BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tbody_valign_middle.html = IMAGE
     2975BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tbody_valign_top.html = IMAGE
     2976BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/td_valign_baseline.html = IMAGE
     2977BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/td_valign_bottom.html = IMAGE
     2978BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/td_valign_middle.html = IMAGE
     2979BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/td_valign_top.html = IMAGE
     2980BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tfoot_valign_baseline.html = IMAGE
     2981BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tfoot_valign_bottom.html = IMAGE
     2982BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tfoot_valign_middle.html = IMAGE
     2983BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tfoot_valign_top.html = IMAGE
     2984BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/th_valign_baseline.html = IMAGE
     2985BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/th_valign_bottom.html = IMAGE
     2986BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/th_valign_middle.html = IMAGE
     2987BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/th_valign_top.html = IMAGE
     2988BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/thead_valign_baseline.html = IMAGE
     2989BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/thead_valign_bottom.html = IMAGE
     2990BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/thead_valign_middle.html = IMAGE
     2991BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/thead_valign_top.html = IMAGE
     2992BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tr_valign_baseline.html = IMAGE
     2993BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tr_valign_bottom.html = IMAGE
     2994BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tr_valign_middle.html = IMAGE
     2995BUG_SENORBLANCO WIN LINUX : tables/mozilla/marvin/tr_valign_top.html = IMAGE
     2996BUG_SENORBLANCO WIN LINUX : tables/mozilla/other/cell_widths.html = IMAGE
     2997BUG_SENORBLANCO WIN LINUX : tables/mozilla_expected_failures/bugs/97619.html = IMAGE
     2998BUG_SENORBLANCO WIN LINUX : tables/mozilla_expected_failures/bugs/bug6933.html = IMAGE
     2999
     3000BUG_SENORBLANCO MAC : css2.1/t0804-c5510-padn-00-b-ag.html = IMAGE
     3001BUG_SENORBLANCO MAC : css2.1/t0905-c414-flt-01-d-g.html = IMAGE
     3002BUG_SENORBLANCO MAC : css2.1/t090501-c414-flt-02-d-g.html = IMAGE
     3003BUG_SENORBLANCO MAC : css2.1/t090501-c414-flt-03-b-g.html = IMAGE
     3004BUG_SENORBLANCO MAC : css2.1/t090501-c414-flt-ln-01-d-g.html = IMAGE
     3005BUG_SENORBLANCO MAC : css2.1/t090501-c5525-flt-l-00-b-g.html = IMAGE
     3006BUG_SENORBLANCO MAC : css2.1/t090501-c5525-flt-r-00-b-g.html = IMAGE
     3007BUG_SENORBLANCO MAC : css2.1/t100304-c43-rpl-bbx-00-d-g.html = IMAGE
     3008BUG_SENORBLANCO MAC : css2.1/t100304-c43-rpl-bbx-01-d-g.html = IMAGE
     3009BUG_SENORBLANCO MAC : css2.1/t1004-c5524-width-00-b-g.html = IMAGE
     3010BUG_SENORBLANCO MAC : css2.1/t100801-c544-valgn-02-d-agi.html = IMAGE
     3011BUG_SENORBLANCO MAC : css2.1/t100801-c544-valgn-03-d-agi.html = IMAGE
     3012BUG_SENORBLANCO MAC : css2.1/t100801-c544-valgn-04-d-agi.html = IMAGE
     3013BUG_SENORBLANCO MAC : fast/backgrounds/repeat/mask-negative-offset-repeat.html = IMAGE
     3014BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize01.html = IMAGE
     3015BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize05.html = IMAGE
     3016BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize06.html = IMAGE
     3017BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize07.html = IMAGE
     3018BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize08.html = IMAGE
     3019BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize09.html = IMAGE
     3020BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize10.html = IMAGE
     3021BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize11.html = IMAGE
     3022BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize12.html = IMAGE
     3023BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize16.html = IMAGE
     3024BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize17.html = IMAGE
     3025BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize18.html = IMAGE
     3026BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize19.html = IMAGE
     3027BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize20.html = IMAGE
     3028BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize21.html = IMAGE
     3029BUG_SENORBLANCO MAC : fast/backgrounds/size/backgroundSize22.html = IMAGE
     3030BUG_SENORBLANCO MAC : fast/backgrounds/size/zero.html = IMAGE
     3031BUG_SENORBLANCO MAC : fast/block/positioning/replaced-inside-fixed-top-bottom.html = IMAGE
     3032BUG_SENORBLANCO MAC : fast/canvas/canvas-as-image.html = IMAGE
     3033BUG_SENORBLANCO MAC : fast/css/value-list-out-of-bounds-crash.html = IMAGE
     3034BUG_SENORBLANCO MAC : fast/forms/input-type-change.html = IMAGE
     3035BUG_SENORBLANCO MAC : fast/replaced/001.html = IMAGE
     3036BUG_SENORBLANCO MAC : fast/replaced/002.html = IMAGE
     3037BUG_SENORBLANCO MAC : fast/replaced/003.html = IMAGE
     3038BUG_SENORBLANCO MAC : fast/replaced/absolute-image-sizing.html = IMAGE
     3039BUG_SENORBLANCO MAC : fast/replaced/image-sizing.html = IMAGE
     3040BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug11026.html = IMAGE
     3041BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug1188.html = IMAGE
     3042BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug1296.html = IMAGE
     3043BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug1430.html = IMAGE
     3044BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug14929.html = IMAGE
     3045BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug15544.html = IMAGE
     3046BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug23235.html = IMAGE
     3047BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug2981-2.html = IMAGE
     3048BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug4093.html = IMAGE
     3049BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug4284.html = IMAGE
     3050BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug4427.html = IMAGE
     3051BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug4523.html = IMAGE
     3052BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug56563.html = IMAGE
     3053BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug6404.html = IMAGE
     3054BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug86708.html = IMAGE
     3055BUG_SENORBLANCO MAC : tables/mozilla/bugs/bug97383.html = IMAGE
     3056BUG_SENORBLANCO MAC : tables/mozilla/core/col_widths_auto_autoFix.html = IMAGE
     3057BUG_SENORBLANCO MAC : tables/mozilla/core/misc.html = IMAGE
     3058BUG_SENORBLANCO MAC : tables/mozilla/marvin/tbody_valign_baseline.html = IMAGE
     3059BUG_SENORBLANCO MAC : tables/mozilla/marvin/tbody_valign_bottom.html = IMAGE
     3060BUG_SENORBLANCO MAC : tables/mozilla/marvin/tbody_valign_middle.html = IMAGE
     3061BUG_SENORBLANCO MAC : tables/mozilla/marvin/tbody_valign_top.html = IMAGE
     3062BUG_SENORBLANCO MAC : tables/mozilla/marvin/td_valign_baseline.html = IMAGE
     3063BUG_SENORBLANCO MAC : tables/mozilla/marvin/td_valign_bottom.html = IMAGE
     3064BUG_SENORBLANCO MAC : tables/mozilla/marvin/td_valign_middle.html = IMAGE
     3065BUG_SENORBLANCO MAC : tables/mozilla/marvin/td_valign_top.html = IMAGE
     3066BUG_SENORBLANCO MAC : tables/mozilla/marvin/tfoot_valign_baseline.html = IMAGE
     3067BUG_SENORBLANCO MAC : tables/mozilla/marvin/tfoot_valign_bottom.html = IMAGE
     3068BUG_SENORBLANCO MAC : tables/mozilla/marvin/tfoot_valign_middle.html = IMAGE
     3069BUG_SENORBLANCO MAC : tables/mozilla/marvin/tfoot_valign_top.html = IMAGE
     3070BUG_SENORBLANCO MAC : tables/mozilla/marvin/th_valign_baseline.html = IMAGE
     3071BUG_SENORBLANCO MAC : tables/mozilla/marvin/th_valign_bottom.html = IMAGE
     3072BUG_SENORBLANCO MAC : tables/mozilla/marvin/th_valign_middle.html = IMAGE
     3073BUG_SENORBLANCO MAC : tables/mozilla/marvin/th_valign_top.html = IMAGE
     3074BUG_SENORBLANCO MAC : tables/mozilla/marvin/thead_valign_baseline.html = IMAGE
     3075BUG_SENORBLANCO MAC : tables/mozilla/marvin/thead_valign_bottom.html = IMAGE
     3076BUG_SENORBLANCO MAC : tables/mozilla/marvin/thead_valign_middle.html = IMAGE
     3077BUG_SENORBLANCO MAC : tables/mozilla/marvin/thead_valign_top.html = IMAGE
     3078BUG_SENORBLANCO MAC : tables/mozilla/marvin/tr_valign_baseline.html = IMAGE
     3079BUG_SENORBLANCO MAC : tables/mozilla/marvin/tr_valign_bottom.html = IMAGE
     3080BUG_SENORBLANCO MAC : tables/mozilla/marvin/tr_valign_middle.html = IMAGE
     3081BUG_SENORBLANCO MAC : tables/mozilla/marvin/tr_valign_top.html = IMAGE
     3082BUG_SENORBLANCO MAC : tables/mozilla_expected_failures/bugs/97619.html = IMAGE
     3083BUG_SENORBLANCO MAC : tables/mozilla_expected_failures/bugs/bug6933.html = IMAGE
  • trunk/WebCore/ChangeLog

    r61340 r61341  
     12010-06-17  Stephen White  <senorblanco@chromium.org>
     2
     3        Reviewed by David Levin.
     4
     5        Fix for slow multiple animated resize issue.
     6        https://bugs.webkit.org/show_bug.cgi?id=38233
     7
     8        The timer-based resize quality approach implemented in
     9        http://trac.webkit.org/changeset/34210 is a good idea, but doesn't
     10        scale to multiple images with animated resizes.  This fix unifies all
     11        outstanding resize timers into a single timer, and removes the "use
     12        last quality" check (which doesn't work when images are overlapping).
     13        It also refactors the copy of this code implemented in
     14        RenderBoxModelObject in http://trac.webkit.org/changeset/53949.
     15
     16        This improves Safari performance for the following IE9 platform demos on my C2D MacPro (10.5):
     17        http://ie.microsoft.com/testdrive/Performance/01FlyingImages/Default.html (4->60fps)
     18        http://ie.microsoft.com/testdrive/Performance/10FlickrExplorer/Default.html (3->16fps)
     19        http://ie.microsoft.com/testdrive/Performance/11BrowserFlip/Default.html (9->60fps)
     20
     21        * rendering/RenderBoxModelObject.cpp:
     22        (WebCore::ImageQualityController::ImageQualityController):
     23        Unify all timers into a single timer, rename RenderBoxModelScaleObserver
     24        to ImageQualityController, and remove the resize quality "stickness",
     25        since it doesn't work with multiple outstanding resizes.
     26        (WebCore::ImageQualityController::objectDestroyed):
     27        gImages global is now m_lastPaintTimeMap member.
     28        (WebCore::ImageQualityController::highQualityRepaintTimerFired):
     29        Function made non-static; repaint all pending resizes (not just one).
     30        (WebCore::ImageQualityController::restartTimer):
     31        Added function to restart timer at 1.05x threshold.
     32        (WebCore::imageQualityController):
     33        Static function to return singleton.
     34        (WebCore::ImageQualityController::shouldPaintAtLowQuality):
     35        Use m_lastPaintTimeMap, not gImages global.  Implement new timer
     36        algorithm.  Remove resize "stickiness".
     37        (WebCore::RenderBoxModelObject::shouldPaintAtLowQuality):
     38        Implement shouldPaintAtLowQuality, which pulls out "this" and passes
     39        the call to the ImageQualityController.
     40        (WebCore::RenderBoxModelObject::~RenderBoxModelObject):
     41        Call ImageQualityController singleton's objectDestroyed() instead of
     42        old static function.
     43        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
     44        Modify shouldPaintAtLowQuality() call to match new class name and
     45        function signature.
     46        * rendering/RenderBoxModelObject.h:
     47        Expose shouldPaintAtLowQuality as a member function.
     48        * rendering/RenderImage.cpp:
     49        (WebCore::RenderImage::~RenderImage):
     50        No need to call objectDestroyed() here anymore, since the
     51        RenderBoxModelObject destructor will do this for us.
     52        (WebCore::RenderImage::paintIntoRect):
     53        Rip out RenderImageScaleObserver, and call
     54        RenderBoxModelObject::shouldPaintAtLowQuality() instead.
     55
    1562010-06-17  Rob Buis  <rwlbuis@gmail.com>
    257
  • trunk/WebCore/rendering/RenderBoxModelObject.cpp

    r60649 r61341  
    55 *           (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
    66 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     7 * Copyright (C) 2010 Google Inc. All rights reserved.
    78 *
    89 * This library is free software; you can redistribute it and/or
     
    4950static const double cLowQualityTimeThreshold = 0.500; // 500 ms
    5051
    51 class RenderBoxModelScaleData : public Noncopyable {
     52typedef HashMap<RenderBoxModelObject*, double> LastPaintTimeMap;
     53
     54class ImageQualityController : public Noncopyable {
    5255public:
    53     RenderBoxModelScaleData(RenderBoxModelObject* object, const IntSize& size, const AffineTransform& transform, double time, bool lowQualityScale)
    54         : m_size(size)
    55         , m_transform(transform)
    56         , m_lastPaintTime(time)
    57         , m_lowQualityScale(lowQualityScale)
    58         , m_highQualityRepaintTimer(object, &RenderBoxModelObject::highQualityRepaintTimerFired)
    59     {
    60     }
    61 
    62     ~RenderBoxModelScaleData()
    63     {
    64         m_highQualityRepaintTimer.stop();
    65     }
    66 
    67     Timer<RenderBoxModelObject>& hiqhQualityRepaintTimer() { return m_highQualityRepaintTimer; }
    68 
    69     const IntSize& size() const { return m_size; }
    70     void setSize(const IntSize& s) { m_size = s; }
    71     double lastPaintTime() const { return m_lastPaintTime; }
    72     void setLastPaintTime(double t) { m_lastPaintTime = t; }
    73     bool useLowQualityScale() const { return m_lowQualityScale; }
    74     const AffineTransform& transform() const { return m_transform; }
    75     void setTransform(const AffineTransform& transform) { m_transform = transform; }
    76     void setUseLowQualityScale(bool b)
    77     {
    78         m_highQualityRepaintTimer.stop();
    79         m_lowQualityScale = b;
    80         if (b)
    81             m_highQualityRepaintTimer.startOneShot(cLowQualityTimeThreshold);
    82     }
     56    ImageQualityController();
     57    bool shouldPaintAtLowQuality(GraphicsContext*, RenderBoxModelObject*, Image*, const IntSize&);
     58    void objectDestroyed(RenderBoxModelObject*);
    8359
    8460private:
    85     IntSize m_size;
    86     AffineTransform m_transform;
    87     double m_lastPaintTime;
    88     bool m_lowQualityScale;
    89     Timer<RenderBoxModelObject> m_highQualityRepaintTimer;
     61    void highQualityRepaintTimerFired(Timer<ImageQualityController>*);
     62    void restartTimer();
     63
     64    LastPaintTimeMap m_lastPaintTimeMap;
     65    Timer<ImageQualityController> m_timer;
    9066};
    9167
    92 class RenderBoxModelScaleObserver {
    93 public:
    94     static bool shouldPaintBackgroundAtLowQuality(GraphicsContext*, RenderBoxModelObject*, Image*, const IntSize&);
    95 
    96     static void boxModelObjectDestroyed(RenderBoxModelObject* object)
    97     {
    98         if (gBoxModelObjects) {
    99             RenderBoxModelScaleData* data = gBoxModelObjects->take(object);
    100             delete data;
    101             if (!gBoxModelObjects->size()) {
    102                 delete gBoxModelObjects;
    103                 gBoxModelObjects = 0;
    104             }
    105         }
    106     }
    107 
    108     static void highQualityRepaintTimerFired(RenderBoxModelObject* object)
    109     {
    110         RenderBoxModelScaleObserver::boxModelObjectDestroyed(object);
    111         object->repaint();
    112     }
    113 
    114     static HashMap<RenderBoxModelObject*, RenderBoxModelScaleData*>* gBoxModelObjects;
    115 };
    116 
    117 bool RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(GraphicsContext* context, RenderBoxModelObject* object, Image* image, const IntSize& size)
     68ImageQualityController::ImageQualityController()
     69    : m_timer(this, &ImageQualityController::highQualityRepaintTimerFired)
     70{
     71}
     72
     73void ImageQualityController::objectDestroyed(RenderBoxModelObject* object)
     74{
     75    m_lastPaintTimeMap.remove(object);
     76    if (m_lastPaintTimeMap.isEmpty())
     77        m_timer.stop();
     78}
     79   
     80void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityController>*)
     81{
     82    for (LastPaintTimeMap::iterator it = m_lastPaintTimeMap.begin(); it != m_lastPaintTimeMap.end(); ++it)
     83        it->first->repaint();
     84}
     85
     86void ImageQualityController::restartTimer()
     87{
     88    m_timer.startOneShot(cLowQualityTimeThreshold * 1.05);
     89}
     90
     91bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderBoxModelObject* object, Image* image, const IntSize& size)
    11892{
    11993    // If the image is not a bitmap image, then none of this is relevant and we just paint at high
    12094    // quality.
    121     if (!image || !image->isBitmapImage())
     95    if (!image || !image->isBitmapImage() || context->paintingDisabled())
    12296        return false;
    12397
     
    127101
    128102    // Look ourselves up in the hashtable.
    129     RenderBoxModelScaleData* data = 0;
    130     if (gBoxModelObjects)
    131         data = gBoxModelObjects->get(object);
     103    LastPaintTimeMap::iterator i = m_lastPaintTimeMap.find(object);
    132104
    133105    const AffineTransform& currentTransform = context->getCTM();
    134106    bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped();
    135107    if (!contextIsScaled && imageSize == size) {
    136         // There is no scale in effect.  If we had a scale in effect before, we can just delete this data.
    137         if (data) {
    138             gBoxModelObjects->remove(object);
    139             delete data;
    140         }
     108        // There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
     109        if (i != m_lastPaintTimeMap.end())
     110            m_lastPaintTimeMap.remove(object);
     111
    141112        return false;
    142113    }
    143114
    144     // There is no need to hash scaled images that always use low quality mode when the page demands it.  This is the iChat case.
     115    // There is no need to hash scaled images that always use low quality mode when the page demands it. This is the iChat case.
    145116    if (object->document()->page()->inLowQualityImageInterpolationMode()) {
    146117        double totalPixels = static_cast<double>(image->width()) * static_cast<double>(image->height());
     
    148119            return true;
    149120    }
    150 
    151     // If there is no data yet, we will paint the first scale at high quality and record the paint time in case a second scale happens
    152     // very soon.
    153     if (!data) {
    154         data = new RenderBoxModelScaleData(object, size, currentTransform, currentTime(), false);
    155         if (!gBoxModelObjects)
    156             gBoxModelObjects = new HashMap<RenderBoxModelObject*, RenderBoxModelScaleData*>;
    157         gBoxModelObjects->set(object, data);
     121    double newTime = currentTime();
     122    if (i != m_lastPaintTimeMap.end() && newTime - i->second >= cLowQualityTimeThreshold && !m_timer.isActive()) {
     123        // If it has been at least cLowQualityTimeThreshold seconds since the
     124        // last time a resize was requested, and the timer is no longer active,
     125        // draw at high quality and don't set the timer.
     126        objectDestroyed(object);
    158127        return false;
    159128    }
    160 
    161     const AffineTransform& tr = data->transform();
    162     bool scaleUnchanged = tr.a() == currentTransform.a() && tr.b() == currentTransform.b() && tr.c() == currentTransform.c() && tr.d() == currentTransform.d();
    163     // We are scaled, but we painted already at this size, so just keep using whatever mode we last painted with.
    164     if ((!contextIsScaled || scaleUnchanged) && data->size() == size)
    165         return data->useLowQualityScale();
    166 
    167     // We have data and our size just changed.  If this change happened quickly, go into low quality mode and then set a repaint
    168     // timer to paint in high quality mode.  Otherwise it is ok to just paint in high quality mode.
    169     double newTime = currentTime();
    170     data->setUseLowQualityScale(newTime - data->lastPaintTime() < cLowQualityTimeThreshold);
    171     data->setLastPaintTime(newTime);
    172     data->setTransform(currentTransform);
    173     data->setSize(size);
    174     return data->useLowQualityScale();
    175 }
    176 
    177 HashMap<RenderBoxModelObject*, RenderBoxModelScaleData*>* RenderBoxModelScaleObserver::gBoxModelObjects = 0;
    178 
    179 void RenderBoxModelObject::highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*)
    180 {
    181     RenderBoxModelScaleObserver::highQualityRepaintTimerFired(this);
     129    // Draw at low quality first and set a timer for high quality.
     130    m_lastPaintTimeMap.set(object, newTime);
     131    restartTimer();
     132    return true;
     133}
     134
     135static ImageQualityController* imageQualityController()
     136{
     137    static ImageQualityController* controller = new ImageQualityController;
     138    return controller;
    182139}
    183140
     
    204161}
    205162
     163bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Image* image, const IntSize& size)
     164{
     165    return imageQualityController()->shouldPaintAtLowQuality(context, this, image, size);
     166}
    206167
    207168RenderBoxModelObject::RenderBoxModelObject(Node* node)
     
    216177    ASSERT(!hasLayer());
    217178    ASSERT(!m_layer);
    218     RenderBoxModelScaleObserver::boxModelObjectDestroyed(this);
     179    imageQualityController()->objectDestroyed(this);
    219180}
    220181
     
    464425    return padding.calcMinValue(w);
    465426}
    466 
    467427
    468428void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, int tx, int ty, int w, int h, InlineFlowBox* box, CompositeOperator op, RenderObject* backgroundObject)
     
    632592            RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
    633593            Image* image = bg->image(clientForBackgroundImage, tileSize);
    634             bool useLowQualityScaling = RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(context, this, image, tileSize);
     594            bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, tileSize);
    635595            context->drawTiledImage(image, style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
    636596        }
  • trunk/WebCore/rendering/RenderBoxModelObject.h

    r60344 r61341  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 * Copyright (C) 2003, 2006, 2007, 2009 Apple Inc. All rights reserved.
     5 * Copyright (C) 2010 Google Inc. All rights reserved.
    56 *
    67 * This library is free software; you can redistribute it and/or
     
    108109    void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
    109110
     111    bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const IntSize&);
     112
    110113private:
    111114    virtual bool isBoxModelObject() const { return true; }
  • trunk/WebCore/rendering/RenderImage.cpp

    r60943 r61341  
    66 *           (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
    77 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
     8 * Copyright (C) 2010 Google Inc. All rights reserved.
    89 *
    910 * This library is free software; you can redistribute it and/or
     
    5354namespace WebCore {
    5455
    55 static const double cInterpolationCutoff = 800. * 800.;
    56 static const double cLowQualityTimeThreshold = 0.050; // 50 ms
    57 
    58 class RenderImageScaleData : public Noncopyable {
    59 public:
    60     RenderImageScaleData(RenderImage* image, const IntSize& size, double time, bool lowQualityScale)
    61         : m_size(size)
    62         , m_time(time)
    63         , m_lowQualityScale(lowQualityScale)
    64         , m_highQualityRepaintTimer(image, &RenderImage::highQualityRepaintTimerFired)
    65     {
    66     }
    67 
    68     ~RenderImageScaleData()
    69     {
    70         m_highQualityRepaintTimer.stop();
    71     }
    72    
    73     const IntSize& size() const { return m_size; }
    74     double time() const { return m_time; }
    75     bool useLowQualityScale() const { return m_lowQualityScale; }
    76     Timer<RenderImage>& hiqhQualityRepaintTimer() { return m_highQualityRepaintTimer; }
    77 
    78     void setSize(const IntSize& s) { m_size = s; }
    79     void setTime(double t) { m_time = t; }
    80     void setUseLowQualityScale(bool b)
    81     {
    82         m_highQualityRepaintTimer.stop();
    83         m_lowQualityScale = b;
    84         if (b)
    85             m_highQualityRepaintTimer.startOneShot(cLowQualityTimeThreshold);
    86     }
    87    
    88 private:
    89     IntSize m_size;
    90     double m_time;
    91     bool m_lowQualityScale;
    92     Timer<RenderImage> m_highQualityRepaintTimer;
    93 };
    94 
    95 class RenderImageScaleObserver {
    96 public:
    97     static bool shouldImagePaintAtLowQuality(RenderImage*, const IntSize&);
    98 
    99     static void imageDestroyed(RenderImage* image)
    100     {
    101         if (gImages) {
    102             RenderImageScaleData* data = gImages->take(image);
    103             delete data;
    104             if (gImages->size() == 0) {
    105                 delete gImages;
    106                 gImages = 0;
    107             }
    108         }
    109     }
    110    
    111     static void highQualityRepaintTimerFired(RenderImage* image)
    112     {
    113         RenderImageScaleObserver::imageDestroyed(image);
    114         image->repaint();
    115     }
    116    
    117     static HashMap<RenderImage*, RenderImageScaleData*>* gImages;
    118 };
    119 
    120 bool RenderImageScaleObserver::shouldImagePaintAtLowQuality(RenderImage* image, const IntSize& size)
    121 {
    122     // If the image is not a bitmap image, then none of this is relevant and we just paint at high
    123     // quality.
    124     if (!image->image() || !image->image()->isBitmapImage())
    125         return false;
    126 
    127     // Make sure to use the unzoomed image size, since if a full page zoom is in effect, the image
    128     // is actually being scaled.
    129     IntSize imageSize(image->image()->width(), image->image()->height());
    130 
    131     // Look ourselves up in the hashtable.
    132     RenderImageScaleData* data = 0;
    133     if (gImages)
    134         data = gImages->get(image);
    135 
    136     if (imageSize == size) {
    137         // There is no scale in effect.  If we had a scale in effect before, we can just delete this data.
    138         if (data) {
    139             gImages->remove(image);
    140             delete data;
    141         }
    142         return false;
    143     }
    144 
    145     // There is no need to hash scaled images that always use low quality mode when the page demands it.  This is the iChat case.
    146     if (image->document()->page()->inLowQualityImageInterpolationMode()) {
    147         double totalPixels = static_cast<double>(image->image()->width()) * static_cast<double>(image->image()->height());
    148         if (totalPixels > cInterpolationCutoff)
    149             return true;
    150     }
    151 
    152     // If there is no data yet, we will paint the first scale at high quality and record the paint time in case a second scale happens
    153     // very soon.
    154     if (!data) {
    155         data = new RenderImageScaleData(image, size, currentTime(), false);
    156         if (!gImages)
    157             gImages = new HashMap<RenderImage*, RenderImageScaleData*>;
    158         gImages->set(image, data);
    159         return false;
    160     }
    161 
    162     // We are scaled, but we painted already at this size, so just keep using whatever mode we last painted with.
    163     if (data->size() == size)
    164         return data->useLowQualityScale();
    165 
    166     // We have data and our size just changed.  If this change happened quickly, go into low quality mode and then set a repaint
    167     // timer to paint in high quality mode.  Otherwise it is ok to just paint in high quality mode.
    168     double newTime = currentTime();
    169     data->setUseLowQualityScale(newTime - data->time() < cLowQualityTimeThreshold);
    170     data->setTime(newTime);
    171     data->setSize(size);
    172     return data->useLowQualityScale();
    173 }
    174 
    175 HashMap<RenderImage*, RenderImageScaleData*>* RenderImageScaleObserver::gImages = 0;
    176 
    177 void RenderImage::highQualityRepaintTimerFired(Timer<RenderImage>*)
    178 {
    179     RenderImageScaleObserver::highQualityRepaintTimerFired(this);
    180 }
    181 
    18256using namespace HTMLNames;
    18357
     
    19569    if (m_cachedImage)
    19670        m_cachedImage->removeClient(this);
    197     RenderImageScaleObserver::imageDestroyed(this);
    19871}
    19972
     
    488361    HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
    489362    CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
    490     bool useLowQualityScaling = RenderImageScaleObserver::shouldImagePaintAtLowQuality(this, rect.size());
     363    bool useLowQualityScaling = shouldPaintAtLowQuality(context, this->image(), rect.size());
    491364    context->drawImage(image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
    492365}
Note: See TracChangeset for help on using the changeset viewer.