--- 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.
/**