Bug 1882714 [wpt PR 44850] - Update wpt metadata, a=testonly
[gecko.git] / widget / android / AndroidVsync.cpp
blob6aed5f1e539cee662cf787d1ebe0a110ef916376
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"
10 #include "nsTArray.h"
12 /**
13 * Implementation for the AndroidVsync class.
16 namespace mozilla {
17 namespace widget {
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);
25 if (!instance) {
26 instance = new AndroidVsync();
27 *weakInstance = instance;
29 return instance;
32 /**
33 * Owned by the Java AndroidVsync instance.
35 class AndroidVsyncSupport final
36 : public java::AndroidVsync::Natives<AndroidVsyncSupport> {
37 public:
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") {}
48 // Called by Java
49 void NotifyVsync(const java::AndroidVsync::LocalRef& aInstance,
50 int64_t aFrameTimeNanos) {
51 auto androidVsync = mAndroidVsync.Lock();
52 if (*androidVsync) {
53 (*androidVsync)->NotifyVsync(aFrameTimeNanos);
57 // Called by the AndroidVsync destructor
58 void Unlink() {
59 auto androidVsync = mAndroidVsync.Lock();
60 *androidVsync = nullptr;
63 protected:
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);
90 } else {
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);
100 } else {
101 impl->mRenderObservers.RemoveElement(aObserver);
103 aObserver->Dispose();
104 impl->UpdateObservingVsync();
107 void AndroidVsync::Impl::UpdateObservingVsync() {
108 bool shouldObserve =
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