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; }