Bug 797431 - Add a flags parameter to PaintWindow. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 15 Oct 2012 17:53:37 +1300
changeset 110380 ab00790e8fedd734508a739b982af34c08a1a238
parent 110379 8dd63acc9c4fbde8bc371c06b10adb81c132defa
child 110381 1bca31fd0e58c29bfdfb713321f55a4078ae489b
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersroc
bugs797431
milestone19.0a1
Bug 797431 - Add a flags parameter to PaintWindow. r=roc
view/src/nsView.cpp
view/src/nsView.h
view/src/nsViewManager.cpp
view/src/nsViewManager.h
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.mm
widget/gonk/nsWindow.cpp
widget/gtk2/nsWindow.cpp
widget/nsIWidgetListener.h
widget/qt/nsWindow.cpp
widget/windows/nsWindowGfx.cpp
widget/xpwidgets/PuppetWidget.cpp
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -1025,20 +1025,20 @@ nsView::RequestWindowClose(nsIWidget* aW
 
 void
 nsView::WillPaintWindow(nsIWidget* aWidget, bool aWillSendDidPaint)
 {
   mViewManager->WillPaintWindow(aWidget, aWillSendDidPaint);
 }
 
 bool
-nsView::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion, bool aSentWillPaint, bool aWillSendDidPaint)
+nsView::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion, uint32_t aFlags)
 {
   nsCOMPtr<nsViewManager> vm = mViewManager;
-  return vm->PaintWindow(aWidget, aRegion, aSentWillPaint, aWillSendDidPaint);
+  return vm->PaintWindow(aWidget, aRegion, aFlags);
 }
 
 void
 nsView::DidPaintWindow()
 {
   mViewManager->DidPaintWindow();
 }
 
--- a/view/src/nsView.h
+++ b/view/src/nsView.h
@@ -163,17 +163,17 @@ public:
 
   // nsIWidgetListener
   virtual nsIPresShell* GetPresShell();
   virtual nsIView* GetView() { return this; }
   bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y);
   bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight);
   bool RequestWindowClose(nsIWidget* aWidget);
   void WillPaintWindow(nsIWidget* aWidget, bool aWillSendDidPaint);
-  bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion, bool aSentDidPaint, bool aWillSendDidPaint);
+  bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion, uint32_t aFlags);
   void DidPaintWindow();
   nsEventStatus HandleEvent(nsGUIEvent* aEvent, bool aUseAttachedEvents);
 
   virtual ~nsView();
 
   nsPoint GetOffsetTo(const nsView* aOther) const;
   nsIWidget* GetNearestWidget(nsPoint* aOffset) const;
   nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const;
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -678,33 +678,33 @@ void nsViewManager::WillPaintWindow(nsIW
 
   nsCOMPtr<nsIPresShell> shell = mPresShell;
   if (shell) {
     shell->WillPaintWindow(aWillSendDidPaint);
   }
 }
 
 bool nsViewManager::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion,
-                                bool aSentWillPaint, bool aWillSendDidPaint)
+                                uint32_t aFlags)
  {
   if (!aWidget || !mContext)
     return false;
 
   NS_ASSERTION(IsPaintingAllowed(),
                "shouldn't be receiving paint events while painting is disallowed!");
 
-  if (!aSentWillPaint && !IsRefreshDriverPaintingEnabled()) {
-    WillPaintWindow(aWidget, aWillSendDidPaint);
+  if (!(aFlags & nsIWidgetListener::SENT_WILL_PAINT) && !IsRefreshDriverPaintingEnabled()) {
+    WillPaintWindow(aWidget, (aFlags & nsIWidgetListener::WILL_SEND_DID_PAINT));
   }
 
   // Get the view pointer here since NS_WILL_PAINT might have
   // destroyed it during CallWillPaintOnObservers (bug 378273).
   nsView* view = nsView::GetViewFor(aWidget);
   if (view && !aRegion.IsEmpty()) {
-    Refresh(view, aRegion, aWillSendDidPaint);
+    Refresh(view, aRegion, (aFlags & nsIWidgetListener::WILL_SEND_DID_PAINT));
   }
 
   return true;
 }
 
 void nsViewManager::DidPaintWindow()
 {
   nsCOMPtr<nsIPresShell> shell = mPresShell;
--- a/view/src/nsViewManager.h
+++ b/view/src/nsViewManager.h
@@ -165,17 +165,17 @@ public: // NOT in nsIViewManager, so pri
 
   // Whether synchronous painting is allowed at the moment. For example,
   // widget geometry changes can cause synchronous painting, so they need to
   // be deferred while refresh is disabled.
   bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
 
   void WillPaintWindow(nsIWidget* aWidget, bool aWillSendDidPaint);
   bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion,
-                   bool aSentWillPaint, bool aWillSendDidPaint);
+                   uint32_t aFlags);
   void DidPaintWindow();
 
   // Call this when you need to let the viewmanager know that it now has
   // pending updates.
   void PostPendingUpdate();
 
   uint32_t AppUnitsPerDevPixel() const
   {
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1004,17 +1004,17 @@ nsWindow::DrawTo(gfxASurface *targetSurf
 
                 nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
 
                 {
                     mozilla::layers::RenderTraceScope trace2("Basic DrawTo", "727272");
                     AutoLayerManagerSetup
                       setupLayerManager(this, ctx, mozilla::layers::BUFFER_NONE);
 
-                    painted = mWidgetListener->PaintWindow(this, region, false, false);
+                    painted = mWidgetListener->PaintWindow(this, region, 0);
                 }
 
                 // XXX uhh.. we can't just ignore this because we no longer have
                 // what we needed before, but let's keep drawing the children anyway?
 #if 0
                 if (!painted)
                     return false;
 #endif
@@ -1024,17 +1024,17 @@ nsWindow::DrawTo(gfxASurface *targetSurf
                 break;
             }
 
             case mozilla::layers::LAYERS_OPENGL: {
 
                 static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager(nullptr))->
                     SetClippingRegion(nsIntRegion(boundsRect));
 
-                painted = mWidgetListener->PaintWindow(this, region, false, false);
+                painted = mWidgetListener->PaintWindow(this, region, 0);
                 break;
             }
 
             default:
                 NS_ERROR("Invalid layer manager");
         }
 
         // We had no covering child, so make sure we draw all the children,
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1434,17 +1434,17 @@ bool nsChildView::PaintWindow(nsIntRegio
   }
 
   if (!listener)
     return false;
 
   bool returnValue = false;
   bool oldDispatchPaint = mIsDispatchPaint;
   mIsDispatchPaint = true;
-  returnValue = listener->PaintWindow(widget, aRegion, true, false);
+  returnValue = listener->PaintWindow(widget, aRegion, SENT_WILL_PAINT);
   mIsDispatchPaint = oldDispatchPaint;
   return returnValue;
 }
 
 #pragma mark -
 
 void nsChildView::ReportMoveEvent()
 {
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -245,17 +245,17 @@ nsWindow::DoDraw(void)
 
     LayerManager* lm = gWindowToRedraw->GetLayerManager();
     if (mozilla::layers::LAYERS_OPENGL == lm->GetBackendType()) {
         LayerManagerOGL* oglm = static_cast<LayerManagerOGL*>(lm);
         oglm->SetClippingRegion(region);
         oglm->SetWorldTransform(sRotationMatrix);
 
         if (nsIWidgetListener* listener = gWindowToRedraw->GetWidgetListener())
-          listener->PaintWindow(gWindowToRedraw, region, false, false);
+          listener->PaintWindow(gWindowToRedraw, region, 0);
     } else if (mozilla::layers::LAYERS_BASIC == lm->GetBackendType()) {
         MOZ_ASSERT(sFramebufferOpen || sUsingOMTC);
         nsRefPtr<gfxASurface> targetSurface;
 
         if(sUsingOMTC)
             targetSurface = sOMTCSurface;
         else
             targetSurface = Framebuffer::BackBuffer();
@@ -266,17 +266,17 @@ nsWindow::DoDraw(void)
             ctx->Clip();
 
             // No double-buffering needed.
             AutoLayerManagerSetup setupLayerManager(
                 gWindowToRedraw, ctx, mozilla::layers::BUFFER_NONE,
                 ScreenRotation(EffectiveScreenRotation()));
 
             if (nsIWidgetListener* listener = gWindowToRedraw->GetWidgetListener())
-              listener->PaintWindow(gWindowToRedraw, region, false, false);
+              listener->PaintWindow(gWindowToRedraw, region, 0);
         }
 
         if (!sUsingOMTC) {
             targetSurface->Flush();
             Framebuffer::Present(region);
         }
     } else {
         NS_RUNTIMEABORT("Unexpected layer manager type");
--- a/widget/gtk2/nsWindow.cpp
+++ b/widget/gtk2/nsWindow.cpp
@@ -2116,31 +2116,31 @@ nsWindow::OnExposeEvent(cairo_t *cr)
         nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface());
 #else
         nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface(cr));
 #endif
         nsBaseWidget::AutoLayerManagerSetup
           setupLayerManager(this, ctx, mozilla::layers::BUFFER_NONE);
 
         if (mWidgetListener)
-            mWidgetListener->PaintWindow(this, region, true, true);
+            mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
 
         g_free(rects);
 
         if (mWidgetListener)
             mWidgetListener->DidPaintWindow();
 
         return TRUE;
 
     } else if (GetLayerManager()->GetBackendType() == mozilla::layers::LAYERS_OPENGL) {
         LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(GetLayerManager());
         manager->SetClippingRegion(region);
 
         if (mWidgetListener)
-            mWidgetListener->PaintWindow(this, region, true, true);
+            mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
 
         g_free(rects);
 
         if (mWidgetListener)
             mWidgetListener->DidPaintWindow();
 
         return TRUE;
     }
@@ -2198,17 +2198,17 @@ nsWindow::OnExposeEvent(cairo_t *cr)
 
 #endif // MOZ_X11
 
     bool painted = false;
     {
       AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering);
 
       if (mWidgetListener)
-        painted = mWidgetListener->PaintWindow(this, region, true, true);
+        painted = mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
     }
 
 #ifdef MOZ_X11
     // PaintWindow can Destroy us (bug 378273), avoid doing any paint
     // operations below if that happened - it will lead to XError and exit().
     if (shaped) {
         if (NS_LIKELY(!mIsDestroyed)) {
             if (painted) {
--- a/widget/nsIWidgetListener.h
+++ b/widget/nsIWidgetListener.h
@@ -113,23 +113,24 @@ public:
   virtual bool RequestWindowClose(nsIWidget* aWidget) { return false; }
 
   /*
    * Indicate that a paint is about to occur on this window.
    */
   virtual void WillPaintWindow(nsIWidget* aWidget, bool aWillSendDidPaint) { }
 
   /**
-   * Paint the specified region of the window. If aSentWillPaint is true,
-   * then WillPaintWindow has already been called. If aWillSendDidPaint is true,
-   * then a call to DidPaintWindow will be made afterwards. Returns true if the
+   * Paint the specified region of the window. Returns true if the
    * notification was handled.
    */
-  virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion,
-                           bool aSentWillPaint, bool aWillSendDidPaint) { return false; }
+  enum {
+    SENT_WILL_PAINT = 1 << 0, /* WillPaintWindow has already been called */
+    WILL_SEND_DID_PAINT = 1 << 1, /* A call to DidPaintWindow will be made afterwards. */
+  };
+  virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion, uint32_t aFlags) { return false; }
 
   /**
    * On some platforms, indicates that a paint occurred.
    */
   virtual void DidPaintWindow() { }
 
   /**
    * Handle an event.
--- a/widget/qt/nsWindow.cpp
+++ b/widget/qt/nsWindow.cpp
@@ -1042,17 +1042,17 @@ nsWindow::DoPaint(QPainter* aPainter, co
         // This is needed for rotate transformation on MeeGo
         // This will work very slow if pixman does not handle rotation very well
         matr.Rotate((M_PI/180) * gOrientationFilter.GetWindowRotationAngle());
         static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager(nullptr))->
             SetWorldTransform(matr);
 #endif //MOZ_ENABLE_QTMOBILITY
 
         if (mWidgetListener)
-          painted = mWidgetListener->PaintWindow(this, region, true, true);
+          painted = mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
         aPainter->endNativePainting();
         if (mWidgetListener)
           mWidgetListener->DidPaintWindow();
         return painted;
     }
 
     gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode();
     int depth = aPainter->device()->depth();
@@ -1100,17 +1100,17 @@ nsWindow::DoPaint(QPainter* aPainter, co
       ctx->SetMatrix(matr);
     }
 
     {
         AutoLayerManagerSetup
             setupLayerManager(this, ctx, mozilla::layers::BUFFER_NONE);
         if (mWidgetListener) {
           nsIntRegion region(rect);
-          painted = mWidgetListener->PaintWindow(this, region, true, true);
+          painted = mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
         }
     }
 
     // DispatchEvent can Destroy us (bug 378273), avoid doing any paint
     // operations below if that happened - it will lead to XError and exit().
     if (NS_UNLIKELY(mIsDestroyed))
         return painted;
 
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -411,17 +411,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
 #else
             doubleBuffering = mozilla::layers::BUFFER_BUFFERED;
 #endif
           }
 
           {
             AutoLayerManagerSetup
                 setupLayerManager(this, thebesContext, doubleBuffering);
-            result = listener->PaintWindow(this, region, true, true);
+            result = listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
           }
 
 #ifdef MOZ_XUL
           if ((IsRenderMode(gfxWindowsPlatform::RENDER_GDI) ||
                IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D))&&
               eTransparencyTransparent == mTransparencyMode) {
             // Data from offscreen drawing surface was copied to memory bitmap of transparent
             // bitmap. Now it can be read from memory bitmap to apply alpha channel and after
@@ -526,25 +526,25 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
                             SRCCOPY);
             }
           }
         }
         break;
       case LAYERS_OPENGL:
         static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager())->
           SetClippingRegion(region);
-        result = listener->PaintWindow(this, region, true, true);
+        result = listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
         break;
 #ifdef MOZ_ENABLE_D3D9_LAYER
       case LAYERS_D3D9:
         {
           LayerManagerD3D9 *layerManagerD3D9 =
             static_cast<mozilla::layers::LayerManagerD3D9*>(GetLayerManager());
           layerManagerD3D9->SetClippingRegion(region);
-          result = listener->PaintWindow(this, region, true, true);
+          result = listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
           if (layerManagerD3D9->DeviceWasRemoved()) {
             mLayerManager->Destroy();
             mLayerManager = nullptr;
             // When our device was removed, we should have gfxWindowsPlatform
             // check if its render mode is up to date!
             gfxWindowsPlatform::GetPlatform()->UpdateRenderMode();
             Invalidate();
           }
@@ -554,17 +554,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
 #ifdef MOZ_ENABLE_D3D10_LAYER
       case LAYERS_D3D10:
         {
           gfxWindowsPlatform::GetPlatform()->UpdateRenderMode();
           LayerManagerD3D10 *layerManagerD3D10 = static_cast<mozilla::layers::LayerManagerD3D10*>(GetLayerManager());
           if (layerManagerD3D10->device() != gfxWindowsPlatform::GetPlatform()->GetD3D10Device()) {
             Invalidate();
           } else {
-            result = listener->PaintWindow(this, region, true, true);
+            result = listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
           }
         }
         break;
 #endif
       default:
         NS_ERROR("Unknown layers backend used!");
         break;
     }
--- a/widget/xpwidgets/PuppetWidget.cpp
+++ b/widget/xpwidgets/PuppetWidget.cpp
@@ -505,24 +505,24 @@ PuppetWidget::Paint()
 
   {
 #ifdef DEBUG
     debug_DumpPaintEvent(stderr, this, region,
                          nsAutoCString("PuppetWidget"), 0);
 #endif
 
     if (mozilla::layers::LAYERS_D3D10 == mLayerManager->GetBackendType()) {
-      mAttachedWidgetListener->PaintWindow(this, region, false, true);
+      mAttachedWidgetListener->PaintWindow(this, region, nsIWidgetListener::WILL_SEND_DID_PAINT);
     } else {
       nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
       ctx->Rectangle(gfxRect(0,0,0,0));
       ctx->Clip();
       AutoLayerManagerSetup setupLayerManager(this, ctx,
                                               BUFFER_NONE);
-      mAttachedWidgetListener->PaintWindow(this, region, false, true);
+      mAttachedWidgetListener->PaintWindow(this, region, nsIWidgetListener::WILL_SEND_DID_PAINT);
       mTabChild->NotifyPainted();
     }
   }
 
   mAttachedWidgetListener->DidPaintWindow();
 
   return NS_OK;
 }