Loading services/surfaceflinger/DisplayHardware/HWC2.cpp +34 −32 Original line number Original line Diff line number Diff line Loading @@ -143,8 +143,8 @@ Error Device::createVirtualDisplay(uint32_t width, uint32_t height, return error; return error; } } auto display = std::make_unique<Display>( auto display = std::make_unique<impl::Display>(*mComposer.get(), mPowerAdvisor, mCapabilities, *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, DisplayType::Virtual); displayId, DisplayType::Virtual); display->setConnected(true); display->setConnected(true); *outDisplay = display.get(); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); mDisplays.emplace(displayId, std::move(display)); Loading Loading @@ -182,8 +182,8 @@ void Device::onHotplug(hwc2_display_t displayId, Connection connection) { return; return; } } auto newDisplay = std::make_unique<Display>( auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mPowerAdvisor, *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType); mCapabilities, displayId, displayType); newDisplay->setConnected(true); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { } else if (connection == Connection::Disconnected) { Loading Loading @@ -224,7 +224,36 @@ Error Device::flushCommands() } } // Display methods // Display methods Display::~Display() = default; Display::Config::Config(Display& display, hwc2_config_t id) : mDisplay(display), mId(id), mWidth(-1), mHeight(-1), mVsyncPeriod(-1), mDpiX(-1), mDpiY(-1) {} Display::Config::Builder::Builder(Display& display, hwc2_config_t id) : mConfig(new Config(display, id)) {} float Display::Config::Builder::getDefaultDensity() { // Default density is based on TVs: 1080p displays get XHIGH density, lower- // resolution displays get TV density. Maybe eventually we'll need to update // it for 4k displays, though hopefully those will just report accurate DPI // information to begin with. This is also used for virtual displays and // older HWC implementations, so be careful about orientation. auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); if (longDimension >= 1080) { return ACONFIGURATION_DENSITY_XHIGH; } else { return ACONFIGURATION_DENSITY_TV; } } namespace impl { Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type) DisplayType type) Loading Loading @@ -272,35 +301,7 @@ Display::~Display() { } } } } Display::Config::Config(Display& display, hwc2_config_t id) : mDisplay(display), mId(id), mWidth(-1), mHeight(-1), mVsyncPeriod(-1), mDpiX(-1), mDpiY(-1) {} Display::Config::Builder::Builder(Display& display, hwc2_config_t id) : mConfig(new Config(display, id)) {} float Display::Config::Builder::getDefaultDensity() { // Default density is based on TVs: 1080p displays get XHIGH density, lower- // resolution displays get TV density. Maybe eventually we'll need to update // it for 4k displays, though hopefully those will just report accurate DPI // information to begin with. This is also used for virtual displays and // older HWC implementations, so be careful about orientation. auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); if (longDimension >= 1080) { return ACONFIGURATION_DENSITY_XHIGH; } else { return ACONFIGURATION_DENSITY_TV; } } // Required by HWC2 display // Required by HWC2 display Error Display::acceptChanges() Error Display::acceptChanges() { { auto intError = mComposer.acceptDisplayChanges(mId); auto intError = mComposer.acceptDisplayChanges(mId); Loading Loading @@ -794,6 +795,7 @@ Layer* Display::getLayerById(hwc2_layer_t id) const return mLayers.at(id).get(); return mLayers.at(id).get(); } } } // namespace impl // Layer methods // Layer methods Loading services/surfaceflinger/DisplayHardware/HWC2.h +124 −70 Original line number Original line Diff line number Diff line Loading @@ -130,16 +130,11 @@ private: }; }; // Convenience C++ class to access hwc2_device_t Display functions directly. // Convenience C++ class to access hwc2_device_t Display functions directly. class Display class Display { { public: public: Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, virtual ~Display(); const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type); ~Display(); class Config class Config { { public: public: class Builder class Builder { { Loading Loading @@ -207,78 +202,136 @@ public: float mDpiY; float mDpiY; }; }; // Required by HWC2 virtual hwc2_display_t getId() const = 0; virtual bool isConnected() const = 0; [[clang::warn_unused_result]] Error acceptChanges(); virtual void setConnected(bool connected) = 0; // For use by Device only [[clang::warn_unused_result]] Error createLayer(Layer** outLayer); virtual const std::unordered_set<DisplayCapability>& getCapabilities() const = 0; [[clang::warn_unused_result]] Error destroyLayer(Layer* layer); [[clang::warn_unused_result]] Error getActiveConfig( [[clang::warn_unused_result]] virtual Error acceptChanges() = 0; std::shared_ptr<const Config>* outConfig) const; [[clang::warn_unused_result]] virtual Error createLayer(Layer** outLayer) = 0; [[clang::warn_unused_result]] Error getActiveConfigIndex(int* outIndex) const; [[clang::warn_unused_result]] virtual Error destroyLayer(Layer* layer) = 0; [[clang::warn_unused_result]] Error getChangedCompositionTypes( [[clang::warn_unused_result]] virtual Error getActiveConfig( std::unordered_map<Layer*, Composition>* outTypes); std::shared_ptr<const Config>* outConfig) const = 0; [[clang::warn_unused_result]] Error getColorModes( [[clang::warn_unused_result]] virtual Error getActiveConfigIndex(int* outIndex) const = 0; std::vector<android::ui::ColorMode>* outModes) const; [[clang::warn_unused_result]] virtual Error getChangedCompositionTypes( std::unordered_map<Layer*, Composition>* outTypes) = 0; [[clang::warn_unused_result]] virtual Error getColorModes( std::vector<android::ui::ColorMode>* outModes) const = 0; // Returns a bitmask which contains HdrMetadata::Type::*. // Returns a bitmask which contains HdrMetadata::Type::*. [[clang::warn_unused_result]] int32_t getSupportedPerFrameMetadata() const; [[clang::warn_unused_result]] virtual int32_t getSupportedPerFrameMetadata() const = 0; [[clang::warn_unused_result]] Error getRenderIntents( [[clang::warn_unused_result]] virtual Error getRenderIntents( android::ui::ColorMode colorMode, android::ui::ColorMode colorMode, std::vector<android::ui::RenderIntent>* outRenderIntents) const; std::vector<android::ui::RenderIntent>* outRenderIntents) const = 0; [[clang::warn_unused_result]] Error getDataspaceSaturationMatrix( [[clang::warn_unused_result]] virtual Error getDataspaceSaturationMatrix( android::ui::Dataspace dataspace, android::mat4* outMatrix); android::ui::Dataspace dataspace, android::mat4* outMatrix) = 0; // Doesn't call into the HWC2 device, so no errors are possible // Doesn't call into the HWC2 device, so no Errors are possible std::vector<std::shared_ptr<const Config>> getConfigs() const; virtual std::vector<std::shared_ptr<const Config>> getConfigs() const = 0; [[clang::warn_unused_result]] Error getName(std::string* outName) const; [[clang::warn_unused_result]] virtual Error getName(std::string* outName) const = 0; [[clang::warn_unused_result]] Error getRequests( [[clang::warn_unused_result]] virtual Error getRequests( DisplayRequest* outDisplayRequests, DisplayRequest* outDisplayRequests, std::unordered_map<Layer*, LayerRequest>* outLayerRequests); std::unordered_map<Layer*, LayerRequest>* outLayerRequests) = 0; [[clang::warn_unused_result]] Error getType(DisplayType* outType) const; [[clang::warn_unused_result]] virtual Error getType(DisplayType* outType) const = 0; [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const; [[clang::warn_unused_result]] virtual Error supportsDoze(bool* outSupport) const = 0; [[clang::warn_unused_result]] Error getHdrCapabilities( [[clang::warn_unused_result]] virtual Error getHdrCapabilities( android::HdrCapabilities* outCapabilities) const; android::HdrCapabilities* outCapabilities) const = 0; [[clang::warn_unused_result]] Error getDisplayedContentSamplingAttributes( [[clang::warn_unused_result]] virtual Error getDisplayedContentSamplingAttributes( android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, uint8_t* outComponentMask) const; uint8_t* outComponentMask) const = 0; [[clang::warn_unused_result]] Error setDisplayContentSamplingEnabled(bool enabled, [[clang::warn_unused_result]] virtual Error setDisplayContentSamplingEnabled( uint8_t componentMask, bool enabled, uint8_t componentMask, uint64_t maxFrames) const = 0; uint64_t maxFrames) const; [[clang::warn_unused_result]] virtual Error getDisplayedContentSample( [[clang::warn_unused_result]] Error getDisplayedContentSample( uint64_t maxFrames, uint64_t timestamp, uint64_t maxFrames, uint64_t timestamp, android::DisplayedFrameStats* outStats) const; android::DisplayedFrameStats* outStats) const = 0; [[clang::warn_unused_result]] Error getReleaseFences( [[clang::warn_unused_result]] virtual Error getReleaseFences( std::unordered_map<Layer*, std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const = 0; android::sp<android::Fence>>* outFences) const; [[clang::warn_unused_result]] virtual Error present( [[clang::warn_unused_result]] Error present( android::sp<android::Fence>* outPresentFence) = 0; android::sp<android::Fence>* outPresentFence); [[clang::warn_unused_result]] virtual Error setActiveConfig( [[clang::warn_unused_result]] Error setActiveConfig( const std::shared_ptr<const Config>& config) = 0; const std::shared_ptr<const Config>& config); [[clang::warn_unused_result]] virtual Error setClientTarget( [[clang::warn_unused_result]] Error setClientTarget( uint32_t slot, const android::sp<android::GraphicBuffer>& target, uint32_t slot, const android::sp<android::GraphicBuffer>& target, const android::sp<android::Fence>& acquireFence, const android::sp<android::Fence>& acquireFence, android::ui::Dataspace dataspace) = 0; android::ui::Dataspace dataspace); [[clang::warn_unused_result]] virtual Error setColorMode( [[clang::warn_unused_result]] Error setColorMode( android::ui::ColorMode mode, android::ui::RenderIntent renderIntent) = 0; android::ui::ColorMode mode, [[clang::warn_unused_result]] virtual Error setColorTransform( android::ui::RenderIntent renderIntent); const android::mat4& matrix, android_color_transform_t hint) = 0; [[clang::warn_unused_result]] Error setColorTransform( [[clang::warn_unused_result]] virtual Error setOutputBuffer( const android::mat4& matrix, android_color_transform_t hint); [[clang::warn_unused_result]] Error setOutputBuffer( const android::sp<android::GraphicBuffer>& buffer, const android::sp<android::GraphicBuffer>& buffer, const android::sp<android::Fence>& releaseFence); const android::sp<android::Fence>& releaseFence) = 0; [[clang::warn_unused_result]] Error setPowerMode(PowerMode mode); [[clang::warn_unused_result]] virtual Error setPowerMode(PowerMode mode) = 0; [[clang::warn_unused_result]] Error setVsyncEnabled(Vsync enabled); [[clang::warn_unused_result]] virtual Error setVsyncEnabled(Vsync enabled) = 0; [[clang::warn_unused_result]] Error validate(uint32_t* outNumTypes, [[clang::warn_unused_result]] virtual Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests); uint32_t* outNumRequests) = 0; [[clang::warn_unused_result]] Error presentOrValidate(uint32_t* outNumTypes, [[clang::warn_unused_result]] virtual Error presentOrValidate( uint32_t* outNumRequests, uint32_t* outNumTypes, uint32_t* outNumRequests, android::sp<android::Fence>* outPresentFence, uint32_t* state); android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0; }; // Other Display methods namespace impl { hwc2_display_t getId() const { return mId; } class Display : public HWC2::Display { bool isConnected() const { return mIsConnected; } public: void setConnected(bool connected); // For use by Device only Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<DisplayCapability>& getCapabilities() const { const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type); ~Display() override; // Required by HWC2 Error acceptChanges() override; Error createLayer(Layer** outLayer) override; Error destroyLayer(Layer* layer) override; Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override; Error getActiveConfigIndex(int* outIndex) const override; Error getChangedCompositionTypes(std::unordered_map<Layer*, Composition>* outTypes) override; Error getColorModes(std::vector<android::ui::ColorMode>* outModes) const override; // Returns a bitmask which contains HdrMetadata::Type::*. int32_t getSupportedPerFrameMetadata() const override; Error getRenderIntents(android::ui::ColorMode colorMode, std::vector<android::ui::RenderIntent>* outRenderIntents) const override; Error getDataspaceSaturationMatrix(android::ui::Dataspace dataspace, android::mat4* outMatrix) override; // Doesn't call into the HWC2 device, so no errors are possible std::vector<std::shared_ptr<const Config>> getConfigs() const override; Error getName(std::string* outName) const override; Error getRequests(DisplayRequest* outDisplayRequests, std::unordered_map<Layer*, LayerRequest>* outLayerRequests) override; Error getType(DisplayType* outType) const override; Error supportsDoze(bool* outSupport) const override; Error getHdrCapabilities(android::HdrCapabilities* outCapabilities) const override; Error getDisplayedContentSamplingAttributes(android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, uint8_t* outComponentMask) const override; Error setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask, uint64_t maxFrames) const override; Error getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp, android::DisplayedFrameStats* outStats) const override; Error getReleaseFences( std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const override; Error present(android::sp<android::Fence>* outPresentFence) override; Error setActiveConfig(const std::shared_ptr<const HWC2::Display::Config>& config) override; Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target, const android::sp<android::Fence>& acquireFence, android::ui::Dataspace dataspace) override; Error setColorMode(android::ui::ColorMode mode, android::ui::RenderIntent renderIntent) override; Error setColorTransform(const android::mat4& matrix, android_color_transform_t hint) override; Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer, const android::sp<android::Fence>& releaseFence) override; Error setPowerMode(PowerMode mode) override; Error setVsyncEnabled(Vsync enabled) override; Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override; Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests, android::sp<android::Fence>* outPresentFence, uint32_t* state) override; // Other Display methods hwc2_display_t getId() const override { return mId; } bool isConnected() const override { return mIsConnected; } void setConnected(bool connected) override; // For use by Device only const std::unordered_set<DisplayCapability>& getCapabilities() const override { return mDisplayCapabilities; return mDisplayCapabilities; }; }; Loading Loading @@ -309,6 +362,7 @@ private: std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs; std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs; std::unordered_set<DisplayCapability> mDisplayCapabilities; std::unordered_set<DisplayCapability> mDisplayCapabilities; }; }; } // namespace impl // Convenience C++ class to access hwc2_device_t Layer functions directly. // Convenience C++ class to access hwc2_device_t Layer functions directly. class Layer class Layer Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.h +32 −29 Original line number Original line Diff line number Diff line Loading @@ -19,9 +19,11 @@ #include <algorithm> #include <algorithm> #include <numeric> #include <numeric> #include "Scheduler/SchedulerUtils.h" #include "android-base/stringprintf.h" #include "android-base/stringprintf.h" #include "DisplayHardware/HWComposer.h" #include "Scheduler/SchedulerUtils.h" namespace android { namespace android { namespace scheduler { namespace scheduler { Loading Loading @@ -51,57 +53,58 @@ public: // baking them in. // baking them in. explicit RefreshRateConfigs( explicit RefreshRateConfigs( const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { // This is the rate that HWC encapsulates right now when the screen is off. init(configs); RefreshRate rate; } rate.type = RefreshRateType::POWER_SAVING; ~RefreshRateConfigs() = default; rate.configId = SCREEN_OFF_CONFIG_ID; rate.name = "ScreenOff"; const std::vector<RefreshRate>& getRefreshRates() { return mRefreshRates; } mRefreshRates.push_back(rate); private: void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { // This is the rate that HWC encapsulates right now when the device is in DOZE mode. mRefreshRates.push_back( RefreshRate{RefreshRateType::POWER_SAVING, SCREEN_OFF_CONFIG_ID, "ScreenOff"}); if (configs.size() < 1) { if (configs.size() < 1) { ALOGE("Device does not have valid configs. Config size is 0."); return; return; } } // Create a map between config index and vsync period. This is all the info we need // from the configs. std::vector<std::pair<int, nsecs_t>> configIdToVsyncPeriod; std::vector<std::pair<int, nsecs_t>> configIdToVsyncPeriod; for (int i = 0; i < configs.size(); ++i) { for (int i = 0; i < configs.size(); ++i) { configIdToVsyncPeriod.push_back(std::make_pair(i, configs.at(i)->getVsyncPeriod())); configIdToVsyncPeriod.emplace_back(i, configs.at(i)->getVsyncPeriod()); } } std::sort(configIdToVsyncPeriod.begin(), configIdToVsyncPeriod.end(), std::sort(configIdToVsyncPeriod.begin(), configIdToVsyncPeriod.end(), [](const std::pair<int, nsecs_t>& a, const std::pair<int, nsecs_t>& b) { [](const std::pair<int, nsecs_t>& a, const std::pair<int, nsecs_t>& b) { return a.second > b.second; return a.second > b.second; }); }); nsecs_t vsyncPeriod = configIdToVsyncPeriod.at(0).second; // When the configs are ordered by the resync rate. We assume that the first one is DEFAULT. nsecs_t vsyncPeriod = configIdToVsyncPeriod[0].second; if (vsyncPeriod != 0) { if (vsyncPeriod != 0) { const float fps = std::chrono::nanoseconds(1).count() / vsyncPeriod; const float fps = 1e9 / vsyncPeriod; rate.type = RefreshRateType::DEFAULT; mRefreshRates.push_back(RefreshRate{RefreshRateType::DEFAULT, rate.configId = configIdToVsyncPeriod.at(0).first; configIdToVsyncPeriod[0].first, rate.name = base::StringPrintf("%2.ffps", fps); base::StringPrintf("%2.ffps", fps)}); mRefreshRates.push_back(rate); } } if (configs.size() < 2) { if (configs.size() < 2) { return; return; } } vsyncPeriod = configIdToVsyncPeriod.at(1).second; // When the configs are ordered by the resync rate. We assume that the second one is // PERFORMANCE, eg. the higher rate. vsyncPeriod = configIdToVsyncPeriod[1].second; if (vsyncPeriod != 0) { if (vsyncPeriod != 0) { const float fps = std::chrono::nanoseconds(1).count() / vsyncPeriod; const float fps = 1e9 / vsyncPeriod; rate.type = RefreshRateType::PERFORMANCE; mRefreshRates.push_back(RefreshRate{RefreshRateType::PERFORMANCE, rate.configId = configIdToVsyncPeriod.at(1).first; configIdToVsyncPeriod[1].first, rate.name = base::StringPrintf("%2.ffps", fps); base::StringPrintf("%2.ffps", fps)}); mRefreshRates.push_back(rate); } for (auto refreshRate : mRefreshRates) { ALOGV("type: %d, id: %d, name: %s", refreshRate.type, refreshRate.configId, refreshRate.name.c_str()); } } } } ~RefreshRateConfigs() = default; const std::vector<RefreshRate>& getRefreshRates() { return mRefreshRates; } private: std::vector<RefreshRate> mRefreshRates; std::vector<RefreshRate> mRefreshRates; }; }; Loading services/surfaceflinger/Scheduler/RefreshRateStats.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -82,9 +82,11 @@ public: std::unordered_map<std::string, int64_t> totalTime; std::unordered_map<std::string, int64_t> totalTime; for (auto config : mRefreshRateConfigs->getRefreshRates()) { for (auto config : mRefreshRateConfigs->getRefreshRates()) { int64_t totalTimeForConfig = 0; if (mConfigModesTotalTime.find(config.configId) != mConfigModesTotalTime.end()) { if (mConfigModesTotalTime.find(config.configId) != mConfigModesTotalTime.end()) { totalTime[config.name] = mConfigModesTotalTime.at(config.configId); totalTimeForConfig = mConfigModesTotalTime.at(config.configId); } } totalTime[config.name] = totalTimeForConfig; } } return totalTime; return totalTime; } } Loading services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -4342,7 +4342,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int if (display->isPrimary()) { if (display->isPrimary()) { mTimeStats->setPowerMode(mode); mTimeStats->setPowerMode(mode); if (mUseScheduler) { if (mUseScheduler && mRefreshRateStats) { // Update refresh rate stats. // Update refresh rate stats. mRefreshRateStats->setPowerMode(mode); mRefreshRateStats->setPowerMode(mode); } } Loading Loading
services/surfaceflinger/DisplayHardware/HWC2.cpp +34 −32 Original line number Original line Diff line number Diff line Loading @@ -143,8 +143,8 @@ Error Device::createVirtualDisplay(uint32_t width, uint32_t height, return error; return error; } } auto display = std::make_unique<Display>( auto display = std::make_unique<impl::Display>(*mComposer.get(), mPowerAdvisor, mCapabilities, *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, DisplayType::Virtual); displayId, DisplayType::Virtual); display->setConnected(true); display->setConnected(true); *outDisplay = display.get(); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); mDisplays.emplace(displayId, std::move(display)); Loading Loading @@ -182,8 +182,8 @@ void Device::onHotplug(hwc2_display_t displayId, Connection connection) { return; return; } } auto newDisplay = std::make_unique<Display>( auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mPowerAdvisor, *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType); mCapabilities, displayId, displayType); newDisplay->setConnected(true); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { } else if (connection == Connection::Disconnected) { Loading Loading @@ -224,7 +224,36 @@ Error Device::flushCommands() } } // Display methods // Display methods Display::~Display() = default; Display::Config::Config(Display& display, hwc2_config_t id) : mDisplay(display), mId(id), mWidth(-1), mHeight(-1), mVsyncPeriod(-1), mDpiX(-1), mDpiY(-1) {} Display::Config::Builder::Builder(Display& display, hwc2_config_t id) : mConfig(new Config(display, id)) {} float Display::Config::Builder::getDefaultDensity() { // Default density is based on TVs: 1080p displays get XHIGH density, lower- // resolution displays get TV density. Maybe eventually we'll need to update // it for 4k displays, though hopefully those will just report accurate DPI // information to begin with. This is also used for virtual displays and // older HWC implementations, so be careful about orientation. auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); if (longDimension >= 1080) { return ACONFIGURATION_DENSITY_XHIGH; } else { return ACONFIGURATION_DENSITY_TV; } } namespace impl { Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type) DisplayType type) Loading Loading @@ -272,35 +301,7 @@ Display::~Display() { } } } } Display::Config::Config(Display& display, hwc2_config_t id) : mDisplay(display), mId(id), mWidth(-1), mHeight(-1), mVsyncPeriod(-1), mDpiX(-1), mDpiY(-1) {} Display::Config::Builder::Builder(Display& display, hwc2_config_t id) : mConfig(new Config(display, id)) {} float Display::Config::Builder::getDefaultDensity() { // Default density is based on TVs: 1080p displays get XHIGH density, lower- // resolution displays get TV density. Maybe eventually we'll need to update // it for 4k displays, though hopefully those will just report accurate DPI // information to begin with. This is also used for virtual displays and // older HWC implementations, so be careful about orientation. auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); if (longDimension >= 1080) { return ACONFIGURATION_DENSITY_XHIGH; } else { return ACONFIGURATION_DENSITY_TV; } } // Required by HWC2 display // Required by HWC2 display Error Display::acceptChanges() Error Display::acceptChanges() { { auto intError = mComposer.acceptDisplayChanges(mId); auto intError = mComposer.acceptDisplayChanges(mId); Loading Loading @@ -794,6 +795,7 @@ Layer* Display::getLayerById(hwc2_layer_t id) const return mLayers.at(id).get(); return mLayers.at(id).get(); } } } // namespace impl // Layer methods // Layer methods Loading
services/surfaceflinger/DisplayHardware/HWC2.h +124 −70 Original line number Original line Diff line number Diff line Loading @@ -130,16 +130,11 @@ private: }; }; // Convenience C++ class to access hwc2_device_t Display functions directly. // Convenience C++ class to access hwc2_device_t Display functions directly. class Display class Display { { public: public: Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, virtual ~Display(); const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type); ~Display(); class Config class Config { { public: public: class Builder class Builder { { Loading Loading @@ -207,78 +202,136 @@ public: float mDpiY; float mDpiY; }; }; // Required by HWC2 virtual hwc2_display_t getId() const = 0; virtual bool isConnected() const = 0; [[clang::warn_unused_result]] Error acceptChanges(); virtual void setConnected(bool connected) = 0; // For use by Device only [[clang::warn_unused_result]] Error createLayer(Layer** outLayer); virtual const std::unordered_set<DisplayCapability>& getCapabilities() const = 0; [[clang::warn_unused_result]] Error destroyLayer(Layer* layer); [[clang::warn_unused_result]] Error getActiveConfig( [[clang::warn_unused_result]] virtual Error acceptChanges() = 0; std::shared_ptr<const Config>* outConfig) const; [[clang::warn_unused_result]] virtual Error createLayer(Layer** outLayer) = 0; [[clang::warn_unused_result]] Error getActiveConfigIndex(int* outIndex) const; [[clang::warn_unused_result]] virtual Error destroyLayer(Layer* layer) = 0; [[clang::warn_unused_result]] Error getChangedCompositionTypes( [[clang::warn_unused_result]] virtual Error getActiveConfig( std::unordered_map<Layer*, Composition>* outTypes); std::shared_ptr<const Config>* outConfig) const = 0; [[clang::warn_unused_result]] Error getColorModes( [[clang::warn_unused_result]] virtual Error getActiveConfigIndex(int* outIndex) const = 0; std::vector<android::ui::ColorMode>* outModes) const; [[clang::warn_unused_result]] virtual Error getChangedCompositionTypes( std::unordered_map<Layer*, Composition>* outTypes) = 0; [[clang::warn_unused_result]] virtual Error getColorModes( std::vector<android::ui::ColorMode>* outModes) const = 0; // Returns a bitmask which contains HdrMetadata::Type::*. // Returns a bitmask which contains HdrMetadata::Type::*. [[clang::warn_unused_result]] int32_t getSupportedPerFrameMetadata() const; [[clang::warn_unused_result]] virtual int32_t getSupportedPerFrameMetadata() const = 0; [[clang::warn_unused_result]] Error getRenderIntents( [[clang::warn_unused_result]] virtual Error getRenderIntents( android::ui::ColorMode colorMode, android::ui::ColorMode colorMode, std::vector<android::ui::RenderIntent>* outRenderIntents) const; std::vector<android::ui::RenderIntent>* outRenderIntents) const = 0; [[clang::warn_unused_result]] Error getDataspaceSaturationMatrix( [[clang::warn_unused_result]] virtual Error getDataspaceSaturationMatrix( android::ui::Dataspace dataspace, android::mat4* outMatrix); android::ui::Dataspace dataspace, android::mat4* outMatrix) = 0; // Doesn't call into the HWC2 device, so no errors are possible // Doesn't call into the HWC2 device, so no Errors are possible std::vector<std::shared_ptr<const Config>> getConfigs() const; virtual std::vector<std::shared_ptr<const Config>> getConfigs() const = 0; [[clang::warn_unused_result]] Error getName(std::string* outName) const; [[clang::warn_unused_result]] virtual Error getName(std::string* outName) const = 0; [[clang::warn_unused_result]] Error getRequests( [[clang::warn_unused_result]] virtual Error getRequests( DisplayRequest* outDisplayRequests, DisplayRequest* outDisplayRequests, std::unordered_map<Layer*, LayerRequest>* outLayerRequests); std::unordered_map<Layer*, LayerRequest>* outLayerRequests) = 0; [[clang::warn_unused_result]] Error getType(DisplayType* outType) const; [[clang::warn_unused_result]] virtual Error getType(DisplayType* outType) const = 0; [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const; [[clang::warn_unused_result]] virtual Error supportsDoze(bool* outSupport) const = 0; [[clang::warn_unused_result]] Error getHdrCapabilities( [[clang::warn_unused_result]] virtual Error getHdrCapabilities( android::HdrCapabilities* outCapabilities) const; android::HdrCapabilities* outCapabilities) const = 0; [[clang::warn_unused_result]] Error getDisplayedContentSamplingAttributes( [[clang::warn_unused_result]] virtual Error getDisplayedContentSamplingAttributes( android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, uint8_t* outComponentMask) const; uint8_t* outComponentMask) const = 0; [[clang::warn_unused_result]] Error setDisplayContentSamplingEnabled(bool enabled, [[clang::warn_unused_result]] virtual Error setDisplayContentSamplingEnabled( uint8_t componentMask, bool enabled, uint8_t componentMask, uint64_t maxFrames) const = 0; uint64_t maxFrames) const; [[clang::warn_unused_result]] virtual Error getDisplayedContentSample( [[clang::warn_unused_result]] Error getDisplayedContentSample( uint64_t maxFrames, uint64_t timestamp, uint64_t maxFrames, uint64_t timestamp, android::DisplayedFrameStats* outStats) const; android::DisplayedFrameStats* outStats) const = 0; [[clang::warn_unused_result]] Error getReleaseFences( [[clang::warn_unused_result]] virtual Error getReleaseFences( std::unordered_map<Layer*, std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const = 0; android::sp<android::Fence>>* outFences) const; [[clang::warn_unused_result]] virtual Error present( [[clang::warn_unused_result]] Error present( android::sp<android::Fence>* outPresentFence) = 0; android::sp<android::Fence>* outPresentFence); [[clang::warn_unused_result]] virtual Error setActiveConfig( [[clang::warn_unused_result]] Error setActiveConfig( const std::shared_ptr<const Config>& config) = 0; const std::shared_ptr<const Config>& config); [[clang::warn_unused_result]] virtual Error setClientTarget( [[clang::warn_unused_result]] Error setClientTarget( uint32_t slot, const android::sp<android::GraphicBuffer>& target, uint32_t slot, const android::sp<android::GraphicBuffer>& target, const android::sp<android::Fence>& acquireFence, const android::sp<android::Fence>& acquireFence, android::ui::Dataspace dataspace) = 0; android::ui::Dataspace dataspace); [[clang::warn_unused_result]] virtual Error setColorMode( [[clang::warn_unused_result]] Error setColorMode( android::ui::ColorMode mode, android::ui::RenderIntent renderIntent) = 0; android::ui::ColorMode mode, [[clang::warn_unused_result]] virtual Error setColorTransform( android::ui::RenderIntent renderIntent); const android::mat4& matrix, android_color_transform_t hint) = 0; [[clang::warn_unused_result]] Error setColorTransform( [[clang::warn_unused_result]] virtual Error setOutputBuffer( const android::mat4& matrix, android_color_transform_t hint); [[clang::warn_unused_result]] Error setOutputBuffer( const android::sp<android::GraphicBuffer>& buffer, const android::sp<android::GraphicBuffer>& buffer, const android::sp<android::Fence>& releaseFence); const android::sp<android::Fence>& releaseFence) = 0; [[clang::warn_unused_result]] Error setPowerMode(PowerMode mode); [[clang::warn_unused_result]] virtual Error setPowerMode(PowerMode mode) = 0; [[clang::warn_unused_result]] Error setVsyncEnabled(Vsync enabled); [[clang::warn_unused_result]] virtual Error setVsyncEnabled(Vsync enabled) = 0; [[clang::warn_unused_result]] Error validate(uint32_t* outNumTypes, [[clang::warn_unused_result]] virtual Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests); uint32_t* outNumRequests) = 0; [[clang::warn_unused_result]] Error presentOrValidate(uint32_t* outNumTypes, [[clang::warn_unused_result]] virtual Error presentOrValidate( uint32_t* outNumRequests, uint32_t* outNumTypes, uint32_t* outNumRequests, android::sp<android::Fence>* outPresentFence, uint32_t* state); android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0; }; // Other Display methods namespace impl { hwc2_display_t getId() const { return mId; } class Display : public HWC2::Display { bool isConnected() const { return mIsConnected; } public: void setConnected(bool connected); // For use by Device only Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<DisplayCapability>& getCapabilities() const { const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type); ~Display() override; // Required by HWC2 Error acceptChanges() override; Error createLayer(Layer** outLayer) override; Error destroyLayer(Layer* layer) override; Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override; Error getActiveConfigIndex(int* outIndex) const override; Error getChangedCompositionTypes(std::unordered_map<Layer*, Composition>* outTypes) override; Error getColorModes(std::vector<android::ui::ColorMode>* outModes) const override; // Returns a bitmask which contains HdrMetadata::Type::*. int32_t getSupportedPerFrameMetadata() const override; Error getRenderIntents(android::ui::ColorMode colorMode, std::vector<android::ui::RenderIntent>* outRenderIntents) const override; Error getDataspaceSaturationMatrix(android::ui::Dataspace dataspace, android::mat4* outMatrix) override; // Doesn't call into the HWC2 device, so no errors are possible std::vector<std::shared_ptr<const Config>> getConfigs() const override; Error getName(std::string* outName) const override; Error getRequests(DisplayRequest* outDisplayRequests, std::unordered_map<Layer*, LayerRequest>* outLayerRequests) override; Error getType(DisplayType* outType) const override; Error supportsDoze(bool* outSupport) const override; Error getHdrCapabilities(android::HdrCapabilities* outCapabilities) const override; Error getDisplayedContentSamplingAttributes(android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, uint8_t* outComponentMask) const override; Error setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask, uint64_t maxFrames) const override; Error getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp, android::DisplayedFrameStats* outStats) const override; Error getReleaseFences( std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const override; Error present(android::sp<android::Fence>* outPresentFence) override; Error setActiveConfig(const std::shared_ptr<const HWC2::Display::Config>& config) override; Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target, const android::sp<android::Fence>& acquireFence, android::ui::Dataspace dataspace) override; Error setColorMode(android::ui::ColorMode mode, android::ui::RenderIntent renderIntent) override; Error setColorTransform(const android::mat4& matrix, android_color_transform_t hint) override; Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer, const android::sp<android::Fence>& releaseFence) override; Error setPowerMode(PowerMode mode) override; Error setVsyncEnabled(Vsync enabled) override; Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override; Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests, android::sp<android::Fence>* outPresentFence, uint32_t* state) override; // Other Display methods hwc2_display_t getId() const override { return mId; } bool isConnected() const override { return mIsConnected; } void setConnected(bool connected) override; // For use by Device only const std::unordered_set<DisplayCapability>& getCapabilities() const override { return mDisplayCapabilities; return mDisplayCapabilities; }; }; Loading Loading @@ -309,6 +362,7 @@ private: std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs; std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs; std::unordered_set<DisplayCapability> mDisplayCapabilities; std::unordered_set<DisplayCapability> mDisplayCapabilities; }; }; } // namespace impl // Convenience C++ class to access hwc2_device_t Layer functions directly. // Convenience C++ class to access hwc2_device_t Layer functions directly. class Layer class Layer Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.h +32 −29 Original line number Original line Diff line number Diff line Loading @@ -19,9 +19,11 @@ #include <algorithm> #include <algorithm> #include <numeric> #include <numeric> #include "Scheduler/SchedulerUtils.h" #include "android-base/stringprintf.h" #include "android-base/stringprintf.h" #include "DisplayHardware/HWComposer.h" #include "Scheduler/SchedulerUtils.h" namespace android { namespace android { namespace scheduler { namespace scheduler { Loading Loading @@ -51,57 +53,58 @@ public: // baking them in. // baking them in. explicit RefreshRateConfigs( explicit RefreshRateConfigs( const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { // This is the rate that HWC encapsulates right now when the screen is off. init(configs); RefreshRate rate; } rate.type = RefreshRateType::POWER_SAVING; ~RefreshRateConfigs() = default; rate.configId = SCREEN_OFF_CONFIG_ID; rate.name = "ScreenOff"; const std::vector<RefreshRate>& getRefreshRates() { return mRefreshRates; } mRefreshRates.push_back(rate); private: void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) { // This is the rate that HWC encapsulates right now when the device is in DOZE mode. mRefreshRates.push_back( RefreshRate{RefreshRateType::POWER_SAVING, SCREEN_OFF_CONFIG_ID, "ScreenOff"}); if (configs.size() < 1) { if (configs.size() < 1) { ALOGE("Device does not have valid configs. Config size is 0."); return; return; } } // Create a map between config index and vsync period. This is all the info we need // from the configs. std::vector<std::pair<int, nsecs_t>> configIdToVsyncPeriod; std::vector<std::pair<int, nsecs_t>> configIdToVsyncPeriod; for (int i = 0; i < configs.size(); ++i) { for (int i = 0; i < configs.size(); ++i) { configIdToVsyncPeriod.push_back(std::make_pair(i, configs.at(i)->getVsyncPeriod())); configIdToVsyncPeriod.emplace_back(i, configs.at(i)->getVsyncPeriod()); } } std::sort(configIdToVsyncPeriod.begin(), configIdToVsyncPeriod.end(), std::sort(configIdToVsyncPeriod.begin(), configIdToVsyncPeriod.end(), [](const std::pair<int, nsecs_t>& a, const std::pair<int, nsecs_t>& b) { [](const std::pair<int, nsecs_t>& a, const std::pair<int, nsecs_t>& b) { return a.second > b.second; return a.second > b.second; }); }); nsecs_t vsyncPeriod = configIdToVsyncPeriod.at(0).second; // When the configs are ordered by the resync rate. We assume that the first one is DEFAULT. nsecs_t vsyncPeriod = configIdToVsyncPeriod[0].second; if (vsyncPeriod != 0) { if (vsyncPeriod != 0) { const float fps = std::chrono::nanoseconds(1).count() / vsyncPeriod; const float fps = 1e9 / vsyncPeriod; rate.type = RefreshRateType::DEFAULT; mRefreshRates.push_back(RefreshRate{RefreshRateType::DEFAULT, rate.configId = configIdToVsyncPeriod.at(0).first; configIdToVsyncPeriod[0].first, rate.name = base::StringPrintf("%2.ffps", fps); base::StringPrintf("%2.ffps", fps)}); mRefreshRates.push_back(rate); } } if (configs.size() < 2) { if (configs.size() < 2) { return; return; } } vsyncPeriod = configIdToVsyncPeriod.at(1).second; // When the configs are ordered by the resync rate. We assume that the second one is // PERFORMANCE, eg. the higher rate. vsyncPeriod = configIdToVsyncPeriod[1].second; if (vsyncPeriod != 0) { if (vsyncPeriod != 0) { const float fps = std::chrono::nanoseconds(1).count() / vsyncPeriod; const float fps = 1e9 / vsyncPeriod; rate.type = RefreshRateType::PERFORMANCE; mRefreshRates.push_back(RefreshRate{RefreshRateType::PERFORMANCE, rate.configId = configIdToVsyncPeriod.at(1).first; configIdToVsyncPeriod[1].first, rate.name = base::StringPrintf("%2.ffps", fps); base::StringPrintf("%2.ffps", fps)}); mRefreshRates.push_back(rate); } for (auto refreshRate : mRefreshRates) { ALOGV("type: %d, id: %d, name: %s", refreshRate.type, refreshRate.configId, refreshRate.name.c_str()); } } } } ~RefreshRateConfigs() = default; const std::vector<RefreshRate>& getRefreshRates() { return mRefreshRates; } private: std::vector<RefreshRate> mRefreshRates; std::vector<RefreshRate> mRefreshRates; }; }; Loading
services/surfaceflinger/Scheduler/RefreshRateStats.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -82,9 +82,11 @@ public: std::unordered_map<std::string, int64_t> totalTime; std::unordered_map<std::string, int64_t> totalTime; for (auto config : mRefreshRateConfigs->getRefreshRates()) { for (auto config : mRefreshRateConfigs->getRefreshRates()) { int64_t totalTimeForConfig = 0; if (mConfigModesTotalTime.find(config.configId) != mConfigModesTotalTime.end()) { if (mConfigModesTotalTime.find(config.configId) != mConfigModesTotalTime.end()) { totalTime[config.name] = mConfigModesTotalTime.at(config.configId); totalTimeForConfig = mConfigModesTotalTime.at(config.configId); } } totalTime[config.name] = totalTimeForConfig; } } return totalTime; return totalTime; } } Loading
services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -4342,7 +4342,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int if (display->isPrimary()) { if (display->isPrimary()) { mTimeStats->setPowerMode(mode); mTimeStats->setPowerMode(mode); if (mUseScheduler) { if (mUseScheduler && mRefreshRateStats) { // Update refresh rate stats. // Update refresh rate stats. mRefreshRateStats->setPowerMode(mode); mRefreshRateStats->setPowerMode(mode); } } Loading