Bug 756601 - Fix bugs with OMTC component alpha. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 10 May 2013 09:02:50 +1200
changeset 142392 3ea8287825682040bdc96aeeabb35386400782b6
parent 142391 a260551434fe50e44d061639f75a82726fc49d08
child 142393 3dcf16f8f334ab5a607e4d92dd4cdc50c9590b6d
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs756601
milestone23.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 756601 - Fix bugs with OMTC component alpha. r=roc
gfx/layers/ThebesLayerBuffer.cpp
gfx/layers/ThebesLayerBuffer.h
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -292,17 +292,17 @@ FillSurface(gfxASurface* aSurface, const
   nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
   ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
   gfxUtils::ClipToRegion(ctx, aRegion);
   ctx->SetColor(aColor);
   ctx->Paint();
 }
 
 already_AddRefed<gfxContext>
-ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource)
+ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint *aTopLeft)
 {
   EnsureBuffer();
 
   nsRefPtr<gfxContext> ctx;
   if (aSource == BUFFER_BOTH && HaveBufferOnWhite()) {
     EnsureBufferOnWhite();
     MOZ_ASSERT(mBuffer, "We don't support azure here yet");
     gfxASurface* surfaces[2] = { mBuffer, mBufferOnWhite };
@@ -337,16 +337,20 @@ ThebesLayerBuffer::GetContextForQuadrant
   int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
   int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
   XSide sideX = aBounds.XMost() <= xBoundary ? RIGHT : LEFT;
   YSide sideY = aBounds.YMost() <= yBoundary ? BOTTOM : TOP;
   nsIntRect quadrantRect = GetQuadrantRectangle(sideX, sideY);
   NS_ASSERTION(quadrantRect.Contains(aBounds), "Messed up quadrants");
   ctx->Translate(-gfxPoint(quadrantRect.x, quadrantRect.y));
 
+  if (aTopLeft) {
+    *aTopLeft = nsIntPoint(quadrantRect.x, quadrantRect.y);
+  }
+
   return ctx.forget();
 }
 
 gfxASurface::gfxContentType
 ThebesLayerBuffer::BufferContentType()
 {
   if (mBuffer) {
     return mBuffer->GetContentType();
@@ -561,16 +565,21 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         // The stuff we need to redraw will wrap around an edge of the
         // buffer, so move the pixels we can keep into a position that
         // lets us redraw in just one quadrant.
         if (mBufferRotation == nsIntPoint(0,0)) {
           nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
           nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
           if (mBuffer) {
             mBuffer->MovePixels(srcRect, dest);
+            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
+              EnsureBufferOnWhite();
+              MOZ_ASSERT(mBufferOnWhite);
+              mBufferOnWhite->MovePixels(srcRect, dest);
+            }
           } else {
             RefPtr<SourceSurface> source = mDTBuffer->Snapshot();
             mDTBuffer->CopySurface(source,
                                    IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
                                    IntPoint(dest.x, dest.y));
           }
           result.mDidSelfCopy = true;
           // Don't set destBuffer; we special-case self-copies, and
@@ -661,22 +670,24 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
   }
   NS_ASSERTION(canHaveRotation || mBufferRotation == nsIntPoint(0,0),
                "Rotation disabled, but we have nonzero rotation?");
 
   nsIntRegion invalidate;
   invalidate.Sub(aLayer->GetValidRegion(), destBufferRect);
   result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate);
 
-  result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH);
+  nsIntPoint topLeft;
+  result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
 
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
     MOZ_ASSERT(mBuffer && mBufferOnWhite, "Must not be using azure!");
-    FillSurface(mBuffer, result.mRegionToDraw, result.mRegionToDraw.GetBounds().TopLeft(), gfxRGBA(0.0, 0.0, 0.0, 1.0));
-    FillSurface(mBufferOnWhite, result.mRegionToDraw, result.mRegionToDraw.GetBounds().TopLeft(), gfxRGBA(1.0, 1.0, 1.0, 1.0));
+    FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
+    FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
+    gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
   } else if (contentType == gfxASurface::CONTENT_COLOR_ALPHA && !isClear) {
     if (result.mContext->IsCairo()) {
       gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
       result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
       result.mContext->Paint();
       result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
     } else {
       nsIntRegionRectIterator iter(result.mRegionToDraw);
--- a/gfx/layers/ThebesLayerBuffer.h
+++ b/gfx/layers/ThebesLayerBuffer.h
@@ -310,19 +310,21 @@ protected:
       mBufferOnWhite = nullptr;
       mDTBufferOnWhite = nullptr;
     } 
   }
 
   /**
    * Get a context at the specified resolution for updating |aBounds|,
    * which must be contained within a single quadrant.
+   *
+   * Optionally returns the TopLeft coordinate of the quadrant being drawn to.
    */
   already_AddRefed<gfxContext>
-  GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource);
+  GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint* aTopLeft = nullptr);
 
   static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion);
 
 protected:
   // Buffer helpers.  Don't use mBuffer directly; instead use one of
   // these helpers.
 
   /**