Bug 1126164 - Avoid setting clip regions on plugin windows if the same clip region was already set. r=roc
authorJim Mathies <jmathies@mozilla.com>
Wed, 28 Jan 2015 09:15:54 -0600
changeset 255235 c49c54cfb1d3b9974e88c3f5337f3ab2140533db
parent 255234 d8b23c23b13142ffee445bdc81c514ac27cb9369
child 255236 470dc6922fa24e41ef2a0d612b7187c7ee5f35a6
push id721
push userjlund@mozilla.com
push dateTue, 21 Apr 2015 23:03:33 +0000
treeherdermozilla-release@d27c9211ebb3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1126164
milestone38.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 1126164 - Avoid setting clip regions on plugin windows if the same clip region was already set. r=roc
widget/gtk/nsWindow.cpp
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/windows/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -4222,19 +4222,21 @@ nsWindow::SetWindowClipRegion(const nsTA
         }
 
         if (!pixman_region32_equal(&intersectRegion, &newRegion)) {
             GetIntRects(intersectRegion, &intersectRects);
             newRects = &intersectRects;
         }
     }
 
-    if (!StoreWindowClipRegion(*newRects))
+    if (IsWindowClipRegionEqual(*newRects))
         return NS_OK;
 
+    StoreWindowClipRegion(*newRects);
+
     if (!mGdkWindow)
         return NS_OK;
 
 #if (MOZ_WIDGET_GTK == 2)
     GdkRegion *region = gdk_region_new(); // aborts on OOM
     for (uint32_t i = 0; i < newRects->Length(); ++i) {
         const nsIntRect& r = newRects->ElementAt(i);
         GdkRectangle rect = { r.x, r.y, r.width, r.height };
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -642,28 +642,31 @@ NS_IMETHODIMP nsBaseWidget::SetCursor(im
 void nsBaseWidget::SetTransparencyMode(nsTransparencyMode aMode) {
 }
 
 nsTransparencyMode nsBaseWidget::GetTransparencyMode() {
   return eTransparencyOpaque;
 }
 
 bool
+nsBaseWidget::IsWindowClipRegionEqual(const nsTArray<nsIntRect>& aRects)
+{
+  return mClipRects &&
+         mClipRectCount == aRects.Length() &&
+         memcmp(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount) == 0;
+}
+
+void
 nsBaseWidget::StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects)
 {
-  if (mClipRects && mClipRectCount == aRects.Length() &&
-      memcmp(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount) == 0)
-    return false;
-
   mClipRectCount = aRects.Length();
   mClipRects = new nsIntRect[mClipRectCount];
   if (mClipRects) {
     memcpy(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount);
   }
-  return true;
 }
 
 void
 nsBaseWidget::GetWindowClipRegion(nsTArray<nsIntRect>* aRects)
 {
   if (mClipRects) {
     aRects->AppendElements(mClipRects.get(), mClipRectCount);
   } else {
@@ -690,41 +693,33 @@ nsBaseWidget::ArrayFromRegion(const nsIn
   }
 }
 
 nsresult
 nsBaseWidget::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
                                   bool aIntersectWithExisting)
 {
   if (!aIntersectWithExisting) {
-    nsBaseWidget::StoreWindowClipRegion(aRects);
+    StoreWindowClipRegion(aRects);
   } else {
-    // In this case still early return if nothing changed.
-    if (mClipRects && mClipRectCount == aRects.Length() &&
-        memcmp(mClipRects,
-               aRects.Elements(),
-               sizeof(nsIntRect)*mClipRectCount) == 0) {
-      return NS_OK;
-    }
-
     // get current rects
     nsTArray<nsIntRect> currentRects;
     GetWindowClipRegion(&currentRects);
     // create region from them
     nsIntRegion currentRegion = RegionFromArray(currentRects);
     // create region from new rects
     nsIntRegion newRegion = RegionFromArray(aRects);
     // intersect regions
     nsIntRegion intersection;
     intersection.And(currentRegion, newRegion);
     // create int rect array from intersection
     nsTArray<nsIntRect> rects;
     ArrayFromRegion(intersection, rects);
     // store
-    nsBaseWidget::StoreWindowClipRegion(rects);
+    StoreWindowClipRegion(rects);
   }
   return NS_OK;
 }
 
 //-------------------------------------------------------------------------
 //
 // Set window shadow style
 //
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -357,19 +357,22 @@ protected:
                                               double aPointerPressure,
                                               uint32_t aPointerOrientation) MOZ_OVERRIDE
   { return NS_ERROR_UNEXPECTED; }
 
   virtual nsresult NotifyIMEInternal(const IMENotification& aIMENotification)
   { return NS_ERROR_NOT_IMPLEMENTED; }
 
 protected:
-  // Stores the clip rectangles in aRects into mClipRects. Returns true
-  // if the new rectangles are different from the old rectangles.
-  bool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
+  // Utility to check if an array of clip rects is equal to our
+  // internally stored clip rect array mClipRects.
+  bool IsWindowClipRegionEqual(const nsTArray<nsIntRect>& aRects);
+
+  // Stores the clip rectangles in aRects into mClipRects.
+  void StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
 
   virtual already_AddRefed<nsIWidget>
   AllocateChildPopupWidget()
   {
     static NS_DEFINE_IID(kCPopUpCID, NS_CHILD_CID);
     nsCOMPtr<nsIWidget> widget = do_CreateInstance(kCPopUpCID);
     return widget.forget();
   }
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6435,16 +6435,20 @@ CreateHRGNFromArray(const nsTArray<nsInt
   ::SetRect(&data->rdh.rcBound, bounds.x, bounds.y, bounds.XMost(), bounds.YMost());
   return ::ExtCreateRegion(nullptr, buf.Length(), data);
 }
 
 nsresult
 nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
                               bool aIntersectWithExisting)
 {
+  if (IsWindowClipRegionEqual(aRects)) {
+    return NS_OK;
+  }
+
   nsBaseWidget::SetWindowClipRegion(aRects, aIntersectWithExisting);
 
   HRGN dest = CreateHRGNFromArray(aRects);
   if (!dest)
     return NS_ERROR_OUT_OF_MEMORY;
 
   if (aIntersectWithExisting) {
     HRGN current = ::CreateRectRgn(0, 0, 0, 0);