mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1095242. Part 4: Unobserve vsync in CompositorVsyncDispatcher. r=kats
This commit is contained in:
parent
9093be777c
commit
ebe0a9bec5
@ -41,6 +41,7 @@ VsyncSource::GetRefreshTimerVsyncDispatcher()
|
||||
|
||||
VsyncSource::Display::Display()
|
||||
: mDispatcherLock("display dispatcher lock")
|
||||
, mRefreshTimerNeedsVsync(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mRefreshTimerVsyncDispatcher = new RefreshTimerVsyncDispatcher();
|
||||
@ -72,10 +73,13 @@ VsyncSource::Display::AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aC
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCompositorVsyncDispatcher);
|
||||
MutexAutoLock lock(mDispatcherLock);
|
||||
if (!mCompositorVsyncDispatchers.Contains(aCompositorVsyncDispatcher)) {
|
||||
mCompositorVsyncDispatchers.AppendElement(aCompositorVsyncDispatcher);
|
||||
{ // scope lock
|
||||
MutexAutoLock lock(mDispatcherLock);
|
||||
if (!mCompositorVsyncDispatchers.Contains(aCompositorVsyncDispatcher)) {
|
||||
mCompositorVsyncDispatchers.AppendElement(aCompositorVsyncDispatcher);
|
||||
}
|
||||
}
|
||||
UpdateVsyncStatus();
|
||||
}
|
||||
|
||||
void
|
||||
@ -83,8 +87,43 @@ VsyncSource::Display::RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher*
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCompositorVsyncDispatcher);
|
||||
MutexAutoLock lock(mDispatcherLock);
|
||||
mCompositorVsyncDispatchers.RemoveElement(aCompositorVsyncDispatcher);
|
||||
{ // Scope lock
|
||||
MutexAutoLock lock(mDispatcherLock);
|
||||
if (mCompositorVsyncDispatchers.Contains(aCompositorVsyncDispatcher)) {
|
||||
mCompositorVsyncDispatchers.RemoveElement(aCompositorVsyncDispatcher);
|
||||
}
|
||||
}
|
||||
UpdateVsyncStatus();
|
||||
}
|
||||
|
||||
void
|
||||
VsyncSource::Display::NotifyRefreshTimerVsyncStatus(bool aEnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mRefreshTimerNeedsVsync = aEnable;
|
||||
UpdateVsyncStatus();
|
||||
}
|
||||
|
||||
void
|
||||
VsyncSource::Display::UpdateVsyncStatus()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// WARNING: This function SHOULD NOT BE CALLED WHILE HOLDING LOCKS
|
||||
// NotifyVsync grabs a lock to dispatch vsync events
|
||||
// When disabling vsync, we wait for the underlying thread to stop on some platforms
|
||||
// We can deadlock if we wait for the underlying vsync thread to stop
|
||||
// while the vsync thread is in NotifyVsync.
|
||||
bool enableVsync = false;
|
||||
{ // scope lock
|
||||
MutexAutoLock lock(mDispatcherLock);
|
||||
enableVsync = !mCompositorVsyncDispatchers.IsEmpty() || mRefreshTimerNeedsVsync;
|
||||
}
|
||||
|
||||
if (enableVsync) {
|
||||
EnableVsync();
|
||||
} else {
|
||||
DisableVsync();
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<RefreshTimerVsyncDispatcher>
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
|
||||
void AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
|
||||
void RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
|
||||
void NotifyRefreshTimerVsyncStatus(bool aEnable);
|
||||
|
||||
// These should all only be called on the main thread
|
||||
virtual void EnableVsync() = 0;
|
||||
@ -56,7 +57,10 @@ public:
|
||||
virtual bool IsVsyncEnabled() = 0;
|
||||
|
||||
private:
|
||||
void UpdateVsyncStatus();
|
||||
|
||||
Mutex mDispatcherLock;
|
||||
bool mRefreshTimerNeedsVsync;
|
||||
nsTArray<nsRefPtr<CompositorVsyncDispatcher>> mCompositorVsyncDispatchers;
|
||||
nsRefPtr<RefreshTimerVsyncDispatcher> mRefreshTimerVsyncDispatcher;
|
||||
};
|
||||
|
@ -18,10 +18,10 @@ namespace mozilla {
|
||||
|
||||
CompositorVsyncDispatcher::CompositorVsyncDispatcher()
|
||||
: mCompositorObserverLock("CompositorObserverLock")
|
||||
, mDidShutdown(false)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gfxPlatform::GetPlatform()->GetHardwareVsync()->AddCompositorVsyncDispatcher(this);
|
||||
}
|
||||
|
||||
CompositorVsyncDispatcher::~CompositorVsyncDispatcher()
|
||||
@ -34,7 +34,7 @@ CompositorVsyncDispatcher::~CompositorVsyncDispatcher()
|
||||
void
|
||||
CompositorVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
// In hardware vsync thread
|
||||
// In vsync thread
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
if (profiler_is_active()) {
|
||||
layers::CompositorParent::PostInsertVsyncProfilerMarker(aVsyncTimestamp);
|
||||
@ -47,12 +47,34 @@ CompositorVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncDispatcher::ObserveVsync(bool aEnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
if (mDidShutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aEnable) {
|
||||
gfxPlatform::GetPlatform()->GetHardwareVsync()->AddCompositorVsyncDispatcher(this);
|
||||
} else {
|
||||
gfxPlatform::GetPlatform()->GetHardwareVsync()->RemoveCompositorVsyncDispatcher(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncDispatcher::SetCompositorVsyncObserver(VsyncObserver* aVsyncObserver)
|
||||
{
|
||||
MOZ_ASSERT(layers::CompositorParent::IsInCompositorThread());
|
||||
MutexAutoLock lock(mCompositorObserverLock);
|
||||
mCompositorVsyncObserver = aVsyncObserver;
|
||||
|
||||
bool observeVsync = aVsyncObserver != nullptr;
|
||||
nsCOMPtr<nsIRunnable> vsyncControl = NS_NewRunnableMethodWithArg<bool>(this,
|
||||
&CompositorVsyncDispatcher::ObserveVsync,
|
||||
observeVsync);
|
||||
NS_DispatchToMainThread(vsyncControl);
|
||||
}
|
||||
|
||||
void
|
||||
@ -63,7 +85,12 @@ CompositorVsyncDispatcher::Shutdown()
|
||||
// shuts down and the CompositorParent shuts down.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gfxPlatform::GetPlatform()->GetHardwareVsync()->RemoveCompositorVsyncDispatcher(this);
|
||||
ObserveVsync(false);
|
||||
mDidShutdown = true;
|
||||
{ // scope lock
|
||||
MutexAutoLock lock(mCompositorObserverLock);
|
||||
mCompositorVsyncObserver = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefreshTimerVsyncDispatcher::RefreshTimerVsyncDispatcher()
|
||||
|
@ -48,9 +48,11 @@ public:
|
||||
|
||||
private:
|
||||
virtual ~CompositorVsyncDispatcher();
|
||||
void ObserveVsync(bool aEnable);
|
||||
|
||||
Mutex mCompositorObserverLock;
|
||||
nsRefPtr<VsyncObserver> mCompositorVsyncObserver;
|
||||
bool mDidShutdown;
|
||||
};
|
||||
|
||||
// Dispatch vsync event to ipc actor parent and chrome RefreshTimer.
|
||||
|
Loading…
Reference in New Issue
Block a user