diff options
| author | 2019-02-27 00:01:45 +0000 | |
|---|---|---|
| committer | 2019-02-27 00:01:45 +0000 | |
| commit | d20dbdb7ed93690d4e55e45c0a67091e1efa1305 (patch) | |
| tree | 36e1bf3534942014382880c48530a42154063914 /services/surfaceflinger/SurfaceFlinger.cpp | |
| parent | 114998a80761a9bb25dec7711deceda13b05d712 (diff) | |
| parent | 447052e2f69efb01023dcc0dce230dd649f0475f (diff) | |
Merge changes from topic "display_policy"
* changes:
SurfaceFlinger: add DISPLAY_EVENT_CONFIG_CHANGED
SurfaceFlinger: add setAllowedDisplayConfigs
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 125 |
1 files changed, 113 insertions, 12 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 68fa04c7a0..daa9ff9047 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -575,11 +575,11 @@ void SurfaceFlinger::bootFinished() if (mUse90Hz) { mPhaseOffsets->setRefreshRateType( scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE); - setRefreshRateTo(RefreshRateType::PERFORMANCE); + setRefreshRateTo(RefreshRateType::PERFORMANCE, ConfigEvent::None); } else { mPhaseOffsets->setRefreshRateType( scheduler::RefreshRateConfigs::RefreshRateType::DEFAULT); - setRefreshRateTo(RefreshRateType::DEFAULT); + setRefreshRateTo(RefreshRateType::DEFAULT, ConfigEvent::None); } })); } @@ -706,11 +706,11 @@ void SurfaceFlinger::init() { if (mUse90Hz) { mScheduler->setExpiredIdleTimerCallback([this] { Mutex::Autolock lock(mStateLock); - setRefreshRateTo(RefreshRateType::DEFAULT); + setRefreshRateTo(RefreshRateType::DEFAULT, ConfigEvent::None); }); mScheduler->setResetIdleTimerCallback([this] { Mutex::Autolock lock(mStateLock); - setRefreshRateTo(RefreshRateType::PERFORMANCE); + setRefreshRateTo(RefreshRateType::PERFORMANCE, ConfigEvent::None); }); } mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(getHwComposer().getConfigs( @@ -918,7 +918,8 @@ int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) { return display->getActiveConfig(); } -void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode) { +void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, + ConfigEvent event) { ATRACE_CALL(); Vector<DisplayInfo> configs; @@ -949,7 +950,7 @@ void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int // Don't check against the current mode yet. Worst case we set the desired // config twice. std::lock_guard<std::mutex> lock(mActiveConfigLock); - mDesiredActiveConfig = ActiveConfigInfo{mode, displayToken}; + mDesiredActiveConfig = ActiveConfigInfo{mode, displayToken, event}; if (!mDesiredActiveConfigChanged) { // This is the first time we set the desired @@ -964,9 +965,11 @@ void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mode) { ATRACE_CALL(); - postMessageSync(new LambdaMessage( - [&]() NO_THREAD_SAFETY_ANALYSIS { setDesiredActiveConfig(displayToken, mode); })); - return NO_ERROR; + + std::vector<int32_t> allowedConfig; + allowedConfig.push_back(mode); + + return setAllowedDisplayConfigs(displayToken, allowedConfig); } void SurfaceFlinger::setActiveConfigInternal() { @@ -980,6 +983,10 @@ void SurfaceFlinger::setActiveConfigInternal() { mScheduler->resyncToHardwareVsync(true, getVsyncPeriod()); ATRACE_INT("ActiveConfigMode", mUpcomingActiveConfig.configId); + if (mUpcomingActiveConfig.event != ConfigEvent::None) { + mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value, + mUpcomingActiveConfig.configId); + } } bool SurfaceFlinger::performSetActiveConfig() NO_THREAD_SAFETY_ANALYSIS { @@ -1028,7 +1035,14 @@ bool SurfaceFlinger::performSetActiveConfig() NO_THREAD_SAFETY_ANALYSIS { return false; } - // Desired active config was set, it is different than the config currently in use. Notify HWC. + // Desired active config was set, it is different than the config currently in use, however + // allowed configs might have change by the time we process the refresh. + // Make sure the desired config is still allowed + if (!isConfigAllowed(*display->getId(), desiredActiveConfig.configId)) { + std::lock_guard<std::mutex> lock(mActiveConfigLock); + mDesiredActiveConfig.configId = display->getActiveConfig(); + return false; + } mUpcomingActiveConfig = desiredActiveConfig; const auto displayId = display->getId(); LOG_ALWAYS_FATAL_IF(!displayId); @@ -1396,7 +1410,18 @@ void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { *compositorTiming = getBE().mCompositorTiming; } -void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate) { +bool SurfaceFlinger::isConfigAllowed(const DisplayId& displayId, int32_t config) { + std::lock_guard lock(mAllowedConfigsLock); + + // if allowed configs are not set yet for this display, every config is considered allowed + if (mAllowedConfigs.find(displayId) == mAllowedConfigs.end()) { + return true; + } + + return mAllowedConfigs[displayId]->isConfigAllowed(config); +} + +void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate, ConfigEvent event) { mPhaseOffsets->setRefreshRateType(refreshRate); const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets(); @@ -1431,6 +1456,11 @@ void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate) { auto configs = getHwComposer().getConfigs(*displayId); for (int i = 0; i < configs.size(); i++) { + if (!isConfigAllowed(*displayId, i)) { + ALOGV("Skipping config %d as it is not part of allowed configs", i); + continue; + } + const nsecs_t vsyncPeriod = configs.at(i)->getVsyncPeriod(); if (vsyncPeriod == 0) { continue; @@ -1439,7 +1469,7 @@ void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate) { // TODO(b/113612090): There should be a better way at determining which config // has the right refresh rate. if (std::abs(fps - newFps) <= 1) { - setDesiredActiveConfig(getInternalDisplayTokenLocked(), i); + setDesiredActiveConfig(getInternalDisplayTokenLocked(), i, event); } } } @@ -4873,6 +4903,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case GET_ANIMATION_FRAME_STATS: case GET_HDR_CAPABILITIES: case SET_ACTIVE_CONFIG: + case SET_ALLOWED_DISPLAY_CONFIGS: case SET_ACTIVE_COLOR_MODE: case INJECT_VSYNC: case SET_POWER_MODE: @@ -5693,6 +5724,76 @@ void SurfaceFlinger::traverseLayersInDisplay(const sp<const DisplayDevice>& disp } } +void SurfaceFlinger::setAllowedDisplayConfigsInternal( + const android::sp<android::IBinder>& displayToken, + std::unique_ptr<const AllowedDisplayConfigs>&& allowedConfigs) { + const auto displayId = getPhysicalDisplayIdLocked(displayToken); + if (!displayId) { + ALOGE("setAllowedDisplayConfigsInternal: getPhysicalDisplayId failed"); + return; + } + + ALOGV("Updating allowed configs"); + { + std::lock_guard lock(mAllowedConfigsLock); + mAllowedConfigs[*displayId] = std::move(allowedConfigs); + } + + // make sure that the current config is still allowed + int currentConfigIndex = getHwComposer().getActiveConfigIndex(*displayId); + if (!isConfigAllowed(*displayId, currentConfigIndex)) { + // TODO(b/122906558): stop querying HWC for the available configs and instead use the cached + // configs queried on boot + auto configs = getHwComposer().getConfigs(*displayId); + + for (int i = 0; i < configs.size(); i++) { + if (isConfigAllowed(*displayId, i)) { + // TODO: we switch to the first allowed config. In the future + // we may want to enhance this logic to pick a similar config + // to the current one + ALOGV("Old config is not allowed - switching to config %d", i); + setDesiredActiveConfig(displayToken, i, ConfigEvent::Changed); + break; + } + } + } +} + +status_t SurfaceFlinger::setAllowedDisplayConfigs(const android::sp<android::IBinder>& displayToken, + const std::vector<int32_t>& allowedConfigs) { + ATRACE_CALL(); + + if (!displayToken) { + ALOGE("setAllowedDisplayConfigs: displayToken is null"); + return BAD_VALUE; + } + + if (!allowedConfigs.size()) { + ALOGE("setAllowedDisplayConfigs: empty config set provided"); + return BAD_VALUE; + } + + { + ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); + const auto displayId = getPhysicalDisplayIdLocked(displayToken); + if (!displayId) { + ALOGE("setAllowedDisplayConfigs: display not found"); + return NAME_NOT_FOUND; + } + } + + auto allowedDisplayConfigsBuilder = AllowedDisplayConfigs::Builder(); + for (int config : allowedConfigs) { + ALOGV("setAllowedDisplayConfigs: Adding config to the allowed configs = %d", config); + allowedDisplayConfigsBuilder.addConfig(config); + } + auto allowedDisplayConfigs = allowedDisplayConfigsBuilder.build(); + postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS { + setAllowedDisplayConfigsInternal(displayToken, std::move(allowedDisplayConfigs)); + })); + return NO_ERROR; +} + // ---------------------------------------------------------------------------- void SetInputWindowsListener::onSetInputWindowsFinished() { |