Bug 1408421 - Improving throttling GenerateFrame() r=jrmuizel

This commit is contained in:
sotaro 2017-11-03 11:22:28 +09:00
Родитель 5c0d27a5e4
Коммит 9bdbc201fd
3 изменённых файлов: 65 добавлений и 28 удалений

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

@ -1141,10 +1141,8 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
return;
}
const uint32_t maxPendingFrameCount = 1;
if (!mForceRendering &&
wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) >= maxPendingFrameCount) {
wr::RenderThread::Get()->TooManyPendingFrames(mApi->GetId())) {
// Render thread is busy, try next time.
ScheduleComposition();
return;

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

@ -23,7 +23,7 @@ static StaticRefPtr<RenderThread> sRenderThread;
RenderThread::RenderThread(base::Thread* aThread)
: mThread(aThread)
, mPendingFrameCountMapLock("RenderThread.mPendingFrameCountMapLock")
, mFrameCountMapLock("RenderThread.mFrameCountMapLock")
, mRenderTextureMapLock("RenderThread.mRenderTextureMapLock")
, mHasShutdown(false)
{
@ -117,8 +117,8 @@ RenderThread::AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRender
mRenderers[aWindowId] = Move(aRenderer);
MutexAutoLock lock(mPendingFrameCountMapLock);
mPendingFrameCounts.Put(AsUint64(aWindowId), 0);
MutexAutoLock lock(mFrameCountMapLock);
mPendingFrameCounts.Put(AsUint64(aWindowId), FrameCount());
}
void
@ -132,7 +132,7 @@ RenderThread::RemoveRenderer(wr::WindowId aWindowId)
mRenderers.erase(aWindowId);
MutexAutoLock lock(mPendingFrameCountMapLock);
MutexAutoLock lock(mFrameCountMapLock);
mPendingFrameCounts.Remove(AsUint64(aWindowId));
}
@ -265,46 +265,77 @@ RenderThread::Resume(wr::WindowId aWindowId)
return renderer->Resume();
}
uint32_t
RenderThread::GetPendingFrameCount(wr::WindowId aWindowId)
bool
RenderThread::TooManyPendingFrames(wr::WindowId aWindowId)
{
MutexAutoLock lock(mPendingFrameCountMapLock);
uint32_t count = 0;
MOZ_ASSERT(mPendingFrameCounts.Get(AsUint64(aWindowId), &count));
mPendingFrameCounts.Get(AsUint64(aWindowId), &count);
return count;
const int64_t maxFrameCount = 1;
// Too many pending frames if pending frames exit more than maxFrameCount
// or if RenderBackend is still processing a frame.
MutexAutoLock lock(mFrameCountMapLock);
FrameCount count;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &count)) {
MOZ_ASSERT(false);
return true;
}
if (count.mPendingCount > maxFrameCount) {
return true;
}
MOZ_ASSERT(count.mPendingCount >= count.mRenderingCount);
return count.mPendingCount > count.mRenderingCount;
}
void
RenderThread::IncPendingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mPendingFrameCountMapLock);
MutexAutoLock lock(mFrameCountMapLock);
// Get the old count.
uint32_t oldCount = 0;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &oldCount)) {
FrameCount count;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &count)) {
MOZ_ASSERT(false);
return;
}
// Update pending frame count.
mPendingFrameCounts.Put(AsUint64(aWindowId), oldCount + 1);
count.mPendingCount = count.mPendingCount + 1;
mPendingFrameCounts.Put(AsUint64(aWindowId), count);
}
void
RenderThread::IncRenderingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mFrameCountMapLock);
// Get the old count.
FrameCount count;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &count)) {
MOZ_ASSERT(false);
return;
}
// Update rendering frame count.
count.mRenderingCount = count.mRenderingCount + 1;
mPendingFrameCounts.Put(AsUint64(aWindowId), count);
}
void
RenderThread::DecPendingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mPendingFrameCountMapLock);
MutexAutoLock lock(mFrameCountMapLock);
// Get the old count.
uint32_t oldCount = 0;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &oldCount)) {
FrameCount count;
if (!mPendingFrameCounts.Get(AsUint64(aWindowId), &count)) {
MOZ_ASSERT(false);
return;
}
MOZ_ASSERT(oldCount > 0);
if (oldCount <= 0) {
MOZ_ASSERT(count.mPendingCount > 0);
MOZ_ASSERT(count.mRenderingCount > 0);
if (count.mPendingCount <= 0) {
return;
}
// Update pending frame count.
mPendingFrameCounts.Put(AsUint64(aWindowId), oldCount - 1);
// Update frame counts.
count.mPendingCount = count.mPendingCount - 1;
count.mRenderingCount = count.mRenderingCount - 1;
mPendingFrameCounts.Put(AsUint64(aWindowId), count);
}
void
@ -379,6 +410,7 @@ extern "C" {
void wr_notifier_new_frame_ready(mozilla::wr::WrWindowId aWindowId)
{
mozilla::wr::RenderThread::Get()->IncRenderingFrameCount(aWindowId);
mozilla::wr::RenderThread::Get()->NewFrameReady(mozilla::wr::WindowId(aWindowId));
}

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

@ -128,10 +128,12 @@ public:
RenderTextureHost* GetRenderTexture(WrExternalImageId aExternalImageId);
/// Can be called from any thread.
uint32_t GetPendingFrameCount(wr::WindowId aWindowId);
bool TooManyPendingFrames(wr::WindowId aWindowId);
/// Can be called from any thread.
void IncPendingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
void IncRenderingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
void DecPendingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
@ -151,8 +153,13 @@ private:
std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
Mutex mPendingFrameCountMapLock;
nsDataHashtable<nsUint64HashKey, uint32_t> mPendingFrameCounts;
struct FrameCount {
int64_t mPendingCount = 0;
int64_t mRenderingCount = 0;
};
Mutex mFrameCountMapLock;
nsDataHashtable<nsUint64HashKey, FrameCount> mPendingFrameCounts;
Mutex mRenderTextureMapLock;
nsRefPtrHashtable<nsUint64HashKey, RenderTextureHost> mRenderTextures;