diff options
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; |