Bug 959781. Ensure we are using the correct content type in BeginPaint and BorrowDrawTargetForPainting. r=mattwoodrow
authorNicholas Cameron <ncameron@mozilla.com>
Thu, 30 Jan 2014 22:39:11 +1300
changeset 181975 c98dcb17b56b631dba8b0e6b326ad3455aa479ad
parent 181974 2249e151e7f0b110a69d494298c443c12fa08487
child 181976 4bf651486f133ba4ff1067de994d8882139c1387
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs959781
milestone29.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 959781. Ensure we are using the correct content type in BeginPaint and BorrowDrawTargetForPainting. r=mattwoodrow
gfx/layers/RotatedBuffer.cpp
gfx/layers/RotatedBuffer.h
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -407,29 +407,30 @@ RotatedContentBuffer::BeginPaint(ThebesL
   // We need to disable rotation if we're going to be resampled when
   // drawing, because we might sample across the rotation boundary.
   bool canHaveRotation = gfxPlatform::BufferRotationEnabled() &&
                          !(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
 
   nsIntRegion validRegion = aLayer->GetValidRegion();
 
   bool canUseOpaqueSurface = aLayer->CanUseOpaqueSurface();
-  ContentType contentType =
+  ContentType layerContentType =
     canUseOpaqueSurface ? gfxContentType::COLOR :
                           gfxContentType::COLOR_ALPHA;
 
   SurfaceMode mode;
   nsIntRegion neededRegion;
   bool canReuseBuffer;
   nsIntRect destBufferRect;
 
   while (true) {
     mode = aLayer->GetSurfaceMode();
     neededRegion = aLayer->GetVisibleRegion();
     canReuseBuffer = HaveBuffer() && BufferSizeOkFor(neededRegion.GetBounds().Size());
+    result.mContentType = layerContentType;
 
     if (canReuseBuffer) {
       if (mBufferRect.Contains(neededRegion.GetBounds())) {
         // We don't need to adjust mBufferRect.
         destBufferRect = mBufferRect;
       } else if (neededRegion.GetBounds().Size() <= mBufferRect.Size()) {
         // The buffer's big enough but doesn't contain everything that's
         // going to be visible. We'll move it.
@@ -449,39 +450,39 @@ RotatedContentBuffer::BeginPaint(ThebesL
       if (!aLayer->GetParent() ||
           !aLayer->GetParent()->SupportsComponentAlphaChildren() ||
           !aLayer->Manager()->IsCompositingCheap() ||
           !aLayer->AsShadowableLayer() ||
           !aLayer->AsShadowableLayer()->HasShadow() ||
           !gfxPlatform::ComponentAlphaEnabled()) {
         mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
       } else {
-        contentType = gfxContentType::COLOR;
+        result.mContentType = gfxContentType::COLOR;
       }
 #endif
     }
 
     if ((aFlags & PAINT_WILL_RESAMPLE) &&
         (!neededRegion.GetBounds().IsEqualInterior(destBufferRect) ||
          neededRegion.GetNumRects() > 1)) {
       // The area we add to neededRegion might not be painted opaquely
       if (mode == SurfaceMode::SURFACE_OPAQUE) {
-        contentType = gfxContentType::COLOR_ALPHA;
+        result.mContentType = gfxContentType::COLOR_ALPHA;
         mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
       }
 
       // We need to validate the entire buffer, to make sure that only valid
       // pixels are sampled
       neededRegion = destBufferRect;
     }
 
     // If we have an existing buffer, but the content type has changed or we
     // have transitioned into/out of component alpha, then we need to recreate it.
     if (HaveBuffer() &&
-        (contentType != BufferContentType() ||
+        (result.mContentType != BufferContentType() ||
         (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) != HaveBufferOnWhite())) {
 
       // We're effectively clearing the valid region, so we need to draw
       // the entire needed region now.
       result.mRegionToInvalidate = aLayer->GetValidRegion();
       validRegion.SetEmpty();
       Clear();
       // Restart decision process with the cleared buffer. We can only go
@@ -492,17 +493,17 @@ RotatedContentBuffer::BeginPaint(ThebesL
     break;
   }
 
   NS_ASSERTION(destBufferRect.Contains(neededRegion.GetBounds()),
                "Destination rect doesn't contain what we need to paint");
 
   result.mRegionToDraw.Sub(neededRegion, validRegion);
 
-  // Do not modify result.mRegionToDraw after this call.
+  // Do not modify result.mRegionToDraw or result.mContentType after this call.
   // Do not modify mBufferRect, mBufferRotation, or mDidSelfCopy,
   // or call CreateBuffer before this call.
   FinalizeFrame(result.mRegionToDraw);
 
   if (result.mRegionToDraw.IsEmpty())
     return result;
 
   nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
@@ -589,17 +590,17 @@ RotatedContentBuffer::BeginPaint(ThebesL
             result.mDidSelfCopy = true;
             mDidSelfCopy = true;
             mBufferRect = destBufferRect;
             mBufferRotation = nsIntPoint(0, 0);
           }
 
           if (!result.mDidSelfCopy) {
             destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
-            CreateBuffer(contentType, destBufferRect, bufferFlags,
+            CreateBuffer(result.mContentType, destBufferRect, bufferFlags,
                          &destDTBuffer, &destDTBufferOnWhite);
             if (!destDTBuffer) {
               return result;
             }
           }
         }
       } else {
         mBufferRect = destBufferRect;
@@ -609,17 +610,17 @@ RotatedContentBuffer::BeginPaint(ThebesL
       // No pixels are going to be kept. The whole visible region
       // will be redrawn, so we don't need to copy anything, so we don't
       // set destBuffer.
       mBufferRect = destBufferRect;
       mBufferRotation = nsIntPoint(0,0);
     }
   } else {
     // The buffer's not big enough, so allocate a new one
-    CreateBuffer(contentType, destBufferRect, bufferFlags,
+    CreateBuffer(result.mContentType, destBufferRect, bufferFlags,
                  &destDTBuffer, &destDTBufferOnWhite);
     if (!destDTBuffer) {
       return result;
     }
   }
 
   NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(),
                "If we're resampling, we need to validate the entire buffer");
@@ -677,32 +678,27 @@ RotatedContentBuffer::BorrowDrawTargetFo
 {
   if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
     return nullptr;
   }
 
   DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(aPaintState.mRegionToDraw.GetBounds(),
                                                          BUFFER_BOTH);
 
-  bool canUseOpaqueSurface = aLayer->CanUseOpaqueSurface();
-  ContentType contentType =
-    canUseOpaqueSurface ? gfxContentType::COLOR :
-                          gfxContentType::COLOR_ALPHA;
-
   if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
     MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
     nsIntRegionRectIterator iter(aPaintState.mRegionToDraw);
     const nsIntRect *iterRect;
     while ((iterRect = iter.Next())) {
       mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
                           ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
       mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
                                  ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
     }
-  } else if (contentType == gfxContentType::COLOR_ALPHA && HaveBuffer()) {
+  } else if (aPaintState.mContentType == gfxContentType::COLOR_ALPHA && HaveBuffer()) {
     // HaveBuffer() => we have an existing buffer that we must clear
     nsIntRegionRectIterator iter(aPaintState.mRegionToDraw);
     const nsIntRect *iterRect;
     while ((iterRect = iter.Next())) {
       result->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     }
   }
 
--- a/gfx/layers/RotatedBuffer.h
+++ b/gfx/layers/RotatedBuffer.h
@@ -209,23 +209,25 @@ public:
    * mRegionToInvalidate is set when the buffer has changed from
    * opaque to transparent or vice versa, since the details of rendering can
    * depend on the buffer type.  mDidSelfCopy is true if we kept our buffer
    * but used MovePixels() to shift its content.
    */
   struct PaintState {
     PaintState()
       : mMode(SurfaceMode::SURFACE_NONE)
+      , mContentType(gfxContentType::SENTINEL)
       , mDidSelfCopy(false)
     {}
 
     nsIntRegion mRegionToDraw;
     nsIntRegion mRegionToInvalidate;
     SurfaceMode mMode;
     DrawRegionClip mClip;
+    ContentType mContentType;
     bool mDidSelfCopy;
   };
 
   enum {
     PAINT_WILL_RESAMPLE = 0x01,
     PAINT_NO_ROTATION = 0x02
   };
   /**