Bug 635035, part 1: Separate the extended draw region and computed draw region so that shadow-layer readback gets the same quadrant as what was drawn. r=mattwoodrow
authorChris Jones <jones.chris.g@gmail.com>
Wed, 09 Mar 2011 11:27:37 -0600
changeset 63366 439f8db100d7d77257c5edbe3436e95e5e347002
parent 63365 cae1cd4aae738d6702bcc80eef63722e9a184292
child 63367 5a3f1c4e63c198dfe1fef41ebb5bfb503ef4f66c
push idunknown
push userunknown
push dateunknown
reviewersmattwoodrow
bugs635035
milestone2.0b13pre
Bug 635035, part 1: Separate the extended draw region and computed draw region so that shadow-layer readback gets the same quadrant as what was drawn. r=mattwoodrow
gfx/layers/basic/BasicLayers.cpp
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -421,32 +421,33 @@ protected:
   BasicLayerManager* BasicManager()
   {
     return static_cast<BasicLayerManager*>(mManager);
   }
 
   virtual void
   PaintBuffer(gfxContext* aContext,
               const nsIntRegion& aRegionToDraw,
+              const nsIntRegion& aExtendedRegionToDraw,
               const nsIntRegion& aRegionToInvalidate,
               LayerManager::DrawThebesLayerCallback aCallback,
               void* aCallbackData)
   {
     if (!aCallback) {
       BasicManager()->SetTransactionIncomplete();
       return;
     }
-    aCallback(this, aContext, aRegionToDraw, aRegionToInvalidate,
+    aCallback(this, aContext, aExtendedRegionToDraw, aRegionToInvalidate,
               aCallbackData);
     // Everything that's visible has been validated. Do this instead of just
     // OR-ing with aRegionToDraw, since that can lead to a very complex region
     // here (OR doesn't automatically simplify to the simplest possible
     // representation of a region.)
     nsIntRegion tmp;
-    tmp.Or(mVisibleRegion, aRegionToDraw);
+    tmp.Or(mVisibleRegion, aExtendedRegionToDraw);
     mValidRegion.Or(mValidRegion, tmp);
   }
 
   Buffer mBuffer;
 };
 
 /**
  * Clips to the smallest device-pixel-aligned rectangle containing aRect
@@ -594,22 +595,23 @@ BasicThebesLayer::PaintThebes(gfxContext
     mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
     if (state.mContext) {
       // The area that became invalid and is visible needs to be repainted
       // (this could be the whole visible area if our buffer switched
       // from RGB to RGBA, because we might need to repaint with
       // subpixel AA)
       state.mRegionToInvalidate.And(state.mRegionToInvalidate, mVisibleRegion);
-      state.mRegionToDraw.ExtendForScaling(paintXRes, paintYRes);
+      nsIntRegion extendedDrawRegion = state.mRegionToDraw;
+      extendedDrawRegion.ExtendForScaling(paintXRes, paintYRes);
       mXResolution = paintXRes;
       mYResolution = paintYRes;
       SetAntialiasingFlags(this, state.mContext);
       PaintBuffer(state.mContext,
-                  state.mRegionToDraw, state.mRegionToInvalidate,
+                  state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
                   aCallback, aCallbackData);
       Mutated();
     } else {
       // It's possible that state.mRegionToInvalidate is nonempty here,
       // if we are shrinking the valid region to nothing.
       NS_ASSERTION(state.mRegionToDraw.IsEmpty(),
                    "If we need to draw, we should have a context");
     }
@@ -1790,16 +1792,17 @@ private:
   BasicShadowLayerManager* BasicManager()
   {
     return static_cast<BasicShadowLayerManager*>(mManager);
   }
 
   NS_OVERRIDE virtual void
   PaintBuffer(gfxContext* aContext,
               const nsIntRegion& aRegionToDraw,
+              const nsIntRegion& aExtendedRegionToDraw,
               const nsIntRegion& aRegionToInvalidate,
               LayerManager::DrawThebesLayerCallback aCallback,
               void* aCallbackData);
 
   NS_OVERRIDE virtual already_AddRefed<gfxASurface>
   CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
 
   // This describes the gfxASurface we hand to mBuffer.  We keep a
@@ -1849,38 +1852,41 @@ BasicShadowableThebesLayer::SetBackBuffe
   // Now the new back buffer has the same (interesting) pixels as the
   // new front buffer, and mValidRegion et al. are correct wrt the new
   // back buffer (i.e. as they were for the old back buffer)
 }
 
 void
 BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext,
                                         const nsIntRegion& aRegionToDraw,
+                                        const nsIntRegion& aExtendedRegionToDraw,
                                         const nsIntRegion& aRegionToInvalidate,
                                         LayerManager::DrawThebesLayerCallback aCallback,
                                         void* aCallbackData)
 {
-  Base::PaintBuffer(aContext, aRegionToDraw, aRegionToInvalidate,
+  Base::PaintBuffer(aContext,
+                    aRegionToDraw, aExtendedRegionToDraw, aRegionToInvalidate,
                     aCallback, aCallbackData);
   if (!HasShadow()) {
     return;
   }
 
   nsIntRegion updatedRegion;
   if (mIsNewBuffer) {
     // A buffer reallocation clears both buffers. The front buffer has all the
     // content by now, but the back buffer is still clear. Here, in effect, we
     // are saying to copy all of the pixels of the front buffer to the back.
     updatedRegion = mVisibleRegion;
     mIsNewBuffer = false;
   } else {
     updatedRegion = aRegionToDraw;
   }
 
-
+  NS_ASSERTION(mBuffer.BufferRect().Contains(aRegionToDraw.GetBounds()),
+               "Update outside of buffer rect!");
   NS_ABORT_IF_FALSE(IsSurfaceDescriptorValid(mBackBuffer),
                     "should have a back buffer by now");
   BasicManager()->PaintedThebesBuffer(BasicManager()->Hold(this),
                                       updatedRegion,
                                       mBuffer.BufferRect(),
                                       mBuffer.BufferRotation(),
                                       mBackBuffer);
 }