Bug 951554. Replace SyncFrontBufferToBackBuffer with PrepareFrame and FinalizeFrame. r=nical

--HG--
extra : rebase_source : 129796a77c5777dac89930907d1f257657115ae3
This commit is contained in:
Nicholas Cameron 2014-01-13 08:54:40 +13:00
parent 2376a54c37
commit 7a06cdfc5b
3 changed files with 97 additions and 53 deletions

View File

@ -411,6 +411,15 @@ protected:
virtual bool HaveBuffer() const;
virtual bool HaveBufferOnWhite() const;
/**
* Any actions that should be performed at the last moment before we begin
* rendering the next frame. I.e., after we calculate what we will draw,
* but before we rotate the buffer and possibly create new buffers.
* aRegionToDraw is the region which is guaranteed to be overwritten when
* drawing the next frame.
*/
virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw) {}
/**
* These members are only set transiently. They're used to map mDTBuffer
* when we're using surfaces that require explicit map/unmap. Only one

View File

@ -540,9 +540,36 @@ ContentClientDoubleBuffered::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion)
}
void
ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
ContentClientDoubleBuffered::PrepareFrame()
{
mIsNewBuffer = false;
if (!mFrontAndBackBufferDiffer) {
return;
}
if (mDidSelfCopy) {
// 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();
return;
}
mBufferRect = mFrontBufferRect;
mBufferRotation = mFrontBufferRotation;
}
// Sync front/back buffers content
// After executing, the new back buffer has the same (interesting) pixels as
// the new front buffer, and mValidRegion et al. are correct wrt the new
// back buffer (i.e. as they were for the old back buffer)
void
ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw)
{
if (!mFrontAndBackBufferDiffer) {
MOZ_ASSERT(!mDidSelfCopy, "If we have to copy the world, then our buffers are different, right?");
return;
}
MOZ_ASSERT(mFrontClient);
@ -554,29 +581,20 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
mFrontUpdatedRegion.GetBounds().width,
mFrontUpdatedRegion.GetBounds().height));
mFrontAndBackBufferDiffer = false;
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;
}
mIsNewBuffer = false;
mFrontAndBackBufferDiffer = false;
// No point in sync'ing what we are going to draw over anyway. And if there is
// nothing to sync at all, there is nothing to do and we can go home early.
updateRegion.Sub(updateRegion, aRegionToDraw);
if (updateRegion.IsEmpty()) {
return;
}
// We need to ensure that we lock these two buffers in the same
// order as the compositor to prevent deadlocks.
@ -765,18 +783,43 @@ private:
DeprecatedTextureClient* mTexture;
};
void
DeprecatedContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
DeprecatedContentClientDoubleBuffered::PrepareFrame()
{
mIsNewBuffer = false;
if (!mFrontAndBackBufferDiffer) {
return;
}
if (mDidSelfCopy) {
// 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();
return;
}
mBufferRect = mFrontBufferRect;
mBufferRotation = mFrontBufferRotation;
}
void
DeprecatedContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw)
{
if (!mFrontAndBackBufferDiffer) {
return;
}
mFrontAndBackBufferDiffer = false;
MOZ_ASSERT(mFrontClient);
MOZ_ASSERT(mFrontClient->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_ONLY);
MOZ_ASSERT(mFrontClient->GetAccessMode() != DeprecatedTextureClient::ACCESS_NONE);
MOZ_ASSERT(!mFrontClientOnWhite ||
mFrontClientOnWhite->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_ONLY);
mFrontClientOnWhite->GetAccessMode() != DeprecatedTextureClient::ACCESS_NONE);
MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>",
this,
@ -786,24 +829,16 @@ DeprecatedContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
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;
mDidSelfCopy = false;
}
// No point in sync'ing what we are going to draw over anyway. And if there is
// nothing to sync at all, there is nothing to do and we can go home early.
updateRegion.Sub(updateRegion, aRegionToDraw);
if (updateRegion.IsEmpty()) {
return;
}
AutoDeprecatedTextureClient autoTextureFront;
@ -820,8 +855,6 @@ DeprecatedContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
// We need to flush our buffers before we unlock our front textures
FlushBuffers();
mFrontAndBackBufferDiffer = false;
}
void
@ -864,7 +897,7 @@ DeprecatedContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer
}
void
ContentClientSingleBuffered::SyncFrontBufferToBackBuffer()
ContentClientSingleBuffered::PrepareFrame()
{
if (!mFrontAndBackBufferDiffer) {
return;
@ -911,7 +944,7 @@ DeprecatedContentClientSingleBuffered::CreateFrontBufferAndNotify(const nsIntRec
}
void
DeprecatedContentClientSingleBuffered::SyncFrontBufferToBackBuffer()
DeprecatedContentClientSingleBuffered::PrepareFrame()
{
mIsNewBuffer = false;
if (!mFrontAndBackBufferDiffer) {
@ -969,7 +1002,6 @@ FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
RotatedContentBuffer::PaintState
ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
RotatedContentBuffer::ContentType aContentType,
uint32_t aFlags)
{
mTextureInfo.mDeprecatedTextureHostFlags = 0;
@ -980,15 +1012,18 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
nsIntRegion validRegion = aLayer->GetValidRegion();
bool canUseOpaqueSurface = aLayer->CanUseOpaqueSurface();
ContentType contentType =
canUseOpaqueSurface ? GFX_CONTENT_COLOR :
GFX_CONTENT_COLOR_ALPHA;
Layer::SurfaceMode mode;
ContentType contentType;
nsIntRegion neededRegion;
bool canReuseBuffer;
nsIntRect destBufferRect;
while (true) {
mode = aLayer->GetSurfaceMode();
contentType = aContentType;
neededRegion = aLayer->GetVisibleRegion();
// If we're going to resample, we need a buffer that's in clamp mode.
canReuseBuffer = neededRegion.GetBounds().Size() <= mBufferRect.Size() &&

View File

@ -99,11 +99,7 @@ public:
uint32_t aFlags) = 0;
virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) = 0;
// Sync front/back buffers content
// After executing, the new back buffer has the same (interesting) pixels as
// the new front buffer, and mValidRegion et al. are correct wrt the new
// back buffer (i.e. as they were for the old back buffer)
virtual void SyncFrontBufferToBackBuffer() {}
virtual void PrepareFrame() {}
// Called as part of the layers transation reply. Conveys data about our
// buffer(s) from the compositor. If appropriate we should swap references
@ -414,7 +410,9 @@ public:
virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) MOZ_OVERRIDE;
virtual void SyncFrontBufferToBackBuffer() MOZ_OVERRIDE;
virtual void PrepareFrame() MOZ_OVERRIDE;
virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw) MOZ_OVERRIDE;
protected:
virtual void CreateFrontBuffer(const nsIntRect& aBufferRect) MOZ_OVERRIDE;
@ -451,7 +449,9 @@ public:
virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) MOZ_OVERRIDE;
virtual void SyncFrontBufferToBackBuffer() MOZ_OVERRIDE;
virtual void PrepareFrame() MOZ_OVERRIDE;
virtual void FinalizeFrame(const nsIntRegion& aRegionToDraw) MOZ_OVERRIDE;
protected:
virtual void CreateFrontBufferAndNotify(const nsIntRect& aBufferRect) MOZ_OVERRIDE;
@ -487,7 +487,7 @@ public:
}
virtual ~ContentClientSingleBuffered() {}
virtual void SyncFrontBufferToBackBuffer() MOZ_OVERRIDE;
virtual void PrepareFrame() MOZ_OVERRIDE;
protected:
virtual void CreateFrontBuffer(const nsIntRect& aBufferRect) MOZ_OVERRIDE {}
@ -503,7 +503,7 @@ public:
}
~DeprecatedContentClientSingleBuffered();
virtual void SyncFrontBufferToBackBuffer() MOZ_OVERRIDE;
virtual void PrepareFrame() MOZ_OVERRIDE;
protected:
virtual void CreateFrontBufferAndNotify(const nsIntRect& aBufferRect) MOZ_OVERRIDE;