1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "AndroidVsync.h"
9 #include "AndroidBridge.h"
13 * Implementation for the AndroidVsync class.
19 StaticDataMutex
<ThreadSafeWeakPtr
<AndroidVsync
>> AndroidVsync::sInstance(
20 "AndroidVsync::sInstance");
22 /* static */ RefPtr
<AndroidVsync
> AndroidVsync::GetInstance() {
23 auto weakInstance
= sInstance
.Lock();
24 RefPtr
<AndroidVsync
> instance(*weakInstance
);
26 instance
= new AndroidVsync();
27 *weakInstance
= instance
;
33 * Owned by the Java AndroidVsync instance.
35 class AndroidVsyncSupport final
36 : public java::AndroidVsync::Natives
<AndroidVsyncSupport
> {
38 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AndroidVsyncSupport
)
40 using Base
= java::AndroidVsync::Natives
<AndroidVsyncSupport
>;
41 using Base::AttachNative
;
42 using Base::DisposeNative
;
44 explicit AndroidVsyncSupport(AndroidVsync
* aAndroidVsync
)
45 : mAndroidVsync(std::move(aAndroidVsync
),
46 "AndroidVsyncSupport::mAndroidVsync") {}
49 void NotifyVsync(const java::AndroidVsync::LocalRef
& aInstance
,
50 int64_t aFrameTimeNanos
) {
51 auto androidVsync
= mAndroidVsync
.Lock();
53 (*androidVsync
)->NotifyVsync(aFrameTimeNanos
);
57 // Called by the AndroidVsync destructor
59 auto androidVsync
= mAndroidVsync
.Lock();
60 *androidVsync
= nullptr;
64 ~AndroidVsyncSupport() = default;
66 DataMutex
<AndroidVsync
*> mAndroidVsync
;
69 AndroidVsync::AndroidVsync() : mImpl("AndroidVsync.mImpl") {
70 AndroidVsyncSupport::Init();
72 auto impl
= mImpl
.Lock();
73 impl
->mSupport
= new AndroidVsyncSupport(this);
74 impl
->mSupportJava
= java::AndroidVsync::New();
75 AndroidVsyncSupport::AttachNative(impl
->mSupportJava
, impl
->mSupport
);
78 AndroidVsync::~AndroidVsync() {
79 auto impl
= mImpl
.Lock();
80 impl
->mInputObservers
.Clear();
81 impl
->mRenderObservers
.Clear();
82 impl
->UpdateObservingVsync();
83 impl
->mSupport
->Unlink();
86 void AndroidVsync::RegisterObserver(Observer
* aObserver
, ObserverType aType
) {
87 auto impl
= mImpl
.Lock();
88 if (aType
== AndroidVsync::INPUT
) {
89 impl
->mInputObservers
.AppendElement(aObserver
);
91 impl
->mRenderObservers
.AppendElement(aObserver
);
93 impl
->UpdateObservingVsync();
96 void AndroidVsync::UnregisterObserver(Observer
* aObserver
, ObserverType aType
) {
97 auto impl
= mImpl
.Lock();
98 if (aType
== AndroidVsync::INPUT
) {
99 impl
->mInputObservers
.RemoveElement(aObserver
);
101 impl
->mRenderObservers
.RemoveElement(aObserver
);
103 aObserver
->Dispose();
104 impl
->UpdateObservingVsync();
107 void AndroidVsync::Impl::UpdateObservingVsync() {
109 !mInputObservers
.IsEmpty() || !mRenderObservers
.IsEmpty();
110 if (shouldObserve
!= mObservingVsync
) {
111 mObservingVsync
= mSupportJava
->ObserveVsync(shouldObserve
);
115 // Always called on the Java UI thread.
116 void AndroidVsync::NotifyVsync(int64_t aFrameTimeNanos
) {
117 MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
119 // Convert aFrameTimeNanos to a TimeStamp. The value converts trivially to
120 // the internal ticks representation of TimeStamp_posix; both use the
121 // monotonic clock and are in nanoseconds.
122 TimeStamp timeStamp
= TimeStamp::FromSystemTime(aFrameTimeNanos
);
124 // Do not keep the lock held while calling OnVsync.
125 nsTArray
<Observer
*> observers
;
127 auto impl
= mImpl
.Lock();
128 observers
.AppendElements(impl
->mInputObservers
);
129 observers
.AppendElements(impl
->mRenderObservers
);
131 for (Observer
* observer
: observers
) {
132 observer
->OnVsync(timeStamp
);
136 void AndroidVsync::OnMaybeUpdateRefreshRate() {
137 MOZ_ASSERT(NS_IsMainThread());
139 auto impl
= mImpl
.Lock();
141 nsTArray
<Observer
*> observers
;
142 observers
.AppendElements(impl
->mRenderObservers
);
144 for (Observer
* observer
: observers
) {
145 observer
->OnMaybeUpdateRefreshRate();
149 } // namespace widget
150 } // namespace mozilla