Bug 1500017 - Use triple buffer with DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChain r=mattwoodrow
This commit is contained in:
@@ -31,6 +31,7 @@ AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline()
|
||||
AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi)
|
||||
: mApi(aApi)
|
||||
, mIdNamespace(mApi->GetNamespace())
|
||||
, mUseTripleBuffering(mApi->GetUseTripleBuffering())
|
||||
, mResourceId(0)
|
||||
, mAsyncImageEpoch{0}
|
||||
, mWillGenerateFrame(false)
|
||||
@@ -550,8 +551,6 @@ AsyncImagePipelineManager::NotifyPipelinesUpdated(wr::WrPipelineInfo aInfo, bool
|
||||
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
|
||||
|
||||
// Increment the count when render happens.
|
||||
// XXX The count is going to be used to delay releasing TextureHosts for multiple rendering.
|
||||
// See Bug 1500017.
|
||||
uint64_t currCount = aRender ? ++mUpdatesCount : mUpdatesCount;
|
||||
auto updates = MakeUnique<PipelineUpdates>(currCount, aRender);
|
||||
|
||||
@@ -630,15 +629,16 @@ AsyncImagePipelineManager::ProcessPipelineUpdates()
|
||||
updates->mQueue.pop();
|
||||
|
||||
if (epoch.isSome()) {
|
||||
ProcessPipelineRendered(pipelineId, *epoch);
|
||||
ProcessPipelineRendered(pipelineId, *epoch, updates->mUpdatesCount);
|
||||
} else {
|
||||
ProcessPipelineRemoved(pipelineId);
|
||||
ProcessPipelineRemoved(pipelineId, updates->mUpdatesCount);
|
||||
}
|
||||
}
|
||||
CheckForTextureHostsNotUsedByGPU();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::ProcessPipelineRendered(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch)
|
||||
AsyncImagePipelineManager::ProcessPipelineRendered(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, const uint64_t aUpdatesCount)
|
||||
{
|
||||
if (auto entry = mPipelineTexturesHolders.Lookup(wr::AsUint64(aPipelineId))) {
|
||||
PipelineTexturesHolder* holder = entry.Data();
|
||||
@@ -647,6 +647,8 @@ AsyncImagePipelineManager::ProcessPipelineRendered(const wr::PipelineId& aPipeli
|
||||
if (aEpoch <= holder->mTextureHosts.front().mEpoch) {
|
||||
break;
|
||||
}
|
||||
// Need to extend holding TextureHost if it is direct bounded texture.
|
||||
HoldUntilNotUsedByGPU(holder->mTextureHosts.front().mTexture, aUpdatesCount);
|
||||
holder->mTextureHosts.pop();
|
||||
}
|
||||
while (!holder->mTextureHostWrappers.empty()) {
|
||||
@@ -668,7 +670,7 @@ AsyncImagePipelineManager::ProcessPipelineRendered(const wr::PipelineId& aPipeli
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::ProcessPipelineRemoved(const wr::PipelineId& aPipelineId)
|
||||
AsyncImagePipelineManager::ProcessPipelineRemoved(const wr::PipelineId& aPipelineId, const uint64_t aUpdatesCount)
|
||||
{
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
@@ -676,6 +678,11 @@ AsyncImagePipelineManager::ProcessPipelineRemoved(const wr::PipelineId& aPipelin
|
||||
if (auto entry = mPipelineTexturesHolders.Lookup(wr::AsUint64(aPipelineId))) {
|
||||
PipelineTexturesHolder* holder = entry.Data();
|
||||
if (holder->mDestroyedEpoch.isSome()) {
|
||||
while (!holder->mTextureHosts.empty()) {
|
||||
// Need to extend holding TextureHost if it is direct bounded texture.
|
||||
HoldUntilNotUsedByGPU(holder->mTextureHosts.front().mTexture, aUpdatesCount);
|
||||
holder->mTextureHosts.pop();
|
||||
}
|
||||
// Explicitly release all of the shared surfaces.
|
||||
while (!holder->mExternalImages.empty()) {
|
||||
DebugOnly<bool> released =
|
||||
@@ -692,6 +699,39 @@ AsyncImagePipelineManager::ProcessPipelineRemoved(const wr::PipelineId& aPipelin
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::HoldUntilNotUsedByGPU(const CompositableTextureHostRef& aTextureHost, uint64_t aUpdatesCount)
|
||||
{
|
||||
MOZ_ASSERT(aTextureHost);
|
||||
|
||||
if (aTextureHost->HasIntermediateBuffer()) {
|
||||
// If texutre is not direct binding texture, gpu has already finished using it.
|
||||
// We could release it now.
|
||||
return;
|
||||
}
|
||||
|
||||
// When Triple buffer is used, we need wait one more WebRender rendering,
|
||||
if (mUseTripleBuffering) {
|
||||
++aUpdatesCount;
|
||||
}
|
||||
|
||||
mTexturesInUseByGPU.emplace(
|
||||
std::make_pair(aUpdatesCount, aTextureHost));
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::CheckForTextureHostsNotUsedByGPU()
|
||||
{
|
||||
uint64_t currCount = mUpdatesCount;
|
||||
|
||||
while (!mTexturesInUseByGPU.empty()) {
|
||||
if (currCount <= mTexturesInUseByGPU.front().first) {
|
||||
break;
|
||||
}
|
||||
mTexturesInUseByGPU.pop();
|
||||
}
|
||||
}
|
||||
|
||||
wr::Epoch
|
||||
AsyncImagePipelineManager::GetNextImageEpoch()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user