[SurfaceFlinger] Add vsync offset information to systrace.
* Trace offset values in DispSyncSource
* Trace offset type in VSyncModulator
* Refactor how offsets are stored so that refresh rate type can be
encoded in VSyncModulator
* Add locking to catch a potential race condition when updating offsets,
as phase offsets can be accessed or updated on multiple threads.
Bug: 133325345
Test: verified that correct offsets are reported in systrace
Change-Id: I38d43b722cd54728a2e4de3df7dd472aceb1de15
diff --git a/services/surfaceflinger/Scheduler/VSyncModulator.cpp b/services/surfaceflinger/Scheduler/VSyncModulator.cpp
index af8f445..381308a 100644
--- a/services/surfaceflinger/Scheduler/VSyncModulator.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncModulator.cpp
@@ -14,28 +14,36 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include "VSyncModulator.h"
+#include <cutils/properties.h>
+#include <utils/Trace.h>
+
#include <cinttypes>
#include <mutex>
namespace android {
+using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType;
+VSyncModulator::VSyncModulator() {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.sf.vsync_trace_detailed_info", value, "0");
+ mTraceDetailedInfo = atoi(value);
+ // Populate the offset map with some default offsets.
+ const Offsets defaultOffsets = {RefreshRateType::DEFAULT, 0, 0};
+ setPhaseOffsets(defaultOffsets, defaultOffsets, defaultOffsets, 0);
+}
+
void VSyncModulator::setPhaseOffsets(Offsets early, Offsets earlyGl, Offsets late,
nsecs_t thresholdForNextVsync) {
- mEarlyOffsets = early;
- mEarlyGlOffsets = earlyGl;
- mLateOffsets = late;
+ std::lock_guard<std::mutex> lock(mMutex);
+ mOffsetMap.insert_or_assign(OffsetType::Early, early);
+ mOffsetMap.insert_or_assign(OffsetType::EarlyGl, earlyGl);
+ mOffsetMap.insert_or_assign(OffsetType::Late, late);
mThresholdForNextVsync = thresholdForNextVsync;
-
- if (mSfConnectionHandle && late.sf != mOffsets.load().sf) {
- mScheduler->setPhaseOffset(mSfConnectionHandle, late.sf);
- }
-
- if (mAppConnectionHandle && late.app != mOffsets.load().app) {
- mScheduler->setPhaseOffset(mAppConnectionHandle, late.app);
- }
- mOffsets = late;
+ updateOffsetsLocked();
}
void VSyncModulator::setTransactionStart(Scheduler::TransactionStart transactionStart) {
@@ -93,21 +101,35 @@
}
VSyncModulator::Offsets VSyncModulator::getOffsets() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mOffsetMap.at(mOffsetType);
+}
+
+VSyncModulator::Offsets VSyncModulator::getNextOffsets() {
+ return mOffsetMap.at(getNextOffsetType());
+}
+
+VSyncModulator::OffsetType VSyncModulator::getNextOffsetType() {
// Early offsets are used if we're in the middle of a refresh rate
// change, or if we recently begin a transaction.
if (mTransactionStart == Scheduler::TransactionStart::EARLY || mRemainingEarlyFrameCount > 0 ||
mRefreshRateChangePending) {
- return mEarlyOffsets;
+ return OffsetType::Early;
} else if (mRemainingRenderEngineUsageCount > 0) {
- return mEarlyGlOffsets;
+ return OffsetType::EarlyGl;
} else {
- return mLateOffsets;
+ return OffsetType::Late;
}
}
void VSyncModulator::updateOffsets() {
- const Offsets desired = getOffsets();
- const Offsets current = mOffsets;
+ std::lock_guard<std::mutex> lock(mMutex);
+ updateOffsetsLocked();
+}
+
+void VSyncModulator::updateOffsetsLocked() {
+ const Offsets desired = getNextOffsets();
+ const Offsets current = mOffsetMap.at(mOffsetType);
bool changed = false;
if (desired.sf != current.sf) {
@@ -128,8 +150,29 @@
}
if (changed) {
- mOffsets = desired;
+ updateOffsetType();
}
}
+void VSyncModulator::updateOffsetType() {
+ mOffsetType = getNextOffsetType();
+ if (!mTraceDetailedInfo) {
+ return;
+ }
+ OffsetType type = mOffsetType;
+ Offsets offsets = mOffsetMap.at(type);
+ ATRACE_INT("Vsync-EarlyOffsetsOn",
+ offsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::Early);
+ ATRACE_INT("Vsync-EarlyGLOffsetsOn",
+ offsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::EarlyGl);
+ ATRACE_INT("Vsync-LateOffsetsOn",
+ offsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::Late);
+ ATRACE_INT("Vsync-HighFpsEarlyOffsetsOn",
+ offsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::Early);
+ ATRACE_INT("Vsync-HighFpsEarlyGLOffsetsOn",
+ offsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::EarlyGl);
+ ATRACE_INT("Vsync-HighFpsLateOffsetsOn",
+ offsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::Late);
+}
+
} // namespace android