diff options
19 files changed, 412 insertions, 0 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index a931709dbd..02270433b6 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -428,6 +428,94 @@ public: return static_cast<status_t>(reply.readInt32()); } + // TODO(b/213909104) : Add unit tests to verify surface flinger boot time APIs + status_t getBootDisplayModeSupport(bool* outSupport) const override { + Parcel data, reply; + status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (error != NO_ERROR) { + ALOGE("getBootDisplayModeSupport: failed to write interface token: %d", error); + return error; + } + error = remote()->transact(BnSurfaceComposer::GET_BOOT_DISPLAY_MODE_SUPPORT, data, &reply); + if (error != NO_ERROR) { + ALOGE("getBootDisplayModeSupport: failed to transact: %d", error); + return error; + } + bool support; + error = reply.readBool(&support); + if (error != NO_ERROR) { + ALOGE("getBootDisplayModeSupport: failed to read support: %d", error); + return error; + } + *outSupport = support; + return NO_ERROR; + } + + status_t setBootDisplayMode(const sp<IBinder>& display, + ui::DisplayModeId displayModeId) override { + Parcel data, reply; + status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (result != NO_ERROR) { + ALOGE("setBootDisplayMode failed to writeInterfaceToken: %d", result); + return result; + } + result = data.writeStrongBinder(display); + if (result != NO_ERROR) { + ALOGE("setBootDisplayMode failed to writeStrongBinder: %d", result); + return result; + } + result = data.writeInt32(displayModeId); + if (result != NO_ERROR) { + ALOGE("setBootDisplayMode failed to writeIint32: %d", result); + return result; + } + result = remote()->transact(BnSurfaceComposer::SET_BOOT_DISPLAY_MODE, data, &reply); + if (result != NO_ERROR) { + ALOGE("setBootDisplayMode failed to transact: %d", result); + } + return result; + } + + status_t clearBootDisplayMode(const sp<IBinder>& display) override { + Parcel data, reply; + status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (result != NO_ERROR) { + ALOGE("clearBootDisplayMode failed to writeInterfaceToken: %d", result); + return result; + } + result = data.writeStrongBinder(display); + if (result != NO_ERROR) { + ALOGE("clearBootDisplayMode failed to writeStrongBinder: %d", result); + return result; + } + result = remote()->transact(BnSurfaceComposer::CLEAR_BOOT_DISPLAY_MODE, data, &reply); + if (result != NO_ERROR) { + ALOGE("clearBootDisplayMode failed to transact: %d", result); + } + return result; + } + + status_t getPreferredBootDisplayMode(const sp<IBinder>& display, + ui::DisplayModeId* displayModeId) override { + Parcel data, reply; + status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (result != NO_ERROR) { + ALOGE("getPreferredBootDisplayMode failed to writeInterfaceToken: %d", result); + return result; + } + result = data.writeStrongBinder(display); + if (result != NO_ERROR) { + ALOGE("getPreferredBootDisplayMode failed to writeStrongBinder: %d", result); + return result; + } + result = remote()->transact(BnSurfaceComposer::GET_PREFERRED_BOOT_DISPLAY_MODE, data, + &reply); + if (result == NO_ERROR) { + reply.writeInt32(*displayModeId); + } + return result; + } + void setAutoLowLatencyMode(const sp<IBinder>& display, bool on) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); @@ -1521,6 +1609,56 @@ status_t BnSurfaceComposer::onTransact( result = reply->writeInt32(result); return result; } + case GET_BOOT_DISPLAY_MODE_SUPPORT: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + bool support = false; + status_t result = getBootDisplayModeSupport(&support); + if (result == NO_ERROR) { + reply->writeBool(support); + } + return result; + } + case SET_BOOT_DISPLAY_MODE: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IBinder> display = nullptr; + status_t result = data.readStrongBinder(&display); + if (result != NO_ERROR) { + ALOGE("setBootDisplayMode failed to readStrongBinder: %d", result); + return result; + } + ui::DisplayModeId displayModeId; + result = data.readInt32(&displayModeId); + if (result != NO_ERROR) { + ALOGE("setBootDisplayMode failed to readInt32: %d", result); + return result; + } + return setBootDisplayMode(display, displayModeId); + } + case CLEAR_BOOT_DISPLAY_MODE: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IBinder> display = nullptr; + status_t result = data.readStrongBinder(&display); + if (result != NO_ERROR) { + ALOGE("clearBootDisplayMode failed to readStrongBinder: %d", result); + return result; + } + return clearBootDisplayMode(display); + } + case GET_PREFERRED_BOOT_DISPLAY_MODE: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IBinder> display = nullptr; + status_t result = data.readStrongBinder(&display); + if (result != NO_ERROR) { + ALOGE("getPreferredBootDisplayMode failed to readStrongBinder: %d", result); + return result; + } + ui::DisplayModeId displayModeId; + result = getPreferredBootDisplayMode(display, &displayModeId); + if (result == NO_ERROR) { + reply->writeInt32(displayModeId); + } + return result; + } case SET_AUTO_LOW_LATENCY_MODE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> display = nullptr; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6a4ddaea9d..b4f6cd513c 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -2075,6 +2075,25 @@ status_t SurfaceComposerClient::setActiveColorMode(const sp<IBinder>& display, return ComposerService::getComposerService()->setActiveColorMode(display, colorMode); } +status_t SurfaceComposerClient::getBootDisplayModeSupport(bool* support) { + return ComposerService::getComposerService()->getBootDisplayModeSupport(support); +} + +status_t SurfaceComposerClient::setBootDisplayMode(const sp<IBinder>& display, + ui::DisplayModeId displayModeId) { + return ComposerService::getComposerService()->setBootDisplayMode(display, displayModeId); +} + +status_t SurfaceComposerClient::clearBootDisplayMode(const sp<IBinder>& display) { + return ComposerService::getComposerService()->clearBootDisplayMode(display); +} + +status_t SurfaceComposerClient::getPreferredBootDisplayMode(const sp<IBinder>& display, + ui::DisplayModeId* displayModeId) { + return ComposerService::getComposerService()->getPreferredBootDisplayMode(display, + displayModeId); +} + void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) { ComposerService::getComposerService()->setAutoLowLatencyMode(display, on); } diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 69dce9d6ed..f37580c491 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -224,6 +224,35 @@ public: ui::ColorMode colorMode) = 0; /** + * Sets the user-preferred display mode that a device should boot in. + */ + virtual status_t setBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId) = 0; + + /** + * Clears the user-preferred display mode. The device should now boot in system preferred + * display mode. + */ + virtual status_t clearBootDisplayMode(const sp<IBinder>& display) = 0; + + /** + * Gets the display mode in which the device boots if there is no user-preferred display mode. + */ + virtual status_t getPreferredBootDisplayMode(const sp<IBinder>& display, + ui::DisplayModeId*) = 0; + + /** + * Gets whether boot time display mode operations are supported on the device. + * + * outSupport + * An output parameter for whether boot time display mode operations are supported. + * + * Returns NO_ERROR upon success. Otherwise, + * NAME_NOT_FOUND if the display is invalid, or + * BAD_VALUE if the output parameter is invalid. + */ + virtual status_t getBootDisplayModeSupport(bool* outSupport) const = 0; + + /** * Switches Auto Low Latency Mode on/off on the connected display, if it is * available. This should only be called if the display supports Auto Low * Latency Mode as reported in #getDynamicDisplayInfo. @@ -645,6 +674,10 @@ public: REMOVE_WINDOW_INFOS_LISTENER, GET_PRIMARY_PHYSICAL_DISPLAY_ID, GET_DISPLAY_DECORATION_SUPPORT, + GET_BOOT_DISPLAY_MODE_SUPPORT, + SET_BOOT_DISPLAY_MODE, + CLEAR_BOOT_DISPLAY_MODE, + GET_PREFERRED_BOOT_DISPLAY_MODE, // Always append new enum to the end. }; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 62758af2c0..c1923232df 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -167,6 +167,15 @@ public: static status_t setActiveColorMode(const sp<IBinder>& display, ui::ColorMode colorMode); + // Gets if boot display mode operations are supported on a device + static status_t getBootDisplayModeSupport(bool* support); + // Sets the user-preferred display mode that a device should boot in + static status_t setBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId); + // Clears the user-preferred display mode + static status_t clearBootDisplayMode(const sp<IBinder>& display); + // Gets the display mode in which the device boots if there is no user-preferred display mode + static status_t getPreferredBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId*); + // Switches on/off Auto Low Latency Mode on the connected display. This should only be // called if the connected display supports Auto Low Latency Mode as reported by // #getAutoLowLatencyModeSupport diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index d5e089aae0..999874bd05 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -755,6 +755,15 @@ public: } status_t setActiveColorMode(const sp<IBinder>& /*display*/, ColorMode /*colorMode*/) override { return NO_ERROR; } + status_t getBootDisplayModeSupport(bool* /*outSupport*/) const override { return NO_ERROR; } + status_t setBootDisplayMode(const sp<IBinder>& /*display*/, ui::DisplayModeId /*id*/) override { + return NO_ERROR; + } + status_t clearBootDisplayMode(const sp<IBinder>& /*display*/) override { return NO_ERROR; } + status_t getPreferredBootDisplayMode(const sp<IBinder>& /*display*/, + ui::DisplayModeId* /*id*/) override { + return NO_ERROR; + } void setAutoLowLatencyMode(const sp<IBinder>& /*display*/, bool /*on*/) override {} void setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {} diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h index dc5c5c8fcf..bd3022b425 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h @@ -106,6 +106,9 @@ public: status_t(PhysicalDisplayId, hal::HWConfigId, const hal::VsyncPeriodChangeConstraints&, hal::VsyncPeriodChangeTimeline*)); + MOCK_METHOD2(setBootDisplayMode, status_t(PhysicalDisplayId, hal::HWConfigId)); + MOCK_METHOD1(clearBootDisplayMode, status_t(PhysicalDisplayId)); + MOCK_METHOD1(getPreferredBootDisplayMode, hal::HWConfigId(PhysicalDisplayId)); MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool)); MOCK_METHOD2(getSupportedContentTypes, status_t(PhysicalDisplayId, std::vector<hal::ContentType>*)); @@ -124,6 +127,7 @@ public: (const, override)); MOCK_METHOD(std::optional<hal::HWDisplayId>, fromPhysicalDisplayId, (PhysicalDisplayId), (const, override)); + MOCK_METHOD(bool, getBootDisplayModeSupport, (), (override)); }; } // namespace mock diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp index 3c578bcd4d..1448e5644e 100644 --- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp @@ -237,6 +237,7 @@ bool AidlComposer::isSupported(OptionalFeature feature) const { case OptionalFeature::RefreshRateSwitching: case OptionalFeature::ExpectedPresentTime: case OptionalFeature::DisplayBrightnessCommand: + case OptionalFeature::BootDisplayConfig: return true; } } @@ -1009,6 +1010,38 @@ V2_4::Error AidlComposer::getLayerGenericMetadataKeys( return V2_4::Error::UNSUPPORTED; } +Error AidlComposer::setBootDisplayConfig(Display display, Config config) { + const auto status = mAidlComposerClient->setBootDisplayConfig(translate<int64_t>(display), + translate<int32_t>(config)); + if (!status.isOk()) { + ALOGE("setBootDisplayConfig failed %s", status.getDescription().c_str()); + return static_cast<Error>(status.getServiceSpecificError()); + } + return Error::NONE; +} + +Error AidlComposer::clearBootDisplayConfig(Display display) { + const auto status = mAidlComposerClient->clearBootDisplayConfig(translate<int64_t>(display)); + if (!status.isOk()) { + ALOGE("clearBootDisplayConfig failed %s", status.getDescription().c_str()); + return static_cast<Error>(status.getServiceSpecificError()); + } + return Error::NONE; +} + +Error AidlComposer::getPreferredBootDisplayConfig(Display display, Config* config) { + int32_t displayConfig; + const auto status = + mAidlComposerClient->getPreferredBootDisplayConfig(translate<int64_t>(display), + &displayConfig); + if (!status.isOk()) { + ALOGE("getPreferredBootDisplayConfig failed %s", status.getDescription().c_str()); + return static_cast<Error>(status.getServiceSpecificError()); + } + *config = translate<uint32_t>(displayConfig); + return Error::NONE; +} + Error AidlComposer::getClientTargetProperty( Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty, float* whitePointNits) { diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h index cdd16e2cba..677001700a 100644 --- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h @@ -213,6 +213,9 @@ public: Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override; Error setLayerBlockingRegion(Display display, Layer layer, const std::vector<IComposerClient::Rect>& blocking) override; + Error setBootDisplayConfig(Display displayId, Config) override; + Error clearBootDisplayConfig(Display displayId) override; + Error getPreferredBootDisplayConfig(Display displayId, Config*) override; private: // Many public functions above simply write a command into the command diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index bb4b7843d6..22f424fd4a 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -81,6 +81,7 @@ public: ExpectedPresentTime, // Whether setDisplayBrightness is able to be applied as part of a display command. DisplayBrightnessCommand, + BootDisplayConfig, }; virtual bool isSupported(OptionalFeature) const = 0; @@ -248,6 +249,7 @@ public: const std::vector<uint8_t>& value) = 0; virtual V2_4::Error getLayerGenericMetadataKeys( std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0; + virtual Error getClientTargetProperty( Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty, float* outWhitePointNits) = 0; @@ -256,6 +258,9 @@ public: virtual Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) = 0; virtual Error setLayerBlockingRegion(Display display, Layer layer, const std::vector<IComposerClient::Rect>& blocking) = 0; + virtual Error setBootDisplayConfig(Display displayId, Config) = 0; + virtual Error clearBootDisplayConfig(Display displayId) = 0; + virtual Error getPreferredBootDisplayConfig(Display displayId, Config*) = 0; }; } // namespace android::Hwc2 diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 34f2e76405..05e3aefac4 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -539,6 +539,21 @@ std::future<Error> Display::setDisplayBrightness( }); } +Error Display::setBootDisplayConfig(hal::HWConfigId configId) { + auto intError = mComposer.setBootDisplayConfig(mId, configId); + return static_cast<Error>(intError); +} + +Error Display::clearBootDisplayConfig() { + auto intError = mComposer.clearBootDisplayConfig(mId); + return static_cast<Error>(intError); +} + +Error Display::getPreferredBootDisplayConfig(hal::HWConfigId* configId) const { + auto intError = mComposer.getPreferredBootDisplayConfig(mId, configId); + return static_cast<Error>(intError); +} + Error Display::setAutoLowLatencyMode(bool on) { auto intError = mComposer.setAutoLowLatencyMode(mId, on); return static_cast<Error>(intError); diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 01a482dfac..57eb12875b 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -149,6 +149,11 @@ public: [[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints( hal::HWConfigId configId, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) = 0; + [[clang::warn_unused_result]] virtual hal::Error setBootDisplayConfig( + hal::HWConfigId configId) = 0; + [[clang::warn_unused_result]] virtual hal::Error clearBootDisplayConfig() = 0; + [[clang::warn_unused_result]] virtual hal::Error getPreferredBootDisplayConfig( + hal::HWConfigId* configId) const = 0; [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0; [[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes( std::vector<hal::ContentType>*) const = 0; @@ -218,6 +223,9 @@ public: hal::Error setActiveConfigWithConstraints(hal::HWConfigId configId, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) override; + hal::Error setBootDisplayConfig(hal::HWConfigId configId) override; + hal::Error clearBootDisplayConfig() override; + hal::Error getPreferredBootDisplayConfig(hal::HWConfigId* configId) const override; hal::Error setAutoLowLatencyMode(bool on) override; hal::Error getSupportedContentTypes( std::vector<hal::ContentType>* outSupportedContentTypes) const override; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 057db46104..44e45973a1 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -801,6 +801,52 @@ std::future<status_t> HWComposer::setDisplayBrightness( }); } +bool HWComposer::getBootDisplayModeSupport() { + return mComposer->isSupported(Hwc2::Composer::OptionalFeature::BootDisplayConfig); +} + +status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId, + hal::HWConfigId displayModeId) { + RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); + const auto error = mDisplayData[displayId].hwcDisplay->setBootDisplayConfig(displayModeId); + if (error == hal::Error::UNSUPPORTED) { + RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION); + } + if (error == hal::Error::BAD_PARAMETER) { + RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE); + } + RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); + return NO_ERROR; +} + +status_t HWComposer::clearBootDisplayMode(PhysicalDisplayId displayId) { + RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); + const auto error = mDisplayData[displayId].hwcDisplay->clearBootDisplayConfig(); + if (error == hal::Error::UNSUPPORTED) { + RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION); + } + if (error == hal::Error::BAD_PARAMETER) { + RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE); + } + RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); + return NO_ERROR; +} + +hal::HWConfigId HWComposer::getPreferredBootDisplayMode(PhysicalDisplayId displayId) { + RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); + hal::HWConfigId displayModeId = -1; + const auto error = + mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId); + if (error == hal::Error::UNSUPPORTED) { + RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION); + } + if (error == hal::Error::BAD_PARAMETER) { + RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE); + } + RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); + return displayModeId; +} + status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) { RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 4fae06d4d8..9e57602e60 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -255,6 +255,12 @@ public: virtual std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const = 0; virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const = 0; + + // Composer 3.0 + virtual bool getBootDisplayModeSupport() = 0; + virtual status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) = 0; + virtual status_t clearBootDisplayMode(PhysicalDisplayId) = 0; + virtual hal::HWConfigId getPreferredBootDisplayMode(PhysicalDisplayId) = 0; }; namespace impl { @@ -381,6 +387,12 @@ public: const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override; + // Composer 3.0 + bool getBootDisplayModeSupport() override; + status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) override; + status_t clearBootDisplayMode(PhysicalDisplayId) override; + hal::HWConfigId getPreferredBootDisplayMode(PhysicalDisplayId) override; + // for debugging ---------------------------------------------------------- void dump(std::string& out) const override; diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp index 0ab1cfb690..d3acecb46c 100644 --- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp @@ -162,6 +162,7 @@ bool HidlComposer::isSupported(OptionalFeature feature) const { return mClient_2_4 != nullptr; case OptionalFeature::ExpectedPresentTime: case OptionalFeature::DisplayBrightnessCommand: + case OptionalFeature::BootDisplayConfig: return false; } } @@ -1216,6 +1217,18 @@ V2_4::Error HidlComposer::getLayerGenericMetadataKeys( return error; } +Error HidlComposer::setBootDisplayConfig(Display /*displayId*/, Config) { + return Error::UNSUPPORTED; +} + +Error HidlComposer::clearBootDisplayConfig(Display /*displayId*/) { + return Error::UNSUPPORTED; +} + +Error HidlComposer::getPreferredBootDisplayConfig(Display /*displayId*/, Config*) { + return Error::UNSUPPORTED; +} + Error HidlComposer::getClientTargetProperty( Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty, float* outWhitePointNits) { diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h index 8282d8afb0..c8c780039e 100644 --- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h @@ -323,6 +323,9 @@ public: Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override; Error setLayerBlockingRegion(Display display, Layer layer, const std::vector<IComposerClient::Rect>& blocking) override; + Error setBootDisplayConfig(Display displayId, Config) override; + Error clearBootDisplayConfig(Display displayId) override; + Error getPreferredBootDisplayConfig(Display displayId, Config*) override; private: class CommandWriter : public CommandWriterBase { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index f8c7aec216..51cb409235 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1426,6 +1426,52 @@ status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, Col return NO_ERROR; } +status_t SurfaceFlinger::getBootDisplayModeSupport(bool* outSupport) const { + auto future = mScheduler->schedule([=]() MAIN_THREAD mutable -> status_t { + *outSupport = getHwComposer().getBootDisplayModeSupport(); + return NO_ERROR; + }); + return future.get(); +} + +status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) { + auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t { + if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { + return getHwComposer().setBootDisplayMode(*displayId, id); + } else { + ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get()); + return BAD_VALUE; + } + }); + return future.get(); +} + +status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) { + auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t { + if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { + return getHwComposer().clearBootDisplayMode(*displayId); + } else { + ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get()); + return BAD_VALUE; + } + }); + return future.get(); +} + +status_t SurfaceFlinger::getPreferredBootDisplayMode(const sp<IBinder>& displayToken, + ui::DisplayModeId* id) { + auto future = mScheduler->schedule([=]() MAIN_THREAD mutable -> status_t { + if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { + *id = getHwComposer().getPreferredBootDisplayMode(*displayId); + return NO_ERROR; + } else { + ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get()); + return BAD_VALUE; + } + }); + return future.get(); +} + void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) { const char* const whence = __func__; static_cast<void>(mScheduler->schedule([=]() MAIN_THREAD { @@ -5404,6 +5450,10 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case SET_DESIRED_DISPLAY_MODE_SPECS: case GET_DESIRED_DISPLAY_MODE_SPECS: case SET_ACTIVE_COLOR_MODE: + case GET_BOOT_DISPLAY_MODE_SUPPORT: + case SET_BOOT_DISPLAY_MODE: + case CLEAR_BOOT_DISPLAY_MODE: + case GET_PREFERRED_BOOT_DISPLAY_MODE: case GET_AUTO_LOW_LATENCY_MODE_SUPPORT: case SET_AUTO_LOW_LATENCY_MODE: case GET_GAME_CONTENT_TYPE_SUPPORT: diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 61cfb4e71a..08d3463d7d 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -531,6 +531,11 @@ private: status_t getDisplayNativePrimaries(const sp<IBinder>& displayToken, ui::DisplayPrimaries&) override; status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode) override; + status_t getBootDisplayModeSupport(bool* outSupport) const override; + status_t setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) override; + status_t clearBootDisplayMode(const sp<IBinder>& displayToken) override; + status_t getPreferredBootDisplayMode(const sp<IBinder>& displayToken, + ui::DisplayModeId* id) override; void setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) override; void setGameContentType(const sp<IBinder>& displayToken, bool on) override; void setPowerMode(const sp<IBinder>& displayToken, int mode) override; diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index ecdadf7ca8..4273401bc7 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -135,6 +135,10 @@ public: V2_4::Error(Display, Config, const IComposerClient::VsyncPeriodChangeConstraints&, VsyncPeriodChangeTimeline*)); MOCK_METHOD2(setAutoLowLatencyMode, V2_4::Error(Display, bool)); + MOCK_METHOD2(getBootDisplayConfigSupport, Error(Display, bool*)); + MOCK_METHOD2(setBootDisplayConfig, Error(Display, Config)); + MOCK_METHOD1(clearBootDisplayConfig, Error(Display)); + MOCK_METHOD2(getPreferredBootDisplayConfig, Error(Display, Config*)); MOCK_METHOD2(getSupportedContentTypes, V2_4::Error(Display, std::vector<IComposerClient::ContentType>*)); MOCK_METHOD2(setContentType, V2_4::Error(Display, IComposerClient::ContentType)); diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h index 7ac0c78dea..9015944f36 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h @@ -86,6 +86,9 @@ public: (hal::HWConfigId, const hal::VsyncPeriodChangeConstraints &, hal::VsyncPeriodChangeTimeline *), (override)); + MOCK_METHOD(hal::Error, setBootDisplayConfig, (hal::HWConfigId), (override)); + MOCK_METHOD(hal::Error, clearBootDisplayConfig, (), (override)); + MOCK_METHOD(hal::Error, getPreferredBootDisplayConfig, (hal::HWConfigId *), (const, override)); MOCK_METHOD(hal::Error, setAutoLowLatencyMode, (bool), (override)); MOCK_METHOD(hal::Error, getSupportedContentTypes, (std::vector<hal::ContentType> *), (const, override)); |