[SF] Updates to not send hints without a present being followed
Updates the hint to be sent through a frame scheduling.
Reduce the number of callbacks to notifyExpectedPresentIfRequired
by making calls only through EventThread.
Timeout hint is sent directly without scheduling a frame
to avoid delay in sending the hint.
A hint through setTransactionState for ScheduleOnTx will
be in a follow up CL
BUG: 316615878
Test: atest NotifyExpectedPresentTest
Change-Id: I60f555d69626656901951808353f4a632e9b5e71
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 4e0b5af..6a916a4 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -53,7 +53,6 @@
#include "mock/MockFrameTimeline.h"
#include "mock/MockFrameTracer.h"
#include "mock/MockSchedulerCallback.h"
-#include "mock/MockVsyncTrackerCallback.h"
#include "mock/system/window/MockNativeWindow.h"
#include "Scheduler/VSyncTracker.h"
@@ -205,8 +204,6 @@
enum class SchedulerCallbackImpl { kNoOp, kMock };
- enum class VsyncTrackerCallbackImpl { kNoOp, kMock };
-
struct DefaultDisplayMode {
// The ID of the injected RefreshRateSelector and its default display mode.
PhysicalDisplayId displayId;
@@ -220,14 +217,13 @@
TimeStats& getTimeStats() { return *mFlinger->mTimeStats; }
- void setupScheduler(
- std::unique_ptr<scheduler::VsyncController> vsyncController,
- std::shared_ptr<scheduler::VSyncTracker> vsyncTracker,
- std::unique_ptr<EventThread> appEventThread, std::unique_ptr<EventThread> sfEventThread,
- DisplayModesVariant modesVariant,
- SchedulerCallbackImpl callbackImpl = SchedulerCallbackImpl::kNoOp,
- VsyncTrackerCallbackImpl vsyncTrackerCallbackImpl = VsyncTrackerCallbackImpl::kNoOp,
- bool useNiceMock = false) {
+ void setupScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController,
+ std::shared_ptr<scheduler::VSyncTracker> vsyncTracker,
+ std::unique_ptr<EventThread> appEventThread,
+ std::unique_ptr<EventThread> sfEventThread,
+ DisplayModesVariant modesVariant,
+ SchedulerCallbackImpl callbackImpl = SchedulerCallbackImpl::kNoOp,
+ bool useNiceMock = false) {
RefreshRateSelectorPtr selectorPtr = ftl::match(
modesVariant,
[](DefaultDisplayMode arg) {
@@ -245,12 +241,6 @@
? static_cast<ISchedulerCallback&>(mNoOpSchedulerCallback)
: static_cast<ISchedulerCallback&>(mSchedulerCallback);
- using VsyncTrackerCallback = scheduler::IVsyncTrackerCallback;
- VsyncTrackerCallback& vsyncTrackerCallback =
- vsyncTrackerCallbackImpl == VsyncTrackerCallbackImpl::kNoOp
- ? static_cast<VsyncTrackerCallback&>(mNoOpVsyncTrackerCallback)
- : static_cast<VsyncTrackerCallback&>(mVsyncTrackerCallback);
-
if (useNiceMock) {
mScheduler =
new testing::NiceMock<scheduler::TestableScheduler>(std::move(vsyncController),
@@ -258,14 +248,12 @@
std::move(selectorPtr),
mFactory,
*mFlinger->mTimeStats,
- schedulerCallback,
- vsyncTrackerCallback);
+ schedulerCallback);
} else {
mScheduler = new scheduler::TestableScheduler(std::move(vsyncController),
std::move(vsyncTracker),
std::move(selectorPtr), mFactory,
- *mFlinger->mTimeStats, schedulerCallback,
- vsyncTrackerCallback);
+ *mFlinger->mTimeStats, schedulerCallback);
}
mScheduler->initVsync(*mTokenManager, 0ms);
@@ -307,8 +295,7 @@
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_, _)).WillRepeatedly(Return(0));
setupScheduler(std::move(vsyncController), std::move(vsyncTracker), std::move(eventThread),
std::move(sfEventThread), DefaultDisplayMode{options.displayId},
- SchedulerCallbackImpl::kNoOp, VsyncTrackerCallbackImpl::kNoOp,
- options.useNiceMock);
+ SchedulerCallbackImpl::kNoOp, options.useNiceMock);
}
void resetScheduler(scheduler::Scheduler* scheduler) { mFlinger->mScheduler.reset(scheduler); }
@@ -698,6 +685,36 @@
frameInterval, timeoutOpt);
}
+ void sendNotifyExpectedPresentHint(PhysicalDisplayId displayId) {
+ ftl::FakeGuard guard(kMainThreadContext);
+ mFlinger->sendNotifyExpectedPresentHint(displayId);
+ }
+
+ bool verifyHintIsScheduledOnPresent(PhysicalDisplayId displayId) {
+ return mFlinger->mNotifyExpectedPresentMap.at(displayId).hintStatus ==
+ SurfaceFlinger::NotifyExpectedPresentHintStatus::ScheduleOnPresent;
+ }
+
+ bool verifyHintIsSent(PhysicalDisplayId displayId) {
+ return mFlinger->mNotifyExpectedPresentMap.at(displayId).hintStatus ==
+ SurfaceFlinger::NotifyExpectedPresentHintStatus::Sent;
+ }
+
+ bool verifyHintStatusIsStart(PhysicalDisplayId displayId) {
+ return mFlinger->mNotifyExpectedPresentMap.at(displayId).hintStatus ==
+ SurfaceFlinger::NotifyExpectedPresentHintStatus::Start;
+ }
+
+ bool verifyHintStatusIsScheduledOnTx(PhysicalDisplayId displayId) {
+ return mFlinger->mNotifyExpectedPresentMap.at(displayId).hintStatus ==
+ SurfaceFlinger::NotifyExpectedPresentHintStatus::ScheduleOnTx;
+ }
+
+ bool verifyLastExpectedPresentTime(PhysicalDisplayId displayId, nsecs_t expectedPresentTime) {
+ return mFlinger->mNotifyExpectedPresentMap.at(displayId)
+ .lastExpectedPresentTimestamp.ns() == expectedPresentTime;
+ }
+
void setNotifyExpectedPresentData(PhysicalDisplayId displayId,
TimePoint lastExpectedPresentTimestamp,
Fps lastFrameInterval) {
@@ -706,6 +723,11 @@
displayData.lastFrameInterval = lastFrameInterval;
}
+ void resetNotifyExpectedPresentHintState(PhysicalDisplayId displayId) {
+ mFlinger->mNotifyExpectedPresentMap.at(displayId).hintStatus =
+ SurfaceFlinger::NotifyExpectedPresentHintStatus::Start;
+ }
+
~TestableSurfaceFlinger() {
// All these pointer and container clears help ensure that GMock does
// not report a leaked object, since the SurfaceFlinger instance may
@@ -1102,8 +1124,6 @@
sp<SurfaceFlinger> mFlinger;
scheduler::mock::SchedulerCallback mSchedulerCallback;
scheduler::mock::NoOpSchedulerCallback mNoOpSchedulerCallback;
- scheduler::mock::VsyncTrackerCallback mVsyncTrackerCallback;
- scheduler::mock::NoOpVsyncTrackerCallback mNoOpVsyncTrackerCallback;
std::unique_ptr<frametimeline::impl::TokenManager> mTokenManager;
scheduler::TestableScheduler* mScheduler = nullptr;
Hwc2::mock::PowerAdvisor mPowerAdvisor;