1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <memory>
20 #include <mutex>
21 #include <unordered_map>
22 #include <vector>
23 
24 #include <android-base/thread_annotations.h>
25 #include <ui/DisplayId.h>
26 #include <ui/FenceTime.h>
27 
28 #include <scheduler/TimeKeeper.h>
29 
30 #include "VSyncTracker.h"
31 #include "VsyncController.h"
32 
33 namespace android::scheduler {
34 
35 class Clock;
36 class VSyncDispatch;
37 class VSyncTracker;
38 
39 // TODO (b/145217110): consider renaming.
40 class VSyncReactor : public VsyncController {
41 public:
42     VSyncReactor(PhysicalDisplayId, std::unique_ptr<Clock> clock, VSyncTracker& tracker,
43                  size_t pendingFenceLimit, bool supportKernelIdleTimer);
44     ~VSyncReactor();
45 
46     bool addPresentFence(std::shared_ptr<FenceTime>) final;
47     void setIgnorePresentFences(bool ignore) final;
48 
49     void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force) final;
50 
51     bool addHwVsyncTimestamp(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
52                              bool* periodFlushed) final;
53 
54     void setDisplayPowerMode(hal::PowerMode powerMode) final;
55 
56     void dump(std::string& result) const final;
57 
58 private:
59     void setIgnorePresentFencesInternal(bool ignore) REQUIRES(mMutex);
60     void updateIgnorePresentFencesInternal() REQUIRES(mMutex);
61     void startPeriodTransitionInternal(ftl::NonNull<DisplayModePtr>) REQUIRES(mMutex);
62     void endPeriodTransition() REQUIRES(mMutex);
63     bool periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_t> hwcVsyncPeriod)
64             REQUIRES(mMutex);
65 
66     const PhysicalDisplayId mId;
67     std::unique_ptr<Clock> const mClock;
68     VSyncTracker& mTracker;
69     size_t const mPendingLimit;
70 
71     mutable std::mutex mMutex;
72     bool mInternalIgnoreFences GUARDED_BY(mMutex) = false;
73     bool mExternalIgnoreFences GUARDED_BY(mMutex) = false;
74     std::vector<std::shared_ptr<android::FenceTime>> mUnfiredFences GUARDED_BY(mMutex);
75 
76     bool mMoreSamplesNeeded GUARDED_BY(mMutex) = false;
77     bool mPeriodConfirmationInProgress GUARDED_BY(mMutex) = false;
78     DisplayModePtr mModePtrTransitioningTo GUARDED_BY(mMutex);
79     std::optional<nsecs_t> mLastHwVsync GUARDED_BY(mMutex);
80 
81     hal::PowerMode mDisplayPowerMode GUARDED_BY(mMutex) = hal::PowerMode::ON;
82 
83     const bool mSupportKernelIdleTimer = false;
84 };
85 
86 class SystemClock : public Clock {
87     nsecs_t now() const final;
88 };
89 
90 } // namespace android::scheduler
91