blob: f2a7791ada46cbbb4f28c19f874b56b0a095a8bf [file] [log] [blame]
Kevin DuBoisb2501ba2019-11-12 14:20:29 -08001/*
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#include "VSyncReactor.h"
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080018#include "TimeKeeper.h"
Kevin DuBoisb2501ba2019-11-12 14:20:29 -080019#include "VSyncDispatch.h"
20#include "VSyncTracker.h"
21
22namespace android::scheduler {
23
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080024Clock::~Clock() = default;
25
26VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
Kevin DuBoisb2501ba2019-11-12 14:20:29 -080027 std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit)
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080028 : mClock(std::move(clock)),
29 mDispatch(std::move(dispatch)),
Kevin DuBoisb2501ba2019-11-12 14:20:29 -080030 mTracker(std::move(tracker)),
31 mPendingLimit(pendingFenceLimit) {}
32
33bool VSyncReactor::addPresentFence(const std::shared_ptr<FenceTime>& fence) {
34 if (!fence) {
35 return false;
36 }
37
38 nsecs_t const signalTime = fence->getCachedSignalTime();
39 if (signalTime == Fence::SIGNAL_TIME_INVALID) {
40 return true;
41 }
42
43 std::lock_guard<std::mutex> lk(mMutex);
44 if (mIgnorePresentFences) {
45 return true;
46 }
47
48 for (auto it = mUnfiredFences.begin(); it != mUnfiredFences.end();) {
49 auto const time = (*it)->getCachedSignalTime();
50 if (time == Fence::SIGNAL_TIME_PENDING) {
51 it++;
52 } else if (time == Fence::SIGNAL_TIME_INVALID) {
53 it = mUnfiredFences.erase(it);
54 } else {
55 mTracker->addVsyncTimestamp(time);
56 it = mUnfiredFences.erase(it);
57 }
58 }
59
60 if (signalTime == Fence::SIGNAL_TIME_PENDING) {
61 if (mPendingLimit == mUnfiredFences.size()) {
62 mUnfiredFences.erase(mUnfiredFences.begin());
63 }
64 mUnfiredFences.push_back(fence);
65 } else {
66 mTracker->addVsyncTimestamp(signalTime);
67 }
68
69 return false; // TODO(b/144707443): add policy for turning on HWVsync.
70}
71
72void VSyncReactor::setIgnorePresentFences(bool ignoration) {
73 std::lock_guard<std::mutex> lk(mMutex);
74 mIgnorePresentFences = ignoration;
75 if (mIgnorePresentFences == true) {
76 mUnfiredFences.clear();
77 }
78}
79
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080080nsecs_t VSyncReactor::computeNextRefresh(int periodOffset) const {
81 auto const now = mClock->now();
82 auto const currentPeriod = periodOffset ? mTracker->currentPeriod() : 0;
83 return mTracker->nextAnticipatedVSyncTimeFrom(now + periodOffset * currentPeriod);
84}
85
86nsecs_t VSyncReactor::expectedPresentTime() {
87 return mTracker->nextAnticipatedVSyncTimeFrom(mClock->now());
88}
89
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080090void VSyncReactor::setPeriod(nsecs_t period) {
91 mTracker->setPeriod(period);
Kevin DuBoisa9fdab72019-11-14 09:44:14 -080092 {
93 std::lock_guard<std::mutex> lk(mMutex);
94 mPeriodChangeInProgress = true;
95 }
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080096}
97
98nsecs_t VSyncReactor::getPeriod() {
99 return mTracker->currentPeriod();
100}
101
Kevin DuBoisa9fdab72019-11-14 09:44:14 -0800102void VSyncReactor::beginResync() {}
103
104void VSyncReactor::endResync() {}
105
106bool VSyncReactor::addResyncSample(nsecs_t timestamp, bool* periodFlushed) {
107 assert(periodFlushed);
108 mTracker->addVsyncTimestamp(timestamp);
109 {
110 std::lock_guard<std::mutex> lk(mMutex);
111 *periodFlushed = mPeriodChangeInProgress;
112 mPeriodChangeInProgress = false;
113 }
114 return false;
115}
116
Kevin DuBoisb2501ba2019-11-12 14:20:29 -0800117} // namespace android::scheduler