Bug 1506762 - Store wr::WebRenderPipelineInfo directly in AsyncImagePipelineManager::PipelineUpdates r=mattwoodrow

This commit is contained in:
sotaro
2018-11-16 22:01:01 +09:00
parent 961ad4214d
commit 1d58f3676d
3 changed files with 27 additions and 44 deletions

View File

@@ -35,6 +35,14 @@ AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline()
, mMixBlendMode(wr::MixBlendMode::Normal)
{}
AsyncImagePipelineManager::PipelineUpdates::PipelineUpdates(RefPtr<wr::WebRenderPipelineInfo> aPipelineInfo,
const uint64_t aUpdatesCount,
const bool aRendered)
: mPipelineInfo(aPipelineInfo)
, mUpdatesCount(aUpdatesCount)
, mRendered(aRendered)
{}
AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi)
: mApi(aApi)
, mIdNamespace(mApi->GetNamespace())
@@ -553,7 +561,7 @@ AsyncImagePipelineManager::HoldExternalImage(const wr::PipelineId& aPipelineId,
}
void
AsyncImagePipelineManager::NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInfo, bool aRender)
AsyncImagePipelineManager::NotifyPipelinesUpdated(RefPtr<wr::WebRenderPipelineInfo> aInfo, bool aRender)
{
// This is called on the render thread, so we just stash the data into
// UpdatesQueue and process it later on the compositor thread.
@@ -561,18 +569,7 @@ AsyncImagePipelineManager::NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInf
// Increment the count when render happens.
uint64_t currCount = aRender ? ++mUpdatesCount : mUpdatesCount;
auto updates = MakeUnique<PipelineUpdates>(currCount, aRender);
for (uintptr_t i = 0; i < aInfo.epochs.length; i++) {
updates->mQueue.emplace(std::make_pair(
aInfo.epochs.data[i].pipeline_id,
Some(aInfo.epochs.data[i].epoch)));
}
for (uintptr_t i = 0; i < aInfo.removed_pipelines.length; i++) {
updates->mQueue.emplace(std::make_pair(
aInfo.removed_pipelines.data[i],
Nothing()));
}
auto updates = MakeUnique<PipelineUpdates>(aInfo, currCount, aRender);
{
// Scope lock to push UpdatesQueue to mUpdatesQueues.
@@ -604,13 +601,7 @@ AsyncImagePipelineManager::ProcessPipelineUpdates()
UniquePtr<PipelineUpdates> updates;
while (true) {
// Clear updates if it is empty. It is a preparation for next PipelineUpdates handling.
if (updates && updates->mQueue.empty()) {
updates = nullptr;
}
// Get new PipelineUpdates if necessary.
if (!updates) {
{
// Scope lock to extract UpdatesQueue from mUpdatesQueues.
MutexAutoLock lock(mUpdatesLock);
if (mUpdatesQueues.empty()) {
@@ -628,19 +619,16 @@ AsyncImagePipelineManager::ProcessPipelineUpdates()
}
MOZ_ASSERT(updates);
if (updates->mQueue.empty()) {
// Try next PipelineUpdates.
continue;
auto& info = updates->mPipelineInfo->Raw();
for (uintptr_t i = 0; i < info.epochs.length; i++) {
ProcessPipelineRendered(info.epochs.data[i].pipeline_id,
info.epochs.data[i].epoch,
updates->mUpdatesCount);
}
wr::PipelineId pipelineId = updates->mQueue.front().first;
Maybe<wr::Epoch> epoch = updates->mQueue.front().second;
updates->mQueue.pop();
if (epoch.isSome()) {
ProcessPipelineRendered(pipelineId, *epoch, updates->mUpdatesCount);
} else {
ProcessPipelineRemoved(pipelineId, updates->mUpdatesCount);
for (uintptr_t i = 0; i < info.removed_pipelines.length; i++) {
ProcessPipelineRemoved(info.removed_pipelines.data[i],
updates->mUpdatesCount);
}
}
CheckForTextureHostsNotUsedByGPU();

View File

@@ -23,6 +23,7 @@ namespace mozilla {
namespace wr {
class DisplayListBuilder;
class WebRenderAPI;
class WebRenderPipelineInfo;
}
namespace layers {
@@ -56,7 +57,7 @@ public:
// This is called from the Renderer thread to notify this class about the
// pipelines in the most recently completed render. A copy of the update
// information is put into mUpdatesQueue.
void NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInfo, bool aRender);
void NotifyPipelinesUpdated(RefPtr<wr::WebRenderPipelineInfo> aInfo, bool aRender);
// This is run on the compositor thread to process mUpdatesQueue. We make
// this a public entry point because we need to invoke it from other places.
@@ -247,10 +248,9 @@ private:
// Used for checking if PipelineUpdates could be processed.
Atomic<uint64_t> mUpdatesCount;
struct PipelineUpdates {
PipelineUpdates(const uint64_t aUpdatesCount, const bool aRendered)
: mUpdatesCount(aUpdatesCount)
, mRendered(aRendered)
{}
PipelineUpdates(RefPtr<wr::WebRenderPipelineInfo> aPipelineInfo,
const uint64_t aUpdatesCount,
const bool aRendered);
bool NeedsToWait(const uint64_t aUpdatesCount) {
MOZ_ASSERT(mUpdatesCount <= aUpdatesCount);
if (mUpdatesCount == aUpdatesCount && !mRendered) {
@@ -259,14 +259,9 @@ private:
}
return false;
}
RefPtr<wr::WebRenderPipelineInfo> mPipelineInfo;
const uint64_t mUpdatesCount;
const bool mRendered;
// Queue to store rendered pipeline epoch information. This is populated from
// the Renderer thread after a render, and is read from the compositor thread
// to free resources (e.g. textures) that are no longer needed. Each entry
// in the queue is a pair that holds the pipeline id and Some(x) for
// a render of epoch x, or Nothing() for a removed pipeline.
std::queue<std::pair<wr::PipelineId, Maybe<wr::Epoch>>> mQueue;
};
std::queue<UniquePtr<PipelineUpdates>> mUpdatesQueues;

View File

@@ -425,7 +425,7 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId,
// removed the relevant renderer. And after that happens we should never reach
// this code at all; it would bail out at the mRenderers.find check above.
MOZ_ASSERT(pipelineMgr);
pipelineMgr->NotifyPipelinesUpdated(info->Raw(), aRender);
pipelineMgr->NotifyPipelinesUpdated(info, aRender);
}
void