Skip to content

Commit 3008021

Browse files
adyabrAndroid (Google) Code Review
authored andcommitted
Merge changes Iec9cde3b,I63916801 into main
* changes: SF: omit vsync callbacks when screen is OFF SF: add a new flag for omiting vsync on screen is OFF
2 parents 27e2f43 + 8e3e2ea commit 3008021

12 files changed

Lines changed: 99 additions & 1 deletion

File tree

services/surfaceflinger/DisplayDevice.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ bool DisplayDevice::isPoweredOn() const {
201201
return mPowerMode != hal::PowerMode::OFF;
202202
}
203203

204+
bool DisplayDevice::isRefreshable() const {
205+
return mPowerMode == hal::PowerMode::DOZE || mPowerMode == hal::PowerMode::ON;
206+
}
207+
204208
ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
205209
return mCompositionDisplay->getState().dataspace;
206210
}

services/surfaceflinger/DisplayDevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class DisplayDevice : public RefBase {
173173
hardware::graphics::composer::hal::PowerMode getPowerMode() const;
174174
void setPowerMode(hardware::graphics::composer::hal::PowerMode);
175175
bool isPoweredOn() const;
176+
bool isRefreshable() const;
176177
void tracePowerMode();
177178

178179
// Enables layer caching on this DisplayDevice

services/surfaceflinger/Scheduler/EventThread.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,16 @@ void EventThread::enableSyntheticVsync(bool enable) {
420420
mCondition.notify_all();
421421
}
422422

423+
void EventThread::omitVsyncDispatching(bool omitted) {
424+
std::lock_guard<std::mutex> lock(mMutex);
425+
if (!mVSyncState || mVSyncState->omitted == omitted) {
426+
return;
427+
}
428+
429+
mVSyncState->omitted = omitted;
430+
mCondition.notify_all();
431+
}
432+
423433
void EventThread::onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
424434
std::lock_guard<std::mutex> lock(mMutex);
425435
mLastVsyncCallbackTime = TimePoint::fromNs(vsyncTime);
@@ -521,7 +531,17 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
521531
}
522532

523533
if (mVSyncState && vsyncRequested) {
524-
mState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
534+
const bool vsyncOmitted =
535+
FlagManager::getInstance().no_vsyncs_on_screen_off() && mVSyncState->omitted;
536+
if (vsyncOmitted) {
537+
mState = State::Idle;
538+
SFTRACE_INT("VsyncPendingScreenOn", 1);
539+
} else {
540+
mState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
541+
if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
542+
SFTRACE_INT("VsyncPendingScreenOn", 0);
543+
}
544+
}
525545
} else {
526546
ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
527547
mState = State::Idle;

services/surfaceflinger/Scheduler/EventThread.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ class EventThread {
106106
// Feed clients with fake VSYNC, e.g. while the display is off.
107107
virtual void enableSyntheticVsync(bool) = 0;
108108

109+
virtual void omitVsyncDispatching(bool) = 0;
110+
109111
virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;
110112

111113
virtual void onHotplugConnectionError(int32_t connectionError) = 0;
@@ -165,6 +167,8 @@ class EventThread : public android::EventThread {
165167

166168
void enableSyntheticVsync(bool) override;
167169

170+
void omitVsyncDispatching(bool) override;
171+
168172
void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;
169173

170174
void onHotplugConnectionError(int32_t connectionError) override;
@@ -240,6 +244,9 @@ class EventThread : public android::EventThread {
240244

241245
// True if VSYNC should be faked, e.g. when display is off.
242246
bool synthetic = false;
247+
248+
// True if VSYNC should not be delivered to apps. Used when the display is off.
249+
bool omitted = false;
243250
};
244251

245252
// TODO(b/74619554): Create per-display threads waiting on respective VSYNC signals,

services/surfaceflinger/Scheduler/Scheduler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,14 @@ void Scheduler::enableSyntheticVsync(bool enable) {
405405
eventThreadFor(Cycle::Render).enableSyntheticVsync(enable);
406406
}
407407

408+
void Scheduler::omitVsyncDispatching(bool omitted) {
409+
eventThreadFor(Cycle::Render).omitVsyncDispatching(omitted);
410+
// Note: If we don't couple Cycle::LastComposite event thread, there is a black screen
411+
// after boot. This is most likely sysui or system_server dependency on sf instance
412+
// Choreographer
413+
eventThreadFor(Cycle::LastComposite).omitVsyncDispatching(omitted);
414+
}
415+
408416
void Scheduler::onFrameRateOverridesChanged() {
409417
const auto [pacesetterId, supportsFrameRateOverrideByContent] = [this] {
410418
std::scoped_lock lock(mDisplayLock);

services/surfaceflinger/Scheduler/Scheduler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class Scheduler : public IEventThreadCallback, android::impl::MessageQueue {
154154
bool onDisplayModeChanged(PhysicalDisplayId, const FrameRateMode&) EXCLUDES(mPolicyLock);
155155

156156
void enableSyntheticVsync(bool = true) REQUIRES(kMainThreadContext);
157+
void omitVsyncDispatching(bool) REQUIRES(kMainThreadContext);
157158

158159
void onHdcpLevelsChanged(Cycle, PhysicalDisplayId, int32_t, int32_t);
159160

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,26 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
36653665
return display;
36663666
}
36673667

3668+
void SurfaceFlinger::incRefreshableDisplays() {
3669+
if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
3670+
mRefreshableDisplays++;
3671+
if (mRefreshableDisplays == 1) {
3672+
ftl::FakeGuard guard(kMainThreadContext);
3673+
mScheduler->omitVsyncDispatching(false);
3674+
}
3675+
}
3676+
}
3677+
3678+
void SurfaceFlinger::decRefreshableDisplays() {
3679+
if (FlagManager::getInstance().no_vsyncs_on_screen_off()) {
3680+
mRefreshableDisplays--;
3681+
if (mRefreshableDisplays == 0) {
3682+
ftl::FakeGuard guard(kMainThreadContext);
3683+
mScheduler->omitVsyncDispatching(true);
3684+
}
3685+
}
3686+
}
3687+
36683688
void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
36693689
const DisplayDeviceState& state) {
36703690
ui::Size resolution(0, 0);
@@ -3756,6 +3776,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
37563776
display->adjustRefreshRate(mScheduler->getPacesetterRefreshRate());
37573777
}
37583778

3779+
if (display->isRefreshable()) {
3780+
incRefreshableDisplays();
3781+
}
3782+
37593783
mDisplays.try_emplace(displayToken, std::move(display));
37603784

37613785
// For an external display, loadDisplayModes already attempted to select the same mode
@@ -3790,6 +3814,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
37903814
} else {
37913815
mScheduler->unregisterDisplay(display->getPhysicalId(), mActiveDisplayId);
37923816
}
3817+
3818+
if (display->isRefreshable()) {
3819+
decRefreshableDisplays();
3820+
}
37933821
}
37943822

37953823
mDisplays.erase(displayToken);
@@ -3824,6 +3852,10 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
38243852
if (display->isVirtual()) {
38253853
releaseVirtualDisplay(display->getVirtualId());
38263854
}
3855+
3856+
if (display->isRefreshable()) {
3857+
decRefreshableDisplays();
3858+
}
38273859
}
38283860

38293861
mDisplays.erase(displayToken);
@@ -5322,7 +5354,15 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
53225354
activeDisplay->isPoweredOn(),
53235355
"Trying to change power mode on inactive display without powering off active display");
53245356

5357+
const bool couldRefresh = display->isRefreshable();
53255358
display->setPowerMode(mode);
5359+
const bool canRefresh = display->isRefreshable();
5360+
5361+
if (couldRefresh && !canRefresh) {
5362+
decRefreshableDisplays();
5363+
} else if (!couldRefresh && canRefresh) {
5364+
incRefreshableDisplays();
5365+
}
53265366

53275367
const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
53285368
if (currentMode == hal::PowerMode::OFF) {

services/surfaceflinger/SurfaceFlinger.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,11 @@ class SurfaceFlinger : public BnSurfaceComposer,
14111411
// Whether a display should be turned on when initialized
14121412
bool mSkipPowerOnForQuiescent;
14131413

1414+
// used for omitting vsync callbacks to apps when the display is not updatable
1415+
int mRefreshableDisplays GUARDED_BY(mStateLock) = 0;
1416+
void incRefreshableDisplays() REQUIRES(mStateLock);
1417+
void decRefreshableDisplays() REQUIRES(mStateLock);
1418+
14141419
frontend::LayerLifecycleManager mLayerLifecycleManager GUARDED_BY(kMainThreadContext);
14151420
frontend::LayerHierarchyBuilder mLayerHierarchyBuilder GUARDED_BY(kMainThreadContext);
14161421
frontend::LayerSnapshotBuilder mLayerSnapshotBuilder GUARDED_BY(kMainThreadContext);

services/surfaceflinger/common/FlagManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ void FlagManager::dump(std::string& result) const {
139139
DUMP_READ_ONLY_FLAG(vrr_bugfix_dropped_frame);
140140
DUMP_READ_ONLY_FLAG(restore_blur_step);
141141
DUMP_READ_ONLY_FLAG(dont_skip_on_early_ro);
142+
DUMP_READ_ONLY_FLAG(no_vsyncs_on_screen_off);
142143
DUMP_READ_ONLY_FLAG(protected_if_client);
143144
DUMP_READ_ONLY_FLAG(idle_screen_refresh_rate_timeout);
144145
DUMP_READ_ONLY_FLAG(graphite_renderengine);
@@ -244,6 +245,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(vulkan_renderengine, "debug.renderengine.vulkan")
244245
FLAG_MANAGER_READ_ONLY_FLAG(renderable_buffer_usage, "")
245246
FLAG_MANAGER_READ_ONLY_FLAG(restore_blur_step, "debug.renderengine.restore_blur_step")
246247
FLAG_MANAGER_READ_ONLY_FLAG(dont_skip_on_early_ro, "")
248+
FLAG_MANAGER_READ_ONLY_FLAG(no_vsyncs_on_screen_off, "debug.sf.no_vsyncs_on_screen_off")
247249
FLAG_MANAGER_READ_ONLY_FLAG(protected_if_client, "")
248250
FLAG_MANAGER_READ_ONLY_FLAG(vrr_bugfix_24q4, "");
249251
FLAG_MANAGER_READ_ONLY_FLAG(vrr_bugfix_dropped_frame, "")

services/surfaceflinger/common/include/common/FlagManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class FlagManager {
7777
bool renderable_buffer_usage() const;
7878
bool restore_blur_step() const;
7979
bool dont_skip_on_early_ro() const;
80+
bool no_vsyncs_on_screen_off() const;
8081
bool protected_if_client() const;
8182
bool idle_screen_refresh_rate_timeout() const;
8283
bool graphite_renderengine() const;

0 commit comments

Comments
 (0)