Bug 1676760 - Use DataMutex for pending vsync tracking and rename variables so that they don't refer to "parent process" even though they're also used in the content process. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D139767
This commit is contained in:
Markus Stange 2022-03-01 22:48:18 +00:00
parent 3865c1aeeb
commit 9912a6a4a3

View File

@ -18,6 +18,7 @@
*/
#include "nsRefreshDriver.h"
#include "mozilla/DataMutex.h"
#include "nsThreadUtils.h"
#ifdef XP_WIN
@ -486,8 +487,8 @@ class VsyncRefreshDriverTimer : public RefreshDriverTimer {
explicit RefreshDriverVsyncObserver(
VsyncRefreshDriverTimer* aVsyncRefreshDriverTimer)
: mVsyncRefreshDriverTimer(aVsyncRefreshDriverTimer),
mParentProcessRefreshTickLock("RefreshTickLock"),
mPendingParentProcessVsync(false),
mLastPendingVsyncNotification(
"RefreshDriverVsyncObserver::mLastPendingVsyncNotification"),
mRecentVsync(TimeStamp::Now()),
mLastTick(TimeStamp::Now()),
mVsyncRate(TimeDuration::Forever()),
@ -500,12 +501,12 @@ class VsyncRefreshDriverTimer : public RefreshDriverTimer {
// This is so that we don't flood the refresh driver with vsync messages
// if the main thread is blocked for long periods of time
{ // scope lock
MonitorAutoLock lock(mParentProcessRefreshTickLock);
mRecentParentProcessVsync = aVsync;
if (mPendingParentProcessVsync) {
auto pendingVsync = mLastPendingVsyncNotification.Lock();
bool hadPendingVsync = pendingVsync->isSome();
*pendingVsync = Some(aVsync);
if (hadPendingVsync) {
return true;
}
mPendingParentProcessVsync = true;
}
if (XRE_IsContentProcess()) {
@ -539,16 +540,19 @@ class VsyncRefreshDriverTimer : public RefreshDriverTimer {
// This clears the input handling start time.
InputTaskManager::Get()->SetInputHandlingStartTime(TimeStamp());
VsyncEvent aVsync;
VsyncEvent vsyncEvent;
{
MonitorAutoLock lock(mParentProcessRefreshTickLock);
aVsync = mRecentParentProcessVsync;
mPendingParentProcessVsync = false;
// Get the last of the queued-up vsync notifications.
auto pendingVsync = mLastPendingVsyncNotification.Lock();
MOZ_RELEASE_ASSERT(
pendingVsync->isSome(),
"We should always have a pending vsync notification here.");
vsyncEvent = pendingVsync->extract();
}
mRecentVsync = aVsync.mTime;
mRecentVsyncId = aVsync.mId;
if (!mBlockUntil.IsNull() && mBlockUntil > aVsync.mTime) {
mRecentVsync = vsyncEvent.mTime;
mRecentVsyncId = vsyncEvent.mId;
if (!mBlockUntil.IsNull() && mBlockUntil > vsyncEvent.mTime) {
if (mProcessedVsync) {
// Re-post vsync update as a normal priority runnable. This way
// runnables already in normal priority queue get processed.
@ -601,7 +605,7 @@ class VsyncRefreshDriverTimer : public RefreshDriverTimer {
}
RefPtr<RefreshDriverVsyncObserver> kungFuDeathGrip(this);
TickRefreshDriver(aVsync.mId, aVsync.mTime);
TickRefreshDriver(vsyncEvent.mId, vsyncEvent.mTime);
}
void Shutdown() {
@ -697,9 +701,16 @@ class VsyncRefreshDriverTimer : public RefreshDriverTimer {
// here.
VsyncRefreshDriverTimer* mVsyncRefreshDriverTimer;
Monitor mParentProcessRefreshTickLock;
VsyncEvent mRecentParentProcessVsync;
bool mPendingParentProcessVsync;
// Non-empty between a call to NotifyVsync and a call to
// NotifyVsyncOnMainThread. When multiple vsync notifications have been
// received between those two calls, this contains the last of the pending
// notifications. This is used both in the parent process and in the child
// process, but it only does something useful in the parent process. In the
// child process, both calls happen on the main thread right after one
// another, so there's only one notification to keep track of; vsync
// notification coalescing for child processes happens at the IPC level
// instead.
DataMutex<Maybe<VsyncEvent>> mLastPendingVsyncNotification;
TimeStamp mRecentVsync;
VsyncId mRecentVsyncId;