Backout rev 4fe82d0824d1 (bug 946658) for suspected Tp5 regression. r=me
authorMats Palmgren <matspal@gmail.com>
Fri, 07 Mar 2014 18:40:58 +0000
changeset 189779 d1c54bc2bb7183795827426dd8fd6ec4f2986cf5
parent 189778 4528bce55006e736340d870b97bc59a228f3c5a3
child 189780 c9f09336bc6c6d350dbffb0f9eba2d0e41a8bb62
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs946658
milestone30.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
Backout rev 4fe82d0824d1 (bug 946658) for suspected Tp5 regression. r=me
view/public/nsViewManager.h
view/src/nsViewManager.cpp
--- a/view/public/nsViewManager.h
+++ b/view/public/nsViewManager.h
@@ -7,17 +7,16 @@
 #define nsViewManager_h___
 
 #include "nscore.h"
 #include "nsView.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsVoidArray.h"
 #include "nsDeviceContext.h"
-#include "nsTArray.h"
 #include "mozilla/EventForwards.h"
 
 class nsIWidget;
 struct nsRect;
 class nsRegion;
 class nsDeviceContext;
 class nsIPresShell;
 
@@ -323,20 +322,16 @@ private:
   static uint32_t gLastUserEventTime;
 
   /* Update the cached RootViewManager pointer on this view manager. */
   void InvalidateHierarchy();
   void FlushPendingInvalidates();
 
   void ProcessPendingUpdatesForView(nsView *aView,
                                     bool aFlushDirtyRegion = true);
-  void ProcessPendingUpdatesRecurse(nsView* aView,
-                                    nsTArray<nsCOMPtr<nsIWidget> >& aWidgets);
-  void ProcessPendingUpdatesPaint(nsIWidget* aWidget);
-
   void FlushDirtyRegionToWidget(nsView* aView);
   /**
    * Call WillPaint() on all view observers under this vm root.
    */
   void CallWillPaintOnObservers();
   void ReparentChildWidgets(nsView* aView, nsIWidget *aNewWidget);
   void ReparentWidgets(nsView* aView, nsView *aParent);
   void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -361,114 +361,84 @@ void nsViewManager::Refresh(nsView *aVie
   }
 
   if (RootViewManager()->mRecursiveRefreshPending) {
     RootViewManager()->mRecursiveRefreshPending = false;
     InvalidateAllViews();
   }
 }
 
-void
-nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
-                                            bool aFlushDirtyRegion)
+void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
+                                                 bool aFlushDirtyRegion)
 {
   NS_ASSERTION(IsRootVM(), "Updates will be missed");
-  if (!aView) {
+
+  // Protect against a null-view.
+  nsViewManager* viewManager = aView ? aView->GetViewManager() : nullptr;
+  if (!aView || !viewManager) {
     return;
   }
 
-  nsCOMPtr<nsIPresShell> rootShell(mPresShell);
-  nsTArray<nsCOMPtr<nsIWidget> > widgets;
-  aView->GetViewManager()->ProcessPendingUpdatesRecurse(aView, widgets);
-  for (uint32_t i = 0; i < widgets.Length(); ++i) {
-    nsView* view = nsView::GetViewFor(widgets[i]);
-    if (view) {
-      view->ResetWidgetBounds(false, true);
-    }
-  }
-  if (rootShell->GetViewManager() != this) {
-    return; // 'this' might have been destroyed
-  }
-  if (aFlushDirtyRegion) {
-    nsAutoScriptBlocker scriptBlocker;
-    SetPainting(true);
-    for (uint32_t i = 0; i < widgets.Length(); ++i) {
-      nsIWidget* widget = widgets[i];
-      nsView* view = nsView::GetViewFor(widget);
-      if (view) {
-        view->GetViewManager()->ProcessPendingUpdatesPaint(widget);
-      }
-    }
-    SetPainting(false);
-  }
-}
-
-void
-nsViewManager::ProcessPendingUpdatesRecurse(nsView* aView,
-                                            nsTArray<nsCOMPtr<nsIWidget> >& aWidgets)
-{
-  if (mPresShell && mPresShell->IsNeverPainting()) {
+  nsIPresShell* presShell = viewManager->mPresShell;
+  if (presShell && presShell->IsNeverPainting()) {
     return;
   }
 
+  if (aView->HasWidget()) {
+    aView->ResetWidgetBounds(false, true);
+  }
+
+  // process pending updates in child view.
   for (nsView* childView = aView->GetFirstChild(); childView;
        childView = childView->GetNextSibling()) {
-    childView->GetViewManager()->
-      ProcessPendingUpdatesRecurse(childView, aWidgets);
+    ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
   }
 
-  nsIWidget* widget = aView->GetWidget();
-  if (widget) {
-    aWidgets.AppendElement(widget);
-  } else {
-    FlushDirtyRegionToWidget(aView);
-  }
-}
+  // 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 && widget->NeedsPaint()) {
+      // If an ancestor widget was hidden and then shown, we could
+      // have a delayed resize to handle.
+      for (nsViewManager *vm = viewManager; vm;
+           vm = vm->mRootView->GetParent()
+                  ? vm->mRootView->GetParent()->GetViewManager()
+                  : nullptr) {
+        if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
+            vm->mRootView->IsEffectivelyVisible() &&
+            vm->mPresShell && vm->mPresShell->IsVisible()) {
+          vm->FlushDelayedResize(true);
+        }
+      }
+      NS_ASSERTION(aView->HasWidget(), "FlushDelayedResize removed our widget!");
 
-void
-nsViewManager::ProcessPendingUpdatesPaint(nsIWidget* aWidget)
-{
-  if (aWidget->NeedsPaint()) {
-    // If an ancestor widget was hidden and then shown, we could
-    // have a delayed resize to handle.
-    for (nsViewManager *vm = this; vm;
-         vm = vm->mRootView->GetParent()
-           ? vm->mRootView->GetParent()->GetViewManager()
-           : nullptr) {
-      if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
-          vm->mRootView->IsEffectivelyVisible() &&
-          vm->mPresShell && vm->mPresShell->IsVisible()) {
-        vm->FlushDelayedResize(true);
-      }
-    }
-    nsView* view = nsView::GetViewFor(aWidget);
-    if (!view) {
-      NS_ERROR("FlushDelayedResize destroyed the nsView?");
-      return;
-    }
-
-    if (mPresShell) {
+      if (presShell) {
 #ifdef MOZ_DUMP_PAINTING
-      if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf_stderr("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n",
-                      mPresShell, view, aWidget);
-      }
+        if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
+          printf_stderr("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", presShell, aView, widget);
+        }
+#endif
+        nsAutoScriptBlocker scriptBlocker;
+        SetPainting(true);
+        presShell->Paint(aView, nsRegion(), nsIPresShell::PAINT_LAYERS);
+#ifdef MOZ_DUMP_PAINTING
+        if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
+          printf_stderr("---- PAINT END ----\n");
+        }
 #endif
 
-      mPresShell->Paint(view, nsRegion(), nsIPresShell::PAINT_LAYERS);
-      view->SetForcedRepaint(false);
-
-#ifdef MOZ_DUMP_PAINTING
-      if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf_stderr("---- PAINT END ----\n");
+        aView->SetForcedRepaint(false);
+        SetPainting(false);
       }
-#endif
+      viewManager->FlushDirtyRegionToWidget(aView);
+    } else {
+      viewManager->FlushDirtyRegionToWidget(aView);
     }
   }
-  FlushDirtyRegionToWidget(nsView::GetViewFor(aWidget));
 }
 
 void nsViewManager::FlushDirtyRegionToWidget(nsView* aView)
 {
   NS_ASSERTION(aView->GetViewManager() == this,
                "FlushDirtyRegionToWidget called on view we don't own");
 
   if (!aView->HasNonEmptyDirtyRegion())