void ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource, const nsIntRegion& aUpdateRegion) { nsRefPtr<gfxContext> destCtx = GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK); destCtx->SetOperator(gfxContext::OPERATOR_SOURCE); bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion); if (isClippingCheap) { gfxUtils::ClipToRegion(destCtx, aUpdateRegion); } if (SupportsAzureContent()) { MOZ_ASSERT(!destCtx->IsCairo()); if (destCtx->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8A8) { destCtx->GetDrawTarget()->ClearRect(Rect(0, 0, mFrontBufferRect.width, mFrontBufferRect.height)); } aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK); } else { aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK); } if (aSource.HaveBufferOnWhite()) { MOZ_ASSERT(HaveBufferOnWhite()); nsRefPtr<gfxContext> destCtx = GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE); destCtx->SetOperator(gfxContext::OPERATOR_SOURCE); bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion); if (isClippingCheap) { gfxUtils::ClipToRegion(destCtx, aUpdateRegion); } if (SupportsAzureContent()) { MOZ_ASSERT(!destCtx->IsCairo()); if (destCtx->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8A8) { destCtx->GetDrawTarget()->ClearRect(Rect(0, 0, mFrontBufferRect.width, mFrontBufferRect.height)); } aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE); } else { aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE); } } }
void ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource, const nsIntRegion& aUpdateRegion) { nsRefPtr<gfxContext> destCtx = GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK); if (!destCtx) { return; } destCtx->SetOperator(gfxContext::OPERATOR_SOURCE); bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion); if (isClippingCheap) { 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); } if (aSource.HaveBufferOnWhite()) { MOZ_ASSERT(HaveBufferOnWhite()); nsRefPtr<gfxContext> destCtx = GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE); destCtx->SetOperator(gfxContext::OPERATOR_SOURCE); bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion); if (isClippingCheap) { 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); } } }
void ContentClientSingleBuffered::SyncFrontBufferToBackBuffer() { if (!mFrontAndBackBufferDiffer) { return; } if (SupportsAzureContent()) { DrawTarget* backBuffer = GetDTBuffer(); if (!backBuffer && mDeprecatedTextureClient) { backBuffer = mDeprecatedTextureClient->LockDrawTarget(); } RefPtr<DrawTarget> oldBuffer; oldBuffer = SetDTBuffer(backBuffer, mBufferRect, mBufferRotation); backBuffer = GetDTBufferOnWhite(); if (!backBuffer && mDeprecatedTextureClientOnWhite) { backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget(); } oldBuffer = SetDTBufferOnWhite(backBuffer); } else { gfxASurface* backBuffer = GetBuffer(); if (!backBuffer && mDeprecatedTextureClient) { backBuffer = mDeprecatedTextureClient->LockSurface(); } nsRefPtr<gfxASurface> oldBuffer; oldBuffer = SetBuffer(backBuffer, mBufferRect, mBufferRotation); backBuffer = GetBufferOnWhite(); if (!backBuffer && mDeprecatedTextureClientOnWhite) { backBuffer = mDeprecatedTextureClientOnWhite->LockSurface(); } oldBuffer = SetBufferOnWhite(backBuffer); } mIsNewBuffer = false; mFrontAndBackBufferDiffer = false; }
void ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer() { if (!mFrontAndBackBufferDiffer) { return; } MOZ_ASSERT(mFrontClient); MOZ_ASSERT(mFrontClient->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_ONLY); MOZ_ASSERT(!mFrontClientOnWhite || mFrontClientOnWhite->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_ONLY); MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>", this, mFrontUpdatedRegion.GetBounds().x, mFrontUpdatedRegion.GetBounds().y, mFrontUpdatedRegion.GetBounds().width, mFrontUpdatedRegion.GetBounds().height)); nsIntRegion updateRegion = mFrontUpdatedRegion; int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x; int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y; // Figure out whether the area we want to copy wraps the edges of our buffer. bool needFullCopy = (xBoundary < updateRegion.GetBounds().XMost() && xBoundary > updateRegion.GetBounds().x) || (yBoundary < updateRegion.GetBounds().YMost() && yBoundary > updateRegion.GetBounds().y); // This is a tricky trade off, we're going to get stuff out of our // frontbuffer now, but the next PaintThebes might throw it all (or mostly) // away if the visible region has changed. This is why in reality we want // this code integrated with PaintThebes to always do the optimal thing. if (needFullCopy) { // We can't easily draw our front buffer into us, since we're going to be // copying stuff around anyway it's easiest if we just move our situation // to non-rotated while we're at it. If this situation occurs we'll have // hit a self-copy path in PaintThebes before as well anyway. mBufferRect.MoveTo(mFrontBufferRect.TopLeft()); mBufferRotation = nsIntPoint(); updateRegion = mBufferRect; } else { mBufferRect = mFrontBufferRect; mBufferRotation = mFrontBufferRotation; } AutoDeprecatedTextureClient autoTextureFront; AutoDeprecatedTextureClient autoTextureFrontOnWhite; if (SupportsAzureContent()) { RotatedBuffer frontBuffer(autoTextureFront.GetDrawTarget(mFrontClient), autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite), mFrontBufferRect, mFrontBufferRotation); UpdateDestinationFrom(frontBuffer, updateRegion); } else { RotatedBuffer frontBuffer(autoTextureFront.GetSurface(mFrontClient), autoTextureFrontOnWhite.GetSurface(mFrontClientOnWhite), mFrontBufferRect, mFrontBufferRotation); UpdateDestinationFrom(frontBuffer, updateRegion); } mIsNewBuffer = false; mFrontAndBackBufferDiffer = false; }
void ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer() { mIsNewBuffer = false; if (!mFrontAndBackBufferDiffer) { return; } MOZ_ASSERT(mFrontClient); MOZ_ASSERT(mFrontClient->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_ONLY); MOZ_ASSERT(!mFrontClientOnWhite || mFrontClientOnWhite->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_ONLY); MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>", this, mFrontUpdatedRegion.GetBounds().x, mFrontUpdatedRegion.GetBounds().y, mFrontUpdatedRegion.GetBounds().width, mFrontUpdatedRegion.GetBounds().height)); nsIntRegion updateRegion = mFrontUpdatedRegion; // This is a tricky trade off, we're going to get stuff out of our // frontbuffer now, but the next PaintThebes might throw it all (or mostly) // away if the visible region has changed. This is why in reality we want // this code integrated with PaintThebes to always do the optimal thing. if (mDidSelfCopy) { mDidSelfCopy = false; // We can't easily draw our front buffer into us, since we're going to be // copying stuff around anyway it's easiest if we just move our situation // to non-rotated while we're at it. If this situation occurs we'll have // hit a self-copy path in PaintThebes before as well anyway. mBufferRect.MoveTo(mFrontBufferRect.TopLeft()); mBufferRotation = nsIntPoint(); updateRegion = mBufferRect; } else { mBufferRect = mFrontBufferRect; mBufferRotation = mFrontBufferRotation; } 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); } mFrontAndBackBufferDiffer = false; }