summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdy Abraham <adyabr@google.com>2020-07-24 11:09:55 -0700
committerAdy Abraham <adyabr@google.com>2020-07-30 21:04:41 +0000
commitf69d11d6aa09629a8af185359147e3c4510d1e89 (patch)
treea375306f03ae8bfd63febe8bbcbdcdbeb4341ed0
parent01d265d4267213611f9818f3097aff050870ca9b (diff)
downloadnative-f69d11d6aa09629a8af185359147e3c4510d1e89.tar.gz
SF: use cached vsync period
Don't query the vsync period from hwc but instead use the cached value in SF. The reason for this change is a race condition with AOD: 1. SF changes refresh rate to from X to Y 2. HWC is caching Y since the display is already in AOD and can't change refresh rate. 3. SF calls HWC to get the display out from AOD and query the refresh rate. At this point HWC returns X as the refresh rate didn't change yet. 4. HWC changes the refresh rate to Y. 5. SF thinks the refresh rate is X -- mismatch. Test: enable / disable AOD in a loop Bug: 160966959 Change-Id: I127c3a445416607dee9402031e07c8fece7d167b (cherry picked from commit 2492a02b8a04f9cd6e806e1bdb55a3dbc4d7ae91)
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp17
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
-rw-r--r--services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp2
3 files changed, 10 insertions, 11 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0ac3d329e9..148749e6f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1566,7 +1566,7 @@ void SurfaceFlinger::signalRefresh() {
mEventQueue->refresh();
}
-nsecs_t SurfaceFlinger::getVsyncPeriod() const {
+nsecs_t SurfaceFlinger::getVsyncPeriodFromHWC() const {
const auto displayId = getInternalDisplayIdLocked();
if (!displayId || !getHwComposer().isConnected(*displayId)) {
return 0;
@@ -1773,7 +1773,7 @@ void SurfaceFlinger::updateVrFlinger() {
setPowerModeInternal(display, currentDisplayPowerMode);
// Reset the timing values to account for the period of the swapped in HWC
- const nsecs_t vsyncPeriod = getVsyncPeriod();
+ const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(vsyncPeriod);
// The present fences returned from vr_hwc are not an accurate
@@ -4192,8 +4192,7 @@ void SurfaceFlinger::onInitializeDisplays() {
{});
setPowerModeInternal(display, hal::PowerMode::ON);
-
- const nsecs_t vsyncPeriod = getVsyncPeriod();
+ const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(vsyncPeriod);
// Use phase of 0 since phase is not known.
@@ -4228,7 +4227,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
if (mInterceptor->isEnabled()) {
mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode));
}
-
+ const auto vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
if (currentMode == hal::PowerMode::OFF) {
if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
@@ -4237,7 +4236,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
getHwComposer().setVsyncEnabled(*displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
- mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
+ mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
}
mVisibleRegionsDirty = true;
@@ -4264,7 +4263,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
getHwComposer().setPowerMode(*displayId, mode);
if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
- mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
+ mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
@@ -4377,7 +4376,7 @@ void SurfaceFlinger::listLayersLocked(std::string& result) const {
}
void SurfaceFlinger::dumpStatsLocked(const DumpArgs& args, std::string& result) const {
- StringAppendF(&result, "%" PRId64 "\n", getVsyncPeriod());
+ StringAppendF(&result, "%" PRId64 "\n", getVsyncPeriodFromHWC());
if (args.size() > 1) {
const auto name = String8(args[1]);
@@ -4442,7 +4441,7 @@ void SurfaceFlinger::dumpVSync(std::string& result) const {
mPhaseConfiguration->dump(result);
StringAppendF(&result,
" present offset: %9" PRId64 " ns\t VSYNC period: %9" PRId64 " ns\n\n",
- dispSyncPresentTimeOffset, getVsyncPeriod());
+ dispSyncPresentTimeOffset, getVsyncPeriodFromHWC());
scheduler::RefreshRateConfigs::Policy policy = mRefreshRateConfigs->getDisplayManagerPolicy();
StringAppendF(&result,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ccaeb2d858..c727574780 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -852,7 +852,7 @@ private:
/* ------------------------------------------------------------------------
* VSync
*/
- nsecs_t getVsyncPeriod() const REQUIRES(mStateLock);
+ nsecs_t getVsyncPeriodFromHWC() const REQUIRES(mStateLock);
// Sets the refresh rate by switching active configs, if they are available for
// the desired refresh rate.
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index ce5f35cdf3..06bdcdc666 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -85,7 +85,7 @@ using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
using HWC2Display = TestableSurfaceFlinger::HWC2Display;
-constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
+constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'667;
constexpr int32_t DEFAULT_DPI = 320;
constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;