SF: Rename VsyncModulator
Adopt Vsync/vsync spelling over the awkward and less common VSync/vSync.
Bug: 160012986
Test: Build
Change-Id: Ibe230906e969d2ef8100ca7b1f5650dfe227c927
diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.cpp b/services/surfaceflinger/Scheduler/VsyncModulator.cpp
new file mode 100644
index 0000000..96d47ad
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/VsyncModulator.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include "VsyncModulator.h"
+
+#include <cutils/properties.h>
+#include <utils/Trace.h>
+
+#include <chrono>
+#include <cinttypes>
+#include <mutex>
+
+namespace android::scheduler {
+
+VSyncModulator::VSyncModulator(IPhaseOffsetControl& phaseOffsetControl,
+ Scheduler::ConnectionHandle appConnectionHandle,
+ Scheduler::ConnectionHandle sfConnectionHandle,
+ const OffsetsConfig& config)
+ : mPhaseOffsetControl(phaseOffsetControl),
+ mAppConnectionHandle(appConnectionHandle),
+ mSfConnectionHandle(sfConnectionHandle),
+ mOffsetsConfig(config) {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.sf.vsync_trace_detailed_info", value, "0");
+ mTraceDetailedInfo = atoi(value);
+}
+
+void VSyncModulator::setPhaseOffsets(const OffsetsConfig& config) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mOffsetsConfig = config;
+ updateOffsetsLocked();
+}
+
+void VSyncModulator::setTransactionStart(Scheduler::TransactionStart transactionStart) {
+ switch (transactionStart) {
+ case Scheduler::TransactionStart::EarlyStart:
+ ALOGW_IF(mExplicitEarlyWakeup, "Already in TransactionStart::EarlyStart");
+ mExplicitEarlyWakeup = true;
+ break;
+ case Scheduler::TransactionStart::EarlyEnd:
+ ALOGW_IF(!mExplicitEarlyWakeup, "Not in TransactionStart::EarlyStart");
+ mExplicitEarlyWakeup = false;
+ break;
+ case Scheduler::TransactionStart::Normal:
+ case Scheduler::TransactionStart::Early:
+ // Non explicit don't change the explicit early wakeup state
+ break;
+ }
+
+ if (mTraceDetailedInfo) {
+ ATRACE_INT("mExplicitEarlyWakeup", mExplicitEarlyWakeup);
+ }
+
+ if (!mExplicitEarlyWakeup &&
+ (transactionStart == Scheduler::TransactionStart::Early ||
+ transactionStart == Scheduler::TransactionStart::EarlyEnd)) {
+ mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT_TRANSACTION;
+ mEarlyTxnStartTime = std::chrono::steady_clock::now();
+ }
+
+ // An early transaction stays an early transaction.
+ if (transactionStart == mTransactionStart ||
+ mTransactionStart == Scheduler::TransactionStart::EarlyEnd) {
+ return;
+ }
+ mTransactionStart = transactionStart;
+ updateOffsets();
+}
+
+void VSyncModulator::onTransactionHandled() {
+ mTxnAppliedTime = std::chrono::steady_clock::now();
+ if (mTransactionStart == Scheduler::TransactionStart::Normal) return;
+ mTransactionStart = Scheduler::TransactionStart::Normal;
+ updateOffsets();
+}
+
+void VSyncModulator::onRefreshRateChangeInitiated() {
+ if (mRefreshRateChangePending) {
+ return;
+ }
+ mRefreshRateChangePending = true;
+ updateOffsets();
+}
+
+void VSyncModulator::onRefreshRateChangeCompleted() {
+ if (!mRefreshRateChangePending) {
+ return;
+ }
+ mRefreshRateChangePending = false;
+ updateOffsets();
+}
+
+void VSyncModulator::onRefreshed(bool usedRenderEngine) {
+ bool updateOffsetsNeeded = false;
+
+ // Apply a margin to account for potential data races
+ // This might make us stay in early offsets for one
+ // additional frame but it's better to be conservative here.
+ if ((mEarlyTxnStartTime.load() + MARGIN_FOR_TX_APPLY) < mTxnAppliedTime.load()) {
+ if (mRemainingEarlyFrameCount > 0) {
+ mRemainingEarlyFrameCount--;
+ updateOffsetsNeeded = true;
+ }
+ }
+ if (usedRenderEngine) {
+ mRemainingRenderEngineUsageCount = MIN_EARLY_GL_FRAME_COUNT_TRANSACTION;
+ updateOffsetsNeeded = true;
+ } else if (mRemainingRenderEngineUsageCount > 0) {
+ mRemainingRenderEngineUsageCount--;
+ updateOffsetsNeeded = true;
+ }
+ if (updateOffsetsNeeded) {
+ updateOffsets();
+ }
+}
+
+VSyncModulator::Offsets VSyncModulator::getOffsets() const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mOffsets;
+}
+
+const VSyncModulator::Offsets& VSyncModulator::getNextOffsets() const {
+ // Early offsets are used if we're in the middle of a refresh rate
+ // change, or if we recently begin a transaction.
+ if (mExplicitEarlyWakeup || mTransactionStart == Scheduler::TransactionStart::EarlyEnd ||
+ mRemainingEarlyFrameCount > 0 || mRefreshRateChangePending) {
+ return mOffsetsConfig.early;
+ } else if (mRemainingRenderEngineUsageCount > 0) {
+ return mOffsetsConfig.earlyGl;
+ } else {
+ return mOffsetsConfig.late;
+ }
+}
+
+void VSyncModulator::updateOffsets() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ updateOffsetsLocked();
+}
+
+void VSyncModulator::updateOffsetsLocked() {
+ const Offsets& offsets = getNextOffsets();
+
+ mPhaseOffsetControl.setPhaseOffset(mSfConnectionHandle, offsets.sf);
+ mPhaseOffsetControl.setPhaseOffset(mAppConnectionHandle, offsets.app);
+
+ mOffsets = offsets;
+
+ if (!mTraceDetailedInfo) {
+ return;
+ }
+
+ const bool isEarly = &offsets == &mOffsetsConfig.early;
+ const bool isEarlyGl = &offsets == &mOffsetsConfig.earlyGl;
+ const bool isLate = &offsets == &mOffsetsConfig.late;
+
+ ATRACE_INT("Vsync-EarlyOffsetsOn", isEarly);
+ ATRACE_INT("Vsync-EarlyGLOffsetsOn", isEarlyGl);
+ ATRACE_INT("Vsync-LateOffsetsOn", isLate);
+}
+
+} // namespace android::scheduler
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion"