Bug 1365196 - Throttle GenerateFrame() r=kats,nical

This commit is contained in:
sotaro 2017-05-19 09:21:38 +09:00
Родитель 8545f35670
Коммит cbec0e500e
5 изменённых файлов: 81 добавлений и 1 удалений

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

@ -122,6 +122,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos
, mIdNameSpace(AllocIdNameSpace())
, mPaused(false)
, mDestroyed(false)
, mIsSnapshotting(false)
{
MOZ_ASSERT(mCompositableHolder);
mCompositableHolder->AddPipeline(mPipelineId);
@ -616,6 +617,8 @@ WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
// Assert the stride of the buffer is what webrender expects
MOZ_ASSERT((uint32_t)(size.width * 4) == stride);
mIsSnapshotting = true;
if (mCompositorScheduler->NeedsComposite()) {
mCompositorScheduler->CancelCurrentCompositeTask();
mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
@ -623,6 +626,8 @@ WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
mApi->Readback(size, buffer, buffer_size);
mIsSnapshotting = false;
return IPC_OK();
}
@ -762,6 +767,15 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
return;
}
const uint32_t maxPendingFrameCount = 2;
if (!mIsSnapshotting &&
wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) > maxPendingFrameCount) {
// Render thread is busy, try next time.
ScheduleComposition();
return;
}
if (PushAPZStateToWR()) {
ScheduleComposition();
}

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

@ -236,6 +236,7 @@ private:
bool mPaused;
bool mDestroyed;
bool mIsSnapshotting;
// Can only be accessed on the compositor thread.
WebRenderScrollData mScrollData;

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

@ -20,6 +20,7 @@ static StaticRefPtr<RenderThread> sRenderThread;
RenderThread::RenderThread(base::Thread* aThread)
: mThread(aThread)
, mPendingFrameCountMapLock("RenderThread.mPendingFrameCountMapLock")
, mRenderTextureMapLock("RenderThread.mRenderTextureMapLock")
{
@ -88,6 +89,9 @@ RenderThread::AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRender
{
MOZ_ASSERT(IsInRenderThread());
mRenderers[aWindowId] = Move(aRenderer);
MutexAutoLock lock(mPendingFrameCountMapLock);
mPendingFrameCounts.Put(AsUint64(aWindowId), 0);
}
void
@ -95,6 +99,9 @@ RenderThread::RemoveRenderer(wr::WindowId aWindowId)
{
MOZ_ASSERT(IsInRenderThread());
mRenderers.erase(aWindowId);
MutexAutoLock lock(mPendingFrameCountMapLock);
mPendingFrameCounts.Remove(AsUint64(aWindowId));
}
RendererOGL*
@ -123,6 +130,7 @@ RenderThread::NewFrameReady(wr::WindowId aWindowId)
}
UpdateAndRender(aWindowId);
DecPendingFrameCount(aWindowId);
}
void
@ -224,6 +232,48 @@ RenderThread::Resume(wr::WindowId aWindowId)
return renderer->Resume();
}
uint32_t
RenderThread::GetPendingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mPendingFrameCountMapLock);
uint32_t count = 0;
MOZ_ASSERT(mPendingFrameCounts.Get(AsUint64(aWindowId), &count));
mPendingFrameCounts.Get(AsUint64(aWindowId), &count);
return count;
}
void
RenderThread::IncPendingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mPendingFrameCountMapLock);
// Get the old count.
uint32_t oldCount = 0;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &oldCount)) {
MOZ_ASSERT(false);
return;
}
// Update pending frame count.
mPendingFrameCounts.Put(AsUint64(aWindowId), oldCount + 1);
}
void
RenderThread::DecPendingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mPendingFrameCountMapLock);
// Get the old count.
uint32_t oldCount = 0;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &oldCount)) {
MOZ_ASSERT(false);
return;
}
MOZ_ASSERT(oldCount > 0);
if (oldCount <= 0) {
return;
}
// Update pending frame count.
mPendingFrameCounts.Put(AsUint64(aWindowId), oldCount - 1);
}
void
RenderThread::RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture)
{
@ -255,6 +305,7 @@ extern "C" {
void wr_notifier_new_frame_ready(WrWindowId aWindowId)
{
mozilla::wr::RenderThread::Get()->IncPendingFrameCount(aWindowId);
mozilla::wr::RenderThread::Get()->NewFrameReady(mozilla::wr::WindowId(aWindowId));
}

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

@ -111,16 +111,25 @@ public:
RenderTextureHost* GetRenderTexture(WrExternalImageId aExternalImageId);
/// Can be called from any thread.
uint32_t GetPendingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
void IncPendingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
void DecPendingFrameCount(wr::WindowId aWindowId);
private:
explicit RenderThread(base::Thread* aThread);
~RenderThread();
base::Thread* const mThread;
std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
Mutex mPendingFrameCountMapLock;
nsDataHashtable<nsUint64HashKey, uint32_t> mPendingFrameCounts;
Mutex mRenderTextureMapLock;
nsDataHashtable<nsUint64HashKey, RefPtr<RenderTextureHost> > mRenderTextures;
};

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

@ -103,6 +103,11 @@ struct ImageDescriptor: public WrImageDescriptor {
}
};
// Whenever possible, use wr::WindowId instead of manipulating uint64_t.
inline uint64_t AsUint64(const WindowId& aId) {
return static_cast<uint64_t>(aId.mHandle);
}
// Whenever possible, use wr::ImageKey instead of manipulating uint64_t.
inline uint64_t AsUint64(const ImageKey& aId) {
return (static_cast<uint64_t>(aId.mNamespace) << 32)