mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
53ad814f85
ScreenManager takes the common parts of ScreenManagerWin, ScreenManagerGtk and ScreenManagerCocoa. It caches all screen information in the new Screen class. The cache are updated when the OS notifies there is a monitor config change; all changes will be pushed to content processes via PContent (patch part 6.) Screen is a pure data object. All platform dependent logic will be in widget specific helper classes. Each process will have a singleton ScreenManager object. Widget specific helper object is held alive by the ScreenManager when necessary, for example to receive updates from the OS. The change to to VsyncDispatcher.cpp is due to unified-build bustage. ScreenManager::ScreenForNativeWidget is not implemented because it will be removed in patch part 6. MozReview-Commit-ID: 5ezytAXSqHp *** fixup MozReview-Commit-ID: DQtq3UVZytA --HG-- extra : rebase_source : c1a5aac713de783586e93109fe3e197ffdc1a3ca
190 lines
5.2 KiB
C++
190 lines
5.2 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "MainThreadUtils.h"
|
|
#include "VsyncDispatcher.h"
|
|
#include "VsyncSource.h"
|
|
#include "gfxPlatform.h"
|
|
#include "mozilla/layers/Compositor.h"
|
|
#include "mozilla/layers/CompositorBridgeParent.h"
|
|
#include "mozilla/layers/CompositorThread.h"
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
#include "GeckoProfiler.h"
|
|
#include "ProfilerMarkers.h"
|
|
#endif
|
|
|
|
using namespace mozilla::layers;
|
|
|
|
namespace mozilla {
|
|
|
|
CompositorVsyncDispatcher::CompositorVsyncDispatcher()
|
|
: mCompositorObserverLock("CompositorObserverLock")
|
|
, mDidShutdown(false)
|
|
{
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
}
|
|
|
|
CompositorVsyncDispatcher::~CompositorVsyncDispatcher()
|
|
{
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
// We auto remove this vsync dispatcher from the vsync source in the nsBaseWidget
|
|
}
|
|
|
|
void
|
|
CompositorVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
|
|
{
|
|
// In vsync thread
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
layers::CompositorBridgeParent::PostInsertVsyncProfilerMarker(aVsyncTimestamp);
|
|
#endif
|
|
|
|
MutexAutoLock lock(mCompositorObserverLock);
|
|
if (mCompositorVsyncObserver) {
|
|
mCompositorVsyncObserver->NotifyVsync(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)
|
|
{
|
|
// When remote compositing or running gtests, vsync observation is
|
|
// initiated on the main thread. Otherwise, it is initiated from the compositor
|
|
// thread.
|
|
MOZ_ASSERT(NS_IsMainThread() || CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
{ // scope lock
|
|
MutexAutoLock lock(mCompositorObserverLock);
|
|
mCompositorVsyncObserver = aVsyncObserver;
|
|
}
|
|
|
|
bool observeVsync = aVsyncObserver != nullptr;
|
|
nsCOMPtr<nsIRunnable> vsyncControl = NewRunnableMethod<bool>(this,
|
|
&CompositorVsyncDispatcher::ObserveVsync,
|
|
observeVsync);
|
|
NS_DispatchToMainThread(vsyncControl);
|
|
}
|
|
|
|
void
|
|
CompositorVsyncDispatcher::Shutdown()
|
|
{
|
|
// Need to explicitly remove CompositorVsyncDispatcher when the nsBaseWidget shuts down.
|
|
// Otherwise, we would get dead vsync notifications between when the nsBaseWidget
|
|
// shuts down and the CompositorBridgeParent shuts down.
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
ObserveVsync(false);
|
|
mDidShutdown = true;
|
|
{ // scope lock
|
|
MutexAutoLock lock(mCompositorObserverLock);
|
|
mCompositorVsyncObserver = nullptr;
|
|
}
|
|
}
|
|
|
|
RefreshTimerVsyncDispatcher::RefreshTimerVsyncDispatcher()
|
|
: mRefreshTimersLock("RefreshTimers lock")
|
|
{
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
}
|
|
|
|
RefreshTimerVsyncDispatcher::~RefreshTimerVsyncDispatcher()
|
|
{
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
}
|
|
|
|
void
|
|
RefreshTimerVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
|
|
{
|
|
MutexAutoLock lock(mRefreshTimersLock);
|
|
|
|
for (size_t i = 0; i < mChildRefreshTimers.Length(); i++) {
|
|
mChildRefreshTimers[i]->NotifyVsync(aVsyncTimestamp);
|
|
}
|
|
|
|
if (mParentRefreshTimer) {
|
|
mParentRefreshTimer->NotifyVsync(aVsyncTimestamp);
|
|
}
|
|
}
|
|
|
|
void
|
|
RefreshTimerVsyncDispatcher::SetParentRefreshTimer(VsyncObserver* aVsyncObserver)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
{ // lock scope because UpdateVsyncStatus runs on main thread and will deadlock
|
|
MutexAutoLock lock(mRefreshTimersLock);
|
|
mParentRefreshTimer = aVsyncObserver;
|
|
}
|
|
|
|
UpdateVsyncStatus();
|
|
}
|
|
|
|
void
|
|
RefreshTimerVsyncDispatcher::AddChildRefreshTimer(VsyncObserver* aVsyncObserver)
|
|
{
|
|
{ // scope lock - called on pbackground thread
|
|
MutexAutoLock lock(mRefreshTimersLock);
|
|
MOZ_ASSERT(aVsyncObserver);
|
|
if (!mChildRefreshTimers.Contains(aVsyncObserver)) {
|
|
mChildRefreshTimers.AppendElement(aVsyncObserver);
|
|
}
|
|
}
|
|
|
|
UpdateVsyncStatus();
|
|
}
|
|
|
|
void
|
|
RefreshTimerVsyncDispatcher::RemoveChildRefreshTimer(VsyncObserver* aVsyncObserver)
|
|
{
|
|
{ // scope lock - called on pbackground thread
|
|
MutexAutoLock lock(mRefreshTimersLock);
|
|
MOZ_ASSERT(aVsyncObserver);
|
|
mChildRefreshTimers.RemoveElement(aVsyncObserver);
|
|
}
|
|
|
|
UpdateVsyncStatus();
|
|
}
|
|
|
|
void
|
|
RefreshTimerVsyncDispatcher::UpdateVsyncStatus()
|
|
{
|
|
if (!NS_IsMainThread()) {
|
|
NS_DispatchToMainThread(NewRunnableMethod(this,
|
|
&RefreshTimerVsyncDispatcher::UpdateVsyncStatus));
|
|
return;
|
|
}
|
|
|
|
gfx::VsyncSource::Display& display = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay();
|
|
display.NotifyRefreshTimerVsyncStatus(NeedsVsync());
|
|
}
|
|
|
|
bool
|
|
RefreshTimerVsyncDispatcher::NeedsVsync()
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MutexAutoLock lock(mRefreshTimersLock);
|
|
return (mParentRefreshTimer != nullptr) || !mChildRefreshTimers.IsEmpty();
|
|
}
|
|
|
|
} // namespace mozilla
|