зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1196308 - Delete Software Compositor Scheduler. r=sotaro
This commit is contained in:
Родитель
563a8d7712
Коммит
7242153201
|
@ -224,81 +224,14 @@ static void SetThreadPriority()
|
|||
hal::SetCurrentThreadPriority(hal::THREAD_PRIORITY_COMPOSITOR);
|
||||
}
|
||||
|
||||
CompositorScheduler::CompositorScheduler(CompositorParent* aCompositorParent)
|
||||
: mCompositorParent(aCompositorParent)
|
||||
, mCurrentCompositeTask(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CompositorScheduler::~CompositorScheduler()
|
||||
{
|
||||
MOZ_ASSERT(!mCompositorParent);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorScheduler::CancelCurrentCompositeTask()
|
||||
{
|
||||
if (mCurrentCompositeTask) {
|
||||
mCurrentCompositeTask->Cancel();
|
||||
mCurrentCompositeTask = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorScheduler::ScheduleTask(CancelableTask* aTask, int aTime)
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::CompositorLoop());
|
||||
MOZ_ASSERT(aTime >= 0);
|
||||
CompositorParent::CompositorLoop()->PostDelayedTask(FROM_HERE, aTask, aTime);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorScheduler::ResumeComposition()
|
||||
{
|
||||
mLastCompose = TimeStamp::Now();
|
||||
ComposeToTarget(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
||||
{
|
||||
mLastCompose = TimeStamp::Now();
|
||||
ComposeToTarget(aTarget, aRect);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(mCompositorParent);
|
||||
mCompositorParent->CompositeToTarget(aTarget, aRect);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorScheduler::Destroy()
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
CancelCurrentCompositeTask();
|
||||
mCompositorParent = nullptr;
|
||||
}
|
||||
|
||||
CompositorSoftwareTimerScheduler::CompositorSoftwareTimerScheduler(CompositorParent* aCompositorParent)
|
||||
: CompositorScheduler(aCompositorParent)
|
||||
{
|
||||
}
|
||||
|
||||
CompositorSoftwareTimerScheduler::~CompositorSoftwareTimerScheduler()
|
||||
{
|
||||
MOZ_ASSERT(!mCurrentCompositeTask);
|
||||
}
|
||||
|
||||
// Used when layout.frame_rate is -1. Needs to be kept in sync with
|
||||
// DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
|
||||
static const int32_t kDefaultFrameRate = 60;
|
||||
|
||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||
static int32_t
|
||||
CalculateCompositionFrameRate()
|
||||
{
|
||||
// Used when layout.frame_rate is -1. Needs to be kept in sync with
|
||||
// DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
|
||||
// TODO: This should actually return the vsync rate.
|
||||
const int32_t defaultFrameRate = 60;
|
||||
int32_t compositionFrameRatePref = gfxPrefs::LayersCompositionFrameRate();
|
||||
if (compositionFrameRatePref < 0) {
|
||||
// Use the same frame rate for composition as for layout.
|
||||
|
@ -306,68 +239,13 @@ CalculateCompositionFrameRate()
|
|||
if (layoutFrameRatePref < 0) {
|
||||
// TODO: The main thread frame scheduling code consults the actual
|
||||
// monitor refresh rate in this case. We should do the same.
|
||||
return kDefaultFrameRate;
|
||||
return defaultFrameRate;
|
||||
}
|
||||
return layoutFrameRatePref;
|
||||
}
|
||||
return compositionFrameRatePref;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorSoftwareTimerScheduler::ScheduleComposition()
|
||||
{
|
||||
if (mCurrentCompositeTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool initialComposition = mLastCompose.IsNull();
|
||||
TimeDuration delta;
|
||||
if (!initialComposition) {
|
||||
delta = TimeStamp::Now() - mLastCompose;
|
||||
}
|
||||
|
||||
int32_t rate = CalculateCompositionFrameRate();
|
||||
|
||||
// If rate == 0 (ASAP mode), minFrameDelta must be 0 so there's no delay.
|
||||
TimeDuration minFrameDelta = TimeDuration::FromMilliseconds(
|
||||
rate == 0 ? 0.0 : std::max(0.0, 1000.0 / rate));
|
||||
|
||||
mCurrentCompositeTask = NewRunnableMethod(this,
|
||||
&CompositorSoftwareTimerScheduler::CallComposite);
|
||||
|
||||
if (!initialComposition && delta < minFrameDelta) {
|
||||
TimeDuration delay = minFrameDelta - delta;
|
||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||
mExpectedComposeStartTime = TimeStamp::Now() + delay;
|
||||
#endif
|
||||
ScheduleTask(mCurrentCompositeTask, delay.ToMilliseconds());
|
||||
} else {
|
||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||
mExpectedComposeStartTime = TimeStamp::Now();
|
||||
#endif
|
||||
ScheduleTask(mCurrentCompositeTask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorSoftwareTimerScheduler::NeedsComposite()
|
||||
{
|
||||
return mCurrentCompositeTask ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorSoftwareTimerScheduler::CallComposite()
|
||||
{
|
||||
Composite(TimeStamp::Now());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorSoftwareTimerScheduler::Composite(TimeStamp aTimestamp)
|
||||
{
|
||||
mCurrentCompositeTask = nullptr;
|
||||
mLastCompose = aTimestamp;
|
||||
ComposeToTarget(nullptr);
|
||||
}
|
||||
|
||||
CompositorVsyncScheduler::Observer::Observer(CompositorVsyncScheduler* aOwner)
|
||||
: mMutex("CompositorVsyncScheduler.Observer.Mutex")
|
||||
|
@ -398,11 +276,12 @@ CompositorVsyncScheduler::Observer::Destroy()
|
|||
}
|
||||
|
||||
CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget)
|
||||
: CompositorScheduler(aCompositorParent)
|
||||
: mCompositorParent(aCompositorParent)
|
||||
, mLastCompose(TimeStamp::Now())
|
||||
, mCurrentCompositeTask(nullptr)
|
||||
, mNeedsComposite(false)
|
||||
, mIsObservingVsync(false)
|
||||
, mVsyncNotificationsSkipped(0)
|
||||
, mCompositorParent(aCompositorParent)
|
||||
, mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
|
||||
, mSetNeedsCompositeMonitor("SetNeedsCompositeMonitor")
|
||||
, mSetNeedsCompositeTask(nullptr)
|
||||
|
@ -414,6 +293,11 @@ CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorParent* aCompositor
|
|||
#ifdef MOZ_WIDGET_GONK
|
||||
GeckoTouchDispatcher::GetInstance()->SetCompositorVsyncScheduler(this);
|
||||
#endif
|
||||
|
||||
// mAsapScheduling is set on the main thread during init,
|
||||
// but is only accessed after on the compositor thread.
|
||||
mAsapScheduling = gfxPrefs::LayersCompositionFrameRate() == 0 ||
|
||||
gfxPlatform::IsInLayoutAsapMode();
|
||||
}
|
||||
|
||||
CompositorVsyncScheduler::~CompositorVsyncScheduler()
|
||||
|
@ -433,13 +317,32 @@ CompositorVsyncScheduler::Destroy()
|
|||
mVsyncObserver->Destroy();
|
||||
mVsyncObserver = nullptr;
|
||||
CancelCurrentSetNeedsCompositeTask();
|
||||
CompositorScheduler::Destroy();
|
||||
CancelCurrentCompositeTask();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::PostCompositeTask(TimeStamp aCompositeTimestamp)
|
||||
{
|
||||
// can be called from the compositor or vsync thread
|
||||
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
||||
if (mCurrentCompositeTask == nullptr) {
|
||||
mCurrentCompositeTask = NewRunnableMethod(this,
|
||||
&CompositorVsyncScheduler::Composite,
|
||||
aCompositeTimestamp);
|
||||
ScheduleTask(mCurrentCompositeTask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::ScheduleComposition()
|
||||
{
|
||||
SetNeedsComposite(true);
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
if (mAsapScheduling) {
|
||||
// Used only for performance testing purposes
|
||||
PostCompositeTask(TimeStamp::Now());
|
||||
} else {
|
||||
SetNeedsComposite(true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -488,14 +391,7 @@ CompositorVsyncScheduler::NotifyVsync(TimeStamp aVsyncTimestamp)
|
|||
// Called from the vsync dispatch thread
|
||||
MOZ_ASSERT(!CompositorParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
||||
if (mCurrentCompositeTask == nullptr) {
|
||||
mCurrentCompositeTask = NewRunnableMethod(this,
|
||||
&CompositorVsyncScheduler::Composite,
|
||||
aVsyncTimestamp);
|
||||
ScheduleTask(mCurrentCompositeTask, 0);
|
||||
}
|
||||
PostCompositeTask(aVsyncTimestamp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -504,7 +400,10 @@ CompositorVsyncScheduler::CancelCurrentCompositeTask()
|
|||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread() || NS_IsMainThread());
|
||||
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
||||
CompositorScheduler::CancelCurrentCompositeTask();
|
||||
if (mCurrentCompositeTask) {
|
||||
mCurrentCompositeTask->Cancel();
|
||||
mCurrentCompositeTask = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -518,7 +417,7 @@ CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
|
|||
|
||||
DispatchTouchEvents(aVsyncTimestamp);
|
||||
|
||||
if (mNeedsComposite) {
|
||||
if (mNeedsComposite || mAsapScheduling) {
|
||||
mNeedsComposite = false;
|
||||
mLastCompose = aVsyncTimestamp;
|
||||
ComposeToTarget(nullptr);
|
||||
|
@ -549,7 +448,8 @@ void
|
|||
CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
||||
{
|
||||
OnForceComposeToTarget();
|
||||
CompositorScheduler::ForceComposeToTarget(aTarget, aRect);
|
||||
mLastCompose = TimeStamp::Now();
|
||||
ComposeToTarget(aTarget, aRect);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -613,22 +513,27 @@ MessageLoop* CompositorParent::CompositorLoop()
|
|||
return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsInCompositorAsapMode()
|
||||
void
|
||||
CompositorVsyncScheduler::ScheduleTask(CancelableTask* aTask, int aTime)
|
||||
{
|
||||
// Returns true if the compositor is allowed to be in ASAP mode
|
||||
// and layout is not in ASAP mode
|
||||
return gfxPrefs::LayersCompositionFrameRate() == 0 &&
|
||||
!gfxPlatform::IsInLayoutAsapMode();
|
||||
MOZ_ASSERT(CompositorParent::CompositorLoop());
|
||||
MOZ_ASSERT(aTime >= 0);
|
||||
CompositorParent::CompositorLoop()->PostDelayedTask(FROM_HERE, aTask, aTime);
|
||||
}
|
||||
|
||||
static bool
|
||||
UseVsyncComposition()
|
||||
void
|
||||
CompositorVsyncScheduler::ResumeComposition()
|
||||
{
|
||||
return gfxPrefs::VsyncAlignedCompositor()
|
||||
&& gfxPrefs::HardwareVsyncEnabled()
|
||||
&& !IsInCompositorAsapMode()
|
||||
&& !gfxPlatform::IsInLayoutAsapMode();
|
||||
mLastCompose = TimeStamp::Now();
|
||||
ComposeToTarget(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(mCompositorParent);
|
||||
mCompositorParent->CompositeToTarget(aTarget, aRect);
|
||||
}
|
||||
|
||||
CompositorParent::CompositorParent(nsIWidget* aWidget,
|
||||
|
@ -675,12 +580,8 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
|
|||
mApzcTreeManager = new APZCTreeManager();
|
||||
}
|
||||
|
||||
if (UseVsyncComposition()) {
|
||||
gfxDebugOnce() << "Enabling vsync compositor";
|
||||
mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget);
|
||||
} else {
|
||||
mCompositorScheduler = new CompositorSoftwareTimerScheduler(this);
|
||||
}
|
||||
gfxDebugOnce() << "Enabling vsync compositor";
|
||||
mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget);
|
||||
|
||||
LayerScope::SetPixelScale(mWidget->GetDefaultScale().scale);
|
||||
}
|
||||
|
|
|
@ -88,21 +88,31 @@ private:
|
|||
friend class CompositorParent;
|
||||
};
|
||||
|
||||
class CompositorScheduler
|
||||
/**
|
||||
* Manages the vsync (de)registration and tracking on behalf of the
|
||||
* compositor when it need to paint.
|
||||
* Turns vsync notifications into scheduled composites.
|
||||
**/
|
||||
class CompositorVsyncScheduler
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorScheduler)
|
||||
explicit CompositorScheduler(CompositorParent* aCompositorParent);
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler)
|
||||
|
||||
virtual void ScheduleComposition() = 0;
|
||||
virtual void CancelCurrentCompositeTask();
|
||||
virtual bool NeedsComposite() = 0;
|
||||
virtual void Composite(TimeStamp aTimestamp) = 0;
|
||||
virtual void ScheduleTask(CancelableTask*, int);
|
||||
virtual void ResumeComposition();
|
||||
virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect);
|
||||
virtual void ComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
|
||||
virtual void Destroy();
|
||||
public:
|
||||
explicit CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget);
|
||||
bool NotifyVsync(TimeStamp aVsyncTimestamp);
|
||||
void SetNeedsComposite(bool aSchedule);
|
||||
void OnForceComposeToTarget();
|
||||
|
||||
void ScheduleTask(CancelableTask*, int);
|
||||
void ResumeComposition();
|
||||
void ComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
|
||||
void PostCompositeTask(TimeStamp aCompositeTimestamp);
|
||||
void Destroy();
|
||||
void ScheduleComposition();
|
||||
void CancelCurrentCompositeTask();
|
||||
bool NeedsComposite();
|
||||
void Composite(TimeStamp aVsyncTimestamp);
|
||||
void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect);
|
||||
|
||||
const TimeStamp& GetLastComposeTime()
|
||||
{
|
||||
|
@ -115,56 +125,7 @@ public:
|
|||
return mExpectedComposeStartTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~CompositorScheduler();
|
||||
|
||||
CompositorParent* mCompositorParent;
|
||||
TimeStamp mLastCompose;
|
||||
CancelableTask* mCurrentCompositeTask;
|
||||
|
||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||
TimeStamp mExpectedComposeStartTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
class CompositorSoftwareTimerScheduler final : public CompositorScheduler
|
||||
{
|
||||
public:
|
||||
explicit CompositorSoftwareTimerScheduler(CompositorParent* aCompositorParent);
|
||||
|
||||
// from CompositorScheduler
|
||||
virtual void ScheduleComposition() override;
|
||||
virtual bool NeedsComposite() override;
|
||||
virtual void Composite(TimeStamp aTimestamp) override;
|
||||
|
||||
void CallComposite();
|
||||
private:
|
||||
virtual ~CompositorSoftwareTimerScheduler();
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages the vsync (de)registration and tracking on behalf of the
|
||||
* compositor when it need to paint.
|
||||
* Turns vsync notifications into scheduled composites.
|
||||
**/
|
||||
|
||||
class CompositorVsyncScheduler final : public CompositorScheduler
|
||||
{
|
||||
public:
|
||||
explicit CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget);
|
||||
bool NotifyVsync(TimeStamp aVsyncTimestamp);
|
||||
void SetNeedsComposite(bool aSchedule);
|
||||
void OnForceComposeToTarget();
|
||||
|
||||
// from CompositorScheduler
|
||||
virtual void ScheduleComposition() override;
|
||||
virtual void CancelCurrentCompositeTask() override;
|
||||
virtual bool NeedsComposite() override;
|
||||
virtual void Composite(TimeStamp aVsyncTimestamp) override;
|
||||
virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect) override;
|
||||
virtual void Destroy() override;
|
||||
|
||||
|
||||
private:
|
||||
virtual ~CompositorVsyncScheduler();
|
||||
|
||||
|
@ -188,10 +149,18 @@ private:
|
|||
CompositorVsyncScheduler* mOwner;
|
||||
};
|
||||
|
||||
CompositorParent* mCompositorParent;
|
||||
TimeStamp mLastCompose;
|
||||
CancelableTask* mCurrentCompositeTask;
|
||||
|
||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||
TimeStamp mExpectedComposeStartTime;
|
||||
#endif
|
||||
|
||||
bool mAsapScheduling;
|
||||
bool mNeedsComposite;
|
||||
bool mIsObservingVsync;
|
||||
int32_t mVsyncNotificationsSkipped;
|
||||
CompositorParent* mCompositorParent;
|
||||
nsRefPtr<CompositorVsyncDispatcher> mCompositorVsyncDispatcher;
|
||||
nsRefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
|
||||
|
||||
|
@ -216,7 +185,7 @@ class CompositorParent final : public PCompositorParent,
|
|||
public ShadowLayersManager
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
|
||||
friend class CompositorScheduler;
|
||||
friend class CompositorVsyncScheduler;
|
||||
|
||||
public:
|
||||
explicit CompositorParent(nsIWidget* aWidget,
|
||||
|
@ -498,7 +467,7 @@ protected:
|
|||
nsRefPtr<APZCTreeManager> mApzcTreeManager;
|
||||
|
||||
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
||||
nsRefPtr<CompositorScheduler> mCompositorScheduler;
|
||||
nsRefPtr<CompositorVsyncScheduler> mCompositorScheduler;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче