Bug 1758688 [wpt PR 33067] - [FedCM] Make revoke a non-static method, a=testonly
[gecko.git] / gfx / thebes / SoftwareVsyncSource.cpp
blobf52c539914efd6d06824c63e1ced6a5c375497ea
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 */
7 #include "SoftwareVsyncSource.h"
8 #include "base/task.h"
9 #include "gfxPlatform.h"
10 #include "nsThreadUtils.h"
12 using namespace mozilla;
14 SoftwareVsyncSource::SoftwareVsyncSource() : mVsyncEnabled(false) {
15 // Mimic 60 fps
16 MOZ_ASSERT(NS_IsMainThread());
17 const double rate = 1000.0 / (double)gfxPlatform::GetSoftwareVsyncRate();
18 mVsyncRate = mozilla::TimeDuration::FromMilliseconds(rate);
19 mVsyncThread = new base::Thread("SoftwareVsyncThread");
20 MOZ_RELEASE_ASSERT(mVsyncThread->Start(),
21 "GFX: Could not start software vsync thread");
24 SoftwareVsyncSource::~SoftwareVsyncSource() {
25 MOZ_ASSERT(NS_IsMainThread());
26 if (mVsyncThread) {
27 mVsyncThread->Stop();
28 delete mVsyncThread;
32 void SoftwareVsyncSource::EnableVsync() {
33 MOZ_ASSERT(mVsyncThread->IsRunning());
34 if (NS_IsMainThread()) {
35 if (mVsyncEnabled) {
36 return;
38 mVsyncEnabled = true;
40 mVsyncThread->message_loop()->PostTask(
41 NewRunnableMethod("SoftwareVsyncSource::EnableVsync", this,
42 &SoftwareVsyncSource::EnableVsync));
43 return;
46 MOZ_ASSERT(IsInSoftwareVsyncThread());
47 TimeStamp vsyncTime = TimeStamp::Now();
48 TimeStamp outputTime = vsyncTime + mVsyncRate;
49 NotifyVsync(vsyncTime, outputTime);
52 void SoftwareVsyncSource::DisableVsync() {
53 MOZ_ASSERT(mVsyncThread->IsRunning());
54 if (NS_IsMainThread()) {
55 if (!mVsyncEnabled) {
56 return;
58 mVsyncEnabled = false;
60 mVsyncThread->message_loop()->PostTask(
61 NewRunnableMethod("SoftwareVsyncSource::DisableVsync", this,
62 &SoftwareVsyncSource::DisableVsync));
63 return;
66 MOZ_ASSERT(IsInSoftwareVsyncThread());
67 if (mCurrentVsyncTask) {
68 mCurrentVsyncTask->Cancel();
69 mCurrentVsyncTask = nullptr;
73 bool SoftwareVsyncSource::IsVsyncEnabled() {
74 MOZ_ASSERT(NS_IsMainThread());
75 return mVsyncEnabled;
78 bool SoftwareVsyncSource::IsInSoftwareVsyncThread() {
79 return mVsyncThread->thread_id() == PlatformThread::CurrentId();
82 void SoftwareVsyncSource::NotifyVsync(
83 const mozilla::TimeStamp& aVsyncTimestamp,
84 const mozilla::TimeStamp& aOutputTimestamp) {
85 MOZ_ASSERT(IsInSoftwareVsyncThread());
87 mozilla::TimeStamp displayVsyncTime = aVsyncTimestamp;
88 mozilla::TimeStamp now = mozilla::TimeStamp::Now();
89 // Posted tasks can only have integer millisecond delays
90 // whereas TimeDurations can have floating point delays.
91 // Thus the vsync timestamp can be in the future, which large parts
92 // of the system can't handle, including animations. Force the timestamp to be
93 // now.
94 if (aVsyncTimestamp > now) {
95 displayVsyncTime = now;
98 VsyncSource::NotifyVsync(displayVsyncTime, aOutputTimestamp);
100 // Prevent skew by still scheduling based on the original
101 // vsync timestamp
102 ScheduleNextVsync(aVsyncTimestamp);
105 mozilla::TimeDuration SoftwareVsyncSource::GetVsyncRate() { return mVsyncRate; }
107 void SoftwareVsyncSource::ScheduleNextVsync(
108 mozilla::TimeStamp aVsyncTimestamp) {
109 MOZ_ASSERT(IsInSoftwareVsyncThread());
110 mozilla::TimeStamp nextVsync = aVsyncTimestamp + mVsyncRate;
111 mozilla::TimeDuration delay = nextVsync - mozilla::TimeStamp::Now();
112 if (delay.ToMilliseconds() < 0) {
113 delay = mozilla::TimeDuration::FromMilliseconds(0);
114 nextVsync = mozilla::TimeStamp::Now();
117 TimeStamp outputTime = nextVsync + mVsyncRate;
119 mCurrentVsyncTask =
120 NewCancelableRunnableMethod<mozilla::TimeStamp, mozilla::TimeStamp>(
121 "SoftwareVsyncSource::NotifyVsync", this,
122 &SoftwareVsyncSource::NotifyVsync, nextVsync, outputTime);
124 RefPtr<Runnable> addrefedTask = mCurrentVsyncTask;
125 mVsyncThread->message_loop()->PostDelayedTask(addrefedTask.forget(),
126 delay.ToMilliseconds());
129 void SoftwareVsyncSource::Shutdown() {
130 MOZ_ASSERT(NS_IsMainThread());
131 DisableVsync();
132 mVsyncThread->Stop();
133 delete mVsyncThread;
134 mVsyncThread = nullptr;