Change the subdoc invalidation callback to handle overflow. (bug 1345891 part 5, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Thu, 03 Aug 2017 21:22:49 -0700
changeset 422429 f886c403b88a78035ae0e2f7fe71c830e40bcb3f
parent 422428 a8ce1cb143034ea116c19bc36a9d899c74767885
child 422430 d77894bb0b45b7e4f135b161785503f9f4725e18
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1345891
milestone57.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
Change the subdoc invalidation callback to handle overflow. (bug 1345891 part 5, r=mattwoodrow)
gfx/layers/LayerTreeInvalidation.cpp
gfx/layers/LayerTreeInvalidation.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -131,17 +131,18 @@ NotifySubdocumentInvalidation(Layer* aLa
           Layer* maskLayer = layer->GetAncestorMaskLayerAt(i);
           NotifySubdocumentInvalidation(maskLayer, aCallback);
         }
       },
       [aCallback] (Layer* layer)
       {
         ContainerLayer* container = layer->AsContainerLayer();
         if (container) {
-          aCallback(container, container->GetLocalVisibleRegion().ToUnknownRegion());
+          nsIntRegion region = container->GetLocalVisibleRegion().ToUnknownRegion();
+          aCallback(container, &region);
         }
       });
 }
 
 struct LayerPropertiesBase : public LayerProperties
 {
   explicit LayerPropertiesBase(Layer* aLayer)
     : mLayer(aLayer)
@@ -466,17 +467,17 @@ public:
         AddRegion(result, bounds.value());
       } else {
         areaOverflowed = true;
       }
       i++;
     }
 
     if (aCallback) {
-      aCallback(container, result);
+      aCallback(container, areaOverflowed ? nullptr : &result);
     }
 
     if (childrenChanged || areaOverflowed) {
       container->SetChildrenChanged(true);
     }
 
     if (container->UseIntermediateSurface()) {
       Maybe<IntRect> bounds;
--- a/gfx/layers/LayerTreeInvalidation.h
+++ b/gfx/layers/LayerTreeInvalidation.h
@@ -16,20 +16,20 @@ namespace layers {
 class Layer;
 class ContainerLayer;
 
 /**
  * Callback for ContainerLayer invalidations.
  *
  * @param aContainer ContainerLayer being invalidated.
  * @param aRegion Invalidated region in the ContainerLayer's coordinate
- * space.
+ * space. If null, then the entire region must be invalidated.
  */
 typedef void (*NotifySubDocInvalidationFunc)(ContainerLayer* aLayer,
-                                             const nsIntRegion& aRegion);
+                                             const nsIntRegion* aRegion);
 
 /**
  * A set of cached layer properties (including those of child layers),
  * used for comparing differences in layer trees.
  */
 struct LayerProperties
 {
 protected:
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -92,16 +92,17 @@
 #include "nsBidiUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsBidi.h"
 
 #include "mozilla/dom/URL.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 uint8_t gNotifySubDocInvalidationData;
 
 // This preference was first introduced in Bug 232227, in order to prevent
 // system colors from being exposed to CSS or canvas.
 constexpr char kUseStandinsForNativeColors[] = "ui.use_standins_for_native_colors";
 
@@ -2604,34 +2605,42 @@ nsPresContext::NotifyInvalidation(uint64
     transaction->mTransactionId = aTransactionId;
   }
 
   transaction->mInvalidations.AppendElement(aRect);
 }
 
 /* static */ void
 nsPresContext::NotifySubDocInvalidation(ContainerLayer* aContainer,
-                                        const nsIntRegion& aRegion)
+                                        const nsIntRegion* aRegion)
 {
   ContainerLayerPresContext *data =
     static_cast<ContainerLayerPresContext*>(
       aContainer->GetUserData(&gNotifySubDocInvalidationData));
   if (!data) {
     return;
   }
 
-  nsIntPoint topLeft = aContainer->GetVisibleRegion().ToUnknownRegion().GetBounds().TopLeft();
-
-  for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
+  uint64_t transactionId = aContainer->Manager()->GetLastTransactionId();
+  IntRect visibleBounds = aContainer->GetVisibleRegion().GetBounds().ToUnknownRect();
+
+  if (!aRegion) {
+    IntRect rect(IntPoint(0, 0), visibleBounds.Size());
+    data->mPresContext->NotifyInvalidation(transactionId, rect);
+    return;
+  }
+
+  nsIntPoint topLeft = visibleBounds.TopLeft();
+  for (auto iter = aRegion->RectIter(); !iter.Done(); iter.Next()) {
     nsIntRect rect(iter.Get());
     //PresContext coordinate space is relative to the start of our visible
     // region. Is this really true? This feels like the wrong way to get the right
     // answer.
     rect.MoveBy(-topLeft);
-    data->mPresContext->NotifyInvalidation(aContainer->Manager()->GetLastTransactionId(), rect);
+    data->mPresContext->NotifyInvalidation(transactionId, rect);
   }
 }
 
 void
 nsPresContext::SetNotifySubDocInvalidationData(ContainerLayer* aContainer)
 {
   ContainerLayerPresContext* pres = new ContainerLayerPresContext;
   pres->mPresContext = this;
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1023,17 +1023,17 @@ public:
   void NotifyDidPaintForSubtree(uint64_t aTransactionId = 0,
                                 const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
   void FireDOMPaintEvent(nsTArray<nsRect>* aList, uint64_t aTransactionId,
                          mozilla::TimeStamp aTimeStamp = mozilla::TimeStamp());
 
   // Callback for catching invalidations in ContainerLayers
   // Passed to LayerProperties::ComputeDifference
   static void NotifySubDocInvalidation(mozilla::layers::ContainerLayer* aContainer,
-                                       const nsIntRegion& aRegion);
+                                       const nsIntRegion* aRegion);
   void SetNotifySubDocInvalidationData(mozilla::layers::ContainerLayer* aContainer);
   static void ClearNotifySubDocInvalidationData(mozilla::layers::ContainerLayer* aContainer);
   bool IsDOMPaintEventPending();
 
   /**
    * Returns the RestyleManager's restyle generation counter.
    */
   uint64_t GetRestyleGeneration() const;