diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 5b0edfe88b35..06ca425d1f4e 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -26,6 +26,7 @@ #include "gfxContext.h" #include "gfxColor.h" #include "gfxUtils.h" +#include "mozilla/gfx/2D.h" #include "Layers.h" #include "SharedTextureImage.h" #include "GLContext.h" @@ -814,13 +815,15 @@ PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect, } } -#ifdef DEBUG gfxIntSize sz = mBackground->GetSize(); +#ifdef DEBUG NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect), "Update outside of background area"); #endif - nsRefPtr ctx = new gfxContext(mBackground); + RefPtr dt = gfxPlatform::GetPlatform()-> + CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height)); + nsRefPtr ctx = new gfxContext(dt); *aCtx = ctx.forget().get(); return NS_OK; diff --git a/gfx/layers/ThebesLayerBuffer.cpp b/gfx/layers/ThebesLayerBuffer.cpp index c48253161c92..772b8fb2427a 100644 --- a/gfx/layers/ThebesLayerBuffer.cpp +++ b/gfx/layers/ThebesLayerBuffer.cpp @@ -71,106 +71,6 @@ RotatedBuffer::GetSourceRectangle(XSide aXSide, YSide aYSide) const return result; } -/** - * @param aXSide LEFT means we draw from the left side of the buffer (which - * is drawn on the right side of mBufferRect). RIGHT means we draw from - * the right side of the buffer (which is drawn on the left side of - * mBufferRect). - * @param aYSide TOP means we draw from the top side of the buffer (which - * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from - * the bottom side of the buffer (which is drawn on the top side of - * mBufferRect). - */ -void -RotatedBuffer::DrawBufferQuadrant(gfxContext* aTarget, - XSide aXSide, YSide aYSide, - ContextSource aSource, - float aOpacity, - gfxASurface* aMask, - const gfxMatrix* aMaskTransform) const -{ - // The rectangle that we're going to fill. Basically we're going to - // render the buffer at mBufferRect + quadrantTranslation to get the - // pixels in the right place, but we're only going to paint within - // mBufferRect - nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide); - nsIntRect fillRect; - if (!fillRect.IntersectRect(mBufferRect, quadrantRect)) { - return; - } - - nsRefPtr source; - - if (aSource == BUFFER_BLACK) { - if (mBuffer) { - source = mBuffer; - } else if (mDTBuffer) { - source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBuffer); - } else { - NS_WARNING("Can't draw a RotatedBuffer without any buffer!"); - return; - } - } else { - MOZ_ASSERT(aSource == BUFFER_WHITE); - if (mBufferOnWhite) { - source = mBufferOnWhite; - } else if (mDTBufferOnWhite) { - source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBufferOnWhite); - } else { - NS_WARNING("Can't draw a RotatedBuffer without any buffer!"); - return; - } - } - - - aTarget->NewPath(); - aTarget->Rectangle(gfxRect(fillRect.x, fillRect.y, - fillRect.width, fillRect.height), - true); - - gfxPoint quadrantTranslation(quadrantRect.x, quadrantRect.y); - nsRefPtr pattern = new gfxPattern(source); - -#ifdef MOZ_GFX_OPTIMIZE_MOBILE - GraphicsFilter filter = GraphicsFilter::FILTER_NEAREST; - pattern->SetFilter(filter); -#endif - - gfxContextMatrixAutoSaveRestore saveMatrix(aTarget); - - // Transform from user -> buffer space. - gfxMatrix transform; - transform.Translate(-quadrantTranslation); - - pattern->SetMatrix(transform); - aTarget->SetPattern(pattern); - - if (aMask) { - if (aOpacity == 1.0) { - aTarget->SetMatrix(*aMaskTransform); - aTarget->Mask(aMask); - } else { - aTarget->PushGroup(GFX_CONTENT_COLOR_ALPHA); - aTarget->Paint(aOpacity); - aTarget->PopGroupToSource(); - aTarget->SetMatrix(*aMaskTransform); - aTarget->Mask(aMask); - } - } else { - if (aOpacity == 1.0) { - aTarget->Fill(); - } else { - aTarget->Save(); - aTarget->Clip(); - aTarget->Paint(aOpacity); - aTarget->Restore(); - } - } - - nsRefPtr surf = aTarget->CurrentSurface(); - surf->Flush(); -} - /** * @param aXSide LEFT means we draw from the left side of the buffer (which * is drawn on the right side of mBufferRect). RIGHT means we draw from @@ -264,21 +164,6 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget, aTarget->Flush(); } -void -RotatedBuffer::DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource, - float aOpacity, - gfxASurface* aMask, - const gfxMatrix* aMaskTransform) const -{ - PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation"); - // Draw four quadrants. We could use REPEAT_, but it's probably better - // not to, to be performance-safe. - DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aMask, aMaskTransform); - DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aMask, aMaskTransform); - DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform); - DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform); -} - void RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource, float aOpacity, @@ -316,74 +201,42 @@ ThebesLayerBuffer::DrawTo(ThebesLayer* aLayer, return; } - if (aTarget->IsCairo()) { - aTarget->Save(); - // If the entire buffer is valid, we can just draw the whole thing, - // no need to clip. But we'll still clip if clipping is cheap --- - // that might let us copy a smaller region of the buffer. - // Also clip to the visible region if we're told to. - if (!aLayer->GetValidRegion().Contains(BufferRect()) || - (ToData(aLayer)->GetClipToVisibleRegion() && - !aLayer->GetVisibleRegion().Contains(BufferRect())) || - IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) { - // We don't want to draw invalid stuff, so we need to clip. Might as - // well clip to the smallest area possible --- the visible region. - // Bug 599189 if there is a non-integer-translation transform in aTarget, - // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong - // and may cause gray lines. - gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion()); - } + RefPtr dt = aTarget->GetDrawTarget(); + MOZ_ASSERT(dt, "Did you pass a non-Azure gfxContext?"); + bool clipped = false; - DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aMask, aMaskTransform); - aTarget->Restore(); - } else { - RefPtr dt = aTarget->GetDrawTarget(); - bool clipped = false; - - // If the entire buffer is valid, we can just draw the whole thing, - // no need to clip. But we'll still clip if clipping is cheap --- - // that might let us copy a smaller region of the buffer. - // Also clip to the visible region if we're told to. - if (!aLayer->GetValidRegion().Contains(BufferRect()) || - (ToData(aLayer)->GetClipToVisibleRegion() && - !aLayer->GetVisibleRegion().Contains(BufferRect())) || - IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) { - // We don't want to draw invalid stuff, so we need to clip. Might as - // well clip to the smallest area possible --- the visible region. - // Bug 599189 if there is a non-integer-translation transform in aTarget, - // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong - // and may cause gray lines. - gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion()); - clipped = true; - } - - RefPtr mask; - if (aMask) { - mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask); - } - - Matrix maskTransform; - if (aMaskTransform) { - maskTransform = ToMatrix(*aMaskTransform); - } - - CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator()); - DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform); - if (clipped) { - dt->PopClip(); - } + // If the entire buffer is valid, we can just draw the whole thing, + // no need to clip. But we'll still clip if clipping is cheap --- + // that might let us copy a smaller region of the buffer. + // Also clip to the visible region if we're told to. + if (!aLayer->GetValidRegion().Contains(BufferRect()) || + (ToData(aLayer)->GetClipToVisibleRegion() && + !aLayer->GetVisibleRegion().Contains(BufferRect())) || + IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) { + // We don't want to draw invalid stuff, so we need to clip. Might as + // well clip to the smallest area possible --- the visible region. + // Bug 599189 if there is a non-integer-translation transform in aTarget, + // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong + // and may cause gray lines. + gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion()); + clipped = true; } -} -static void -FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion, - const nsIntPoint& aOffset, const gfxRGBA& aColor) -{ - nsRefPtr ctx = new gfxContext(aSurface); - ctx->Translate(-gfxPoint(aOffset.x, aOffset.y)); - gfxUtils::ClipToRegion(ctx, aRegion); - ctx->SetColor(aColor); - ctx->Paint(); + RefPtr mask; + if (aMask) { + mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask); + } + + Matrix maskTransform; + if (aMaskTransform) { + maskTransform = ToMatrix(*aMaskTransform); + } + + CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator()); + DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform); + if (clipped) { + dt->PopClip(); + } } already_AddRefed @@ -398,41 +251,17 @@ ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, Context if (!EnsureBufferOnWhite()) { return nullptr; } - if (mBuffer) { - MOZ_ASSERT(mBufferOnWhite); - gfxASurface* surfaces[2] = { mBuffer, mBufferOnWhite }; - nsRefPtr surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces)); - - // XXX If the device offset is set on the individual surfaces instead of on - // the tee surface, we render in the wrong place. Why? - gfxPoint deviceOffset = mBuffer->GetDeviceOffset(); - surfaces[0]->SetDeviceOffset(gfxPoint(0, 0)); - surfaces[1]->SetDeviceOffset(gfxPoint(0, 0)); - surf->SetDeviceOffset(deviceOffset); - - surf->SetAllowUseAsSource(false); - ctx = new gfxContext(surf); - } else { - MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite); - RefPtr dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite); - ctx = new gfxContext(dualDT); - } + MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite); + RefPtr dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite); + ctx = new gfxContext(dualDT); } else if (aSource == BUFFER_WHITE) { if (!EnsureBufferOnWhite()) { return nullptr; } - if (mBufferOnWhite) { - ctx = new gfxContext(mBufferOnWhite); - } else { - ctx = new gfxContext(mDTBufferOnWhite); - } + ctx = new gfxContext(mDTBufferOnWhite); } else { // BUFFER_BLACK, or BUFFER_BOTH with a single buffer. - if (mBuffer) { - ctx = new gfxContext(mBuffer); - } else { - ctx = new gfxContext(mDTBuffer); - } + ctx = new gfxContext(mDTBuffer); } // Figure out which quadrant to draw in @@ -454,9 +283,6 @@ ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, Context gfxContentType ThebesLayerBuffer::BufferContentType() { - if (mBuffer) { - return mBuffer->GetContentType(); - } if (mBufferProvider) { return mBufferProvider->GetContentType(); } @@ -482,67 +308,38 @@ ThebesLayerBuffer::BufferSizeOkFor(const nsIntSize& aSize) aSize < mBufferRect.Size())); } -bool -ThebesLayerBuffer::IsAzureBuffer() -{ - MOZ_ASSERT(!(mDTBuffer && mBuffer), "Trying to use Azure and Thebes in the same buffer?"); - if (mDTBuffer) { - return true; - } - if (mBuffer) { - return false; - } - if (mBufferProvider) { - return gfxPlatform::GetPlatform()->SupportsAzureContentForType( - mBufferProvider->BackendType()); - } - return SupportsAzureContent(); -} - bool ThebesLayerBuffer::EnsureBuffer() { - if ((!mBuffer && !mDTBuffer) && mBufferProvider) { - if (IsAzureBuffer()) { - mDTBuffer = mBufferProvider->LockDrawTarget(); - mBuffer = nullptr; - } else { - mBuffer = mBufferProvider->LockSurface(); - mDTBuffer = nullptr; - } + if (!mDTBuffer && mBufferProvider) { + mDTBuffer = mBufferProvider->LockDrawTarget(); } - NS_WARN_IF_FALSE(mBuffer || mDTBuffer, "no buffer"); - return mBuffer || mDTBuffer; + NS_WARN_IF_FALSE(mDTBuffer, "no buffer"); + return !!mDTBuffer; } bool ThebesLayerBuffer::EnsureBufferOnWhite() { - if ((!mBufferOnWhite && !mDTBufferOnWhite) && mBufferProviderOnWhite) { - if (IsAzureBuffer()) { - mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget(); - mBufferOnWhite = nullptr; - } else { - mBufferOnWhite = mBufferProviderOnWhite->LockSurface(); - mDTBufferOnWhite = nullptr; - } + if (!mDTBufferOnWhite && mBufferProviderOnWhite) { + mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget(); } - NS_WARN_IF_FALSE(mBufferOnWhite || mDTBufferOnWhite, "no buffer"); - return mBufferOnWhite || mDTBufferOnWhite; + NS_WARN_IF_FALSE(mDTBufferOnWhite, "no buffer"); + return mDTBufferOnWhite; } bool ThebesLayerBuffer::HaveBuffer() const { - return mDTBuffer || mBuffer || mBufferProvider; + return mDTBuffer || mBufferProvider; } bool ThebesLayerBuffer::HaveBufferOnWhite() const { - return mDTBufferOnWhite || mBufferOnWhite || mBufferProviderOnWhite; + return mDTBufferOnWhite || mBufferProviderOnWhite; } static void @@ -680,8 +477,6 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, return result; nsIntRect drawBounds = result.mRegionToDraw.GetBounds(); - nsRefPtr destBuffer; - nsRefPtr destBufferOnWhite; RefPtr destDTBuffer; RefPtr destDTBufferOnWhite; uint32_t bufferFlags = canHaveRotation ? ALLOW_REPEAT : 0; @@ -714,28 +509,16 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, if (mBufferRotation == nsIntPoint(0,0)) { nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size()); nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft(); - if (IsAzureBuffer()) { - MOZ_ASSERT(mDTBuffer); - mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height), - IntPoint(dest.x, dest.y)); - if (mode == Layer::SURFACE_COMPONENT_ALPHA) { - if (!EnsureBufferOnWhite()) { - return result; - } - MOZ_ASSERT(mDTBufferOnWhite); - mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height), - IntPoint(dest.x, dest.y)); - } - } else { - MOZ_ASSERT(mBuffer); - mBuffer->MovePixels(srcRect, dest); - if (mode == Layer::SURFACE_COMPONENT_ALPHA) { - if (!EnsureBufferOnWhite()) { - return result; - } - MOZ_ASSERT(mBufferOnWhite); - mBufferOnWhite->MovePixels(srcRect, dest); + MOZ_ASSERT(mDTBuffer); + mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height), + IntPoint(dest.x, dest.y)); + if (mode == Layer::SURFACE_COMPONENT_ALPHA) { + if (!EnsureBufferOnWhite()) { + return result; } + MOZ_ASSERT(mDTBufferOnWhite); + mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height), + IntPoint(dest.x, dest.y)); } result.mDidSelfCopy = true; mDidSelfCopy = true; @@ -745,50 +528,48 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, } else { // With azure and a data surface perform an buffer unrotate // (SelfCopy). - if (IsAzureBuffer()) { - unsigned char* data; - IntSize size; - int32_t stride; - SurfaceFormat format; + unsigned char* data; + IntSize size; + int32_t stride; + SurfaceFormat format; - if (mDTBuffer->LockBits(&data, &size, &stride, &format)) { + if (mDTBuffer->LockBits(&data, &size, &stride, &format)) { + uint8_t bytesPerPixel = BytesPerPixel(format); + BufferUnrotate(data, + size.width * bytesPerPixel, + size.height, stride, + newRotation.x * bytesPerPixel, newRotation.y); + mDTBuffer->ReleaseBits(data); + + if (mode == Layer::SURFACE_COMPONENT_ALPHA) { + if (!EnsureBufferOnWhite()) { + return result; + } + MOZ_ASSERT(mDTBufferOnWhite); + mDTBufferOnWhite->LockBits(&data, &size, &stride, &format); uint8_t bytesPerPixel = BytesPerPixel(format); BufferUnrotate(data, size.width * bytesPerPixel, size.height, stride, newRotation.x * bytesPerPixel, newRotation.y); - mDTBuffer->ReleaseBits(data); - - if (mode == Layer::SURFACE_COMPONENT_ALPHA) { - if (!EnsureBufferOnWhite()) { - return result; - } - MOZ_ASSERT(mDTBufferOnWhite); - mDTBufferOnWhite->LockBits(&data, &size, &stride, &format); - uint8_t bytesPerPixel = BytesPerPixel(format); - BufferUnrotate(data, - size.width * bytesPerPixel, - size.height, stride, - newRotation.x * bytesPerPixel, newRotation.y); - mDTBufferOnWhite->ReleaseBits(data); - } - - // Buffer unrotate moves all the pixels, note that - // we self copied for SyncBackToFrontBuffer - result.mDidSelfCopy = true; - mDidSelfCopy = true; - mBufferRect = destBufferRect; - mBufferRotation = nsIntPoint(0, 0); + mDTBufferOnWhite->ReleaseBits(data); } + + // Buffer unrotate moves all the pixels, note that + // we self copied for SyncBackToFrontBuffer + result.mDidSelfCopy = true; + mDidSelfCopy = true; + mBufferRect = destBufferRect; + mBufferRotation = nsIntPoint(0, 0); } if (!result.mDidSelfCopy) { destBufferRect = ComputeBufferRect(neededRegion.GetBounds()); CreateBuffer(contentType, destBufferRect, bufferFlags, - getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite), &destDTBuffer, &destDTBufferOnWhite); - if (!destBuffer && !destDTBuffer) + if (!destDTBuffer) { return result; + } } } } else { @@ -805,10 +586,10 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, } else { // The buffer's not big enough, so allocate a new one CreateBuffer(contentType, destBufferRect, bufferFlags, - getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite), &destDTBuffer, &destDTBufferOnWhite); - if (!destBuffer && !destDTBuffer) + if (!destDTBuffer) { return result; + } } NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(), @@ -818,37 +599,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, // and we do not need to clear it below. bool isClear = !HaveBuffer(); - if (destBuffer) { - if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) { - // Copy the bits - nsRefPtr tmpCtx = new gfxContext(destBuffer); - nsIntPoint offset = -destBufferRect.TopLeft(); - tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); - tmpCtx->Translate(gfxPoint(offset.x, offset.y)); - if (!EnsureBuffer()) { - return result; - } - DrawBufferWithRotation(tmpCtx, BUFFER_BLACK); - - if (mode == Layer::SURFACE_COMPONENT_ALPHA) { - if (!EnsureBufferOnWhite()) { - return result; - } - NS_ASSERTION(destBufferOnWhite, "Must have a white buffer!"); - nsRefPtr tmpCtx = new gfxContext(destBufferOnWhite); - tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); - tmpCtx->Translate(gfxPoint(offset.x, offset.y)); - DrawBufferWithRotation(tmpCtx, BUFFER_WHITE); - } - } - - mBuffer = destBuffer.forget(); - mDTBuffer = nullptr; - mBufferRect = destBufferRect; - mBufferOnWhite = destBufferOnWhite.forget(); - mDTBufferOnWhite = nullptr; - mBufferRotation = nsIntPoint(0,0); - } else if (destDTBuffer) { + if (destDTBuffer) { if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) { // Copy the bits nsIntPoint offset = -destBufferRect.TopLeft(); @@ -875,9 +626,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, } mDTBuffer = destDTBuffer.forget(); - mBuffer = nullptr; mDTBufferOnWhite = destDTBufferOnWhite.forget(); - mBufferOnWhite = nullptr; mBufferRect = destBufferRect; mBufferRotation = nsIntPoint(0,0); } @@ -893,37 +642,20 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, result.mClip = CLIP_DRAW_SNAPPED; if (mode == Layer::SURFACE_COMPONENT_ALPHA) { - if (IsAzureBuffer()) { - MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite); - nsIntRegionRectIterator iter(result.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 { - MOZ_ASSERT(mBuffer && mBufferOnWhite); - 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)); + MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite); + nsIntRegionRectIterator iter(result.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 == GFX_CONTENT_COLOR_ALPHA && !isClear) { - if (IsAzureBuffer()) { - nsIntRegionRectIterator iter(result.mRegionToDraw); - const nsIntRect *iterRect; - while ((iterRect = iter.Next())) { - result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height)); - } - // Clear will do something expensive with a complex clip pushed, so clip - // here. - } else { - MOZ_ASSERT(result.mContext->IsCairo()); - result.mContext->Save(); - gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw); - result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR); - result.mContext->Paint(); - result.mContext->Restore(); + nsIntRegionRectIterator iter(result.mRegionToDraw); + const nsIntRect *iterRect; + while ((iterRect = iter.Next())) { + result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height)); } } diff --git a/gfx/layers/ThebesLayerBuffer.h b/gfx/layers/ThebesLayerBuffer.h index 05e9a11e6b16..dc8b6c1450b9 100644 --- a/gfx/layers/ThebesLayerBuffer.h +++ b/gfx/layers/ThebesLayerBuffer.h @@ -55,15 +55,6 @@ class RotatedBuffer { public: typedef gfxContentType ContentType; - RotatedBuffer(gfxASurface* aBuffer, gfxASurface* aBufferOnWhite, - const nsIntRect& aBufferRect, - const nsIntPoint& aBufferRotation) - : mBuffer(aBuffer) - , mBufferOnWhite(aBufferOnWhite) - , mBufferRect(aBufferRect) - , mBufferRotation(aBufferRotation) - , mDidSelfCopy(false) - { } RotatedBuffer(gfx::DrawTarget* aDTBuffer, gfx::DrawTarget* aDTBufferOnWhite, const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation) @@ -85,11 +76,6 @@ public: BUFFER_WHITE, // The buffer with white background, only valid with component alpha. BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading. }; - void DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource, - float aOpacity = 1.0, - gfxASurface* aMask = nullptr, - const gfxMatrix* aMaskTransform = nullptr) const; - void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource, float aOpacity = 1.0, gfx::CompositionOp aOperator = gfx::OP_OVER, @@ -104,8 +90,8 @@ public: const nsIntRect& BufferRect() const { return mBufferRect; } const nsIntPoint& BufferRotation() const { return mBufferRotation; } - virtual bool HaveBuffer() const { return mBuffer || mDTBuffer; } - virtual bool HaveBufferOnWhite() const { return mBufferOnWhite || mDTBufferOnWhite; } + virtual bool HaveBuffer() const { return mDTBuffer; } + virtual bool HaveBufferOnWhite() const { return mDTBufferOnWhite; } protected: @@ -124,11 +110,6 @@ protected: * buffer. aMaskTransform must be non-null if aMask is non-null, and is used * to adjust the coordinate space of the mask. */ - void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide, - ContextSource aSource, - float aOpacity, - gfxASurface* aMask, - const gfxMatrix* aMaskTransform) const; void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide, ContextSource aSource, float aOpacity, @@ -136,8 +117,6 @@ protected: gfx::SourceSurface* aMask, const gfx::Matrix* aMaskTransform) const; - nsRefPtr mBuffer; - nsRefPtr mBufferOnWhite; RefPtr mDTBuffer; RefPtr mDTBufferOnWhite; /** The area of the ThebesLayer that is covered by the buffer as a whole */ @@ -196,8 +175,6 @@ public: */ void Clear() { - mBuffer = nullptr; - mBufferOnWhite = nullptr; mDTBuffer = nullptr; mDTBufferOnWhite = nullptr; mBufferProvider = nullptr; @@ -264,18 +241,13 @@ public: */ virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, - gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface, RefPtr* aBlackDT, RefPtr* aWhiteDT) = 0; - virtual bool SupportsAzureContent() const - { return false; } /** * Get the underlying buffer, if any. This is useful because we can pass * in the buffer as the default "reference surface" if there is one. * Don't use it for anything else! */ - gfxASurface* GetBuffer() { return mBuffer; } - gfxASurface* GetBufferOnWhite() { return mBufferOnWhite; } gfx::DrawTarget* GetDTBuffer() { return mDTBuffer; } gfx::DrawTarget* GetDTBufferOnWhite() { return mDTBufferOnWhite; } @@ -288,35 +260,11 @@ public: gfxASurface* aMask, const gfxMatrix* aMaskTransform); protected: - // If this buffer is currently using Azure. - bool IsAzureBuffer(); - - already_AddRefed - SetBuffer(gfxASurface* aBuffer, - const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation) - { - MOZ_ASSERT(!SupportsAzureContent()); - nsRefPtr tmp = mBuffer.forget(); - mBuffer = aBuffer; - mBufferRect = aBufferRect; - mBufferRotation = aBufferRotation; - return tmp.forget(); - } - - already_AddRefed - SetBufferOnWhite(gfxASurface* aBuffer) - { - MOZ_ASSERT(!SupportsAzureContent()); - nsRefPtr tmp = mBufferOnWhite.forget(); - mBufferOnWhite = aBuffer; - return tmp.forget(); - } - TemporaryRef SetDTBuffer(gfx::DrawTarget* aBuffer, - const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation) + const nsIntRect& aBufferRect, + const nsIntPoint& aBufferRotation) { - MOZ_ASSERT(SupportsAzureContent()); RefPtr tmp = mDTBuffer.forget(); mDTBuffer = aBuffer; mBufferRect = aBufferRect; @@ -327,7 +275,6 @@ protected: TemporaryRef SetDTBufferOnWhite(gfx::DrawTarget* aBuffer) { - MOZ_ASSERT(SupportsAzureContent()); RefPtr tmp = mDTBufferOnWhite.forget(); mDTBufferOnWhite = aBuffer; return tmp.forget(); @@ -348,11 +295,10 @@ protected: { // Only this buffer provider can give us a buffer. If we // already have one, something has gone wrong. - MOZ_ASSERT(!aClient || (!mBuffer && !mDTBuffer)); + MOZ_ASSERT(!aClient || !mDTBuffer); mBufferProvider = aClient; if (!mBufferProvider) { - mBuffer = nullptr; mDTBuffer = nullptr; } } @@ -361,11 +307,10 @@ protected: { // Only this buffer provider can give us a buffer. If we // already have one, something has gone wrong. - MOZ_ASSERT(!aClient || (!mBufferOnWhite && !mDTBufferOnWhite)); + MOZ_ASSERT(!aClient || !mDTBufferOnWhite); mBufferProviderOnWhite = aClient; if (!mBufferProviderOnWhite) { - mBufferOnWhite = nullptr; mDTBufferOnWhite = nullptr; } } @@ -382,9 +327,6 @@ protected: static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion); protected: - // Buffer helpers. Don't use mBuffer directly; instead use one of - // these helpers. - /** * Return the buffer's content type. Requires a valid buffer or * buffer provider. diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 8ff89ece35cc..c5201c26142f 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -82,37 +82,17 @@ void ContentClientBasic::CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, - gfxASurface** aBlackSurface, - gfxASurface** aWhiteSurface, RefPtr* aBlackDT, RefPtr* aWhiteDT) { MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA)); - if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { - gfxImageFormat format = - gfxPlatform::GetPlatform()->OptimalFormatForContent(aType); + MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent()); + gfxImageFormat format = + gfxPlatform::GetPlatform()->OptimalFormatForContent(aType); - *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( - IntSize(aRect.width, aRect.height), - ImageFormatToSurfaceFormat(format)); - return; - } - - nsRefPtr referenceSurface = GetBuffer(); - if (!referenceSurface) { - gfxContext* defaultTarget = mManager->GetDefaultTarget(); - if (defaultTarget) { - referenceSurface = defaultTarget->CurrentSurface(); - } else { - nsIWidget* widget = mManager->GetRetainerWidget(); - if (!widget || !(referenceSurface = widget->GetThebesSurface())) { - referenceSurface = mManager->GetTarget()->CurrentSurface(); - } - } - } - nsRefPtr ret = referenceSurface->CreateSimilarSurface( - aType, gfxIntSize(aRect.width, aRect.height)); - *aBlackSurface = ret.forget().get(); + *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( + IntSize(aRect.width, aRect.height), + ImageFormatToSurfaceFormat(format)); } void @@ -219,27 +199,10 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType, mIsNewBuffer = true; } -bool -ContentClientBasic::SupportsAzureContent() const -{ - return gfxPlatform::GetPlatform()->SupportsAzureContent(); -} - -bool -ContentClientRemoteBuffer::SupportsAzureContent() const -{ - MOZ_ASSERT(mDeprecatedTextureClient); - - return gfxPlatform::GetPlatform()->SupportsAzureContentForType( - mDeprecatedTextureClient->BackendType()); -} - void ContentClientRemoteBuffer::CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, - gfxASurface** aBlackSurface, - gfxASurface** aWhiteSurface, RefPtr* aBlackDT, RefPtr* aWhiteDT) { @@ -248,19 +211,11 @@ ContentClientRemoteBuffer::CreateBuffer(ContentType aType, return; } - if (gfxPlatform::GetPlatform()->SupportsAzureContentForType( - mDeprecatedTextureClient->BackendType())) { - *aBlackDT = mDeprecatedTextureClient->LockDrawTarget(); - if (aFlags & BUFFER_COMPONENT_ALPHA) { - *aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget(); - } - } else { - nsRefPtr ret = mDeprecatedTextureClient->LockSurface(); - *aBlackSurface = ret.forget().get(); - if (aFlags & BUFFER_COMPONENT_ALPHA) { - nsRefPtr retWhite = mDeprecatedTextureClientOnWhite->LockSurface(); - *aWhiteSurface = retWhite.forget().get(); - } + MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContentForType( + mDeprecatedTextureClient->BackendType())); + *aBlackDT = mDeprecatedTextureClient->LockDrawTarget(); + if (aFlags & BUFFER_COMPONENT_ALPHA) { + *aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget(); } } @@ -471,15 +426,6 @@ struct AutoDeprecatedTextureClient { mTexture->Unlock(); } } - gfxASurface* GetSurface(DeprecatedTextureClient* aTexture) - { - MOZ_ASSERT(!mTexture); - mTexture = aTexture; - if (mTexture) { - return mTexture->LockSurface(); - } - return nullptr; - } DrawTarget* GetDrawTarget(DeprecatedTextureClient* aTexture) { MOZ_ASSERT(!mTexture); @@ -536,25 +482,15 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer() AutoDeprecatedTextureClient autoTextureFront; AutoDeprecatedTextureClient autoTextureFrontOnWhite; - if (SupportsAzureContent()) { - // We need to ensure that we lock these two buffers in the same - // order as the compositor to prevent deadlocks. - DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient); - DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite); - RotatedBuffer frontBuffer(dt, - dtOnWhite, - mFrontBufferRect, - mFrontBufferRotation); - UpdateDestinationFrom(frontBuffer, updateRegion); - } else { - gfxASurface* surf = autoTextureFront.GetSurface(mFrontClient); - gfxASurface* surfOnWhite = autoTextureFrontOnWhite.GetSurface(mFrontClientOnWhite); - RotatedBuffer frontBuffer(surf, - surfOnWhite, - mFrontBufferRect, - mFrontBufferRotation); - UpdateDestinationFrom(frontBuffer, updateRegion); - } + // We need to ensure that we lock these two buffers in the same + // order as the compositor to prevent deadlocks. + DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient); + DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite); + RotatedBuffer frontBuffer(dt, + dtOnWhite, + mFrontBufferRect, + mFrontBufferRotation); + UpdateDestinationFrom(frontBuffer, updateRegion); mFrontAndBackBufferDiffer = false; } @@ -575,12 +511,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource, gfxUtils::ClipToRegion(destCtx, aUpdateRegion); } - if (SupportsAzureContent()) { - MOZ_ASSERT(!destCtx->IsCairo()); - aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE); - } else { - aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK); - } + aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE); if (aSource.HaveBufferOnWhite()) { MOZ_ASSERT(HaveBufferOnWhite()); @@ -593,12 +524,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource, gfxUtils::ClipToRegion(destCtx, aUpdateRegion); } - if (SupportsAzureContent()) { - MOZ_ASSERT(!destCtx->IsCairo()); - aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE); - } else { - aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE); - } + aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE); } } @@ -630,57 +556,30 @@ ContentClientSingleBuffered::SyncFrontBufferToBackBuffer() } mFrontAndBackBufferDiffer = false; - if (SupportsAzureContent()) { - DrawTarget* backBuffer = GetDTBuffer(); - if (!backBuffer && mDeprecatedTextureClient) { - backBuffer = mDeprecatedTextureClient->LockDrawTarget(); - } - if (!backBuffer) { - NS_WARNING("Could not lock texture client"); - return; - } + DrawTarget* backBuffer = GetDTBuffer(); + if (!backBuffer && mDeprecatedTextureClient) { + backBuffer = mDeprecatedTextureClient->LockDrawTarget(); + } + if (!backBuffer) { + NS_WARNING("Could not lock texture client"); + return; + } - RefPtr oldBuffer; - oldBuffer = SetDTBuffer(backBuffer, - mBufferRect, - mBufferRotation); - - backBuffer = GetDTBufferOnWhite(); - if (!backBuffer && mDeprecatedTextureClientOnWhite) { - backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget(); - } - if (!backBuffer) { - NS_WARNING("Could not lock texture client (on white)"); - return; - } - - oldBuffer = SetDTBufferOnWhite(backBuffer); - } else { - gfxASurface* backBuffer = GetBuffer(); - if (!backBuffer && mDeprecatedTextureClient) { - backBuffer = mDeprecatedTextureClient->LockSurface(); - } - if (!backBuffer) { - NS_WARNING("Could not lock texture client"); - return; - } - - nsRefPtr oldBuffer; - oldBuffer = SetBuffer(backBuffer, + RefPtr oldBuffer; + oldBuffer = SetDTBuffer(backBuffer, mBufferRect, mBufferRotation); - backBuffer = GetBufferOnWhite(); - if (!backBuffer && mDeprecatedTextureClientOnWhite) { - backBuffer = mDeprecatedTextureClientOnWhite->LockSurface(); - } - if (!backBuffer) { - NS_WARNING("Could not lock texture client (on white)"); - return; - } - - oldBuffer = SetBufferOnWhite(backBuffer); + backBuffer = GetDTBufferOnWhite(); + if (!backBuffer && mDeprecatedTextureClientOnWhite) { + backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget(); } + if (!backBuffer) { + NS_WARNING("Could not lock texture client (on white)"); + return; + } + + oldBuffer = SetDTBufferOnWhite(backBuffer); } static void @@ -900,39 +799,19 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer, "BeginUpdate should always modify the draw region in the same way!"); FillSurface(onBlack, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0)); FillSurface(onWhite, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0)); - if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { - RefPtr onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize()); - RefPtr onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize()); - RefPtr dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT); - result.mContext = new gfxContext(dt); - } else { - gfxASurface* surfaces[2] = { onBlack.get(), onWhite.get() }; - nsRefPtr surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces)); - - // XXX If the device offset is set on the individual surfaces instead of on - // the tee surface, we render in the wrong place. Why? - gfxPoint deviceOffset = onBlack->GetDeviceOffset(); - onBlack->SetDeviceOffset(gfxPoint(0, 0)); - onWhite->SetDeviceOffset(gfxPoint(0, 0)); - surf->SetDeviceOffset(deviceOffset); - - // Using this surface as a source will likely go horribly wrong, since - // only the onBlack surface will really be used, so alpha information will - // be incorrect. - surf->SetAllowUseAsSource(false); - result.mContext = new gfxContext(surf); - } + MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent()); + RefPtr onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize()); + RefPtr onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize()); + RefPtr dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT); + result.mContext = new gfxContext(dt); } else { result.mContext = nullptr; } } else { nsRefPtr surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw); - if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { - RefPtr dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize()); - result.mContext = new gfxContext(dt); - } else { - result.mContext = new gfxContext(surf); - } + MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent()); + RefPtr dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize()); + result.mContext = new gfxContext(dt); } if (!result.mContext) { NS_WARNING("unable to get context for update"); diff --git a/gfx/layers/client/ContentClient.h b/gfx/layers/client/ContentClient.h index 2826b3a2e445..af9449f239f1 100644 --- a/gfx/layers/client/ContentClient.h +++ b/gfx/layers/client/ContentClient.h @@ -154,9 +154,7 @@ public: } virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, - gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface, RefPtr* aBlackDT, RefPtr* aWhiteDT) MOZ_OVERRIDE; - virtual bool SupportsAzureContent() const; virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE { @@ -237,11 +235,8 @@ public: } virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, - gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface, RefPtr* aBlackDT, RefPtr* aWhiteDT) MOZ_OVERRIDE; - virtual bool SupportsAzureContent() const MOZ_OVERRIDE; - void DestroyBuffers(); virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE