blob: 8de35b1c2fa305fe34f810136d413558d157e394 [file] [log] [blame]
Alec Mourib488afa2019-05-23 10:22:24 -07001/*
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
Alec Mourid7599d82019-05-22 19:58:00 -070017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
Alec Mourib488afa2019-05-23 10:22:24 -070019#include "VSyncModulator.h"
20
Alec Mourid7599d82019-05-22 19:58:00 -070021#include <cutils/properties.h>
22#include <utils/Trace.h>
23
Alec Mourib488afa2019-05-23 10:22:24 -070024#include <cinttypes>
25#include <mutex>
26
Dominik Laskowskieddeda12019-07-19 11:54:13 -070027namespace android::scheduler {
Alec Mourib488afa2019-05-23 10:22:24 -070028
Dominik Laskowskieddeda12019-07-19 11:54:13 -070029VSyncModulator::VSyncModulator(Scheduler& scheduler,
Dominik Laskowski98041832019-08-01 18:35:59 -070030 Scheduler::ConnectionHandle appConnectionHandle,
31 Scheduler::ConnectionHandle sfConnectionHandle,
Dominik Laskowskieddeda12019-07-19 11:54:13 -070032 const OffsetsConfig& config)
33 : mScheduler(scheduler),
34 mAppConnectionHandle(appConnectionHandle),
35 mSfConnectionHandle(sfConnectionHandle),
36 mOffsetsConfig(config) {
Alec Mourid7599d82019-05-22 19:58:00 -070037 char value[PROPERTY_VALUE_MAX];
38 property_get("debug.sf.vsync_trace_detailed_info", value, "0");
39 mTraceDetailedInfo = atoi(value);
Alec Mourid7599d82019-05-22 19:58:00 -070040}
41
Dominik Laskowskieddeda12019-07-19 11:54:13 -070042void VSyncModulator::setPhaseOffsets(const OffsetsConfig& config) {
Alec Mourid7599d82019-05-22 19:58:00 -070043 std::lock_guard<std::mutex> lock(mMutex);
Dominik Laskowskieddeda12019-07-19 11:54:13 -070044 mOffsetsConfig = config;
Alec Mourid7599d82019-05-22 19:58:00 -070045 updateOffsetsLocked();
Alec Mourib488afa2019-05-23 10:22:24 -070046}
47
48void VSyncModulator::setTransactionStart(Scheduler::TransactionStart transactionStart) {
49 if (transactionStart == Scheduler::TransactionStart::EARLY) {
50 mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT_TRANSACTION;
51 }
52
53 // An early transaction stays an early transaction.
54 if (transactionStart == mTransactionStart ||
55 mTransactionStart == Scheduler::TransactionStart::EARLY) {
56 return;
57 }
58 mTransactionStart = transactionStart;
59 updateOffsets();
60}
61
62void VSyncModulator::onTransactionHandled() {
63 if (mTransactionStart == Scheduler::TransactionStart::NORMAL) return;
64 mTransactionStart = Scheduler::TransactionStart::NORMAL;
65 updateOffsets();
66}
67
68void VSyncModulator::onRefreshRateChangeInitiated() {
69 if (mRefreshRateChangePending) {
70 return;
71 }
72 mRefreshRateChangePending = true;
73 updateOffsets();
74}
75
76void VSyncModulator::onRefreshRateChangeCompleted() {
77 if (!mRefreshRateChangePending) {
78 return;
79 }
80 mRefreshRateChangePending = false;
81 updateOffsets();
82}
83
84void VSyncModulator::onRefreshed(bool usedRenderEngine) {
85 bool updateOffsetsNeeded = false;
86 if (mRemainingEarlyFrameCount > 0) {
87 mRemainingEarlyFrameCount--;
88 updateOffsetsNeeded = true;
89 }
90 if (usedRenderEngine) {
91 mRemainingRenderEngineUsageCount = MIN_EARLY_GL_FRAME_COUNT_TRANSACTION;
92 updateOffsetsNeeded = true;
93 } else if (mRemainingRenderEngineUsageCount > 0) {
94 mRemainingRenderEngineUsageCount--;
95 updateOffsetsNeeded = true;
96 }
97 if (updateOffsetsNeeded) {
98 updateOffsets();
99 }
100}
101
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700102VSyncModulator::Offsets VSyncModulator::getOffsets() const {
Alec Mourid7599d82019-05-22 19:58:00 -0700103 std::lock_guard<std::mutex> lock(mMutex);
Alec Mourib656aed2019-06-21 16:27:05 -0700104 return mOffsets;
Alec Mourid7599d82019-05-22 19:58:00 -0700105}
106
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700107const VSyncModulator::Offsets& VSyncModulator::getNextOffsets() const {
Alec Mourib488afa2019-05-23 10:22:24 -0700108 // Early offsets are used if we're in the middle of a refresh rate
109 // change, or if we recently begin a transaction.
110 if (mTransactionStart == Scheduler::TransactionStart::EARLY || mRemainingEarlyFrameCount > 0 ||
111 mRefreshRateChangePending) {
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700112 return mOffsetsConfig.early;
Alec Mourib488afa2019-05-23 10:22:24 -0700113 } else if (mRemainingRenderEngineUsageCount > 0) {
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700114 return mOffsetsConfig.earlyGl;
Alec Mourib488afa2019-05-23 10:22:24 -0700115 } else {
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700116 return mOffsetsConfig.late;
Alec Mourib488afa2019-05-23 10:22:24 -0700117 }
118}
119
120void VSyncModulator::updateOffsets() {
Alec Mourid7599d82019-05-22 19:58:00 -0700121 std::lock_guard<std::mutex> lock(mMutex);
122 updateOffsetsLocked();
123}
124
125void VSyncModulator::updateOffsetsLocked() {
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700126 const Offsets& offsets = getNextOffsets();
Alec Mourib488afa2019-05-23 10:22:24 -0700127
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700128 mScheduler.setPhaseOffset(mSfConnectionHandle, offsets.sf);
129 mScheduler.setPhaseOffset(mAppConnectionHandle, offsets.app);
Alec Mourib488afa2019-05-23 10:22:24 -0700130
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700131 mOffsets = offsets;
Ady Abraham11b6a702019-06-27 11:24:19 -0700132
Alec Mourid7599d82019-05-22 19:58:00 -0700133 if (!mTraceDetailedInfo) {
134 return;
135 }
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700136
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700137 const bool isEarly = &offsets == &mOffsetsConfig.early;
138 const bool isEarlyGl = &offsets == &mOffsetsConfig.earlyGl;
139 const bool isLate = &offsets == &mOffsetsConfig.late;
140
Ady Abraham2139f732019-11-13 18:56:40 -0800141 ATRACE_INT("Vsync-EarlyOffsetsOn", isEarly);
142 ATRACE_INT("Vsync-EarlyGLOffsetsOn", isEarlyGl);
143 ATRACE_INT("Vsync-LateOffsetsOn", isLate);
Alec Mourid7599d82019-05-22 19:58:00 -0700144}
145
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700146} // namespace android::scheduler