Bug 1126164 - Avoid setting clip regions on plugin windows if the same clip region was already set. r=roc, a=sledru
authorJim Mathies <jmathies@mozilla.com>
Wed, 28 Jan 2015 09:15:54 -0600
changeset 243621 e32f606d51e3
parent 243620 2dd8d79e19e4
child 243622 734264bcd6d1
push id4419
push userryanvm@gmail.com
push date2015-02-02 15:44 +0000
treeherdermozilla-beta@ea6cff5fd829 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sledru
bugs1126164
milestone36.0
Bug 1126164 - Avoid setting clip regions on plugin windows if the same clip region was already set. r=roc, a=sledru
widget/gtk/nsWindow.cpp
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/windows/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -4183,19 +4183,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
@@ -630,28 +630,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 {
@@ -678,41 +681,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
@@ -335,19 +335,22 @@ protected:
   virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
                                               TouchPointerState aPointerState,
                                               nsIntPoint aPointerScreenPoint,
                                               double aPointerPressure,
                                               uint32_t aPointerOrientation)
   { return NS_ERROR_UNEXPECTED; }
 
 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
@@ -6536,16 +6536,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);