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
Родитель 1b4925d2fb
Коммит 23ba974c05
3 изменённых файлов: 58 добавлений и 6 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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