Optimize painting for HTMLProgressElement
authoryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Mar 2010 21:02:51 +0000 (21:02 +0000)
committeryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Mar 2010 21:02:51 +0000 (21:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=36113
Cache the progress bar's position, so it is not required to recalculate
it for each repaint.
Call repaintRectangle() when the position changes.

Reviewed by Darin Adler.

No new tests, as no new functionality introduced.

* html/HTMLProgressElement.cpp:
* platform/qt/RenderThemeQt.cpp:
* platform/qt/RenderThemeQt.h:
* rendering/RenderProgress.cpp:
* rendering/RenderProgress.h:
* rendering/RenderTheme.cpp:
* rendering/RenderTheme.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@56126 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/html/HTMLProgressElement.cpp
WebCore/platform/qt/RenderThemeQt.cpp
WebCore/platform/qt/RenderThemeQt.h
WebCore/rendering/RenderProgress.cpp
WebCore/rendering/RenderProgress.h
WebCore/rendering/RenderTheme.cpp
WebCore/rendering/RenderTheme.h

index 0c4cd0f..97b5205 100644 (file)
@@ -1,3 +1,30 @@
+2010-03-17  Yael Aharon  <yael.aharon@nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Optimize painting for HTMLProgressElement
+        https://bugs.webkit.org/show_bug.cgi?id=36113
+        Cache the progress bar's position, so it is not required to recalculate
+        it for each repaint. 
+        Call repaintRectangle() when the position changes.
+
+        No new tests, as no new functionality introduced.
+
+        * html/HTMLProgressElement.cpp:
+        (WebCore::HTMLProgressElement::parseMappedAttribute):
+        * platform/qt/RenderThemeQt.cpp:
+        (WebCore::RenderThemeQt::getNumberOfPixelsForProgressPosition):
+        (WebCore::RenderThemeQt::paintProgressBar):
+        * platform/qt/RenderThemeQt.h:
+        * rendering/RenderProgress.cpp:
+        (WebCore::RenderProgress::RenderProgress):
+        (WebCore::RenderProgress::updateFromElement):
+        * rendering/RenderProgress.h:
+        (WebCore::RenderProgress::position):
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::getNumberOfPixelsForProgressPosition):
+        * rendering/RenderTheme.h:
+
 2010-03-17  Antonio Gomes  <tonikitoo@webkit.org>
 
         Mac Buildfix: Using ASSERT_UNUSED instead of ASSERT.
index 95b9391..132fcde 100644 (file)
@@ -58,11 +58,13 @@ const AtomicString& HTMLProgressElement::formControlType() const
 
 void HTMLProgressElement::parseMappedAttribute(MappedAttribute* attribute)
 {
-    if (attribute->name() == valueAttr)
-        setNeedsStyleRecalc();
-    else if (attribute->name() == maxAttr)
-        setNeedsStyleRecalc();
-    else
+    if (attribute->name() == valueAttr) {
+        if (renderer())
+            renderer()->updateFromElement();
+    } else if (attribute->name() == maxAttr) {
+        if (renderer())
+            renderer()->updateFromElement();
+    } else
         HTMLFormControlElement::parseMappedAttribute(attribute);
 }
 
index 8fe653a..653c946 100644 (file)
@@ -41,9 +41,6 @@
 #include "GraphicsContext.h"
 #include "HTMLInputElement.h"
 #include "HTMLMediaElement.h"
-#if ENABLE(PROGRESS_TAG)
-#include "HTMLProgressElement.h"
-#endif
 #include "HTMLNames.h"
 #include "NotImplemented.h"
 #include "Page.h"
@@ -642,6 +639,12 @@ bool RenderThemeQt::paintMenuListButton(RenderObject* o, const RenderObject::Pai
 }
 
 #if ENABLE(PROGRESS_TAG)
+bool RenderThemeQt::getNumberOfPixelsForProgressPosition(double position, int& progressSize) const
+{
+    progressSize = 65536 * position;
+    return false;
+}
+
 void RenderThemeQt::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
 {
     style->setBoxShadow(0);
@@ -659,11 +662,10 @@ bool RenderThemeQt::paintProgressBar(RenderObject* o, const RenderObject::PaintI
     initializeCommonQStyleOptions(option, o);
 
     RenderProgress* renderProgress = toRenderProgress(o);
-    HTMLProgressElement* element = static_cast<HTMLProgressElement*>(renderProgress->node());
     option.rect = r;
-    option.maximum = element->max();
+    option.maximum = 65536;
     option.minimum = 0;
-    option.progress = element->value();
+    option.progress = renderProgress->position();
 
     const QPoint topLeft = r.topLeft();
     p.painter->translate(topLeft);
index 5c0e53f..fcdad29 100644 (file)
@@ -124,6 +124,13 @@ protected:
     virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
     virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
 
+#if ENABLE(PROGRESS_TAG)
+    // Helper method for optimizing the paint area of the progress bar.
+    // If supported, it returns number of pixels needed to draw the progress bar up to the progress position.
+    // progressSize is the value that is passed back to RenderTheme during drawing.
+    virtual bool getNumberOfPixelsForProgressPosition(double position, int& progressSize) const;
+#endif
+
 #if ENABLE(VIDEO)
     virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
     virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
index 985e97a..8a57612 100644 (file)
@@ -37,6 +37,7 @@ static const int defaultProgressHeight = 20;
 
 RenderProgress::RenderProgress(HTMLProgressElement* element)
     : RenderBlock(element)
+    , m_position(-1)
 {
     setSize(IntSize(defaultProgressWidth, defaultProgressHeight));
     setReplaced(true);
@@ -95,7 +96,22 @@ void RenderProgress::layout()
 
 void RenderProgress::updateFromElement()
 {
-    setNeedsLayoutAndPrefWidthsRecalc();
+    HTMLProgressElement* element = static_cast<HTMLProgressElement*>(node());
+    double position = element->position();
+    int oldPosition = m_position;
+    bool canOptimize = theme()->getNumberOfPixelsForProgressPosition(position, m_position);
+    if (oldPosition == m_position)
+        return;
+
+    IntRect paintRect = contentBoxRect();
+    if (canOptimize) {
+        // FIXME: Need to handle indeterminate progress bar and RTL
+        int adjustedPosition = (m_position >= 0) ? m_position : 0;
+        int adjustedOldPosition = (oldPosition >= 0) ? oldPosition : 0;
+        paintRect.setX(std::min(adjustedPosition, adjustedOldPosition));
+        paintRect.setWidth(std::max(adjustedPosition, adjustedOldPosition) - paintRect.x());
+    }
+    repaintRectangle(paintRect);
 }
 
 } // namespace WebCore
index ee60d9d..0a90fde 100644 (file)
@@ -31,6 +31,7 @@ class HTMLProgressElement;
 class RenderProgress : public RenderBlock {
 public:
     RenderProgress(HTMLProgressElement*);
+    int position() { return m_position; }
 
 private:
     virtual const char* renderName() const { return "RenderProgress"; }
@@ -39,6 +40,7 @@ private:
     virtual void calcPrefWidths();
     virtual void layout();
     virtual void updateFromElement();
+    int m_position;
 };
 
 inline RenderProgress* toRenderProgress(RenderObject* object)
index ffa3eb7..7c284a6 100644 (file)
@@ -840,6 +840,12 @@ void RenderTheme::adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*)
 }
 
 #if ENABLE(PROGRESS_TAG)
+bool RenderTheme::getNumberOfPixelsForProgressPosition(double , int& progressSize) const
+{
+    progressSize = 0;
+    return false;
+}
+
 void RenderTheme::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const
 {
 }
index 30c48d1..fbdf910 100644 (file)
@@ -169,6 +169,13 @@ public:
     // Method for painting the caps lock indicator
     virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return 0; };
 
+#if ENABLE(PROGRESS_TAG)
+    // Helper method for optimizing the paint area of the progress bar.
+    // If supported, it returns number of pixels needed to draw the progress bar up to the progress position.
+    // progressSize is the value that is passed back to RenderTheme during drawing.
+    virtual bool getNumberOfPixelsForProgressPosition(double position, int& progressSize) const;
+#endif
+
 #if ENABLE(VIDEO)
     // Media controls
     virtual bool hitTestMediaControlPart(RenderObject*, const IntPoint& absPoint);