Bug 809273 - Add code for handling dual buffers in ContentHost. r=nrc

This commit is contained in:
Matt Woodrow 2013-04-22 14:40:52 +12:00
parent 5e1eb6f49e
commit 2a7f252e64
3 changed files with 58 additions and 6 deletions

View File

@ -101,6 +101,8 @@ struct TextureFactoryIdentifier
typedef uint32_t TextureIdentifier;
const TextureIdentifier TextureFront = 1;
const TextureIdentifier TextureBack = 2;
const TextureIdentifier TextureOnWhiteFront = 3;
const TextureIdentifier TextureOnWhiteBack = 4;
/**
* Information required by the compositor from the content-side for creating or

View File

@ -31,6 +31,8 @@ ContentHostBase::DestroyFrontHost()
{
MOZ_ASSERT(!mTextureHost || mTextureHost->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
MOZ_ASSERT(!mTextureHostOnWhite || mTextureHostOnWhite->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
mTextureHost = nullptr;
mTextureHostOnWhite = nullptr;
}
@ -213,15 +215,19 @@ ContentHostSingleBuffered::EnsureTextureHost(TextureIdentifier aTextureId,
ISurfaceAllocator* aAllocator,
const TextureInfo& aTextureInfo)
{
MOZ_ASSERT(aTextureId == TextureFront);
mNewFrontHost = TextureHost::CreateTextureHost(aSurface.type(),
aTextureInfo.mTextureHostFlags,
aTextureInfo.mTextureFlags);
MOZ_ASSERT(aTextureId == TextureFront ||
aTextureId == TextureOnWhiteFront);
RefPtr<TextureHost> *newHost =
(aTextureId == TextureFront) ? &mNewFrontHost : &mNewFrontHostOnWhite;
mNewFrontHost->SetBuffer(new SurfaceDescriptor(aSurface), aAllocator);
*newHost = TextureHost::CreateTextureHost(aSurface.type(),
aTextureInfo.mTextureHostFlags,
aTextureInfo.mTextureFlags);
(*newHost)->SetBuffer(new SurfaceDescriptor(aSurface), aAllocator);
Compositor* compositor = GetCompositor();
if (compositor) {
mNewFrontHost->SetCompositor(compositor);
(*newHost)->SetCompositor(compositor);
}
return true;
@ -232,7 +238,10 @@ ContentHostSingleBuffered::DestroyTextures()
{
MOZ_ASSERT(!mNewFrontHost || mNewFrontHost->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
MOZ_ASSERT(!mNewFrontHostOnWhite || mNewFrontHostOnWhite->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
mNewFrontHost = nullptr;
mNewFrontHostOnWhite = nullptr;
// don't touch mTextureHost, we might need it for compositing
}
@ -254,9 +263,14 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
DestroyFrontHost();
mTextureHost = mNewFrontHost;
mNewFrontHost = nullptr;
if (mNewFrontHostOnWhite) {
mTextureHostOnWhite = mNewFrontHostOnWhite;
mNewFrontHostOnWhite = nullptr;
}
}
MOZ_ASSERT(mTextureHost);
MOZ_ASSERT(!mNewFrontHostOnWhite, "New white host without a new black?");
// updated is in screen coordinates. Convert it to buffer coordinates.
nsIntRegion destRegion(aUpdated);
@ -278,6 +292,9 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
"updated region lies across rotation boundaries!");
mTextureHost->Update(*mTextureHost->GetBuffer(), &destRegion);
if (mTextureHostOnWhite) {
mTextureHostOnWhite->Update(*mTextureHostOnWhite->GetBuffer(), &destRegion);
}
mInitialised = true;
mBufferRect = aData.rect();
@ -311,12 +328,19 @@ ContentHostDoubleBuffered::EnsureTextureHost(TextureIdentifier aTextureId,
mNewFrontHost = newHost;
return true;
}
if (aTextureId == TextureOnWhiteFront) {
mNewFrontHostOnWhite = newHost;
return true;
}
if (aTextureId == TextureBack) {
mBackHost = newHost;
mBufferRect = nsIntRect();
mBufferRotation = nsIntPoint();
return true;
}
if (aTextureId == TextureOnWhiteBack) {
mBackHostOnWhite = newHost;
}
NS_ERROR("Bad texture identifier");
return false;
@ -331,12 +355,24 @@ ContentHostDoubleBuffered::DestroyTextures()
mNewFrontHost = nullptr;
}
if (mNewFrontHostOnWhite) {
MOZ_ASSERT(mNewFrontHostOnWhite->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
mNewFrontHostOnWhite = nullptr;
}
if (mBackHost) {
MOZ_ASSERT(mBackHost->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
mBackHost = nullptr;
}
if (mBackHostOnWhite) {
MOZ_ASSERT(mBackHostOnWhite->GetDeAllocator(),
"We won't be able to destroy our SurfaceDescriptor");
mBackHostOnWhite = nullptr;
}
// don't touch mTextureHost, we might need it for compositing
}
@ -357,16 +393,28 @@ ContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData,
DestroyFrontHost();
mTextureHost = mNewFrontHost;
mNewFrontHost = nullptr;
if (mNewFrontHostOnWhite) {
mTextureHostOnWhite = mNewFrontHostOnWhite;
mNewFrontHostOnWhite = nullptr;
}
}
MOZ_ASSERT(mTextureHost);
MOZ_ASSERT(!mNewFrontHostOnWhite, "New white host without a new black?");
MOZ_ASSERT(mBackHost);
RefPtr<TextureHost> oldFront = mTextureHost;
mTextureHost = mBackHost;
mBackHost = oldFront;
oldFront = mTextureHostOnWhite;
mTextureHostOnWhite = mBackHostOnWhite;
mBackHostOnWhite = oldFront;
mTextureHost->Update(*mTextureHost->GetBuffer());
if (mTextureHostOnWhite) {
mTextureHostOnWhite->Update(*mTextureHostOnWhite->GetBuffer());
}
mInitialised = true;
mBufferRect = aData.rect();

View File

@ -125,6 +125,7 @@ protected:
// the old one which might still be used for compositing. So we store it
// here and move it to mTextureHost once we do the first buffer swap.
RefPtr<TextureHost> mNewFrontHost;
RefPtr<TextureHost> mNewFrontHostOnWhite;
bool mPaintWillResample;
bool mInitialised;
};
@ -163,6 +164,7 @@ protected:
// only swap it with the front buffer (mTextureHost) when we are told by the
// content thread.
RefPtr<TextureHost> mBackHost;
RefPtr<TextureHost> mBackHostOnWhite;
};
/**