Bug 539356 - Part 13 - Only repaint widgets that have had changes since the last paint. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Sat, 30 Jun 2012 15:06:12 +1200
changeset 98016 d9f3358435ba92c61829714d842ae8d8d637ba68
parent 98015 ce5e9fefee191532a6164c7c697b6b97d2a699ae
child 98017 0c75abcb72ff937cdd7b36cd5217100d08ba2fbc
push id23017
push userryanvm@gmail.com
push dateSat, 30 Jun 2012 19:29:24 +0000
treeherdermozilla-central@4c2ddc60f360 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs539356
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 539356 - Part 13 - Only repaint widgets that have had changes since the last paint. r=roc
layout/generic/nsFrame.cpp
view/src/nsViewManager.cpp
widget/nsIWidget.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4658,16 +4658,20 @@ nsIFrame::SchedulePaint(PRUint32 aFlags)
     nsIFrame *displayRoot = nsLayoutUtils::GetDisplayRootFrame(this);
     NS_ASSERTION(displayRoot, "Need a display root to schedule a paint!");
     if (!displayRoot) {
       return;
     }
     pres = displayRoot->PresContext();
   }
   pres->PresShell()->ScheduleViewManagerFlush(aFlags);
+  nsIWidget *widget = GetNearestWidget();
+  if (widget) {
+    widget->SetNeedsPaint(true);
+  }
 }
 
 Layer*
 nsIFrame::InvalidateLayer(PRUint32 aDisplayItemKey, const nsIntRect* aDamageRect)
 {
   NS_ASSERTION(aDisplayItemKey > 0, "Need a key");
 
   Layer* layer = FrameLayerBuilder::GetDedicatedLayer(this, aDisplayItemKey);
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -373,17 +373,18 @@ void nsViewManager::ProcessPendingUpdate
        childView = childView->GetNextSibling()) {
     ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
   }
 
   // Push out updates after we've processed the children; ensures that
   // damage is applied based on the final widget geometry
   if (aFlushDirtyRegion) {
     nsIWidget *widget = aView->GetWidget();
-    if (widget) {
+    if (widget && widget->NeedsPaint()) {
+      widget->SetNeedsPaint(false);
 #ifdef DEBUG_INVALIDATIONS
       printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
 #endif
       nsAutoScriptBlocker scriptBlocker;
       mPresShell->Paint(aView, nsRegion(), nsIPresShell::PaintType_NoComposite, false);
 #ifdef DEBUG_INVALIDATIONS
       printf("---- PAINT END ----\n");
 #endif
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -382,16 +382,17 @@ class nsIWidget : public nsISupports {
       { }
     };
 
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWIDGET_IID)
 
     nsIWidget()
       : mLastChild(nsnull)
       , mPrevSibling(nsnull)
+      , mNeedsPaint(false)
     {}
 
         
     /**
      * Create and initialize a widget. 
      *
      * All the arguments can be NULL in which case a top level window
      * with size 0 is created. The event callback function has to be
@@ -1565,25 +1566,33 @@ class nsIWidget : public nsISupports {
 
     /**
      * Returns true to indicate that this widget paints an opaque background
      * that we want to be visible under the page, so layout should not force
      * a default background.
      */
     virtual bool WidgetPaintsBackground() { return false; }
 
+    void SetNeedsPaint(bool aNeedsPaint) { mNeedsPaint = aNeedsPaint; }
+    bool NeedsPaint() { 
+      if (!mNeedsPaint) {
+        return false;
+      }
+      return true;
+    }
 protected:
 
     // keep the list of children.  We also keep track of our siblings.
     // The ownership model is as follows: parent holds a strong ref to
     // the first element of the list, and each element holds a strong
     // ref to the next element in the list.  The prevsibling and
     // lastchild pointers are weak, which is fine as long as they are
     // maintained properly.
     nsCOMPtr<nsIWidget> mFirstChild;
     nsIWidget* mLastChild;
     nsCOMPtr<nsIWidget> mNextSibling;
     nsIWidget* mPrevSibling;
+    bool mNeedsPaint;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIWidget, NS_IWIDGET_IID)
 
 #endif // nsIWidget_h__