Bug 539356 - Part 20 - Simplify regions to avoid excessive region calculation. r=roc
authorOleg Romashin <romaxa@gmail.com>
Wed, 29 Aug 2012 17:48:43 +1200
changeset 108556 b5559af3cf948dfe2acc031c7cda3cd1f0cd7216
parent 108555 4372c4914958f5f9effcf48f8cfceccb5fc2f158
child 108557 8d12f7ceea1348759586a95baf5c763567226fc9
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersroc
bugs539356
milestone18.0a1
Bug 539356 - Part 20 - Simplify regions to avoid excessive region calculation. r=roc
gfx/layers/LayerTreeInvalidation.cpp
gfx/layers/Layers.h
gfx/layers/basic/BasicThebesLayer.h
gfx/layers/d3d10/ThebesLayerD3D10.cpp
gfx/layers/d3d9/ThebesLayerD3D9.cpp
gfx/layers/opengl/ThebesLayerOGL.cpp
layout/base/nsDisplayList.cpp
layout/base/nsPresShell.cpp
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -112,17 +112,17 @@ struct LayerPropertiesBase : public Laye
       // old and new bounds.
       if (!aCallback) {
         ClearInvalidations(mLayer);
         return result;
       }
     }
 
     result = result.Union(ComputeChangeInternal(aCallback));
-    result = result.Union(TransformRect(mLayer->GetInvalidRect(), mTransform));
+    result = result.Union(TransformRect(mLayer->GetInvalidRegion().GetBounds(), mTransform));
 
     if (mMaskLayer && otherMask) {
       nsIntRect maskDiff = mMaskLayer->ComputeChange(aCallback);
       result = result.Union(TransformRect(maskDiff, mTransform));
     }
 
     if (mUseClipRect && otherClip) {
       if (!mClipRect.IsEqualInterior(*otherClip)) {
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -956,33 +956,33 @@ public:
   void LogSelf(const char* aPrefix="");
 
   static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
 
   /**
    * Returns the current area of the layer (in layer-space coordinates)
    * marked as needed to be recomposited.
    */
-  const nsIntRect& GetInvalidRect() { return mInvalidRect; }
+  const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; }
 
   /**
    * Mark the entirety of the layer's visible region as being invalid.
    */
-  void SetInvalidRectToVisibleRegion() { mInvalidRect = GetVisibleRegion().GetBounds(); }
+  void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion(); }
 
   /**
    * Adds to the current invalid rect.
    */
-  void AddInvalidRect(const nsIntRect& aRect) { mInvalidRect = mInvalidRect.Union(aRect); }
+  void AddInvalidRect(const nsIntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); }
 
   /**
    * Clear the invalid rect, marking the layer as being identical to what is currently
    * composited.
    */
-  void ClearInvalidRect() { mInvalidRect.SetEmpty(); }
+  void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
 
 
 #ifdef DEBUG
   void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; }
   uint32_t GetDebugColorIndex() { return mDebugColorIndex; }
 #endif
 
 protected:
@@ -1036,17 +1036,17 @@ protected:
   float mPostXScale;
   float mPostYScale;
   gfx3DMatrix mEffectiveTransform;
   AnimationArray mAnimations;
   InfallibleTArray<AnimData> mAnimationData;
   float mOpacity;
   nsIntRect mClipRect;
   nsIntRect mTileSourceRect;
-  nsIntRect mInvalidRect;
+  nsIntRegion mInvalidRegion;
   uint32_t mContentFlags;
   bool mUseClipRect;
   bool mUseTileSourceRect;
   bool mIsFixedPosition;
   gfxPoint mAnchor;
   DebugOnly<uint32_t> mDebugColorIndex;
 };
 
--- a/gfx/layers/basic/BasicThebesLayer.h
+++ b/gfx/layers/basic/BasicThebesLayer.h
@@ -32,18 +32,19 @@ public:
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ThebesLayer::SetVisibleRegion(aRegion);
   }
   virtual void InvalidateRegion(const nsIntRegion& aRegion)
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
-    mValidRegion.Sub(mValidRegion, aRegion);
-    AddInvalidRect(aRegion.GetBounds());
+    mInvalidRegion.Or(mInvalidRegion, aRegion);
+    mInvalidRegion.SimplifyOutward(10);
+    mValidRegion.Sub(mValidRegion, mInvalidRegion);
   }
 
   virtual void PaintThebes(gfxContext* aContext,
                            Layer* aMaskLayer,
                            LayerManager::DrawThebesLayerCallback aCallback,
                            void* aCallbackData,
                            ReadbackProcessor* aReadback);
 
--- a/gfx/layers/d3d10/ThebesLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
@@ -40,18 +40,19 @@ ThebesLayerD3D10::ThebesLayerD3D10(Layer
 
 ThebesLayerD3D10::~ThebesLayerD3D10()
 {
 }
 
 void
 ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
 {
-  mValidRegion.Sub(mValidRegion, aRegion);
-  AddInvalidRect(aRegion.GetBounds());
+  mInvalidRegion.Or(mInvalidRegion, aRegion);
+  mInvalidRegion.SimplifyOutward(10);
+  mValidRegion.Sub(mValidRegion, mInvalidRegion);
 }
 
 void ThebesLayerD3D10::CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,
                                   ID3D10Texture2D* aDest, const nsIntPoint &aDestOffset,
                                   const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion)
 {
   nsIntRegion retainedRegion;
   nsIntRegionRectIterator iter(aCopyRegion);
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
@@ -44,18 +44,19 @@ ThebesLayerD3D9::~ThebesLayerD3D9()
  * layer content retention. This is a guesstimate. Profiling could be done to
  * figure out the optimal threshold.
  */
 #define RETENTION_THRESHOLD 16384
 
 void
 ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
 {
-  mValidRegion.Sub(mValidRegion, aRegion);
-  AddInvalidRect(aRegion.GetBounds());
+  mInvalidRegion.Or(mInvalidRegion, aRegion);
+  mInvalidRegion.SimplifyOutward(10);
+  mValidRegion.Sub(mValidRegion, mInvalidRegion);
 }
 
 void
 ThebesLayerD3D9::CopyRegion(IDirect3DTexture9* aSrc, const nsIntPoint &aSrcOffset,
                             IDirect3DTexture9* aDest, const nsIntPoint &aDestOffset,
                             const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion)
 {
   nsRefPtr<IDirect3DSurface9> srcSurface, dstSurface;
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -784,18 +784,19 @@ ThebesLayerOGL::SetVisibleRegion(const n
   if (aRegion.IsEqual(mVisibleRegion))
     return;
   ThebesLayer::SetVisibleRegion(aRegion);
 }
 
 void
 ThebesLayerOGL::InvalidateRegion(const nsIntRegion &aRegion)
 {
-  mValidRegion.Sub(mValidRegion, aRegion);
-  AddInvalidRect(aRegion.GetBounds());
+  mInvalidRegion.Or(mInvalidRegion, aRegion);
+  mInvalidRegion.SimplifyOutward(10);
+  mValidRegion.Sub(mValidRegion, mInvalidRegion);
 }
 
 void
 ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
                             const nsIntPoint& aOffset)
 {
   if (!mBuffer && !CreateSurface()) {
     return;
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1087,16 +1087,18 @@ void nsDisplayList::PaintForFrame(nsDisp
   layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
                                aBuilder, (aFlags & PAINT_NO_COMPOSITE) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT);
   aBuilder->SetIsCompositingCheap(temp);
   layerBuilder->DidEndTransaction();
 
   nsIntRect invalid;
   if (props) {
     invalid = props->ComputeDifferences(root, computeInvalidFunc);
+  } else if (widgetTransaction) {
+    LayerProperties::ClearInvalidations(root);
   }
 
   if (view) {
     if (props) {
       if (!invalid.IsEmpty()) {
         nsRect rect(presContext->DevPixelsToAppUnits(invalid.x),
                     presContext->DevPixelsToAppUnits(invalid.y),
                     presContext->DevPixelsToAppUnits(invalid.width),
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5249,16 +5249,18 @@ PresShell::Paint(nsIView*           aVie
       nsAutoPtr<LayerProperties> props(computeInvalidRect ? 
                                          LayerProperties::CloneFrom(layerManager->GetRoot()) : 
                                          nullptr);
 
       if (layerManager->EndEmptyTransaction((aType == PaintType_NoComposite) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT)) {
         nsIntRect invalid;
         if (props) {
           invalid = props->ComputeDifferences(layerManager->GetRoot(), computeInvalidFunc);
+        } else {
+          LayerProperties::ClearInvalidations(layerManager->GetRoot());
         }
         if (!invalid.IsEmpty()) {
           if (props) {
             nsRect rect(presContext->DevPixelsToAppUnits(invalid.x),
                         presContext->DevPixelsToAppUnits(invalid.y),
                         presContext->DevPixelsToAppUnits(invalid.width),
                         presContext->DevPixelsToAppUnits(invalid.height));
             aViewToPaint->GetViewManager()->InvalidateViewNoSuppression(aViewToPaint, rect);