Loading services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +5 −8 Original line number Diff line number Diff line Loading @@ -87,20 +87,17 @@ public: MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync)); MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId)); MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId)); MOCK_CONST_METHOD1( getConfigs, std::vector<std::shared_ptr<const HWC2::Display::Config>>(PhysicalDisplayId)); MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(PhysicalDisplayId)); MOCK_CONST_METHOD1(getActiveConfigIndex, int(PhysicalDisplayId)); MOCK_CONST_METHOD1(getModes, DisplayModes(PhysicalDisplayId)); MOCK_CONST_METHOD1(getActiveMode, DisplayModePtr(PhysicalDisplayId)); MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId)); MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent)); MOCK_CONST_METHOD0(isUsingVrComposer, bool()); MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId)); MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId)); MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId)); MOCK_METHOD4(setActiveConfigWithConstraints, status_t(PhysicalDisplayId, size_t, const hal::VsyncPeriodChangeConstraints&, MOCK_METHOD4(setActiveModeWithConstraints, status_t(PhysicalDisplayId, HwcConfigIndexType, const hal::VsyncPeriodChangeConstraints&, hal::VsyncPeriodChangeTimeline*)); MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool)); MOCK_METHOD2(getSupportedContentTypes, Loading services/surfaceflinger/DisplayDevice.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ void DisplayDevice::dump(std::string& result) const { result.append(" "); StringAppendF(&result, "powerMode=%s (%d), ", to_string(mPowerMode).c_str(), static_cast<int32_t>(mPowerMode)); StringAppendF(&result, "activeConfig=%d, ", mActiveConfig.value()); StringAppendF(&result, "activeConfig=%zu, ", mActiveConfig.value()); StringAppendF(&result, "deviceProductInfo="); if (mDeviceProductInfo) { mDeviceProductInfo->dump(result); Loading services/surfaceflinger/DisplayHardware/DisplayMode.h 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "DisplayHardware/Hal.h" #include "Scheduler/HwcStrongTypes.h" #include <android/configuration.h> #include <utils/Timers.h> #include <memory> #include <vector> namespace android { namespace hal = android::hardware::graphics::composer::hal; class DisplayMode; using DisplayModePtr = std::shared_ptr<const DisplayMode>; using DisplayModes = std::vector<DisplayModePtr>; class DisplayMode { public: class Builder { public: explicit Builder(hal::HWConfigId id) : mDisplayMode(new DisplayMode(id)) {} DisplayModePtr build() { return std::const_pointer_cast<const DisplayMode>(std::move(mDisplayMode)); } Builder& setId(HwcConfigIndexType id) { mDisplayMode->mId = id; return *this; } Builder& setWidth(int32_t width) { mDisplayMode->mWidth = width; return *this; } Builder& setHeight(int32_t height) { mDisplayMode->mHeight = height; return *this; } Builder& setVsyncPeriod(int32_t vsyncPeriod) { mDisplayMode->mVsyncPeriod = vsyncPeriod; return *this; } Builder& setDpiX(int32_t dpiX) { if (dpiX == -1) { mDisplayMode->mDpiX = getDefaultDensity(); } else { mDisplayMode->mDpiX = dpiX / 1000.0f; } return *this; } Builder& setDpiY(int32_t dpiY) { if (dpiY == -1) { mDisplayMode->mDpiY = getDefaultDensity(); } else { mDisplayMode->mDpiY = dpiY / 1000.0f; } return *this; } Builder& setConfigGroup(int32_t configGroup) { mDisplayMode->mConfigGroup = configGroup; return *this; } private: float 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(mDisplayMode->mWidth, mDisplayMode->mHeight); if (longDimension >= 1080) { return ACONFIGURATION_DENSITY_XHIGH; } else { return ACONFIGURATION_DENSITY_TV; } } std::shared_ptr<DisplayMode> mDisplayMode; }; HwcConfigIndexType getId() const { return mId; } hal::HWConfigId getHwcId() const { return mHwcId; } int32_t getWidth() const { return mWidth; } int32_t getHeight() const { return mHeight; } nsecs_t getVsyncPeriod() const { return mVsyncPeriod; } float getDpiX() const { return mDpiX; } float getDpiY() const { return mDpiY; } int32_t getConfigGroup() const { return mConfigGroup; } private: explicit DisplayMode(hal::HWConfigId id) : mHwcId(id) {} hal::HWConfigId mHwcId; HwcConfigIndexType mId; int32_t mWidth = -1; int32_t mHeight = -1; nsecs_t mVsyncPeriod = -1; float mDpiX = -1; float mDpiY = -1; int32_t mConfigGroup = -1; }; } // namespace android No newline at end of file services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -77,9 +77,8 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displa mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER); const auto& activeConfig = mHwc.getActiveConfig(displayId); ui::Size limitedSize = limitFramebufferSize(activeConfig->getWidth(), activeConfig->getHeight()); const auto& activeMode = mHwc.getActiveMode(displayId); ui::Size limitedSize = limitFramebufferSize(activeMode->getWidth(), activeMode->getHeight()); mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height); mConsumer->setMaxAcquiredBufferCount( SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1); Loading services/surfaceflinger/DisplayHardware/HWC2.cpp +6 −190 Original line number Diff line number Diff line Loading @@ -68,33 +68,6 @@ inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys, // Display methods Display::~Display() = default; Display::Config::Config(Display& display, HWConfigId id) : mDisplay(display), mId(id), mWidth(-1), mHeight(-1), mVsyncPeriod(-1), mDpiX(-1), mDpiY(-1) {} Display::Config::Builder::Builder(Display& display, HWConfigId 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, Loading Loading @@ -162,93 +135,12 @@ Error Display::destroyLayer(HWC2::Layer* layer) { return Error::NONE; } Error Display::getActiveConfig( std::shared_ptr<const Display::Config>* outConfig) const { ALOGV("[%" PRIu64 "] getActiveConfig", mId); HWConfigId configId = 0; auto intError = mComposer.getActiveConfig(mId, &configId); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); *outConfig = nullptr; return error; } if (mConfigs.count(configId) != 0) { *outConfig = mConfigs.at(configId); } else { ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId); // Return no error, but the caller needs to check for a null pointer to // detect this case *outConfig = nullptr; } return Error::NONE; } bool Display::isVsyncPeriodSwitchSupported() const { ALOGV("[%" PRIu64 "] isVsyncPeriodSwitchSupported()", mId); return mComposer.isVsyncPeriodSwitchSupported(); } Error Display::getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const { ALOGV("[%" PRIu64 "] getDisplayVsyncPeriod", mId); Error error; if (isVsyncPeriodSwitchSupported()) { Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0; auto intError = mComposer.getDisplayVsyncPeriod(mId, &vsyncPeriodNanos); error = static_cast<Error>(intError); *outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos); } else { // Get the default vsync period std::shared_ptr<const Display::Config> config; error = getActiveConfig(&config); if (error != Error::NONE) { return error; } if (!config) { // HWC has updated the display modes and hasn't notified us yet. return Error::BAD_CONFIG; } *outVsyncPeriod = config->getVsyncPeriod(); } return error; } Error Display::getActiveConfigIndex(int* outIndex) const { ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId); HWConfigId configId = 0; auto intError = mComposer.getActiveConfig(mId, &configId); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); *outIndex = -1; return error; } auto pos = mConfigs.find(configId); if (pos != mConfigs.end()) { *outIndex = std::distance(mConfigs.begin(), pos); ALOGV("[%" PRIu64 "] index = %d", mId, *outIndex); } else { ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId); // Return no error, but the caller needs to check for a negative index // to detect this case *outIndex = -1; } return Error::NONE; } Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) { std::vector<Hwc2::Layer> layerIds; std::vector<Hwc2::IComposerClient::Composition> types; Loading Loading @@ -335,15 +227,6 @@ Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* return static_cast<Error>(intError); } std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const { std::vector<std::shared_ptr<const Config>> configs; for (const auto& element : mConfigs) { configs.emplace_back(element.second); } return configs; } Error Display::getName(std::string* outName) const { auto intError = mComposer.getDisplayName(mId, outName); Loading Loading @@ -486,16 +369,10 @@ Error Display::present(sp<Fence>* outPresentFence) return Error::NONE; } Error Display::setActiveConfigWithConstraints( const std::shared_ptr<const HWC2::Display::Config>& config, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* outTimeline) { Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* outTimeline) { ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId); if (config->getDisplayId() != mId) { ALOGE("setActiveConfigWithConstraints received config %u for the wrong display %" PRIu64 " (expected %" PRIu64 ")", config->getId(), config->getDisplayId(), mId); return Error::BAD_CONFIG; } if (isVsyncPeriodSwitchSupported()) { Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints; Loading @@ -503,8 +380,7 @@ Error Display::setActiveConfigWithConstraints( hwc2Constraints.seamlessRequired = constraints.seamlessRequired; Hwc2::VsyncPeriodChangeTimeline vsyncPeriodChangeTimeline = {}; auto intError = mComposer.setActiveConfigWithConstraints(mId, config->getId(), hwc2Constraints, auto intError = mComposer.setActiveConfigWithConstraints(mId, configId, hwc2Constraints, &vsyncPeriodChangeTimeline); outTimeline->newVsyncAppliedTimeNanos = vsyncPeriodChangeTimeline.newVsyncAppliedTimeNanos; outTimeline->refreshRequired = vsyncPeriodChangeTimeline.refreshRequired; Loading @@ -519,25 +395,13 @@ Error Display::setActiveConfigWithConstraints( ALOGE("setActiveConfigWithConstraints received constraints that can't be satisfied"); } auto intError_2_4 = mComposer.setActiveConfig(mId, config->getId()); auto intError_2_4 = mComposer.setActiveConfig(mId, configId); outTimeline->newVsyncAppliedTimeNanos = std::max(now, constraints.desiredTimeNanos); outTimeline->refreshRequired = true; outTimeline->refreshTimeNanos = now; return static_cast<Error>(intError_2_4); } Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) { if (config->getDisplayId() != mId) { ALOGE("setActiveConfig received config %u for the wrong display %" PRIu64 " (expected %" PRIu64 ")", config->getId(), config->getDisplayId(), mId); return Error::BAD_CONFIG; } auto intError = mComposer.setActiveConfig(mId, config->getId()); return static_cast<Error>(intError); } Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, const sp<Fence>& acquireFence, Dataspace dataspace) { Loading Loading @@ -681,58 +545,10 @@ Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProp void Display::setConnected(bool connected) { if (!mIsConnected && connected) { mComposer.setClientTargetSlotCount(mId); if (mType == DisplayType::PHYSICAL) { loadConfigs(); } } mIsConnected = connected; } int32_t Display::getAttribute(HWConfigId configId, Attribute attribute) { int32_t value = 0; auto intError = mComposer.getDisplayAttribute(mId, configId, attribute, &value); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, configId, to_string(attribute).c_str(), to_string(error).c_str(), intError); return -1; } return value; } void Display::loadConfig(HWConfigId configId) { ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); auto config = Config::Builder(*this, configId) .setWidth(getAttribute(configId, hal::Attribute::WIDTH)) .setHeight(getAttribute(configId, hal::Attribute::HEIGHT)) .setVsyncPeriod(getAttribute(configId, hal::Attribute::VSYNC_PERIOD)) .setDpiX(getAttribute(configId, hal::Attribute::DPI_X)) .setDpiY(getAttribute(configId, hal::Attribute::DPI_Y)) .setConfigGroup(getAttribute(configId, hal::Attribute::CONFIG_GROUP)) .build(); mConfigs.emplace(configId, std::move(config)); } void Display::loadConfigs() { ALOGV("[%" PRIu64 "] loadConfigs", mId); std::vector<HWConfigId> configIds; auto intError = mComposer.getDisplayConfigs(mId, &configIds); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, to_string(error).c_str(), intError); return; } for (auto configId : configIds) { loadConfig(configId); } } // Other Display methods HWC2::Layer* Display::getLayerById(HWLayerId id) const { Loading Loading
services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +5 −8 Original line number Diff line number Diff line Loading @@ -87,20 +87,17 @@ public: MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync)); MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId)); MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId)); MOCK_CONST_METHOD1( getConfigs, std::vector<std::shared_ptr<const HWC2::Display::Config>>(PhysicalDisplayId)); MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(PhysicalDisplayId)); MOCK_CONST_METHOD1(getActiveConfigIndex, int(PhysicalDisplayId)); MOCK_CONST_METHOD1(getModes, DisplayModes(PhysicalDisplayId)); MOCK_CONST_METHOD1(getActiveMode, DisplayModePtr(PhysicalDisplayId)); MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId)); MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent)); MOCK_CONST_METHOD0(isUsingVrComposer, bool()); MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId)); MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId)); MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId)); MOCK_METHOD4(setActiveConfigWithConstraints, status_t(PhysicalDisplayId, size_t, const hal::VsyncPeriodChangeConstraints&, MOCK_METHOD4(setActiveModeWithConstraints, status_t(PhysicalDisplayId, HwcConfigIndexType, const hal::VsyncPeriodChangeConstraints&, hal::VsyncPeriodChangeTimeline*)); MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool)); MOCK_METHOD2(getSupportedContentTypes, Loading
services/surfaceflinger/DisplayDevice.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ void DisplayDevice::dump(std::string& result) const { result.append(" "); StringAppendF(&result, "powerMode=%s (%d), ", to_string(mPowerMode).c_str(), static_cast<int32_t>(mPowerMode)); StringAppendF(&result, "activeConfig=%d, ", mActiveConfig.value()); StringAppendF(&result, "activeConfig=%zu, ", mActiveConfig.value()); StringAppendF(&result, "deviceProductInfo="); if (mDeviceProductInfo) { mDeviceProductInfo->dump(result); Loading
services/surfaceflinger/DisplayHardware/DisplayMode.h 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "DisplayHardware/Hal.h" #include "Scheduler/HwcStrongTypes.h" #include <android/configuration.h> #include <utils/Timers.h> #include <memory> #include <vector> namespace android { namespace hal = android::hardware::graphics::composer::hal; class DisplayMode; using DisplayModePtr = std::shared_ptr<const DisplayMode>; using DisplayModes = std::vector<DisplayModePtr>; class DisplayMode { public: class Builder { public: explicit Builder(hal::HWConfigId id) : mDisplayMode(new DisplayMode(id)) {} DisplayModePtr build() { return std::const_pointer_cast<const DisplayMode>(std::move(mDisplayMode)); } Builder& setId(HwcConfigIndexType id) { mDisplayMode->mId = id; return *this; } Builder& setWidth(int32_t width) { mDisplayMode->mWidth = width; return *this; } Builder& setHeight(int32_t height) { mDisplayMode->mHeight = height; return *this; } Builder& setVsyncPeriod(int32_t vsyncPeriod) { mDisplayMode->mVsyncPeriod = vsyncPeriod; return *this; } Builder& setDpiX(int32_t dpiX) { if (dpiX == -1) { mDisplayMode->mDpiX = getDefaultDensity(); } else { mDisplayMode->mDpiX = dpiX / 1000.0f; } return *this; } Builder& setDpiY(int32_t dpiY) { if (dpiY == -1) { mDisplayMode->mDpiY = getDefaultDensity(); } else { mDisplayMode->mDpiY = dpiY / 1000.0f; } return *this; } Builder& setConfigGroup(int32_t configGroup) { mDisplayMode->mConfigGroup = configGroup; return *this; } private: float 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(mDisplayMode->mWidth, mDisplayMode->mHeight); if (longDimension >= 1080) { return ACONFIGURATION_DENSITY_XHIGH; } else { return ACONFIGURATION_DENSITY_TV; } } std::shared_ptr<DisplayMode> mDisplayMode; }; HwcConfigIndexType getId() const { return mId; } hal::HWConfigId getHwcId() const { return mHwcId; } int32_t getWidth() const { return mWidth; } int32_t getHeight() const { return mHeight; } nsecs_t getVsyncPeriod() const { return mVsyncPeriod; } float getDpiX() const { return mDpiX; } float getDpiY() const { return mDpiY; } int32_t getConfigGroup() const { return mConfigGroup; } private: explicit DisplayMode(hal::HWConfigId id) : mHwcId(id) {} hal::HWConfigId mHwcId; HwcConfigIndexType mId; int32_t mWidth = -1; int32_t mHeight = -1; nsecs_t mVsyncPeriod = -1; float mDpiX = -1; float mDpiY = -1; int32_t mConfigGroup = -1; }; } // namespace android No newline at end of file
services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -77,9 +77,8 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displa mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER); const auto& activeConfig = mHwc.getActiveConfig(displayId); ui::Size limitedSize = limitFramebufferSize(activeConfig->getWidth(), activeConfig->getHeight()); const auto& activeMode = mHwc.getActiveMode(displayId); ui::Size limitedSize = limitFramebufferSize(activeMode->getWidth(), activeMode->getHeight()); mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height); mConsumer->setMaxAcquiredBufferCount( SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1); Loading
services/surfaceflinger/DisplayHardware/HWC2.cpp +6 −190 Original line number Diff line number Diff line Loading @@ -68,33 +68,6 @@ inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys, // Display methods Display::~Display() = default; Display::Config::Config(Display& display, HWConfigId id) : mDisplay(display), mId(id), mWidth(-1), mHeight(-1), mVsyncPeriod(-1), mDpiX(-1), mDpiY(-1) {} Display::Config::Builder::Builder(Display& display, HWConfigId 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, Loading Loading @@ -162,93 +135,12 @@ Error Display::destroyLayer(HWC2::Layer* layer) { return Error::NONE; } Error Display::getActiveConfig( std::shared_ptr<const Display::Config>* outConfig) const { ALOGV("[%" PRIu64 "] getActiveConfig", mId); HWConfigId configId = 0; auto intError = mComposer.getActiveConfig(mId, &configId); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); *outConfig = nullptr; return error; } if (mConfigs.count(configId) != 0) { *outConfig = mConfigs.at(configId); } else { ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId); // Return no error, but the caller needs to check for a null pointer to // detect this case *outConfig = nullptr; } return Error::NONE; } bool Display::isVsyncPeriodSwitchSupported() const { ALOGV("[%" PRIu64 "] isVsyncPeriodSwitchSupported()", mId); return mComposer.isVsyncPeriodSwitchSupported(); } Error Display::getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const { ALOGV("[%" PRIu64 "] getDisplayVsyncPeriod", mId); Error error; if (isVsyncPeriodSwitchSupported()) { Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0; auto intError = mComposer.getDisplayVsyncPeriod(mId, &vsyncPeriodNanos); error = static_cast<Error>(intError); *outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos); } else { // Get the default vsync period std::shared_ptr<const Display::Config> config; error = getActiveConfig(&config); if (error != Error::NONE) { return error; } if (!config) { // HWC has updated the display modes and hasn't notified us yet. return Error::BAD_CONFIG; } *outVsyncPeriod = config->getVsyncPeriod(); } return error; } Error Display::getActiveConfigIndex(int* outIndex) const { ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId); HWConfigId configId = 0; auto intError = mComposer.getActiveConfig(mId, &configId); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); *outIndex = -1; return error; } auto pos = mConfigs.find(configId); if (pos != mConfigs.end()) { *outIndex = std::distance(mConfigs.begin(), pos); ALOGV("[%" PRIu64 "] index = %d", mId, *outIndex); } else { ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId); // Return no error, but the caller needs to check for a negative index // to detect this case *outIndex = -1; } return Error::NONE; } Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) { std::vector<Hwc2::Layer> layerIds; std::vector<Hwc2::IComposerClient::Composition> types; Loading Loading @@ -335,15 +227,6 @@ Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* return static_cast<Error>(intError); } std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const { std::vector<std::shared_ptr<const Config>> configs; for (const auto& element : mConfigs) { configs.emplace_back(element.second); } return configs; } Error Display::getName(std::string* outName) const { auto intError = mComposer.getDisplayName(mId, outName); Loading Loading @@ -486,16 +369,10 @@ Error Display::present(sp<Fence>* outPresentFence) return Error::NONE; } Error Display::setActiveConfigWithConstraints( const std::shared_ptr<const HWC2::Display::Config>& config, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* outTimeline) { Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* outTimeline) { ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId); if (config->getDisplayId() != mId) { ALOGE("setActiveConfigWithConstraints received config %u for the wrong display %" PRIu64 " (expected %" PRIu64 ")", config->getId(), config->getDisplayId(), mId); return Error::BAD_CONFIG; } if (isVsyncPeriodSwitchSupported()) { Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints; Loading @@ -503,8 +380,7 @@ Error Display::setActiveConfigWithConstraints( hwc2Constraints.seamlessRequired = constraints.seamlessRequired; Hwc2::VsyncPeriodChangeTimeline vsyncPeriodChangeTimeline = {}; auto intError = mComposer.setActiveConfigWithConstraints(mId, config->getId(), hwc2Constraints, auto intError = mComposer.setActiveConfigWithConstraints(mId, configId, hwc2Constraints, &vsyncPeriodChangeTimeline); outTimeline->newVsyncAppliedTimeNanos = vsyncPeriodChangeTimeline.newVsyncAppliedTimeNanos; outTimeline->refreshRequired = vsyncPeriodChangeTimeline.refreshRequired; Loading @@ -519,25 +395,13 @@ Error Display::setActiveConfigWithConstraints( ALOGE("setActiveConfigWithConstraints received constraints that can't be satisfied"); } auto intError_2_4 = mComposer.setActiveConfig(mId, config->getId()); auto intError_2_4 = mComposer.setActiveConfig(mId, configId); outTimeline->newVsyncAppliedTimeNanos = std::max(now, constraints.desiredTimeNanos); outTimeline->refreshRequired = true; outTimeline->refreshTimeNanos = now; return static_cast<Error>(intError_2_4); } Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) { if (config->getDisplayId() != mId) { ALOGE("setActiveConfig received config %u for the wrong display %" PRIu64 " (expected %" PRIu64 ")", config->getId(), config->getDisplayId(), mId); return Error::BAD_CONFIG; } auto intError = mComposer.setActiveConfig(mId, config->getId()); return static_cast<Error>(intError); } Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, const sp<Fence>& acquireFence, Dataspace dataspace) { Loading Loading @@ -681,58 +545,10 @@ Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProp void Display::setConnected(bool connected) { if (!mIsConnected && connected) { mComposer.setClientTargetSlotCount(mId); if (mType == DisplayType::PHYSICAL) { loadConfigs(); } } mIsConnected = connected; } int32_t Display::getAttribute(HWConfigId configId, Attribute attribute) { int32_t value = 0; auto intError = mComposer.getDisplayAttribute(mId, configId, attribute, &value); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, configId, to_string(attribute).c_str(), to_string(error).c_str(), intError); return -1; } return value; } void Display::loadConfig(HWConfigId configId) { ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); auto config = Config::Builder(*this, configId) .setWidth(getAttribute(configId, hal::Attribute::WIDTH)) .setHeight(getAttribute(configId, hal::Attribute::HEIGHT)) .setVsyncPeriod(getAttribute(configId, hal::Attribute::VSYNC_PERIOD)) .setDpiX(getAttribute(configId, hal::Attribute::DPI_X)) .setDpiY(getAttribute(configId, hal::Attribute::DPI_Y)) .setConfigGroup(getAttribute(configId, hal::Attribute::CONFIG_GROUP)) .build(); mConfigs.emplace(configId, std::move(config)); } void Display::loadConfigs() { ALOGV("[%" PRIu64 "] loadConfigs", mId); std::vector<HWConfigId> configIds; auto intError = mComposer.getDisplayConfigs(mId, &configIds); auto error = static_cast<Error>(intError); if (error != Error::NONE) { ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, to_string(error).c_str(), intError); return; } for (auto configId : configIds) { loadConfig(configId); } } // Other Display methods HWC2::Layer* Display::getLayerById(HWLayerId id) const { Loading