Bug 800859. Part 1: Refactor PaintType into two independent flags. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 19 Oct 2012 14:20:39 +1300
changeset 111227 6e108817d0c564adc2ab27ba379f8f85e6e6afde
parent 111226 f18a8893e7ff0fd50bba83427b8ae0eb52ac369a
child 111228 1bf5c18ae382f29e7442aae37dac48a815eb6425
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersmattwoodrow
bugs800859
milestone19.0a1
Bug 800859. Part 1: Refactor PaintType into two independent flags. r=mattwoodrow
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
view/src/nsViewManager.cpp
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -109,20 +109,20 @@ typedef struct CapturingContentInfo {
   // capture should only be allowed during a mousedown event
   bool mAllowed;
   bool mPointerLock;
   bool mRetargetToElement;
   bool mPreventDrag;
   nsIContent* mContent;
 } CapturingContentInfo;
 
-// ebc1bbe4-5456-4c62-ba1f-c2ef7387963e
+// f50f99bc-e178-4e67-89ea-f2aee5923f6d
 #define NS_IPRESSHELL_IID \
-{ 0xebc1bbe4, 0x5456, 0x4c62, \
-  { 0xba, 0x1f, 0xc2, 0xef, 0x73, 0x87, 0x96, 0x3e } }
+{ 0xf50f99bc, 0xe178, 0x4e67, \
+  { 0x89, 0xea, 0xf2, 0xae, 0xe5, 0x92, 0x3f, 0x6d } }
 
 // debug VerifyReflow flags
 #define VERIFY_REFLOW_ON                    0x01
 #define VERIFY_REFLOW_NOISY                 0x02
 #define VERIFY_REFLOW_ALL                   0x04
 #define VERIFY_REFLOW_DUMP_COMMANDS         0x08
 #define VERIFY_REFLOW_NOISY_RC              0x10
 #define VERIFY_REFLOW_REALLY_NOISY_RC       0x20
@@ -1223,49 +1223,55 @@ 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;
 
-  enum PaintType {
-    PaintType_Composite, /* Just composite the layers, don't do ThebesLayer painting. */
-    PaintType_NoComposite, /* Only paint ThebesLayers, don't composite. */
-    PaintType_Full /* Do a full transaction. */
+  enum PaintFlags {
+    /* Update the layer tree and paint ThebesLayers. If this is not specified,
+     * we may still have to do it if the layer tree lost ThebesLayer contents
+     * we need for compositing. */
+    PAINT_LAYERS = 0x01,
+    /* Composite layers to the window. */
+    PAINT_COMPOSITE = 0x02,
+    PAINT_WILL_SEND_DID_PAINT = 0x80
   };
   virtual void Paint(nsIView* aViewToPaint, const nsRegion& aDirtyRegion,
-                     PaintType aType, bool aWillSendDidPaint) = 0;
+                     uint32_t aFlags) = 0;
   virtual nsresult HandleEvent(nsIFrame*       aFrame,
                                nsGUIEvent*     aEvent,
                                bool            aDontRetargetEvents,
                                nsEventStatus*  aEventStatus) = 0;
   virtual bool ShouldIgnoreInvalidation() = 0;
   /**
-   * Notify that we're going to call Paint with PaintType_NoComposite
-   * or PaintType_Full on the root pres shell (which might not be this one, since
-   * WillPaint is called on all descendant presshells). This is issued at a time when
-   * it's safe to modify widget geometry.
+   * Notify that we're going to call Paint with PAINT_LAYERS
+   * on the pres shell for a widget (which might not be this one, since
+   * WillPaint is called on all presshells in the same toplevel window as the
+   * painted widget). This is issued at a time when it's safe to modify
+   * widget geometry.
    */
   virtual void WillPaint(bool aWillSendDidPaint) = 0;
   /**
-   * Notify that we called Paint with PaintType_NoComposite. Only fires on the
-   * root pres shell. This is issued at a time when it's safe to modify
-   * widget geometry.
+   * Notify that we called Paint with PAINT_LAYERS. Only fires on the
+   * pres shell for the painted widget. This is issued at a time when it's
+   * safe to modify widget geometry.
    */
   virtual void DidPaint() = 0;
   /**
-   * Notify that we're going to call Paint with PaintType_Composite
-   * or PaintType_Full.  This is issued at a time when it's safe to
-   * modify widget geometry.
+   * Notify that we're going to call Paint with PAINT_COMPOSITE.
+   * Fires on the presshell for the painted widget.
+   * This is issued at a time when it's safe to modify widget geometry.
    */
   virtual void WillPaintWindow(bool aWillSendDidPaint) = 0;
   /**
-   * Notify that we called Paint with PaintType_Composite or PaintType_Full.
+   * Notify that we called Paint with PAINT_COMPOSITE.
+   * Fires on the presshell for the painted widget.
    * This is issued at a time when it's safe to modify widget geometry.
    */
   virtual void DidPaintWindow() = 0;
 
   /**
    * Ensures that the refresh driver is running, and schedules a view 
    * manager flush on the next tick.
    */
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5227,26 +5227,25 @@ public:
     }
   }
 
 private:
   bool mWillSendDidPaint;
 };
 
 void
-PresShell::Paint(nsIView*           aViewToPaint,
-                 const nsRegion&    aDirtyRegion,
-                 PaintType          aType,
-                 bool               aWillSendDidPaint)
+PresShell::Paint(nsIView*        aViewToPaint,
+                 const nsRegion& aDirtyRegion,
+                 uint32_t        aFlags)
 {
   SAMPLE_LABEL("Paint", "PresShell::Paint");
   NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
   NS_ASSERTION(aViewToPaint, "null view");
 
-  nsAutoNotifyDidPaint notifyDidPaint(aWillSendDidPaint);
+  nsAutoNotifyDidPaint notifyDidPaint((aFlags & PAINT_WILL_SEND_DID_PAINT) != 0);
 
   nsPresContext* presContext = GetPresContext();
   AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
 
   nsIFrame* frame = aViewToPaint->GetFrame();
 
   bool isRetainingManager;
   LayerManager* layerManager =
@@ -5260,17 +5259,17 @@ PresShell::Paint(nsIView*           aVie
 
   if (frame && isRetainingManager) {
     // Try to do an empty transaction, if the frame tree does not
     // need to be updated. Do not try to do an empty transaction on
     // a non-retained layer manager (like the BasicLayerManager that
     // draws the window title bar on Mac), because a) it won't work
     // and b) below we don't want to clear NS_FRAME_UPDATE_LAYER_TREE,
     // that will cause us to forget to update the real layer manager!
-    if (aType == PaintType_Composite) {
+    if (!(aFlags & PAINT_LAYERS)) {
       if (layerManager->HasShadowManager()) {
         return;
       }
       layerManager->BeginTransaction();
       if (layerManager->EndEmptyTransaction()) {
         return;
       }
       NS_WARNING("Must complete empty transaction when compositing!");
@@ -5283,17 +5282,18 @@ PresShell::Paint(nsIView*           aVie
         presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
       bool computeInvalidRect = computeInvalidFunc ||
                                 (layerManager->GetBackendType() == LAYERS_BASIC);
 
       nsAutoPtr<LayerProperties> props(computeInvalidRect ? 
                                          LayerProperties::CloneFrom(layerManager->GetRoot()) : 
                                          nullptr);
 
-      if (layerManager->EndEmptyTransaction((aType == PaintType_NoComposite) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT)) {
+      if (layerManager->EndEmptyTransaction((aFlags & PAINT_COMPOSITE) ?
+            LayerManager::END_DEFAULT : LayerManager::END_NO_COMPOSITE)) {
         nsIntRect invalid;
         if (props) {
           invalid = props->ComputeDifferences(layerManager->GetRoot(), computeInvalidFunc);
         } else {
           LayerProperties::ClearInvalidations(layerManager->GetRoot());
         }
         if (props) {
           if (!invalid.IsEmpty()) {
@@ -5318,52 +5318,51 @@ PresShell::Paint(nsIView*           aVie
     layerManager->BeginTransaction();
   }
   if (frame) {
     frame->ClearPresShellsFromLastPaint();
   }
 
   nscolor bgcolor = ComputeBackstopColor(aViewToPaint);
   uint32_t flags = nsLayoutUtils::PAINT_WIDGET_LAYERS | nsLayoutUtils::PAINT_EXISTING_TRANSACTION;
-  if (aType == PaintType_NoComposite) {
+  if (!(aFlags & PAINT_COMPOSITE)) {
     flags |= nsLayoutUtils::PAINT_NO_COMPOSITE;
   }
 
   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.
     nsLayoutUtils::PaintFrame(nullptr, frame, aDirtyRegion, bgcolor, flags);
 
     frame->EndDeferringInvalidatesForDisplayRoot();
-    if (aType != PaintType_Composite) {
+    if (aFlags & PAINT_LAYERS) {
       presContext->NotifyDidPaintForSubtree();
     }
     return;
   }
 
   nsRefPtr<ColorLayer> root = layerManager->CreateColorLayer();
   if (root) {
     nsPresContext* pc = GetPresContext();
     nsIntRect bounds =
       pc->GetVisibleArea().ToOutsidePixels(pc->AppUnitsPerDevPixel());
     bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
     root->SetColor(bgcolor);
     root->SetVisibleRegion(bounds);
     layerManager->SetRoot(root);
   }
-  layerManager->EndTransaction(NULL, NULL, aType == PaintType_NoComposite ?
-                                             LayerManager::END_NO_COMPOSITE :
-                                             LayerManager::END_DEFAULT);
-
-  if (aType != PaintType_Composite) {
+  layerManager->EndTransaction(NULL, NULL, (aFlags & PAINT_COMPOSITE) ?
+    LayerManager::END_DEFAULT : LayerManager::END_NO_COMPOSITE);
+
+  if (aFlags & PAINT_LAYERS) {
     presContext->NotifyDidPaintForSubtree();
   }
 }
 
 // static
 void
 nsIPresShell::SetCapturingContent(nsIContent* aContent, uint8_t aFlags)
 {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -178,17 +178,17 @@ public:
 
   virtual void SetDisplayPort(const nsRect& aDisplayPort);
 
   virtual nsresult SetResolution(float aXResolution, float aYResolution);
 
   //nsIViewObserver interface
 
   virtual void Paint(nsIView* aViewToPaint, const nsRegion& aDirtyRegion,
-                     PaintType aType, bool aWillSendDidPaint);
+                     uint32_t aFlags);
   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/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -359,21 +359,22 @@ void nsViewManager::Refresh(nsView *aVie
     NS_ASSERTION(GetDisplayRootFor(aView) == aView,
                  "Widgets that we paint must all be display roots");
 
     if (mPresShell) {
 #ifdef DEBUG_INVALIDATIONS
       printf("--COMPOSITE-- %p\n", mPresShell);
 #endif
       if (IsRefreshDriverPaintingEnabled()) {
-        mPresShell->Paint(aView, damageRegion, nsIPresShell::PaintType_Composite,
-                          false);
+        mPresShell->Paint(aView, damageRegion, nsIPresShell::PAINT_COMPOSITE);
       } else {
-        mPresShell->Paint(aView, damageRegion, nsIPresShell::PaintType_Full,
-                          aWillSendDidPaint);
+        mPresShell->Paint(aView, damageRegion,
+                          nsIPresShell::PAINT_LAYERS |
+                          nsIPresShell::PAINT_COMPOSITE |
+                          (aWillSendDidPaint ? nsIPresShell::PAINT_WILL_SEND_DID_PAINT : 0));
       }
 #ifdef DEBUG_INVALIDATIONS
       printf("--ENDCOMPOSITE--\n");
 #endif
       mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
     }
 
     SetPainting(false);
@@ -428,17 +429,19 @@ void nsViewManager::ProcessPendingUpdate
         NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
 
         SetPainting(true);
 #ifdef DEBUG_INVALIDATIONS
         printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
 #endif
         nsAutoScriptBlocker scriptBlocker;
         NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
-        mPresShell->Paint(aView, nsRegion(), nsIPresShell::PaintType_NoComposite, true);
+        mPresShell->Paint(aView, nsRegion(),
+                          nsIPresShell::PAINT_LAYERS |
+                          nsIPresShell::PAINT_WILL_SEND_DID_PAINT);
 #ifdef DEBUG_INVALIDATIONS
         printf("---- PAINT END ----\n");
 #endif
         aView->SetForcedRepaint(false);
         SetPainting(false);
       }
     }
     FlushDirtyRegionToWidget(aView);