Back out eb80ab6ee07b (bug 721627) and 06d02e7132b2 (bug 721294) for orange and red
authorPhil Ringnalda <philringnalda@gmail.com>
Fri, 27 Jan 2012 20:31:29 -0800
changeset 86873 d68b6a9939d8d52f49cd8d9f06dd49968c65a5f9
parent 86872 024b7dac0eaf9d03dda150f826111d66d0a01c7e
child 86874 22986f29b1bdc66cea2bfca45bc35552b6a73108
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs721627, 721294
milestone12.0a1
backs outeb80ab6ee07b7316fe51227659fa4158221bd17d
Back out eb80ab6ee07b (bug 721627) and 06d02e7132b2 (bug 721294) for orange and red
layout/base/FrameLayerBuilder.cpp
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/generic/nsImageFrame.cpp
layout/generic/nsImageFrame.h
view/src/nsViewManager.cpp
view/src/nsViewManager.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -214,17 +214,17 @@ protected:
                     const FrameLayerBuilder::Clip& aClip);
     nsIFrame* GetActiveScrolledRoot() { return mActiveScrolledRoot; }
 
     /**
      * If this represents only a nsDisplayImage, and the image type
      * supports being optimized to an ImageLayer (TYPE_RASTER only) returns
      * an ImageContainer for the image.
      */
-    already_AddRefed<ImageContainer> CanOptimizeImageLayer(LayerManager* aManager);
+    nsRefPtr<ImageContainer> CanOptimizeImageLayer(LayerManager* aManager);
 
     /**
      * The region of visible content in the layer, relative to the
      * container layer (which is at the snapped top-left of the display
      * list reference frame).
      */
     nsIntRegion  mVisibleRegion;
     /**
@@ -963,17 +963,17 @@ ContainerState::FindOpaqueBackgroundColo
       target->mVisibleRegion.GetBounds().ToAppUnits(appUnitsPerDevPixel);
     rect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale);
     return mBuilder->LayerBuilder()->
       FindOpaqueColorCovering(mBuilder, candidate->mLayer, rect);
   }
   return NS_RGBA(0,0,0,0);
 }
 
-already_AddRefed<ImageContainer>
+nsRefPtr<ImageContainer>
 ContainerState::ThebesLayerData::CanOptimizeImageLayer(LayerManager* aManager)
 {
   if (!mImage || !mImageClip.mRoundedClipRects.IsEmpty()) {
     return nsnull;
   }
 
   return mImage->GetContainer(aManager);
 }
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -138,18 +138,18 @@ typedef struct CapturingContentInfo {
   // capture should only be allowed during a mousedown event
   bool mAllowed;
   bool mRetargetToElement;
   bool mPreventDrag;
   nsIContent* mContent;
 } CapturingContentInfo;
 
 #define NS_IPRESSHELL_IID    \
-        { 0x87acd089, 0x8da7, 0x4438, \
-          { 0xa5, 0xcd, 0x90, 0x1e, 0x5d, 0x8f, 0xd8, 0x19 } }
+{ 0x3ab5b116, 0x2d73, 0x431c, \
+ { 0x9a, 0x4b, 0x6c, 0x91, 0x9e, 0x42, 0x45, 0xc3 } }
 
 // Constants for ScrollContentIntoView() function
 #define NS_PRESSHELL_SCROLL_TOP      0
 #define NS_PRESSHELL_SCROLL_BOTTOM   100
 #define NS_PRESSHELL_SCROLL_LEFT     0
 #define NS_PRESSHELL_SCROLL_RIGHT    100
 #define NS_PRESSHELL_SCROLL_CENTER   50
 #define NS_PRESSHELL_SCROLL_ANYWHERE -1
@@ -1140,31 +1140,23 @@ public:
    * Dispatch a mouse move event based on the most recent mouse position if
    * this PresShell is visible. This is used when the contents of the page
    * moved (aFromScroll is false) or scrolled (aFromScroll is true).
    */
   virtual void SynthesizeMouseMove(bool aFromScroll) = 0;
 
   virtual void Paint(nsIView* aViewToPaint, nsIWidget* aWidget,
                      const nsRegion& aDirtyRegion, const nsIntRegion& aIntDirtyRegion,
-                     bool aWillSendDidPaint) = 0;
+                     bool aPaintDefaultBackground, bool aWillSendDidPaint) = 0;
   virtual nsresult HandleEvent(nsIFrame*       aFrame,
                                nsGUIEvent*     aEvent,
                                bool            aDontRetargetEvents,
                                nsEventStatus*  aEventStatus) = 0;
   virtual bool ShouldIgnoreInvalidation() = 0;
-  /**
-   * Notify that the NS_WILL_PAINT event was received. Fires on every
-   * visible presshell in the document tree.
-   */
   virtual void WillPaint(bool aWillSendDidPaint) = 0;
-  /**
-   * Notify that the NS_DID_PAINT event was received. Only fires on the
-   * root pres shell.
-   */
   virtual void DidPaint() = 0;
   virtual void ScheduleViewManagerFlush() = 0;
   virtual void ClearMouseCaptureOnView(nsIView* aView) = 0;
   virtual bool IsVisible() = 0;
   virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) = 0;
 
   /**
    * Refresh observer management.
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5422,16 +5422,17 @@ PresShell::ProcessSynthMouseMoveEvent(bo
   }
 }
 
 void
 PresShell::Paint(nsIView*           aViewToPaint,
                  nsIWidget*         aWidgetToPaint,
                  const nsRegion&    aDirtyRegion,
                  const nsIntRegion& aIntDirtyRegion,
+                 bool               aPaintDefaultBackground,
                  bool               aWillSendDidPaint)
 {
 #ifdef NS_FUNCTION_TIMER
   NS_TIME_FUNCTION_DECLARE_DOCURL;
   const nsRect& bounds__ = aDirtyRegion.GetBounds();
   NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (document: %s, dirty rect: (<%f, %f>, <%f, %f>)",
                            MOZ_FUNCTION_NAME, __LINE__, docURL__.get(),
                            NSCoordToFloat(bounds__.x),
@@ -5443,17 +5444,17 @@ PresShell::Paint(nsIView*           aVie
   SAMPLE_LABEL("Paint", "PresShell::Paint");
   NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
   NS_ASSERTION(aViewToPaint, "null view");
   NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
 
   nsPresContext* presContext = GetPresContext();
   AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
 
-  nsIFrame* frame = aViewToPaint->GetFrame();
+  nsIFrame* frame = aPaintDefaultBackground ? nsnull : aViewToPaint->GetFrame();
 
   bool isRetainingManager;
   LayerManager* layerManager =
     aWidgetToPaint->GetLayerManager(&isRetainingManager);
   NS_ASSERTION(layerManager, "Must be in paint event");
   layerManager->BeginTransaction();
 
   if (frame && isRetainingManager) {
@@ -5482,16 +5483,19 @@ PresShell::Paint(nsIView*           aVie
   if (frame) {
     // Defer invalidates that are triggered during painting, and discard
     // invalidates of areas that are already being repainted.
     // The layer system can trigger invalidates during painting
     // (see FrameLayerBuilder).
     frame->BeginDeferringInvalidatesForDisplayRoot(aDirtyRegion);
 
     // We can paint directly into the widget using its layer manager.
+    // When we get rid of child widgets, this will be the only path we
+    // need. (aPaintDefaultBackground will never be needed since the
+    // chrome can always paint a default background.)
     nsLayoutUtils::PaintFrame(nsnull, frame, aDirtyRegion, bgcolor,
                               nsLayoutUtils::PAINT_WIDGET_LAYERS |
                               nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
 
     frame->EndDeferringInvalidatesForDisplayRoot();
     presContext->NotifyDidPaintForSubtree();
     return;
   }
@@ -7199,21 +7203,20 @@ PresShell::WillPaint(bool aWillSendDidPa
 
 void
 PresShell::DidPaint()
 {
   if (mPaintingSuppressed || !mIsActive || !IsVisible()) {
     return;
   }
 
-  NS_ASSERTION(mPresContext->IsRoot(), "Should only call DidPaint on root presshells");
-
   nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
-  // This should only be called on root presshells, but maybe if a document
-  // tree is torn down we might not be a root presshell...
+  if (!rootPresContext) {
+    return;
+  }
   if (rootPresContext == mPresContext) {
     rootPresContext->UpdatePluginGeometry();
   }
 }
 
 bool
 PresShell::IsVisible()
 {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -311,17 +311,17 @@ public:
   virtual void SetDisplayPort(const nsRect& aDisplayPort);
 
   virtual nsresult SetResolution(float aXResolution, float aYResolution);
 
   //nsIViewObserver interface
 
   virtual void Paint(nsIView* aViewToPaint, nsIWidget* aWidget,
                      const nsRegion& aDirtyRegion, const nsIntRegion& aIntDirtyRegion,
-                     bool aWillSendDidPaint);
+                     bool aPaintDefaultBackground, bool aWillSendDidPaint);
   virtual nsresult HandleEvent(nsIFrame*       aFrame,
                                nsGUIEvent*     aEvent,
                                bool            aDontRetargetEvents,
                                nsEventStatus*  aEventStatus);
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsEvent* aEvent,
                                                         nsEventStatus* aStatus);
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1205,23 +1205,29 @@ nsDisplayImage::Paint(nsDisplayListBuild
                       nsRenderingContext* aCtx) {
   static_cast<nsImageFrame*>(mFrame)->
     PaintImage(*aCtx, ToReferenceFrame(), mVisibleRect, mImage,
                aBuilder->ShouldSyncDecodeImages()
                  ? (PRUint32) imgIContainer::FLAG_SYNC_DECODE
                  : (PRUint32) imgIContainer::FLAG_NONE);
 }
 
-already_AddRefed<ImageContainer>
+nsCOMPtr<imgIContainer>
+nsDisplayImage::GetImage()
+{
+  return mImage;
+}
+
+nsRefPtr<ImageContainer>
 nsDisplayImage::GetContainer(LayerManager* aManager)
 {
-  nsRefPtr<ImageContainer> container;
-  nsresult rv = mImage->GetImageContainer(aManager, getter_AddRefs(container));
-  NS_ENSURE_SUCCESS(rv, nsnull);
-  return container.forget();
+  ImageContainer* container;
+  nsresult rv = mImage->GetImageContainer(aManager, &container);
+  NS_ENSURE_SUCCESS(rv, NULL);
+  return container;
 }
 
 void
 nsDisplayImage::ConfigureLayer(ImageLayer* aLayer)
 {
   aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
   
   PRInt32 factor = mFrame->PresContext()->AppUnitsPerDevPixel();
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -381,22 +381,23 @@ public:
     : nsDisplayItem(aBuilder, aFrame), mImage(aImage) {
     MOZ_COUNT_CTOR(nsDisplayImage);
   }
   virtual ~nsDisplayImage() {
     MOZ_COUNT_DTOR(nsDisplayImage);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx);
+  nsCOMPtr<imgIContainer> GetImage();
  
   /**
    * Returns an ImageContainer for this image if the image type
    * supports it (TYPE_RASTER only).
    */
-  already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager);
+  nsRefPtr<ImageContainer> GetContainer(LayerManager* aManager);
   
   /**
    * Configure an ImageLayer for this display item.
    * Set the required filter and scaling transform.
    */
   void ConfigureLayer(ImageLayer* aLayer);
 
   NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -332,18 +332,17 @@ nsIView* nsIViewManager::GetDisplayRootF
 }
 
 /**
    aRegion is given in device coordinates!!
    aContext may be null, in which case layers should be used for
    rendering.
 */
 void nsViewManager::Refresh(nsView *aView, nsIWidget *aWidget,
-                            const nsIntRegion& aRegion,
-                            bool aWillSendDidPaint)
+                            const nsIntRegion& aRegion)
 {
   NS_ASSERTION(aView == nsView::GetViewFor(aWidget), "view widget mismatch");
   NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
 
   // damageRegion is the damaged area, in twips, relative to the view origin
   nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel());
   // move region from widget coordinates into view coordinates
   damageRegion.MoveBy(-aView->ViewToWidgetOffset());
@@ -364,34 +363,44 @@ void nsViewManager::Refresh(nsView *aVie
     RootViewManager()->mRecursiveRefreshPending = true;
     return;
   }  
 
   {
     nsAutoScriptBlocker scriptBlocker;
     SetPainting(true);
 
-    NS_ASSERTION(GetDisplayRootFor(aView) == aView,
-                 "Widgets that we paint must all be display roots");
-
-    if (mPresShell) {
-      mPresShell->Paint(aView, aWidget, damageRegion, aRegion,
-                        aWillSendDidPaint);
-      mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
-    }
+    RenderViews(aView, aWidget, damageRegion, aRegion, false, false);
 
     SetPainting(false);
   }
 
   if (RootViewManager()->mRecursiveRefreshPending) {
     RootViewManager()->mRecursiveRefreshPending = false;
     InvalidateAllViews();
   }
 }
 
+// aRC and aRegion are in view coordinates
+void nsViewManager::RenderViews(nsView *aView, nsIWidget *aWidget,
+                                const nsRegion& aRegion,
+                                const nsIntRegion& aIntRegion,
+                                bool aPaintDefaultBackground,
+                                bool aWillSendDidPaint)
+{
+  NS_ASSERTION(GetDisplayRootFor(aView) == aView,
+               "Widgets that we paint must all be display roots");
+
+  if (mPresShell) {
+    mPresShell->Paint(aView, aWidget, aRegion, aIntRegion,
+                      aPaintDefaultBackground, aWillSendDidPaint);
+    mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
+  }
+}
+
 void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
                                                  bool aFlushDirtyRegion)
 {
   NS_ASSERTION(IsRootVM(), "Updates will be missed");
 
   // Protect against a null-view.
   if (!aView) {
     return;
@@ -805,24 +814,24 @@ NS_IMETHODIMP nsViewManager::DispatchEve
           // destroyed it during CallWillPaintOnObservers (bug 378273).
           view = nsView::GetViewFor(event->widget);
         }
 
         if (!view || event->region.IsEmpty())
           break;
 
         // Paint.
-        Refresh(view, event->widget, event->region, event->willSendDidPaint);
+        Refresh(view, event->widget, event->region);
 
         break;
       }
 
     case NS_DID_PAINT: {
       nsRefPtr<nsViewManager> rootVM = RootViewManager();
-      rootVM->CallDidPaintOnObserver();
+      rootVM->CallDidPaintOnObservers();
       break;
     }
 
     case NS_CREATE:
     case NS_DESTROY:
     case NS_SETZLEVEL:
       /* Don't pass these events through. Passing them through
          causes performance problems on pages with lots of views/frames 
@@ -1383,24 +1392,31 @@ nsViewManager::CallWillPaintOnObservers(
           shell->WillPaint(aWillSendDidPaint);
         }
       }
     }
   }
 }
 
 void
-nsViewManager::CallDidPaintOnObserver()
+nsViewManager::CallDidPaintOnObservers()
 {
   NS_PRECONDITION(IsRootVM(), "Must be root VM for this to be called!");
 
-  if (mRootView && mRootView->IsEffectivelyVisible()) {
-    nsCOMPtr<nsIPresShell> shell = GetPresShell();
-    if (shell) {
-      shell->DidPaint();
+  PRInt32 index;
+  for (index = 0; index < mVMCount; index++) {
+    nsViewManager* vm = (nsViewManager*)gViewManagers->ElementAt(index);
+    if (vm->RootViewManager() == this) {
+      // One of our kids.
+      if (vm->mRootView && vm->mRootView->IsEffectivelyVisible()) {
+        nsCOMPtr<nsIPresShell> shell = vm->GetPresShell();
+        if (shell) {
+          shell->DidPaint();
+        }
+      }
     }
   }
 }
 
 NS_IMETHODIMP
 nsViewManager::GetLastUserEventTime(PRUint32& aTime)
 {
   aTime = gLastUserEventTime;
--- a/view/src/nsViewManager.h
+++ b/view/src/nsViewManager.h
@@ -148,26 +148,30 @@ private:
   void FlushPendingInvalidates();
   void ProcessPendingUpdatesForView(nsView *aView,
                                     bool aFlushDirtyRegion = true);
   void FlushDirtyRegionToWidget(nsView* aView);
   /**
    * Call WillPaint() on all view observers under this vm root.
    */
   void CallWillPaintOnObservers(bool aWillSendDidPaint);
-  void CallDidPaintOnObserver();
+  void CallDidPaintOnObservers();
   void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
   void ReparentWidgets(nsIView* aView, nsIView *aParent);
   void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
 
   void InvalidateViews(nsView *aView);
 
   // aView is the view for aWidget and aRegion is relative to aWidget.
-  void Refresh(nsView *aView, nsIWidget *aWidget, const nsIntRegion& aRegion,
-               bool aWillSendDidPaint);
+  void Refresh(nsView *aView, nsIWidget *aWidget, const nsIntRegion& aRegion);
+  // aRootView is the view for aWidget, aRegion is relative to aRootView, and
+  // aIntRegion is relative to aWidget.
+  void RenderViews(nsView *aRootView, nsIWidget *aWidget,
+                   const nsRegion& aRegion, const nsIntRegion& aIntRegion,
+                   bool aPaintDefaultBackground, bool aWillSendDidPaint);
 
   void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut);
   void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut,
                                           nscoord aY1, nscoord aY2, bool aInCutOut);
 
   // Utilities
 
   bool IsViewInserted(nsView *aView);