Loading services/surfaceflinger/Scheduler/PhaseOffsets.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -86,8 +86,9 @@ PhaseOffsets::PhaseOffsets() { mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs}; } PhaseOffsets::Offsets PhaseOffsets::getCurrentOffsets() const { switch (mRefreshRateType) { PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate( android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const { switch (refreshRateType) { case RefreshRateConfigs::RefreshRateType::PERFORMANCE: return mHighRefreshRateOffsets; default: Loading services/surfaceflinger/Scheduler/PhaseOffsets.h +9 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public: virtual nsecs_t getCurrentAppOffset() = 0; virtual nsecs_t getCurrentSfOffset() = 0; virtual Offsets getOffsetsForRefreshRate( RefreshRateConfigs::RefreshRateType refreshRateType) const = 0; virtual Offsets getCurrentOffsets() const = 0; virtual void setRefreshRateType(RefreshRateConfigs::RefreshRateType refreshRateType) = 0; virtual void dump(std::string& result) const = 0; Loading @@ -55,8 +57,14 @@ public: nsecs_t getCurrentAppOffset() override; nsecs_t getCurrentSfOffset() override; // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. Offsets getOffsetsForRefreshRate( RefreshRateConfigs::RefreshRateType refreshRateType) const override; // Returns early, early GL, and late offsets for Apps and SF. Offsets getCurrentOffsets() const override; Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateType); } // This function should be called when the device is switching between different // refresh rates, to properly update the offsets. Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.h +22 −7 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ public: std::string name; // Refresh rate in frames per second, rounded to the nearest integer. uint32_t fps = 0; // config Id (returned from HWC2::Display::Config::getId()) hwc2_config_t id; }; // TODO(b/122916473): Get this information from configs prepared by vendors, instead of Loading @@ -62,13 +64,24 @@ public: return nullptr; } RefreshRateType getRefreshRateType(hwc2_config_t id) const { for (const auto& [type, refreshRate] : mRefreshRates) { if (refreshRate->id == id) { return type; } } return RefreshRateType::DEFAULT; } void populate(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { mRefreshRates.clear(); // This is the rate that HWC encapsulates right now when the device is in DOZE mode. mRefreshRates.emplace(RefreshRateType::POWER_SAVING, std::make_shared<RefreshRate>( RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0})); RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID})); if (configs.size() < 1) { ALOGE("Device does not have valid configs. Config size is 0."); Loading @@ -91,11 +104,12 @@ public: nsecs_t vsyncPeriod = configIdToVsyncPeriod[0].second; if (vsyncPeriod != 0) { const float fps = 1e9 / vsyncPeriod; const int configId = configIdToVsyncPeriod[0].first; mRefreshRates.emplace(RefreshRateType::DEFAULT, std::make_shared<RefreshRate>( RefreshRate{configIdToVsyncPeriod[0].first, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps)})); RefreshRate{configId, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps), configs.at(configId)->getId()})); } if (configs.size() < 2) { Loading @@ -107,11 +121,12 @@ public: vsyncPeriod = configIdToVsyncPeriod[1].second; if (vsyncPeriod != 0) { const float fps = 1e9 / vsyncPeriod; const int configId = configIdToVsyncPeriod[1].first; mRefreshRates.emplace(RefreshRateType::PERFORMANCE, std::make_shared<RefreshRate>( RefreshRate{configIdToVsyncPeriod[1].first, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps)})); RefreshRate{configId, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps), configs.at(configId)->getId()})); } } Loading services/surfaceflinger/Scheduler/SchedulerUtils.h +1 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ static constexpr size_t ARRAY_SIZE = 30; // the config is not visible to SF, and is completely maintained by HWC. However, we would // still like to keep track of time when the device is in this config. static constexpr int SCREEN_OFF_CONFIG_ID = -1; static constexpr uint32_t HWC2_SCREEN_OFF_CONFIG_ID = 0xffffffff; // This number is used when we try to determine how long does a given layer stay relevant. // Currently it is set to 100ms, because that would indicate 10Hz rendering. Loading services/surfaceflinger/SurfaceFlinger.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -860,7 +860,9 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, info.xdpi = xdpi; info.ydpi = ydpi; info.fps = 1e9 / hwConfig->getVsyncPeriod(); info.appVsyncOffset = mPhaseOffsets->getCurrentAppOffset(); const auto refreshRateType = mRefreshRateConfigs.getRefreshRateType(hwConfig->getId()); const auto offset = mPhaseOffsets->getOffsetsForRefreshRate(refreshRateType); info.appVsyncOffset = offset.late.app; // This is how far in advance a buffer must be queued for // presentation at a given time. If you want a buffer to appear Loading @@ -874,8 +876,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, // // We add an additional 1ms to allow for processing time and // differences between the ideal and actual refresh rate. info.presentationDeadline = hwConfig->getVsyncPeriod() - mPhaseOffsets->getCurrentSfOffset() + 1000000; info.presentationDeadline = hwConfig->getVsyncPeriod() - offset.late.sf + 1000000; // All non-virtual displays are currently considered secure. info.secure = true; Loading Loading
services/surfaceflinger/Scheduler/PhaseOffsets.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -86,8 +86,9 @@ PhaseOffsets::PhaseOffsets() { mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs}; } PhaseOffsets::Offsets PhaseOffsets::getCurrentOffsets() const { switch (mRefreshRateType) { PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate( android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const { switch (refreshRateType) { case RefreshRateConfigs::RefreshRateType::PERFORMANCE: return mHighRefreshRateOffsets; default: Loading
services/surfaceflinger/Scheduler/PhaseOffsets.h +9 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public: virtual nsecs_t getCurrentAppOffset() = 0; virtual nsecs_t getCurrentSfOffset() = 0; virtual Offsets getOffsetsForRefreshRate( RefreshRateConfigs::RefreshRateType refreshRateType) const = 0; virtual Offsets getCurrentOffsets() const = 0; virtual void setRefreshRateType(RefreshRateConfigs::RefreshRateType refreshRateType) = 0; virtual void dump(std::string& result) const = 0; Loading @@ -55,8 +57,14 @@ public: nsecs_t getCurrentAppOffset() override; nsecs_t getCurrentSfOffset() override; // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. Offsets getOffsetsForRefreshRate( RefreshRateConfigs::RefreshRateType refreshRateType) const override; // Returns early, early GL, and late offsets for Apps and SF. Offsets getCurrentOffsets() const override; Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateType); } // This function should be called when the device is switching between different // refresh rates, to properly update the offsets. Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.h +22 −7 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ public: std::string name; // Refresh rate in frames per second, rounded to the nearest integer. uint32_t fps = 0; // config Id (returned from HWC2::Display::Config::getId()) hwc2_config_t id; }; // TODO(b/122916473): Get this information from configs prepared by vendors, instead of Loading @@ -62,13 +64,24 @@ public: return nullptr; } RefreshRateType getRefreshRateType(hwc2_config_t id) const { for (const auto& [type, refreshRate] : mRefreshRates) { if (refreshRate->id == id) { return type; } } return RefreshRateType::DEFAULT; } void populate(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { mRefreshRates.clear(); // This is the rate that HWC encapsulates right now when the device is in DOZE mode. mRefreshRates.emplace(RefreshRateType::POWER_SAVING, std::make_shared<RefreshRate>( RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0})); RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID})); if (configs.size() < 1) { ALOGE("Device does not have valid configs. Config size is 0."); Loading @@ -91,11 +104,12 @@ public: nsecs_t vsyncPeriod = configIdToVsyncPeriod[0].second; if (vsyncPeriod != 0) { const float fps = 1e9 / vsyncPeriod; const int configId = configIdToVsyncPeriod[0].first; mRefreshRates.emplace(RefreshRateType::DEFAULT, std::make_shared<RefreshRate>( RefreshRate{configIdToVsyncPeriod[0].first, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps)})); RefreshRate{configId, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps), configs.at(configId)->getId()})); } if (configs.size() < 2) { Loading @@ -107,11 +121,12 @@ public: vsyncPeriod = configIdToVsyncPeriod[1].second; if (vsyncPeriod != 0) { const float fps = 1e9 / vsyncPeriod; const int configId = configIdToVsyncPeriod[1].first; mRefreshRates.emplace(RefreshRateType::PERFORMANCE, std::make_shared<RefreshRate>( RefreshRate{configIdToVsyncPeriod[1].first, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps)})); RefreshRate{configId, base::StringPrintf("%2.ffps", fps), static_cast<uint32_t>(fps), configs.at(configId)->getId()})); } } Loading
services/surfaceflinger/Scheduler/SchedulerUtils.h +1 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ static constexpr size_t ARRAY_SIZE = 30; // the config is not visible to SF, and is completely maintained by HWC. However, we would // still like to keep track of time when the device is in this config. static constexpr int SCREEN_OFF_CONFIG_ID = -1; static constexpr uint32_t HWC2_SCREEN_OFF_CONFIG_ID = 0xffffffff; // This number is used when we try to determine how long does a given layer stay relevant. // Currently it is set to 100ms, because that would indicate 10Hz rendering. Loading
services/surfaceflinger/SurfaceFlinger.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -860,7 +860,9 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, info.xdpi = xdpi; info.ydpi = ydpi; info.fps = 1e9 / hwConfig->getVsyncPeriod(); info.appVsyncOffset = mPhaseOffsets->getCurrentAppOffset(); const auto refreshRateType = mRefreshRateConfigs.getRefreshRateType(hwConfig->getId()); const auto offset = mPhaseOffsets->getOffsetsForRefreshRate(refreshRateType); info.appVsyncOffset = offset.late.app; // This is how far in advance a buffer must be queued for // presentation at a given time. If you want a buffer to appear Loading @@ -874,8 +876,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, // // We add an additional 1ms to allow for processing time and // differences between the ideal and actual refresh rate. info.presentationDeadline = hwConfig->getVsyncPeriod() - mPhaseOffsets->getCurrentSfOffset() + 1000000; info.presentationDeadline = hwConfig->getVsyncPeriod() - offset.late.sf + 1000000; // All non-virtual displays are currently considered secure. info.secure = true; Loading