blob: 84b391246ead48550b22ee1b18fe506d64c048c3 [file] [log] [blame]
Chethan Kumar R E70750f22021-11-23 17:39:01 +05301/*
2 * Copyright 2021 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
18/*
19 Reference for some of the classes and functions has been taken from unittests
20 present in frameworks/native/services/surfaceflinger/tests/unittests
21*/
22
23#pragma once
24
25#include "Clock.h"
26#include "Layer.h"
27#include "Scheduler/EventThread.h"
28#include "Scheduler/RefreshRateConfigs.h"
29#include "Scheduler/Scheduler.h"
30#include "Scheduler/VSyncTracker.h"
31#include "Scheduler/VsyncModulator.h"
32#include "scheduler/TimeKeeper.h"
33
34namespace android::fuzz {
35
36constexpr int64_t kVsyncPeriods[] = {static_cast<int64_t>(1e9f / 30),
37 static_cast<int64_t>(1e9f / 60),
38 static_cast<int64_t>(1e9f / 72),
39 static_cast<int64_t>(1e9f / 90),
40 static_cast<int64_t>(1e9f / 120)};
41
42android::scheduler::RefreshRateConfigs::LayerVoteType kLayerVoteTypes[] =
43 {android::scheduler::RefreshRateConfigs::LayerVoteType::NoVote,
44 android::scheduler::RefreshRateConfigs::LayerVoteType::Min,
45 android::scheduler::RefreshRateConfigs::LayerVoteType::Max,
46 android::scheduler::RefreshRateConfigs::LayerVoteType::Heuristic,
47 android::scheduler::RefreshRateConfigs::LayerVoteType::ExplicitDefault,
48 android::scheduler::RefreshRateConfigs::LayerVoteType::ExplicitExactOrMultiple};
49
50class FuzzImplClock : public android::scheduler::Clock {
51public:
52 nsecs_t now() const { return 1; }
53};
54
55class ClockWrapper : public android::scheduler::Clock {
56public:
57 ClockWrapper(std::shared_ptr<android::scheduler::Clock> const& clock) : mClock(clock) {}
58
59 nsecs_t now() const { return mClock->now(); }
60
61private:
62 std::shared_ptr<android::scheduler::Clock> const mClock;
63};
64
65} // namespace android::fuzz
66
67namespace android {
68
69using namespace std::chrono_literals;
70
71class FakeClock : public Clock {
72public:
73 virtual ~FakeClock() = default;
74 std::chrono::steady_clock::time_point now() const override { return mNow; }
75
76 void advanceTime(std::chrono::nanoseconds delta) { mNow += delta; }
77
78private:
79 std::chrono::steady_clock::time_point mNow;
80};
81
82class FuzzImplLayer : public Layer {
83public:
84 FuzzImplLayer(SurfaceFlinger* flinger, std::string name)
85 : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {}
86 explicit FuzzImplLayer(SurfaceFlinger* flinger) : FuzzImplLayer(flinger, "FuzzLayer") {}
87
88 const char* getType() const override { return ""; }
89
90 bool isVisible() const override { return true; }
91
92 sp<Layer> createClone() override { return nullptr; }
93};
94
95class FuzzImplVSyncSource : public VSyncSource {
96public:
97 const char* getName() const override { return "fuzz"; }
98
99 void setVSyncEnabled(bool /* enable */) override {}
100
101 void setCallback(Callback* /* callback */) override {}
102
103 void setDuration(std::chrono::nanoseconds /* workDuration */,
104 std::chrono::nanoseconds /* readyDuration */) override {}
105
Rachel Leeef2e21f2022-02-01 14:51:34 -0800106 VSyncData getLatestVSyncData() const override { return {}; }
107
Chethan Kumar R E70750f22021-11-23 17:39:01 +0530108 void dump(std::string& /* result */) const override {}
109};
110
111class FuzzImplVSyncTracker : public scheduler::VSyncTracker {
112public:
113 FuzzImplVSyncTracker(nsecs_t period) { mPeriod = period; }
114
115 FuzzImplVSyncTracker() = default;
116
117 bool addVsyncTimestamp(nsecs_t /* timestamp */) override { return true; }
118
119 nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t /* timePoint */) const override { return 1; }
120
121 nsecs_t currentPeriod() const override { return 1; }
122
123 void setPeriod(nsecs_t /* period */) override {}
124
125 void resetModel() override {}
126
127 bool needsMoreSamples() const override { return true; }
128
129 bool isVSyncInPhase(nsecs_t /* timePoint */, Fps /* frameRate */) const override {
130 return true;
131 }
132
133 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
134 if (timePoint % mPeriod == 0) {
135 return timePoint;
136 }
137 return (timePoint - (timePoint % mPeriod) + mPeriod);
138 }
139
140 void dump(std::string& /* result */) const override {}
141
142protected:
143 nsecs_t mPeriod;
144};
145
146class FuzzImplVSyncDispatch : public scheduler::VSyncDispatch {
147public:
148 CallbackToken registerCallback(Callback /* callbackFn */,
149 std::string /* callbackName */) override {
150 return CallbackToken{};
151 }
152
153 void unregisterCallback(CallbackToken /* token */) override {}
154
155 scheduler::ScheduleResult schedule(CallbackToken /* token */,
156 ScheduleTiming /* scheduleTiming */) override {
157 return (scheduler::ScheduleResult)0;
158 }
159
160 scheduler::CancelResult cancel(CallbackToken /* token */) override {
161 return (scheduler::CancelResult)0;
162 }
163
164 void dump(std::string& /* result */) const override {}
165};
166
167} // namespace android
168
169namespace android::scheduler {
170
171DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod,
172 ui::Size resolution = ui::Size()) {
173 return DisplayMode::Builder(hal::HWConfigId(modeId.value()))
174 .setId(modeId)
175 .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
176 .setVsyncPeriod(int32_t(vsyncPeriod))
177 .setGroup(group)
178 .setHeight(resolution.height)
179 .setWidth(resolution.width)
180 .build();
181}
182
183class ControllableClock : public TimeKeeper {
184public:
185 nsecs_t now() const { return 1; };
186 void alarmAt(std::function<void()> /* callback */, nsecs_t /* time */) override {}
187 void alarmCancel() override {}
188 void dump(std::string& /* result */) const override {}
189
190 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
191 mCallback = callback;
192 mNextCallbackTime = time;
193 }
194
195 nsecs_t fakeTime() const { return mCurrentTime; }
196
197 void advanceToNextCallback() {
198 mCurrentTime = mNextCallbackTime;
199 if (mCallback) {
200 mCallback();
201 }
202 }
203
204 void advanceBy(nsecs_t advancement) {
205 mCurrentTime += advancement;
206 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
207 mCallback();
208 }
209 };
210
211 void setLag(nsecs_t lag) { mLag = lag; }
212
213private:
214 std::function<void()> mCallback;
215 nsecs_t mNextCallbackTime = 0;
216 nsecs_t mCurrentTime = 0;
217 nsecs_t mLag = 0;
218};
219
220static VsyncModulator::TimePoint Now() {
221 static VsyncModulator::TimePoint now;
222 return now += VsyncModulator::MIN_EARLY_TRANSACTION_TIME;
223}
224
225class FuzzImplVsyncModulator : public VsyncModulator {
226public:
227 FuzzImplVsyncModulator(const VsyncConfigSet& config, Now now) : VsyncModulator(config, now) {}
228
229 void binderDied(const wp<IBinder>& token) { VsyncModulator::binderDied(token); }
230};
231} // namespace android::scheduler