summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ady Abraham <adyabr@google.com> 2024-11-14 14:42:49 -0800
committer Ady Abraham <adyabr@google.com> 2024-11-14 22:46:31 +0000
commit708ebfbcfabb8f28cb88c5b39b099424e894530e (patch)
tree8cde48e9e669cd418f20110dc3899fc1f4011046
parent7a3c56f80f101c0c4500f574fc44feb4fbb23de9 (diff)
SF: add a backdoor to introduce a janky frame to HWC
Bug: 346503493 Test: adb shell service call SurfaceFlinger 1046 i32 3Test: adb root && adb shell service call SurfaceFlinger 1046 i32 3 Flag: EXEMPT bugfix Change-Id: Ic4a837ef06aca40a24db9c1121e19e3e1a1e0d80
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp6
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp6
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h4
-rw-r--r--services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h4
-rw-r--r--services/surfaceflinger/Scheduler/src/FrameTargeter.cpp1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp11
6 files changed, 30 insertions, 2 deletions
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 98b6666a1f..ee813bf340 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -895,6 +895,12 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr
})) {
editState().earliestPresentTime = frameTargetPtrOpt->get()->earliestPresentTime();
editState().expectedPresentTime = frameTargetPtrOpt->get()->expectedPresentTime().ns();
+ const auto debugPresentDelay = frameTargetPtrOpt->get()->debugPresentDelay();
+ if (debugPresentDelay) {
+ SFTRACE_FORMAT_INSTANT("DEBUG delaying presentation by %.2fms",
+ debugPresentDelay->ns() / 1e6f);
+ editState().expectedPresentTime += debugPresentDelay->ns();
+ }
}
editState().frameInterval = refreshArgs.frameInterval;
editState().powerCallback = refreshArgs.powerCallback;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 8c587a9376..2875650ed0 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -203,12 +203,16 @@ void Scheduler::run() {
void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
TimePoint expectedVsyncTime) {
+ const auto debugPresentDelay = mDebugPresentDelay.load();
+ mDebugPresentDelay.store(std::nullopt);
+
const FrameTargeter::BeginFrameArgs beginFrameArgs =
{.frameBeginTime = SchedulerClock::now(),
.vsyncId = vsyncId,
.expectedVsyncTime = expectedVsyncTime,
.sfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration,
- .hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration};
+ .hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration,
+ .debugPresentTimeDelay = debugPresentDelay};
ftl::NonNull<const Display*> pacesetterPtr = pacesetterPtrLocked();
pacesetterPtr->targeterPtr->beginFrame(beginFrameArgs, *pacesetterPtr->schedulePtr);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 8340880918..61c68a9473 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -337,6 +337,8 @@ public:
// recovery should begin.
void addBufferStuffedUids(BufferStuffingMap bufferStuffedUids);
+ void setDebugPresentDelay(TimePoint delay) { mDebugPresentDelay = delay; }
+
private:
friend class TestableScheduler;
@@ -602,6 +604,8 @@ private:
FrameRateOverrideMappings mFrameRateOverrideMappings;
SmallAreaDetectionAllowMappings mSmallAreaDetectionAllowMappings;
+
+ std::atomic<std::optional<TimePoint>> mDebugPresentDelay;
};
} // namespace scheduler
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
index 2185bb07ec..813d4dedff 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
@@ -53,6 +53,8 @@ public:
TimePoint expectedPresentTime() const { return mExpectedPresentTime; }
+ std::optional<TimePoint> debugPresentDelay() const { return mDebugPresentTimeDelay; }
+
std::optional<TimePoint> earliestPresentTime() const { return mEarliestPresentTime; }
// Equivalent to `expectedSignaledPresentFence` unless running N VSYNCs ahead.
@@ -84,6 +86,7 @@ protected:
TimePoint mFrameBeginTime;
TimePoint mExpectedPresentTime;
std::optional<TimePoint> mEarliestPresentTime;
+ std::optional<TimePoint> mDebugPresentTimeDelay;
TracedOrdinal<bool> mFramePending;
TracedOrdinal<bool> mFrameMissed;
@@ -135,6 +138,7 @@ public:
TimePoint expectedVsyncTime;
Duration sfWorkDuration;
Duration hwcMinWorkDuration;
+ std::optional<TimePoint> debugPresentTimeDelay; // used to introduce jank for testing
};
void beginFrame(const BeginFrameArgs&, const IVsyncSource&);
diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
index 3ee1e541c3..4f16130aa5 100644
--- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
+++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
@@ -86,6 +86,7 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v
IsFencePendingFuncPtr isFencePendingFuncPtr) {
mVsyncId = args.vsyncId;
mFrameBeginTime = args.frameBeginTime;
+ mDebugPresentTimeDelay = args.debugPresentTimeDelay;
// The `expectedVsyncTime`, which was predicted when this frame was scheduled, is normally in
// the future relative to `frameBeginTime`, but may not be for delayed frames. Adjust
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9854174bbd..f9e5db0079 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -6263,7 +6263,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
}
// Numbers from 1000 to 1045 are currently used for backdoors. The code
// in onTransact verifies that the user is root, and has access to use SF.
- if (code >= 1000 && code <= 1045) {
+ if (code >= 1000 && code <= 1046) {
ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
return OK;
}
@@ -6796,6 +6796,15 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
}
return err;
}
+ // Introduce jank to HWC
+ case 1046: {
+ int32_t jankDelayMs = 0;
+ if (data.readInt32(&jankDelayMs) != NO_ERROR) {
+ return BAD_VALUE;
+ }
+ mScheduler->setDebugPresentDelay(TimePoint::fromNs(ms2ns(jankDelayMs)));
+ return NO_ERROR;
+ }
}
}
return err;