diff options
author | Kaiyi Li <kaiyili@google.com> | 2024-01-24 19:22:14 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-01-24 19:22:14 +0000 |
commit | 121ca7be9a0224e8f1fc6fb4d989458363662047 (patch) | |
tree | 752d6057243c9a1889ecd2fea72439fd1e3c33fa | |
parent | b620da79528efa3667dc9814fe4d8f7dfabc40dc (diff) | |
parent | 32fc2c7b201d9d7072755af736bde68a1f6ce979 (diff) | |
download | goldfish-opengl-121ca7be9a0224e8f1fc6fb4d989458363662047.tar.gz |
Reformat hwc3 am: 32fc2c7b20
Original change: https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/2907560
Change-Id: I83f9be08f35807da973f742fefe6caebe6fae90b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
39 files changed, 5110 insertions, 5502 deletions
diff --git a/system/hwc3/ClientFrameComposer.cpp b/system/hwc3/ClientFrameComposer.cpp index bccfa69d..10c6ce89 100644 --- a/system/hwc3/ClientFrameComposer.cpp +++ b/system/hwc3/ClientFrameComposer.cpp @@ -34,134 +34,127 @@ namespace aidl::android::hardware::graphics::composer3::impl { HWC3::Error ClientFrameComposer::init() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - HWC3::Error error = mDrmClient.init(); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to initialize DrmClient", __FUNCTION__); - return error; - } + HWC3::Error error = mDrmClient.init(); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to initialize DrmClient", __FUNCTION__); + return error; + } - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error ClientFrameComposer::registerOnHotplugCallback( - const HotplugCallback& cb) { - return mDrmClient.registerOnHotplugCallback(cb); - return HWC3::Error::None; +HWC3::Error ClientFrameComposer::registerOnHotplugCallback(const HotplugCallback& cb) { + return mDrmClient.registerOnHotplugCallback(cb); + return HWC3::Error::None; } HWC3::Error ClientFrameComposer::unregisterOnHotplugCallback() { - return mDrmClient.unregisterOnHotplugCallback(); + return mDrmClient.unregisterOnHotplugCallback(); } HWC3::Error ClientFrameComposer::onDisplayCreate(Display* display) { - const auto displayId = display->getId(); - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); + const auto displayId = display->getId(); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - // Ensure created. - mDisplayInfos.emplace(displayId, DisplayInfo{}); + // Ensure created. + mDisplayInfos.emplace(displayId, DisplayInfo{}); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error ClientFrameComposer::onDisplayDestroy(Display* display) { - const auto displayId = display->getId(); - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); + const auto displayId = display->getId(); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - auto it = mDisplayInfos.find(displayId); - if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, - displayId); - return HWC3::Error::BadDisplay; - } + auto it = mDisplayInfos.find(displayId); + if (it == mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; + } - mDisplayInfos.erase(it); + mDisplayInfos.erase(it); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error ClientFrameComposer::onDisplayClientTargetSet(Display* display) { - const auto displayId = display->getId(); - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - - auto it = mDisplayInfos.find(displayId); - if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, - displayId); - return HWC3::Error::BadDisplay; - } - - DisplayInfo& displayInfo = it->second; - - auto [drmBufferCreateError, drmBuffer] = - mDrmClient.create(display->getClientTarget().getBuffer()); - if (drmBufferCreateError != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer", - __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - displayInfo.clientTargetDrmBuffer = std::move(drmBuffer); - - return HWC3::Error::None; + const auto displayId = display->getId(); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); + + auto it = mDisplayInfos.find(displayId); + if (it == mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; + } + + DisplayInfo& displayInfo = it->second; + + auto [drmBufferCreateError, drmBuffer] = + mDrmClient.create(display->getClientTarget().getBuffer()); + if (drmBufferCreateError != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer", __FUNCTION__, + displayId); + return HWC3::Error::NoResources; + } + displayInfo.clientTargetDrmBuffer = std::move(drmBuffer); + + return HWC3::Error::None; } HWC3::Error ClientFrameComposer::onActiveConfigChange(Display* /*display*/) { - return HWC3::Error::None; + return HWC3::Error::None; }; -HWC3::Error ClientFrameComposer::validateDisplay(Display* display, - DisplayChanges* outChanges) { - const auto displayId = display->getId(); - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); +HWC3::Error ClientFrameComposer::validateDisplay(Display* display, DisplayChanges* outChanges) { + const auto displayId = display->getId(); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - const std::vector<Layer*>& layers = display->getOrderedLayers(); + const std::vector<Layer*>& layers = display->getOrderedLayers(); - for (Layer* layer : layers) { - const auto layerId = layer->getId(); - const auto layerCompositionType = layer->getCompositionType(); + for (Layer* layer : layers) { + const auto layerId = layer->getId(); + const auto layerCompositionType = layer->getCompositionType(); - if (layerCompositionType != Composition::CLIENT) { - outChanges->addLayerCompositionChange(displayId, layerId, Composition::CLIENT); - continue; + if (layerCompositionType != Composition::CLIENT) { + outChanges->addLayerCompositionChange(displayId, layerId, Composition::CLIENT); + continue; + } } - } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error ClientFrameComposer::presentDisplay( Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, - ::android::base::unique_fd>* /*outLayerFences*/) { - const auto displayId = display->getId(); - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - - auto displayInfoIt = mDisplayInfos.find(displayId); - if (displayInfoIt == mDisplayInfos.end()) { - ALOGE("%s: failed to find display buffers for display:%" PRIu64, - __FUNCTION__, displayId); - return HWC3::Error::BadDisplay; - } - - DisplayInfo& displayInfo = displayInfoIt->second; - if (!displayInfo.clientTargetDrmBuffer) { - ALOGW("%s: display:%" PRIu64 " no client target set, nothing to present.", - __FUNCTION__, displayId); - return HWC3::Error::None; - } + std::unordered_map<int64_t, ::android::base::unique_fd>* /*outLayerFences*/) { + const auto displayId = display->getId(); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); + + auto displayInfoIt = mDisplayInfos.find(displayId); + if (displayInfoIt == mDisplayInfos.end()) { + ALOGE("%s: failed to find display buffers for display:%" PRIu64, __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; + } - ::android::base::unique_fd fence = display->getClientTarget().getFence(); + DisplayInfo& displayInfo = displayInfoIt->second; + if (!displayInfo.clientTargetDrmBuffer) { + ALOGW("%s: display:%" PRIu64 " no client target set, nothing to present.", __FUNCTION__, + displayId); + return HWC3::Error::None; + } - auto [flushError, flushCompleteFence] = mDrmClient.flushToDisplay( - static_cast<uint32_t>(displayId), displayInfo.clientTargetDrmBuffer, fence); - if (flushError != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to flush drm buffer" PRIu64, - __FUNCTION__, displayId); - } + ::android::base::unique_fd fence = display->getClientTarget().getFence(); + + auto [flushError, flushCompleteFence] = mDrmClient.flushToDisplay( + static_cast<uint32_t>(displayId), displayInfo.clientTargetDrmBuffer, fence); + if (flushError != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to flush drm buffer" PRIu64, __FUNCTION__, displayId); + } - *outDisplayFence = std::move(flushCompleteFence); - return flushError; + *outDisplayFence = std::move(flushCompleteFence); + return flushError; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/ClientFrameComposer.h b/system/hwc3/ClientFrameComposer.h index 87988072..18603505 100644 --- a/system/hwc3/ClientFrameComposer.h +++ b/system/hwc3/ClientFrameComposer.h @@ -29,53 +29,49 @@ namespace aidl::android::hardware::graphics::composer3::impl { // A frame composer which always fallsback to client composition // (a.k.a make SurfaceFlinger do the composition). class ClientFrameComposer : public FrameComposer { - public: - ClientFrameComposer() = default; + public: + ClientFrameComposer() = default; - ClientFrameComposer(const ClientFrameComposer&) = delete; - ClientFrameComposer& operator=(const ClientFrameComposer&) = delete; + ClientFrameComposer(const ClientFrameComposer&) = delete; + ClientFrameComposer& operator=(const ClientFrameComposer&) = delete; - ClientFrameComposer(ClientFrameComposer&&) = delete; - ClientFrameComposer& operator=(ClientFrameComposer&&) = delete; + ClientFrameComposer(ClientFrameComposer&&) = delete; + ClientFrameComposer& operator=(ClientFrameComposer&&) = delete; - HWC3::Error init() override; + HWC3::Error init() override; - HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; + HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; - HWC3::Error unregisterOnHotplugCallback() override; + HWC3::Error unregisterOnHotplugCallback() override; - HWC3::Error onDisplayCreate(Display* display) override; + HWC3::Error onDisplayCreate(Display* display) override; - HWC3::Error onDisplayDestroy(Display* display) override; + HWC3::Error onDisplayDestroy(Display* display) override; - HWC3::Error onDisplayClientTargetSet(Display* display) override; + HWC3::Error onDisplayClientTargetSet(Display* display) override; - HWC3::Error onActiveConfigChange(Display* display) override; + HWC3::Error onActiveConfigChange(Display* display) override; - // Determines if this composer can compose the given layers on the given - // display and requests changes for layers that can't not be composed. - HWC3::Error validateDisplay(Display* display, - DisplayChanges* outChanges) override; + // Determines if this composer can compose the given layers on the given + // display and requests changes for layers that can't not be composed. + HWC3::Error validateDisplay(Display* display, DisplayChanges* outChanges) override; - // Performs the actual composition of layers and presents the composed result - // to the display. - HWC3::Error presentDisplay( - Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) - override; + // Performs the actual composition of layers and presents the composed result + // to the display. + HWC3::Error presentDisplay( + Display* display, ::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) override; - const DrmClient* getDrmPresenter() const override { - return &mDrmClient; - } + const DrmClient* getDrmPresenter() const override { return &mDrmClient; } - private: - struct DisplayInfo { - std::shared_ptr<DrmBuffer> clientTargetDrmBuffer; - }; + private: + struct DisplayInfo { + std::shared_ptr<DrmBuffer> clientTargetDrmBuffer; + }; - std::unordered_map<int64_t, DisplayInfo> mDisplayInfos; + std::unordered_map<int64_t, DisplayInfo> mDisplayInfos; - DrmClient mDrmClient; + DrmClient mDrmClient; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Common.cpp b/system/hwc3/Common.cpp index edbe93ce..7ee26572 100644 --- a/system/hwc3/Common.cpp +++ b/system/hwc3/Common.cpp @@ -21,79 +21,75 @@ namespace aidl::android::hardware::graphics::composer3::impl { bool IsAutoDevice() { - // gcar_emu_x86_64, sdk_car_md_x86_64, cf_x86_64_auto, cf_x86_64_only_auto_md - const std::string product_name = ::android::base::GetProperty("ro.product.name", ""); - return product_name.find("car_") || product_name.find("_auto"); + // gcar_emu_x86_64, sdk_car_md_x86_64, cf_x86_64_auto, cf_x86_64_only_auto_md + const std::string product_name = ::android::base::GetProperty("ro.product.name", ""); + return product_name.find("car_") || product_name.find("_auto"); } -bool IsCuttlefish() { - return ::android::base::GetProperty("ro.product.board", "") == "cutf"; -} +bool IsCuttlefish() { return ::android::base::GetProperty("ro.product.board", "") == "cutf"; } bool IsCuttlefishFoldable() { - return IsCuttlefish() && - ::android::base::GetProperty("ro.product.name", "").find("foldable") != - std::string::npos; + return IsCuttlefish() && ::android::base::GetProperty("ro.product.name", "").find("foldable") != + std::string::npos; } - bool IsInNoOpCompositionMode() { - const std::string mode = ::android::base::GetProperty("ro.vendor.hwcomposer.mode", ""); - DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.mode is %s", __FUNCTION__, mode.c_str()); - return mode == "noop"; + const std::string mode = ::android::base::GetProperty("ro.vendor.hwcomposer.mode", ""); + DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.mode is %s", __FUNCTION__, mode.c_str()); + return mode == "noop"; } bool IsInClientCompositionMode() { - const std::string mode = ::android::base::GetProperty("ro.vendor.hwcomposer.mode", ""); - DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.mode is %s", __FUNCTION__, mode.c_str()); - return mode == "client"; + const std::string mode = ::android::base::GetProperty("ro.vendor.hwcomposer.mode", ""); + DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.mode is %s", __FUNCTION__, mode.c_str()); + return mode == "client"; } bool IsInGem5DisplayFinderMode() { - const std::string mode = - ::android::base::GetProperty("ro.vendor.hwcomposer.display_finder_mode", ""); - DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.display_finder_mode is %s", - __FUNCTION__, mode.c_str()); - return mode == "gem5"; + const std::string mode = + ::android::base::GetProperty("ro.vendor.hwcomposer.display_finder_mode", ""); + DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.display_finder_mode is %s", __FUNCTION__, + mode.c_str()); + return mode == "gem5"; } bool IsInNoOpDisplayFinderMode() { - const std::string mode = - ::android::base::GetProperty("ro.vendor.hwcomposer.display_finder_mode", ""); - DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.display_finder_mode is %s", - __FUNCTION__, mode.c_str()); - return mode == "noop"; + const std::string mode = + ::android::base::GetProperty("ro.vendor.hwcomposer.display_finder_mode", ""); + DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.display_finder_mode is %s", __FUNCTION__, + mode.c_str()); + return mode == "noop"; } bool IsInDrmDisplayFinderMode() { - const std::string mode = - ::android::base::GetProperty("ro.vendor.hwcomposer.display_finder_mode", ""); - DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.display_finder_mode is %s", - __FUNCTION__, mode.c_str()); - return mode == "drm"; + const std::string mode = + ::android::base::GetProperty("ro.vendor.hwcomposer.display_finder_mode", ""); + DEBUG_LOG("%s: sysprop ro.vendor.hwcomposer.display_finder_mode is %s", __FUNCTION__, + mode.c_str()); + return mode == "drm"; } std::string toString(HWC3::Error error) { - switch (error) { - case HWC3::Error::None: - return "None"; - case HWC3::Error::BadConfig: - return "BadConfig"; - case HWC3::Error::BadDisplay: - return "BadDisplay"; - case HWC3::Error::BadLayer: - return "BadLayer"; - case HWC3::Error::BadParameter: - return "BadParameter"; - case HWC3::Error::NoResources: - return "NoResources"; - case HWC3::Error::NotValidated: - return "NotValidated"; - case HWC3::Error::Unsupported: - return "Unsupported"; - case HWC3::Error::SeamlessNotAllowed: - return "SeamlessNotAllowed"; - } + switch (error) { + case HWC3::Error::None: + return "None"; + case HWC3::Error::BadConfig: + return "BadConfig"; + case HWC3::Error::BadDisplay: + return "BadDisplay"; + case HWC3::Error::BadLayer: + return "BadLayer"; + case HWC3::Error::BadParameter: + return "BadParameter"; + case HWC3::Error::NoResources: + return "NoResources"; + case HWC3::Error::NotValidated: + return "NotValidated"; + case HWC3::Error::Unsupported: + return "Unsupported"; + case HWC3::Error::SeamlessNotAllowed: + return "SeamlessNotAllowed"; + } } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Common.h b/system/hwc3/Common.h index bca365b8..b4109e6e 100644 --- a/system/hwc3/Common.h +++ b/system/hwc3/Common.h @@ -32,7 +32,7 @@ #include <utils/Trace.h> // Uncomment to enable additional debug logging. -//#define DEBUG_RANCHU_HWC +// #define DEBUG_RANCHU_HWC #if defined(DEBUG_RANCHU_HWC) #define DEBUG_LOG ALOGE @@ -55,34 +55,26 @@ bool IsInDrmDisplayFinderMode(); namespace HWC3 { enum class Error : int32_t { - None = 0, - BadConfig = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_BAD_CONFIG, - BadDisplay = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_BAD_DISPLAY, - BadLayer = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_BAD_LAYER, - BadParameter = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_BAD_PARAMETER, - NoResources = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_NO_RESOURCES, - NotValidated = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_NOT_VALIDATED, - Unsupported = aidl::android::hardware::graphics::composer3::IComposerClient:: - EX_UNSUPPORTED, - SeamlessNotAllowed = aidl::android::hardware::graphics::composer3:: - IComposerClient::EX_SEAMLESS_NOT_ALLOWED, + None = 0, + BadConfig = aidl::android::hardware::graphics::composer3::IComposerClient::EX_BAD_CONFIG, + BadDisplay = aidl::android::hardware::graphics::composer3::IComposerClient::EX_BAD_DISPLAY, + BadLayer = aidl::android::hardware::graphics::composer3::IComposerClient::EX_BAD_LAYER, + BadParameter = aidl::android::hardware::graphics::composer3::IComposerClient::EX_BAD_PARAMETER, + NoResources = aidl::android::hardware::graphics::composer3::IComposerClient::EX_NO_RESOURCES, + NotValidated = aidl::android::hardware::graphics::composer3::IComposerClient::EX_NOT_VALIDATED, + Unsupported = aidl::android::hardware::graphics::composer3::IComposerClient::EX_UNSUPPORTED, + SeamlessNotAllowed = + aidl::android::hardware::graphics::composer3::IComposerClient::EX_SEAMLESS_NOT_ALLOWED, }; } // namespace HWC3 std::string toString(HWC3::Error error); inline ndk::ScopedAStatus ToBinderStatus(HWC3::Error error) { - if (error != HWC3::Error::None) { - return ndk::ScopedAStatus::fromServiceSpecificError( - static_cast<int32_t>(error)); - } - return ndk::ScopedAStatus::ok(); + if (error != HWC3::Error::None) { + return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(error)); + } + return ndk::ScopedAStatus::ok(); } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Composer.cpp b/system/hwc3/Composer.cpp index b2a1b7e8..aa70b3b1 100644 --- a/system/hwc3/Composer.cpp +++ b/system/hwc3/Composer.cpp @@ -23,93 +23,90 @@ namespace aidl::android::hardware::graphics::composer3::impl { -ndk::ScopedAStatus Composer::createClient( - std::shared_ptr<IComposerClient>* outClient) { - DEBUG_LOG("%s", __FUNCTION__); - - std::unique_lock<std::mutex> lock(mClientMutex); - - const bool previousClientDestroyed = waitForClientDestroyedLocked(lock); - if (!previousClientDestroyed) { - ALOGE("%s: failed as composer client already exists", __FUNCTION__); - *outClient = nullptr; - return ToBinderStatus(HWC3::Error::NoResources); - } - - auto client = ndk::SharedRefBase::make<ComposerClient>(); - if (!client) { - ALOGE("%s: failed to init composer client", __FUNCTION__); - *outClient = nullptr; - return ToBinderStatus(HWC3::Error::NoResources); - } - - auto error = client->init(); - if (error != HWC3::Error::None) { - *outClient = nullptr; - return ToBinderStatus(error); - } - - auto clientDestroyed = [this]() { onClientDestroyed(); }; - client->setOnClientDestroyed(clientDestroyed); - - mClient = client; - *outClient = client; - - return ndk::ScopedAStatus::ok(); +ndk::ScopedAStatus Composer::createClient(std::shared_ptr<IComposerClient>* outClient) { + DEBUG_LOG("%s", __FUNCTION__); + + std::unique_lock<std::mutex> lock(mClientMutex); + + const bool previousClientDestroyed = waitForClientDestroyedLocked(lock); + if (!previousClientDestroyed) { + ALOGE("%s: failed as composer client already exists", __FUNCTION__); + *outClient = nullptr; + return ToBinderStatus(HWC3::Error::NoResources); + } + + auto client = ndk::SharedRefBase::make<ComposerClient>(); + if (!client) { + ALOGE("%s: failed to init composer client", __FUNCTION__); + *outClient = nullptr; + return ToBinderStatus(HWC3::Error::NoResources); + } + + auto error = client->init(); + if (error != HWC3::Error::None) { + *outClient = nullptr; + return ToBinderStatus(error); + } + + auto clientDestroyed = [this]() { onClientDestroyed(); }; + client->setOnClientDestroyed(clientDestroyed); + + mClient = client; + *outClient = client; + + return ndk::ScopedAStatus::ok(); } -bool Composer::waitForClientDestroyedLocked( - std::unique_lock<std::mutex>& lock) { - if (!mClient.expired()) { - // In surface flinger we delete a composer client on one thread and - // then create a new client on another thread. Although surface - // flinger ensures the calls are made in that sequence (destroy and - // then create), sometimes the calls land in the composer service - // inverted (create and then destroy). Wait for a brief period to - // see if the existing client is destroyed. - constexpr const auto kTimeout = std::chrono::seconds(5); - mClientDestroyedCondition.wait_for( - lock, kTimeout, [this]() -> bool { return mClient.expired(); }); +bool Composer::waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock) { if (!mClient.expired()) { - ALOGW("%s: previous client was not destroyed", __FUNCTION__); + // In surface flinger we delete a composer client on one thread and + // then create a new client on another thread. Although surface + // flinger ensures the calls are made in that sequence (destroy and + // then create), sometimes the calls land in the composer service + // inverted (create and then destroy). Wait for a brief period to + // see if the existing client is destroyed. + constexpr const auto kTimeout = std::chrono::seconds(5); + mClientDestroyedCondition.wait_for(lock, kTimeout, + [this]() -> bool { return mClient.expired(); }); + if (!mClient.expired()) { + ALOGW("%s: previous client was not destroyed", __FUNCTION__); + } } - } - return mClient.expired(); + return mClient.expired(); } void Composer::onClientDestroyed() { - std::lock_guard<std::mutex> lock(mClientMutex); + std::lock_guard<std::mutex> lock(mClientMutex); - mClientDestroyedCondition.notify_all(); + mClientDestroyedCondition.notify_all(); } -binder_status_t Composer::dump(int fd, const char** /*args*/, - uint32_t /*numArgs*/) { - DEBUG_LOG("%s", __FUNCTION__); +binder_status_t Composer::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) { + DEBUG_LOG("%s", __FUNCTION__); - std::string output("TODO"); + std::string output("TODO"); - write(fd, output.c_str(), output.size()); - return STATUS_OK; + write(fd, output.c_str(), output.size()); + return STATUS_OK; } ndk::ScopedAStatus Composer::getCapabilities(std::vector<Capability>* caps) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - caps->clear(); - caps->emplace_back(Capability::PRESENT_FENCE_IS_NOT_RELIABLE); - caps->emplace_back(Capability::BOOT_DISPLAY_CONFIG); + caps->clear(); + caps->emplace_back(Capability::PRESENT_FENCE_IS_NOT_RELIABLE); + caps->emplace_back(Capability::BOOT_DISPLAY_CONFIG); - return ndk::ScopedAStatus::ok(); + return ndk::ScopedAStatus::ok(); } ::ndk::SpAIBinder Composer::createBinder() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto binder = BnComposer::createBinder(); - AIBinder_setInheritRt(binder.get(), true); - return binder; + auto binder = BnComposer::createBinder(); + AIBinder_setInheritRt(binder.get(), true); + return binder; } } // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file diff --git a/system/hwc3/Composer.h b/system/hwc3/Composer.h index f5641696..e46e951a 100644 --- a/system/hwc3/Composer.h +++ b/system/hwc3/Composer.h @@ -28,26 +28,25 @@ namespace aidl::android::hardware::graphics::composer3::impl { // This class is basically just the interface to create a client. class Composer : public BnComposer { - public: - Composer() = default; + public: + Composer() = default; - binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; + binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; - // compser3 api - ndk::ScopedAStatus createClient( - std::shared_ptr<IComposerClient>* client) override; - ndk::ScopedAStatus getCapabilities(std::vector<Capability>* caps) override; + // compser3 api + ndk::ScopedAStatus createClient(std::shared_ptr<IComposerClient>* client) override; + ndk::ScopedAStatus getCapabilities(std::vector<Capability>* caps) override; - protected: - ndk::SpAIBinder createBinder() override; + protected: + ndk::SpAIBinder createBinder() override; - private: - bool waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock); - void onClientDestroyed(); + private: + bool waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock); + void onClientDestroyed(); - std::mutex mClientMutex; - std::weak_ptr<ComposerClient> mClient GUARDED_BY(mClientMutex); - std::condition_variable mClientDestroyedCondition; + std::mutex mClientMutex; + std::weak_ptr<ComposerClient> mClient GUARDED_BY(mClientMutex); + std::condition_variable mClientDestroyedCondition; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/ComposerClient.cpp b/system/hwc3/ComposerClient.cpp index 16d8eb1a..a7e0247f 100644 --- a/system/hwc3/ComposerClient.cpp +++ b/system/hwc3/ComposerClient.cpp @@ -27,724 +27,693 @@ namespace aidl::android::hardware::graphics::composer3::impl { namespace { -#define GET_DISPLAY_OR_RETURN_ERROR() \ - Display* display = getDisplay(displayId); \ - if (display == nullptr) { \ - ALOGE("%s failed to get display:%" PRIu64, __FUNCTION__, displayId); \ - return ToBinderStatus(HWC3::Error::BadDisplay); \ - } +#define GET_DISPLAY_OR_RETURN_ERROR() \ + Display* display = getDisplay(displayId); \ + if (display == nullptr) { \ + ALOGE("%s failed to get display:%" PRIu64, __FUNCTION__, displayId); \ + return ToBinderStatus(HWC3::Error::BadDisplay); \ + } } // namespace using ::aidl::android::hardware::graphics::common::PixelFormat; class ComposerClient::CommandResultWriter { - public: - CommandResultWriter(std::vector<CommandResultPayload>* results) - : mIndex(0), mResults(results) {} - - void nextCommand() { ++mIndex; } - - void addError(HWC3::Error error) { - CommandError commandErrorResult; - commandErrorResult.commandIndex = mIndex; - commandErrorResult.errorCode = static_cast<int32_t>(error); - mResults->emplace_back(std::move(commandErrorResult)); - } - - void addPresentFence(int64_t displayId, ::android::base::unique_fd fence) { - if (fence >= 0) { - PresentFence presentFenceResult; - presentFenceResult.display = displayId; - presentFenceResult.fence = ndk::ScopedFileDescriptor(fence.release()); - mResults->emplace_back(std::move(presentFenceResult)); - } - } - - void addReleaseFences( - int64_t displayId, - std::unordered_map<int64_t, ::android::base::unique_fd> layerFences) { - ReleaseFences releaseFencesResult; - releaseFencesResult.display = displayId; - for (auto& [layer, layerFence] : layerFences) { - if (layerFence >= 0) { - ReleaseFences::Layer releaseFencesLayerResult; - releaseFencesLayerResult.layer = layer; - releaseFencesLayerResult.fence = - ndk::ScopedFileDescriptor(layerFence.release()); - releaseFencesResult.layers.emplace_back( - std::move(releaseFencesLayerResult)); - } - } - mResults->emplace_back(std::move(releaseFencesResult)); - } - - void addChanges(const DisplayChanges& changes) { - if (changes.compositionChanges) { - mResults->emplace_back(*changes.compositionChanges); - } - if (changes.displayRequestChanges) { - mResults->emplace_back(*changes.displayRequestChanges); - } - } - - void addPresentOrValidateResult(int64_t displayId, - PresentOrValidate::Result pov) { - PresentOrValidate result; - result.display = displayId; - result.result = pov; - mResults->emplace_back(std::move(result)); - } - - private: - int32_t mIndex = 0; - std::vector<CommandResultPayload>* mResults = nullptr; + public: + CommandResultWriter(std::vector<CommandResultPayload>* results) + : mIndex(0), mResults(results) {} + + void nextCommand() { ++mIndex; } + + void addError(HWC3::Error error) { + CommandError commandErrorResult; + commandErrorResult.commandIndex = mIndex; + commandErrorResult.errorCode = static_cast<int32_t>(error); + mResults->emplace_back(std::move(commandErrorResult)); + } + + void addPresentFence(int64_t displayId, ::android::base::unique_fd fence) { + if (fence >= 0) { + PresentFence presentFenceResult; + presentFenceResult.display = displayId; + presentFenceResult.fence = ndk::ScopedFileDescriptor(fence.release()); + mResults->emplace_back(std::move(presentFenceResult)); + } + } + + void addReleaseFences(int64_t displayId, + std::unordered_map<int64_t, ::android::base::unique_fd> layerFences) { + ReleaseFences releaseFencesResult; + releaseFencesResult.display = displayId; + for (auto& [layer, layerFence] : layerFences) { + if (layerFence >= 0) { + ReleaseFences::Layer releaseFencesLayerResult; + releaseFencesLayerResult.layer = layer; + releaseFencesLayerResult.fence = ndk::ScopedFileDescriptor(layerFence.release()); + releaseFencesResult.layers.emplace_back(std::move(releaseFencesLayerResult)); + } + } + mResults->emplace_back(std::move(releaseFencesResult)); + } + + void addChanges(const DisplayChanges& changes) { + if (changes.compositionChanges) { + mResults->emplace_back(*changes.compositionChanges); + } + if (changes.displayRequestChanges) { + mResults->emplace_back(*changes.displayRequestChanges); + } + } + + void addPresentOrValidateResult(int64_t displayId, PresentOrValidate::Result pov) { + PresentOrValidate result; + result.display = displayId; + result.result = pov; + mResults->emplace_back(std::move(result)); + } + + private: + int32_t mIndex = 0; + std::vector<CommandResultPayload>* mResults = nullptr; }; ComposerClient::ComposerClient() { DEBUG_LOG("%s", __FUNCTION__); } ComposerClient::~ComposerClient() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - destroyDisplaysLocked(); + destroyDisplaysLocked(); - if (mOnClientDestroyed) { - mOnClientDestroyed(); - } + if (mOnClientDestroyed) { + mOnClientDestroyed(); + } } HWC3::Error ComposerClient::init() { - DEBUG_LOG("%s", __FUNCTION__); - - HWC3::Error error = HWC3::Error::None; - - std::unique_lock<std::mutex> lock(mStateMutex); - - mResources = std::make_unique<ComposerResources>(); - if (!mResources) { - ALOGE("%s failed to allocate ComposerResources", __FUNCTION__); - return HWC3::Error::NoResources; - } - - error = mResources->init(); - if (error != HWC3::Error::None) { - ALOGE("%s failed to initialize ComposerResources", __FUNCTION__); - return error; - } - - error = Device::getInstance().getComposer(&mComposer); - if (error != HWC3::Error::None) { - ALOGE("%s failed to get FrameComposer", __FUNCTION__); - return error; - } - - const auto HotplugCallback = [this](bool connected, // - uint32_t id, // - uint32_t width, // - uint32_t height, // - uint32_t dpiX, // - uint32_t dpiY, // - uint32_t refreshRate) { - handleHotplug(connected, id, width, height, dpiX, dpiY, refreshRate); - }; - error = mComposer->registerOnHotplugCallback(HotplugCallback); - if (error != HWC3::Error::None) { - ALOGE("%s failed to register hotplug callback", __FUNCTION__); - return error; - } + DEBUG_LOG("%s", __FUNCTION__); - error = createDisplaysLocked(); - if (error != HWC3::Error::None) { - ALOGE("%s failed to create displays.", __FUNCTION__); - return error; - } + HWC3::Error error = HWC3::Error::None; - DEBUG_LOG("%s initialized!", __FUNCTION__); - return HWC3::Error::None; + std::unique_lock<std::mutex> lock(mStateMutex); + + mResources = std::make_unique<ComposerResources>(); + if (!mResources) { + ALOGE("%s failed to allocate ComposerResources", __FUNCTION__); + return HWC3::Error::NoResources; + } + + error = mResources->init(); + if (error != HWC3::Error::None) { + ALOGE("%s failed to initialize ComposerResources", __FUNCTION__); + return error; + } + + error = Device::getInstance().getComposer(&mComposer); + if (error != HWC3::Error::None) { + ALOGE("%s failed to get FrameComposer", __FUNCTION__); + return error; + } + + const auto HotplugCallback = [this](bool connected, // + uint32_t id, // + uint32_t width, // + uint32_t height, // + uint32_t dpiX, // + uint32_t dpiY, // + uint32_t refreshRate) { + handleHotplug(connected, id, width, height, dpiX, dpiY, refreshRate); + }; + error = mComposer->registerOnHotplugCallback(HotplugCallback); + if (error != HWC3::Error::None) { + ALOGE("%s failed to register hotplug callback", __FUNCTION__); + return error; + } + + error = createDisplaysLocked(); + if (error != HWC3::Error::None) { + ALOGE("%s failed to create displays.", __FUNCTION__); + return error; + } + + DEBUG_LOG("%s initialized!", __FUNCTION__); + return HWC3::Error::None; } -ndk::ScopedAStatus ComposerClient::createLayer(int64_t displayId, - int32_t bufferSlotCount, +ndk::ScopedAStatus ComposerClient::createLayer(int64_t displayId, int32_t bufferSlotCount, int64_t* layerId) { - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - HWC3::Error error = display->createLayer(layerId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to create layer", __FUNCTION__, - displayId); - return ToBinderStatus(error); - } + HWC3::Error error = display->createLayer(layerId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to create layer", __FUNCTION__, displayId); + return ToBinderStatus(error); + } - error = mResources->addLayer(displayId, *layerId, static_cast<uint32_t>(bufferSlotCount)); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " resources failed to create layer", - __FUNCTION__, displayId); - return ToBinderStatus(error); - } + error = mResources->addLayer(displayId, *layerId, static_cast<uint32_t>(bufferSlotCount)); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " resources failed to create layer", __FUNCTION__, displayId); + return ToBinderStatus(error); + } - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::createVirtualDisplay( - int32_t /*width*/, int32_t /*height*/, PixelFormat /*formatHint*/, - int32_t /*outputBufferSlotCount*/, VirtualDisplay* /*display*/) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::createVirtualDisplay(int32_t /*width*/, int32_t /*height*/, + PixelFormat /*formatHint*/, + int32_t /*outputBufferSlotCount*/, + VirtualDisplay* /*display*/) { + DEBUG_LOG("%s", __FUNCTION__); - return ToBinderStatus(HWC3::Error::Unsupported); + return ToBinderStatus(HWC3::Error::Unsupported); } -ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t displayId, - int64_t layerId) { - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); +ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t displayId, int64_t layerId) { + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - HWC3::Error error = display->destroyLayer(layerId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to destroy layer:%" PRIu64, - __FUNCTION__, displayId, layerId); - return ToBinderStatus(error); - } + HWC3::Error error = display->destroyLayer(layerId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to destroy layer:%" PRIu64, __FUNCTION__, displayId, + layerId); + return ToBinderStatus(error); + } - error = mResources->removeLayer(displayId, layerId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " resources failed to destroy layer:%" PRIu64, - __FUNCTION__, displayId, layerId); - return ToBinderStatus(error); - } + error = mResources->removeLayer(displayId, layerId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " resources failed to destroy layer:%" PRIu64, __FUNCTION__, + displayId, layerId); + return ToBinderStatus(error); + } - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay( - int64_t /*displayId*/) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t /*displayId*/) { + DEBUG_LOG("%s", __FUNCTION__); - return ToBinderStatus(HWC3::Error::Unsupported); + return ToBinderStatus(HWC3::Error::Unsupported); } ndk::ScopedAStatus ComposerClient::executeCommands( const std::vector<DisplayCommand>& commands, std::vector<CommandResultPayload>* commandResultPayloads) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - mCommandResults = - std::make_unique<CommandResultWriter>(commandResultPayloads); + mCommandResults = std::make_unique<CommandResultWriter>(commandResultPayloads); - for (const DisplayCommand& command : commands) { - executeDisplayCommand(command); - mCommandResults->nextCommand(); - } + for (const DisplayCommand& command : commands) { + executeDisplayCommand(command); + mCommandResults->nextCommand(); + } - mCommandResults.reset(); + mCommandResults.reset(); - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t displayId, - int32_t* config) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t displayId, int32_t* config) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getActiveConfig(config)); + return ToBinderStatus(display->getActiveConfig(config)); } -ndk::ScopedAStatus ComposerClient::getColorModes( - int64_t displayId, std::vector<ColorMode>* colorModes) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getColorModes(int64_t displayId, + std::vector<ColorMode>* colorModes) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getColorModes(colorModes)); + return ToBinderStatus(display->getColorModes(colorModes)); } -ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix( - common::Dataspace dataspace, std::vector<float>* matrix) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(common::Dataspace dataspace, + std::vector<float>* matrix) { + DEBUG_LOG("%s", __FUNCTION__); - if (dataspace != common::Dataspace::SRGB_LINEAR) { - return ToBinderStatus(HWC3::Error::BadParameter); - } + if (dataspace != common::Dataspace::SRGB_LINEAR) { + return ToBinderStatus(HWC3::Error::BadParameter); + } - // clang-format off + // clang-format off constexpr std::array<float, 16> kUnit { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; - // clang-format on - matrix->clear(); - matrix->insert(matrix->begin(), kUnit.begin(), kUnit.end()); + // clang-format on + matrix->clear(); + matrix->insert(matrix->begin(), kUnit.begin(), kUnit.end()); - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::getDisplayAttribute( - int64_t displayId, int32_t config, DisplayAttribute attribute, - int32_t* value) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayAttribute(int64_t displayId, int32_t config, + DisplayAttribute attribute, int32_t* value) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayAttribute(config, attribute, value)); + return ToBinderStatus(display->getDisplayAttribute(config, attribute, value)); } -ndk::ScopedAStatus ComposerClient::getDisplayCapabilities( - int64_t displayId, std::vector<DisplayCapability>* outCaps) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(int64_t displayId, + std::vector<DisplayCapability>* outCaps) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayCapabilities(outCaps)); + return ToBinderStatus(display->getDisplayCapabilities(outCaps)); } -ndk::ScopedAStatus ComposerClient::getDisplayConfigs( - int64_t displayId, std::vector<int32_t>* outConfigs) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayConfigs(int64_t displayId, + std::vector<int32_t>* outConfigs) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayConfigs(outConfigs)); + return ToBinderStatus(display->getDisplayConfigs(outConfigs)); } -ndk::ScopedAStatus ComposerClient::getDisplayConnectionType( - int64_t displayId, DisplayConnectionType* outType) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(int64_t displayId, + DisplayConnectionType* outType) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayConnectionType(outType)); + return ToBinderStatus(display->getDisplayConnectionType(outType)); } ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData( int64_t displayId, DisplayIdentification* outIdentification) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus( - display->getDisplayIdentificationData(outIdentification)); + return ToBinderStatus(display->getDisplayIdentificationData(outIdentification)); } -ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t displayId, - std::string* outName) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t displayId, std::string* outName) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayName(outName)); + return ToBinderStatus(display->getDisplayName(outName)); } -ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod( - int64_t displayId, int32_t* outVsyncPeriod) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(int64_t displayId, + int32_t* outVsyncPeriod) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayVsyncPeriod(outVsyncPeriod)); + return ToBinderStatus(display->getDisplayVsyncPeriod(outVsyncPeriod)); } -ndk::ScopedAStatus ComposerClient::getDisplayedContentSample( - int64_t displayId, int64_t maxFrames, int64_t timestamp, - DisplayContentSample* outSamples) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(int64_t displayId, int64_t maxFrames, + int64_t timestamp, + DisplayContentSample* outSamples) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus( - display->getDisplayedContentSample(maxFrames, timestamp, outSamples)); + return ToBinderStatus(display->getDisplayedContentSample(maxFrames, timestamp, outSamples)); } ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes( int64_t displayId, DisplayContentSamplingAttributes* outAttributes) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus( - display->getDisplayedContentSamplingAttributes(outAttributes)); + return ToBinderStatus(display->getDisplayedContentSamplingAttributes(outAttributes)); } ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation( int64_t displayId, common::Transform* outOrientation) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDisplayPhysicalOrientation(outOrientation)); + return ToBinderStatus(display->getDisplayPhysicalOrientation(outOrientation)); } -ndk::ScopedAStatus ComposerClient::getHdrCapabilities( - int64_t displayId, HdrCapabilities* outCapabilities) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t displayId, + HdrCapabilities* outCapabilities) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getHdrCapabilities(outCapabilities)); + return ToBinderStatus(display->getHdrCapabilities(outCapabilities)); } -ndk::ScopedAStatus ComposerClient::getOverlaySupport( - OverlayProperties* properties) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getOverlaySupport(OverlayProperties* properties) { + DEBUG_LOG("%s", __FUNCTION__); - // no supported combinations - properties->combinations.clear(); + // no supported combinations + properties->combinations.clear(); - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount( - int32_t* outCount) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* outCount) { + DEBUG_LOG("%s", __FUNCTION__); - // Not supported. - *outCount = 0; + // Not supported. + *outCount = 0; - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys( int64_t displayId, std::vector<PerFrameMetadataKey>* outKeys) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getPerFrameMetadataKeys(outKeys)); + return ToBinderStatus(display->getPerFrameMetadataKeys(outKeys)); } ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes( int64_t displayId, ReadbackBufferAttributes* outAttributes) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getReadbackBufferAttributes(outAttributes)); + return ToBinderStatus(display->getReadbackBufferAttributes(outAttributes)); } ndk::ScopedAStatus ComposerClient::getReadbackBufferFence( int64_t displayId, ndk::ScopedFileDescriptor* outAcquireFence) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getReadbackBufferFence(outAcquireFence)); + return ToBinderStatus(display->getReadbackBufferFence(outAcquireFence)); } -ndk::ScopedAStatus ComposerClient::getRenderIntents( - int64_t displayId, ColorMode mode, std::vector<RenderIntent>* outIntents) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getRenderIntents(int64_t displayId, ColorMode mode, + std::vector<RenderIntent>* outIntents) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getRenderIntents(mode, outIntents)); + return ToBinderStatus(display->getRenderIntents(mode, outIntents)); } -ndk::ScopedAStatus ComposerClient::getSupportedContentTypes( - int64_t displayId, std::vector<ContentType>* outTypes) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(int64_t displayId, + std::vector<ContentType>* outTypes) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getSupportedContentTypes(outTypes)); + return ToBinderStatus(display->getSupportedContentTypes(outTypes)); } ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport( - int64_t displayId, - std::optional<common::DisplayDecorationSupport>* outSupport) { - DEBUG_LOG("%s", __FUNCTION__); + int64_t displayId, std::optional<common::DisplayDecorationSupport>* outSupport) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getDecorationSupport(outSupport)); + return ToBinderStatus(display->getDecorationSupport(outSupport)); } ndk::ScopedAStatus ComposerClient::registerCallback( const std::shared_ptr<IComposerCallback>& callback) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - const bool isFirstRegisterCallback = mCallbacks == nullptr; + const bool isFirstRegisterCallback = mCallbacks == nullptr; - mCallbacks = callback; + mCallbacks = callback; - for (auto& [_, display] : mDisplays) { - display->registerCallback(callback); - } + for (auto& [_, display] : mDisplays) { + display->registerCallback(callback); + } - if (isFirstRegisterCallback) { - lock.unlock(); - for (auto& [displayId, _] : mDisplays) { - mCallbacks->onHotplug(displayId, /*connected=*/true); + if (isFirstRegisterCallback) { + lock.unlock(); + for (auto& [displayId, _] : mDisplays) { + mCallbacks->onHotplug(displayId, /*connected=*/true); + } } - } - return ndk::ScopedAStatus::ok(); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t displayId, - int32_t configId) { - DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, - configId); +ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t displayId, int32_t configId) { + DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, configId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setActiveConfig(configId)); + return ToBinderStatus(display->setActiveConfig(configId)); } ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints( - int64_t displayId, int32_t configId, - const VsyncPeriodChangeConstraints& constraints, + int64_t displayId, int32_t configId, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* outTimeline) { - DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, - configId); + DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, configId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setActiveConfigWithConstraints( - configId, constraints, outTimeline)); + return ToBinderStatus( + display->setActiveConfigWithConstraints(configId, constraints, outTimeline)); } -ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t displayId, - int32_t configId) { - DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, - configId); +ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t displayId, int32_t configId) { + DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, configId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setBootConfig(configId)); + return ToBinderStatus(display->setBootConfig(configId)); } ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t displayId) { - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->clearBootConfig()); + return ToBinderStatus(display->clearBootConfig()); } -ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig( - int64_t displayId, int32_t* outConfigId) { - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); +ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(int64_t displayId, + int32_t* outConfigId) { + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->getPreferredBootConfig(outConfigId)); + return ToBinderStatus(display->getPreferredBootConfig(outConfigId)); } ndk::ScopedAStatus ComposerClient::getHdrConversionCapabilities( std::vector<aidl::android::hardware::graphics::common::HdrConversionCapability>* capabilities) { - DEBUG_LOG("%s", __FUNCTION__); - capabilities->clear(); - return ToBinderStatus(HWC3::Error::None); + DEBUG_LOG("%s", __FUNCTION__); + capabilities->clear(); + return ToBinderStatus(HWC3::Error::None); } ndk::ScopedAStatus ComposerClient::setHdrConversionStrategy( const aidl::android::hardware::graphics::common::HdrConversionStrategy& conversionStrategy, aidl::android::hardware::graphics::common::Hdr* preferredHdrOutputType) { - DEBUG_LOG("%s", __FUNCTION__); - using HdrConversionStrategyTag = aidl::android::hardware::graphics::common::HdrConversionStrategy::Tag; - switch (conversionStrategy.getTag()) { - case HdrConversionStrategyTag::autoAllowedHdrTypes: { - auto autoHdrTypes = conversionStrategy.get<HdrConversionStrategyTag::autoAllowedHdrTypes>(); - if (autoHdrTypes.size() != 0) { - return ToBinderStatus(HWC3::Error::Unsupported); - } - break; - } - case HdrConversionStrategyTag::passthrough: - case HdrConversionStrategyTag::forceHdrConversion: { - break; + DEBUG_LOG("%s", __FUNCTION__); + using HdrConversionStrategyTag = + aidl::android::hardware::graphics::common::HdrConversionStrategy::Tag; + switch (conversionStrategy.getTag()) { + case HdrConversionStrategyTag::autoAllowedHdrTypes: { + auto autoHdrTypes = + conversionStrategy.get<HdrConversionStrategyTag::autoAllowedHdrTypes>(); + if (autoHdrTypes.size() != 0) { + return ToBinderStatus(HWC3::Error::Unsupported); + } + break; + } + case HdrConversionStrategyTag::passthrough: + case HdrConversionStrategyTag::forceHdrConversion: { + break; + } } - } - *preferredHdrOutputType = aidl::android::hardware::graphics::common::Hdr::INVALID; - return ToBinderStatus(HWC3::Error::None); + *preferredHdrOutputType = aidl::android::hardware::graphics::common::Hdr::INVALID; + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t displayId, - bool on) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t displayId, bool on) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setAutoLowLatencyMode(on)); + return ToBinderStatus(display->setAutoLowLatencyMode(on)); } -ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t displayId, - int32_t count) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t displayId, int32_t count) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus( - mResources->setDisplayClientTargetCacheSize(displayId, static_cast<uint32_t>(count))); + return ToBinderStatus( + mResources->setDisplayClientTargetCacheSize(displayId, static_cast<uint32_t>(count))); } -ndk::ScopedAStatus ComposerClient::setColorMode(int64_t displayId, - ColorMode mode, +ndk::ScopedAStatus ComposerClient::setColorMode(int64_t displayId, ColorMode mode, RenderIntent intent) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setColorMode(mode, intent)); + return ToBinderStatus(display->setColorMode(mode, intent)); } -ndk::ScopedAStatus ComposerClient::setContentType(int64_t displayId, - ContentType type) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::setContentType(int64_t displayId, ContentType type) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setContentType(type)); + return ToBinderStatus(display->setContentType(type)); } ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled( - int64_t displayId, bool enable, FormatColorComponent componentMask, - int64_t maxFrames) { - DEBUG_LOG("%s", __FUNCTION__); + int64_t displayId, bool enable, FormatColorComponent componentMask, int64_t maxFrames) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setDisplayedContentSamplingEnabled( - enable, componentMask, maxFrames)); + return ToBinderStatus( + display->setDisplayedContentSamplingEnabled(enable, componentMask, maxFrames)); } -ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t displayId, - PowerMode mode) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t displayId, PowerMode mode) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setPowerMode(mode)); + return ToBinderStatus(display->setPowerMode(mode)); } ndk::ScopedAStatus ComposerClient::setReadbackBuffer( - int64_t displayId, - const aidl::android::hardware::common::NativeHandle& buffer, + int64_t displayId, const aidl::android::hardware::common::NativeHandle& buffer, const ndk::ScopedFileDescriptor& releaseFence) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - // Owned by mResources. - buffer_handle_t importedBuffer = nullptr; + // Owned by mResources. + buffer_handle_t importedBuffer = nullptr; - auto releaser = mResources->createReleaser(true /* isBuffer */); - auto error = mResources->getDisplayReadbackBuffer( - displayId, buffer, &importedBuffer, releaser.get()); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to get readback buffer from resources.", __FUNCTION__); - return ToBinderStatus(error); - } + auto releaser = mResources->createReleaser(true /* isBuffer */); + auto error = + mResources->getDisplayReadbackBuffer(displayId, buffer, &importedBuffer, releaser.get()); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to get readback buffer from resources.", __FUNCTION__); + return ToBinderStatus(error); + } - error = display->setReadbackBuffer(importedBuffer, releaseFence); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to set readback buffer to display.", __FUNCTION__); - return ToBinderStatus(error); - } + error = display->setReadbackBuffer(importedBuffer, releaseFence); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to set readback buffer to display.", __FUNCTION__); + return ToBinderStatus(error); + } - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::None); } -ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t displayId, - bool enabled) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t displayId, bool enabled) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setVsyncEnabled(enabled)); + return ToBinderStatus(display->setVsyncEnabled(enabled)); } -ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t displayId, - int32_t timeoutMs) { - DEBUG_LOG("%s", __FUNCTION__); +ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t displayId, int32_t timeoutMs) { + DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); + GET_DISPLAY_OR_RETURN_ERROR(); - return ToBinderStatus(display->setIdleTimerEnabled(timeoutMs)); + return ToBinderStatus(display->setIdleTimerEnabled(timeoutMs)); } -ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled( - int64_t displayId, bool) { +ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t displayId, + bool) { DEBUG_LOG("%s", __FUNCTION__); GET_DISPLAY_OR_RETURN_ERROR(); @@ -753,681 +722,643 @@ ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled( } ndk::SpAIBinder ComposerClient::createBinder() { - auto binder = BnComposerClient::createBinder(); - AIBinder_setInheritRt(binder.get(), true); - return binder; + auto binder = BnComposerClient::createBinder(); + AIBinder_setInheritRt(binder.get(), true); + return binder; } namespace { -#define DISPATCH_LAYER_COMMAND(layerCmd, display, layer, field, funcName) \ - do { \ - if (layerCmd.field) { \ - ComposerClient::executeLayerCommandSetLayer##funcName(display, layer, \ - *layerCmd.field); \ - } \ - } while (0) - -#define DISPATCH_DISPLAY_COMMAND(displayCmd, display, field, funcName) \ - do { \ - if (displayCmd.field) { \ - executeDisplayCommand##funcName(display, *displayCmd.field); \ - } \ - } while (0) +#define DISPATCH_LAYER_COMMAND(layerCmd, display, layer, field, funcName) \ + do { \ + if (layerCmd.field) { \ + ComposerClient::executeLayerCommandSetLayer##funcName(display, layer, \ + *layerCmd.field); \ + } \ + } while (0) + +#define DISPATCH_DISPLAY_COMMAND(displayCmd, display, field, funcName) \ + do { \ + if (displayCmd.field) { \ + executeDisplayCommand##funcName(display, *displayCmd.field); \ + } \ + } while (0) #define DISPATCH_DISPLAY_BOOL_COMMAND(displayCmd, display, field, funcName) \ - do { \ - if (displayCmd.field) { \ - executeDisplayCommand##funcName(display); \ - } \ - } while (0) - -#define DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCmd, display, field, \ - data, funcName) \ - do { \ - if (displayCmd.field) { \ - executeDisplayCommand##funcName(display, displayCmd.data); \ - } \ - } while (0) - -#define LOG_DISPLAY_COMMAND_ERROR(display, error) \ - do { \ - const std::string errorString = toString(error); \ - ALOGE("%s: display:%" PRId64 " failed with:%s", __FUNCTION__, \ - display->getId(), errorString.c_str()); \ - } while (0) - -#define LOG_LAYER_COMMAND_ERROR(display, layer, error) \ - do { \ - const std::string errorString = toString(error); \ - ALOGE("%s: display:%" PRId64 " layer:%" PRId64 " failed with:%s", \ - __FUNCTION__, display->getId(), layer->getId(), \ - errorString.c_str()); \ - } while (0) + do { \ + if (displayCmd.field) { \ + executeDisplayCommand##funcName(display); \ + } \ + } while (0) + +#define DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCmd, display, field, data, funcName) \ + do { \ + if (displayCmd.field) { \ + executeDisplayCommand##funcName(display, displayCmd.data); \ + } \ + } while (0) + +#define LOG_DISPLAY_COMMAND_ERROR(display, error) \ + do { \ + const std::string errorString = toString(error); \ + ALOGE("%s: display:%" PRId64 " failed with:%s", __FUNCTION__, display->getId(), \ + errorString.c_str()); \ + } while (0) + +#define LOG_LAYER_COMMAND_ERROR(display, layer, error) \ + do { \ + const std::string errorString = toString(error); \ + ALOGE("%s: display:%" PRId64 " layer:%" PRId64 " failed with:%s", __FUNCTION__, \ + display->getId(), layer->getId(), errorString.c_str()); \ + } while (0) } // namespace -void ComposerClient::executeDisplayCommand( - const DisplayCommand& displayCommand) { - Display* display = getDisplay(displayCommand.display); - if (display == nullptr) { - mCommandResults->addError(HWC3::Error::BadDisplay); - return; - } - - for (const LayerCommand& layerCmd : displayCommand.layers) { - executeLayerCommand(display, layerCmd); - } - - DISPATCH_DISPLAY_COMMAND(displayCommand, display, colorTransformMatrix, - SetColorTransform); - DISPATCH_DISPLAY_COMMAND(displayCommand, display, brightness, SetBrightness); - DISPATCH_DISPLAY_COMMAND(displayCommand, display, clientTarget, - SetClientTarget); - DISPATCH_DISPLAY_COMMAND(displayCommand, display, virtualDisplayOutputBuffer, - SetOutputBuffer); - DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, display, - validateDisplay, expectedPresentTime, - ValidateDisplay); - DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, display, acceptDisplayChanges, - AcceptDisplayChanges); - DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, display, presentDisplay, - PresentDisplay); - DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA( - displayCommand, display, presentOrValidateDisplay, expectedPresentTime, - PresentOrValidateDisplay); -} - -void ComposerClient::executeLayerCommand(Display* display, - const LayerCommand& layerCommand) { - Layer* layer = display->getLayer(layerCommand.layer); - if (layer == nullptr) { - mCommandResults->addError(HWC3::Error::BadLayer); - return; - } - - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, cursorPosition, - CursorPosition); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, buffer, Buffer); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, damage, SurfaceDamage); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, blendMode, BlendMode); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, color, Color); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, composition, - Composition); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, dataspace, Dataspace); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, displayFrame, - DisplayFrame); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, planeAlpha, PlaneAlpha); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, sidebandStream, - SidebandStream); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, sourceCrop, SourceCrop); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, transform, Transform); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, visibleRegion, - VisibleRegion); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, z, ZOrder); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, colorTransform, - ColorTransform); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, brightness, Brightness); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, perFrameMetadata, - PerFrameMetadata); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, perFrameMetadataBlob, - PerFrameMetadataBlobs); -} - -void ComposerClient::executeDisplayCommandSetColorTransform( - Display* display, const std::vector<float>& matrix) { - DEBUG_LOG("%s", __FUNCTION__); - - auto error = display->setColorTransform(matrix); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } -} - -void ComposerClient::executeDisplayCommandSetBrightness( - Display* display, const DisplayBrightness& brightness) { - DEBUG_LOG("%s", __FUNCTION__); - - auto error = display->setBrightness(brightness.brightness); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } -} - -void ComposerClient::executeDisplayCommandSetClientTarget( - Display* display, const ClientTarget& clientTarget) { - DEBUG_LOG("%s", __FUNCTION__); - - // Owned by mResources. - buffer_handle_t importedBuffer = nullptr; - - auto releaser = mResources->createReleaser(/*isBuffer=*/true); - auto error = mResources->getDisplayClientTarget( - display->getId(), clientTarget.buffer, &importedBuffer, releaser.get()); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - return; - } - - error = display->setClientTarget(importedBuffer, clientTarget.buffer.fence, - clientTarget.dataspace, clientTarget.damage); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - return; - } -} - -void ComposerClient::executeDisplayCommandSetOutputBuffer( - Display* display, const Buffer& buffer) { - DEBUG_LOG("%s", __FUNCTION__); - - // Owned by mResources. - buffer_handle_t importedBuffer = nullptr; - - auto releaser = mResources->createReleaser(/*isBuffer=*/true); - auto error = mResources->getDisplayOutputBuffer( - display->getId(), buffer, &importedBuffer, releaser.get()); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - return; - } - - error = display->setOutputBuffer(importedBuffer, buffer.fence); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - return; - } +void ComposerClient::executeDisplayCommand(const DisplayCommand& displayCommand) { + Display* display = getDisplay(displayCommand.display); + if (display == nullptr) { + mCommandResults->addError(HWC3::Error::BadDisplay); + return; + } + + for (const LayerCommand& layerCmd : displayCommand.layers) { + executeLayerCommand(display, layerCmd); + } + + DISPATCH_DISPLAY_COMMAND(displayCommand, display, colorTransformMatrix, SetColorTransform); + DISPATCH_DISPLAY_COMMAND(displayCommand, display, brightness, SetBrightness); + DISPATCH_DISPLAY_COMMAND(displayCommand, display, clientTarget, SetClientTarget); + DISPATCH_DISPLAY_COMMAND(displayCommand, display, virtualDisplayOutputBuffer, SetOutputBuffer); + DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, display, validateDisplay, + expectedPresentTime, ValidateDisplay); + DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, display, acceptDisplayChanges, + AcceptDisplayChanges); + DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, display, presentDisplay, PresentDisplay); + DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, display, presentOrValidateDisplay, + expectedPresentTime, PresentOrValidateDisplay); +} + +void ComposerClient::executeLayerCommand(Display* display, const LayerCommand& layerCommand) { + Layer* layer = display->getLayer(layerCommand.layer); + if (layer == nullptr) { + mCommandResults->addError(HWC3::Error::BadLayer); + return; + } + + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, cursorPosition, CursorPosition); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, buffer, Buffer); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, damage, SurfaceDamage); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, blendMode, BlendMode); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, color, Color); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, composition, Composition); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, dataspace, Dataspace); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, displayFrame, DisplayFrame); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, planeAlpha, PlaneAlpha); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, sidebandStream, SidebandStream); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, sourceCrop, SourceCrop); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, transform, Transform); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, visibleRegion, VisibleRegion); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, z, ZOrder); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, colorTransform, ColorTransform); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, brightness, Brightness); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, perFrameMetadata, PerFrameMetadata); + DISPATCH_LAYER_COMMAND(layerCommand, display, layer, perFrameMetadataBlob, + PerFrameMetadataBlobs); +} + +void ComposerClient::executeDisplayCommandSetColorTransform(Display* display, + const std::vector<float>& matrix) { + DEBUG_LOG("%s", __FUNCTION__); + + auto error = display->setColorTransform(matrix); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } +} + +void ComposerClient::executeDisplayCommandSetBrightness(Display* display, + const DisplayBrightness& brightness) { + DEBUG_LOG("%s", __FUNCTION__); + + auto error = display->setBrightness(brightness.brightness); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } +} + +void ComposerClient::executeDisplayCommandSetClientTarget(Display* display, + const ClientTarget& clientTarget) { + DEBUG_LOG("%s", __FUNCTION__); + + // Owned by mResources. + buffer_handle_t importedBuffer = nullptr; + + auto releaser = mResources->createReleaser(/*isBuffer=*/true); + auto error = mResources->getDisplayClientTarget(display->getId(), clientTarget.buffer, + &importedBuffer, releaser.get()); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + return; + } + + error = display->setClientTarget(importedBuffer, clientTarget.buffer.fence, + clientTarget.dataspace, clientTarget.damage); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + return; + } +} + +void ComposerClient::executeDisplayCommandSetOutputBuffer(Display* display, const Buffer& buffer) { + DEBUG_LOG("%s", __FUNCTION__); + + // Owned by mResources. + buffer_handle_t importedBuffer = nullptr; + + auto releaser = mResources->createReleaser(/*isBuffer=*/true); + auto error = mResources->getDisplayOutputBuffer(display->getId(), buffer, &importedBuffer, + releaser.get()); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + return; + } + + error = display->setOutputBuffer(importedBuffer, buffer.fence); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + return; + } } void ComposerClient::executeDisplayCommandValidateDisplay( - Display* display, - const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { - DEBUG_LOG("%s", __FUNCTION__); + Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = display->setExpectedPresentTime(expectedPresentTime); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } + auto error = display->setExpectedPresentTime(expectedPresentTime); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } - DisplayChanges changes; + DisplayChanges changes; - error = display->validate(&changes); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } else { - mCommandResults->addChanges(changes); - } + error = display->validate(&changes); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } else { + mCommandResults->addChanges(changes); + } - mResources->setDisplayMustValidateState(display->getId(), false); + mResources->setDisplayMustValidateState(display->getId(), false); } -void ComposerClient::executeDisplayCommandAcceptDisplayChanges( - Display* display) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeDisplayCommandAcceptDisplayChanges(Display* display) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = display->acceptChanges(); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } + auto error = display->acceptChanges(); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } } void ComposerClient::executeDisplayCommandPresentOrValidateDisplay( - Display* display, - const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { - DEBUG_LOG("%s", __FUNCTION__); + Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { + DEBUG_LOG("%s", __FUNCTION__); - // TODO: Support SKIP_VALIDATE. + // TODO: Support SKIP_VALIDATE. - auto error = display->setExpectedPresentTime(expectedPresentTime); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } + auto error = display->setExpectedPresentTime(expectedPresentTime); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } - DisplayChanges changes; + DisplayChanges changes; - error = display->validate(&changes); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } else { - const int64_t displayId = display->getId(); - mCommandResults->addChanges(changes); - mCommandResults->addPresentOrValidateResult( - displayId, PresentOrValidate::Result::Validated); - } + error = display->validate(&changes); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } else { + const int64_t displayId = display->getId(); + mCommandResults->addChanges(changes); + mCommandResults->addPresentOrValidateResult(displayId, + PresentOrValidate::Result::Validated); + } - mResources->setDisplayMustValidateState(display->getId(), false); + mResources->setDisplayMustValidateState(display->getId(), false); } void ComposerClient::executeDisplayCommandPresentDisplay(Display* display) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - if (mResources->mustValidateDisplay(display->getId())) { - ALOGE("%s: display:%" PRIu64 " not validated", __FUNCTION__, - display->getId()); - mCommandResults->addError(HWC3::Error::NotValidated); - return; - } + if (mResources->mustValidateDisplay(display->getId())) { + ALOGE("%s: display:%" PRIu64 " not validated", __FUNCTION__, display->getId()); + mCommandResults->addError(HWC3::Error::NotValidated); + return; + } - ::android::base::unique_fd displayFence; - std::unordered_map<int64_t, ::android::base::unique_fd> layerFences; + ::android::base::unique_fd displayFence; + std::unordered_map<int64_t, ::android::base::unique_fd> layerFences; - auto error = display->present(&displayFence, &layerFences); - if (error != HWC3::Error::None) { - LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); - } else { - const int64_t displayId = display->getId(); - mCommandResults->addPresentFence(displayId, std::move(displayFence)); - mCommandResults->addReleaseFences(displayId, std::move(layerFences)); - } + auto error = display->present(&displayFence, &layerFences); + if (error != HWC3::Error::None) { + LOG_DISPLAY_COMMAND_ERROR(display, error); + mCommandResults->addError(error); + } else { + const int64_t displayId = display->getId(); + mCommandResults->addPresentFence(displayId, std::move(displayFence)); + mCommandResults->addReleaseFences(displayId, std::move(layerFences)); + } } void ComposerClient::executeLayerCommandSetLayerCursorPosition( Display* display, Layer* layer, const common::Point& cursorPosition) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setCursorPosition(cursorPosition); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setCursorPosition(cursorPosition); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerBuffer(Display* display, - Layer* layer, +void ComposerClient::executeLayerCommandSetLayerBuffer(Display* display, Layer* layer, const Buffer& buffer) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - // Owned by mResources. - buffer_handle_t importedBuffer = nullptr; + // Owned by mResources. + buffer_handle_t importedBuffer = nullptr; - auto releaser = mResources->createReleaser(/*isBuffer=*/true); - auto error = - mResources->getLayerBuffer(display->getId(), layer->getId(), buffer, - &importedBuffer, releaser.get()); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - return; - } + auto releaser = mResources->createReleaser(/*isBuffer=*/true); + auto error = mResources->getLayerBuffer(display->getId(), layer->getId(), buffer, + &importedBuffer, releaser.get()); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + return; + } - error = layer->setBuffer(importedBuffer, buffer.fence); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + error = layer->setBuffer(importedBuffer, buffer.fence); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerSurfaceDamage( - Display* display, Layer* layer, - const std::vector<std::optional<common::Rect>>& damage) { - DEBUG_LOG("%s", __FUNCTION__); + Display* display, Layer* layer, const std::vector<std::optional<common::Rect>>& damage) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setSurfaceDamage(damage); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setSurfaceDamage(damage); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerBlendMode( - Display* display, Layer* layer, const ParcelableBlendMode& blendMode) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerBlendMode(Display* display, Layer* layer, + const ParcelableBlendMode& blendMode) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setBlendMode(blendMode.blendMode); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setBlendMode(blendMode.blendMode); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerColor(Display* display, - Layer* layer, +void ComposerClient::executeLayerCommandSetLayerColor(Display* display, Layer* layer, const Color& color) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setColor(color); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setColor(color); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerComposition( Display* display, Layer* layer, const ParcelableComposition& composition) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setCompositionType(composition.composition); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setCompositionType(composition.composition); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerDataspace( - Display* display, Layer* layer, const ParcelableDataspace& dataspace) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerDataspace(Display* display, Layer* layer, + const ParcelableDataspace& dataspace) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setDataspace(dataspace.dataspace); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setDataspace(dataspace.dataspace); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerDisplayFrame( - Display* display, Layer* layer, const common::Rect& rect) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerDisplayFrame(Display* display, Layer* layer, + const common::Rect& rect) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setDisplayFrame(rect); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setDisplayFrame(rect); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerPlaneAlpha( - Display* display, Layer* layer, const PlaneAlpha& planeAlpha) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerPlaneAlpha(Display* display, Layer* layer, + const PlaneAlpha& planeAlpha) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setPlaneAlpha(planeAlpha.alpha); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setPlaneAlpha(planeAlpha.alpha); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerSidebandStream( - Display* display, Layer* layer, - const aidl::android::hardware::common::NativeHandle& handle) { - DEBUG_LOG("%s", __FUNCTION__); + Display* display, Layer* layer, const aidl::android::hardware::common::NativeHandle& handle) { + DEBUG_LOG("%s", __FUNCTION__); - // Owned by mResources. - buffer_handle_t importedStream = nullptr; + // Owned by mResources. + buffer_handle_t importedStream = nullptr; - auto releaser = mResources->createReleaser(/*isBuffer=*/false); - auto error = mResources->getLayerSidebandStream( - display->getId(), layer->getId(), handle, &importedStream, - releaser.get()); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - return; - } + auto releaser = mResources->createReleaser(/*isBuffer=*/false); + auto error = mResources->getLayerSidebandStream(display->getId(), layer->getId(), handle, + &importedStream, releaser.get()); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + return; + } - error = layer->setSidebandStream(importedStream); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + error = layer->setSidebandStream(importedStream); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerSourceCrop( - Display* display, Layer* layer, const common::FRect& sourceCrop) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerSourceCrop(Display* display, Layer* layer, + const common::FRect& sourceCrop) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setSourceCrop(sourceCrop); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setSourceCrop(sourceCrop); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerTransform( - Display* display, Layer* layer, const ParcelableTransform& transform) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerTransform(Display* display, Layer* layer, + const ParcelableTransform& transform) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setTransform(transform.transform); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setTransform(transform.transform); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerVisibleRegion( - Display* display, Layer* layer, - const std::vector<std::optional<common::Rect>>& visibleRegion) { - DEBUG_LOG("%s", __FUNCTION__); + Display* display, Layer* layer, const std::vector<std::optional<common::Rect>>& visibleRegion) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setVisibleRegion(visibleRegion); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setVisibleRegion(visibleRegion); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerZOrder(Display* display, - Layer* layer, +void ComposerClient::executeLayerCommandSetLayerZOrder(Display* display, Layer* layer, const ZOrder& zOrder) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setZOrder(zOrder.z); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setZOrder(zOrder.z); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerPerFrameMetadata( Display* display, Layer* layer, const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setPerFrameMetadata(perFrameMetadata); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setPerFrameMetadata(perFrameMetadata); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerColorTransform( Display* display, Layer* layer, const std::vector<float>& colorTransform) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setColorTransform(colorTransform); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setColorTransform(colorTransform); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } -void ComposerClient::executeLayerCommandSetLayerBrightness( - Display* display, Layer* layer, const LayerBrightness& brightness) { - DEBUG_LOG("%s", __FUNCTION__); +void ComposerClient::executeLayerCommandSetLayerBrightness(Display* display, Layer* layer, + const LayerBrightness& brightness) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setBrightness(brightness.brightness); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setBrightness(brightness.brightness); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } void ComposerClient::executeLayerCommandSetLayerPerFrameMetadataBlobs( Display* display, Layer* layer, - const std::vector<std::optional<PerFrameMetadataBlob>>& - perFrameMetadataBlob) { - DEBUG_LOG("%s", __FUNCTION__); + const std::vector<std::optional<PerFrameMetadataBlob>>& perFrameMetadataBlob) { + DEBUG_LOG("%s", __FUNCTION__); - auto error = layer->setPerFrameMetadataBlobs(perFrameMetadataBlob); - if (error != HWC3::Error::None) { - LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); - } + auto error = layer->setPerFrameMetadataBlobs(perFrameMetadataBlob); + if (error != HWC3::Error::None) { + LOG_LAYER_COMMAND_ERROR(display, layer, error); + mCommandResults->addError(error); + } } Display* ComposerClient::getDisplay(int64_t displayId) { - auto it = mDisplays.find(displayId); - if (it == mDisplays.end()) { - ALOGE("%s: no display:%" PRIu64, __FUNCTION__, displayId); - return nullptr; - } - return it->second.get(); + auto it = mDisplays.find(displayId); + if (it == mDisplays.end()) { + ALOGE("%s: no display:%" PRIu64, __FUNCTION__, displayId); + return nullptr; + } + return it->second.get(); } HWC3::Error ComposerClient::createDisplaysLocked() { - DEBUG_LOG("%s", __FUNCTION__); - - if (!mComposer) { - ALOGE("%s composer not initialized!", __FUNCTION__); - return HWC3::Error::NoResources; - } + DEBUG_LOG("%s", __FUNCTION__); - std::vector<DisplayMultiConfigs> displays; + if (!mComposer) { + ALOGE("%s composer not initialized!", __FUNCTION__); + return HWC3::Error::NoResources; + } - HWC3::Error error = findDisplays(mComposer->getDrmPresenter(), &displays); - if (error != HWC3::Error::None) { - ALOGE("%s failed to find display configs", __FUNCTION__); - return error; - } + std::vector<DisplayMultiConfigs> displays; - for (const auto& iter : displays) { - error = - createDisplayLocked(iter.displayId, iter.activeConfigId, iter.configs); + HWC3::Error error = findDisplays(mComposer->getDrmPresenter(), &displays); if (error != HWC3::Error::None) { - ALOGE("%s failed to create display from config", __FUNCTION__); - return error; + ALOGE("%s failed to find display configs", __FUNCTION__); + return error; } - } - return HWC3::Error::None; + for (const auto& iter : displays) { + error = createDisplayLocked(iter.displayId, iter.activeConfigId, iter.configs); + if (error != HWC3::Error::None) { + ALOGE("%s failed to create display from config", __FUNCTION__); + return error; + } + } + + return HWC3::Error::None; } -HWC3::Error ComposerClient::createDisplayLocked( - int64_t displayId, int32_t activeConfigId, - const std::vector<DisplayConfig>& configs) { - DEBUG_LOG("%s", __FUNCTION__); +HWC3::Error ComposerClient::createDisplayLocked(int64_t displayId, int32_t activeConfigId, + const std::vector<DisplayConfig>& configs) { + DEBUG_LOG("%s", __FUNCTION__); - if (!mComposer) { - ALOGE("%s composer not initialized!", __FUNCTION__); - return HWC3::Error::NoResources; - } + if (!mComposer) { + ALOGE("%s composer not initialized!", __FUNCTION__); + return HWC3::Error::NoResources; + } - auto display = std::make_unique<Display>(mComposer, displayId); - if (display == nullptr) { - ALOGE("%s failed to allocate display", __FUNCTION__); - return HWC3::Error::NoResources; - } + auto display = std::make_unique<Display>(mComposer, displayId); + if (display == nullptr) { + ALOGE("%s failed to allocate display", __FUNCTION__); + return HWC3::Error::NoResources; + } - HWC3::Error error = display->init(configs, activeConfigId); - if (error != HWC3::Error::None) { - ALOGE("%s failed to initialize display:%" PRIu64, __FUNCTION__, displayId); - return error; - } + HWC3::Error error = display->init(configs, activeConfigId); + if (error != HWC3::Error::None) { + ALOGE("%s failed to initialize display:%" PRIu64, __FUNCTION__, displayId); + return error; + } - error = mComposer->onDisplayCreate(display.get()); - if (error != HWC3::Error::None) { - ALOGE("%s failed to register display:%" PRIu64 " with composer", - __FUNCTION__, displayId); - return error; - } + error = mComposer->onDisplayCreate(display.get()); + if (error != HWC3::Error::None) { + ALOGE("%s failed to register display:%" PRIu64 " with composer", __FUNCTION__, displayId); + return error; + } - display->setPowerMode(PowerMode::ON); + display->setPowerMode(PowerMode::ON); - DEBUG_LOG("%s: adding display:%" PRIu64, __FUNCTION__, displayId); - mDisplays.emplace(displayId, std::move(display)); + DEBUG_LOG("%s: adding display:%" PRIu64, __FUNCTION__, displayId); + mDisplays.emplace(displayId, std::move(display)); - error = mResources->addPhysicalDisplay(displayId); - if (error != HWC3::Error::None) { - ALOGE("%s failed to initialize display:%" PRIu64 " resources", __FUNCTION__, - displayId); - return error; - } + error = mResources->addPhysicalDisplay(displayId); + if (error != HWC3::Error::None) { + ALOGE("%s failed to initialize display:%" PRIu64 " resources", __FUNCTION__, displayId); + return error; + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error ComposerClient::destroyDisplaysLocked() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::vector<int64_t> displayIds; - for (const auto& [displayId, _] : mDisplays) { - displayIds.push_back(displayId); - } - for (const int64_t displayId : displayIds) { - destroyDisplayLocked(displayId); - } + std::vector<int64_t> displayIds; + for (const auto& [displayId, _] : mDisplays) { + displayIds.push_back(displayId); + } + for (const int64_t displayId : displayIds) { + destroyDisplayLocked(displayId); + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error ComposerClient::destroyDisplayLocked(int64_t displayId) { - DEBUG_LOG("%s display:%" PRId64, __FUNCTION__, displayId); + DEBUG_LOG("%s display:%" PRId64, __FUNCTION__, displayId); - auto it = mDisplays.find(displayId); - if (it == mDisplays.end()) { - ALOGE("%s: display:%" PRId64 " no such display?", __FUNCTION__, displayId); - return HWC3::Error::BadDisplay; - } + auto it = mDisplays.find(displayId); + if (it == mDisplays.end()) { + ALOGE("%s: display:%" PRId64 " no such display?", __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; + } - Display* display = it->second.get(); + Display* display = it->second.get(); - display->setPowerMode(PowerMode::OFF); + display->setPowerMode(PowerMode::OFF); - HWC3::Error error = mComposer->onDisplayDestroy(it->second.get()); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " failed to destroy with frame composer", - __FUNCTION__, displayId); - } + HWC3::Error error = mComposer->onDisplayDestroy(it->second.get()); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " failed to destroy with frame composer", __FUNCTION__, + displayId); + } - error = mResources->removeDisplay(displayId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " failed to destroy with resources", - __FUNCTION__, displayId); - } + error = mResources->removeDisplay(displayId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " failed to destroy with resources", __FUNCTION__, displayId); + } - mDisplays.erase(it); + mDisplays.erase(it); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error ComposerClient::handleHotplug(bool connected, uint32_t id, - uint32_t width, uint32_t height, - uint32_t dpiX, uint32_t dpiY, +HWC3::Error ComposerClient::handleHotplug(bool connected, uint32_t id, uint32_t width, + uint32_t height, uint32_t dpiX, uint32_t dpiY, uint32_t refreshRate) { - if (!mCallbacks) { - return HWC3::Error::None; - } - - const int64_t displayId = static_cast<int64_t>(id); - - if (connected) { - const int32_t configId = static_cast<int32_t>(id); - const std::vector<DisplayConfig> configs = { - DisplayConfig(configId, static_cast<int>(width), - static_cast<int>(height), static_cast<int>(dpiX), - static_cast<int>(dpiY), static_cast<int>(refreshRate))}; - { - std::unique_lock<std::mutex> lock(mStateMutex); - createDisplayLocked(displayId, configId, configs); + if (!mCallbacks) { + return HWC3::Error::None; } - ALOGI("Connecting display:%" PRIu32 " w:%" PRIu32 " h:%" PRIu32 - " dpiX:%" PRIu32 " dpiY %" PRIu32 "fps %" PRIu32, - id, width, height, dpiX, dpiY, refreshRate); - mCallbacks->onHotplug(displayId, /*connected=*/true); - } else { - ALOGI("Disconnecting display:%" PRIu64, displayId); - mCallbacks->onHotplug(displayId, /*connected=*/false); - - Display* display = getDisplay(displayId); - if (display != nullptr) { - std::unique_lock<std::mutex> lock(mStateMutex); - destroyDisplayLocked(displayId); + const int64_t displayId = static_cast<int64_t>(id); + + if (connected) { + const int32_t configId = static_cast<int32_t>(id); + const std::vector<DisplayConfig> configs = {DisplayConfig( + configId, static_cast<int>(width), static_cast<int>(height), static_cast<int>(dpiX), + static_cast<int>(dpiY), static_cast<int>(refreshRate))}; + { + std::unique_lock<std::mutex> lock(mStateMutex); + createDisplayLocked(displayId, configId, configs); + } + + ALOGI("Connecting display:%" PRIu32 " w:%" PRIu32 " h:%" PRIu32 " dpiX:%" PRIu32 + " dpiY %" PRIu32 "fps %" PRIu32, + id, width, height, dpiX, dpiY, refreshRate); + mCallbacks->onHotplug(displayId, /*connected=*/true); + } else { + ALOGI("Disconnecting display:%" PRIu64, displayId); + mCallbacks->onHotplug(displayId, /*connected=*/false); + + Display* display = getDisplay(displayId); + if (display != nullptr) { + std::unique_lock<std::mutex> lock(mStateMutex); + destroyDisplayLocked(displayId); + } } - } - return HWC3::Error::None; + return HWC3::Error::None; } } // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file diff --git a/system/hwc3/ComposerClient.h b/system/hwc3/ComposerClient.h index 41ca7ba1..9b76d415 100644 --- a/system/hwc3/ComposerClient.h +++ b/system/hwc3/ComposerClient.h @@ -29,224 +29,196 @@ namespace aidl::android::hardware::graphics::composer3::impl { class ComposerClient : public BnComposerClient { - public: - ComposerClient(); - virtual ~ComposerClient(); - - HWC3::Error init(); - - void setOnClientDestroyed(std::function<void()> onClientDestroyed) { - mOnClientDestroyed = onClientDestroyed; - } - - // HWC3 interface: - ndk::ScopedAStatus createLayer(int64_t displayId, int32_t bufferSlotCount, - int64_t* layer) override; - ndk::ScopedAStatus createVirtualDisplay(int32_t width, int32_t height, - common::PixelFormat formatHint, - int32_t outputBufferSlotCount, - VirtualDisplay* display) override; - ndk::ScopedAStatus destroyLayer(int64_t displayId, int64_t layer) override; - ndk::ScopedAStatus destroyVirtualDisplay(int64_t displayId) override; - ndk::ScopedAStatus executeCommands( - const std::vector<DisplayCommand>& commands, - std::vector<CommandResultPayload>* results) override; - ndk::ScopedAStatus getActiveConfig(int64_t displayId, - int32_t* config) override; - ndk::ScopedAStatus getColorModes(int64_t displayId, - std::vector<ColorMode>* colorModes) override; - ndk::ScopedAStatus getDataspaceSaturationMatrix( - common::Dataspace dataspace, std::vector<float>* matrix) override; - ndk::ScopedAStatus getDisplayAttribute(int64_t displayId, int32_t config, - DisplayAttribute attribute, - int32_t* value) override; - ndk::ScopedAStatus getDisplayCapabilities( - int64_t displayId, std::vector<DisplayCapability>* caps) override; - ndk::ScopedAStatus getDisplayConfigs(int64_t displayId, - std::vector<int32_t>* configs) override; - ndk::ScopedAStatus getDisplayConnectionType( - int64_t displayId, DisplayConnectionType* type) override; - ndk::ScopedAStatus getDisplayIdentificationData( - int64_t displayId, DisplayIdentification* id) override; - ndk::ScopedAStatus getDisplayName(int64_t displayId, - std::string* name) override; - ndk::ScopedAStatus getDisplayVsyncPeriod(int64_t displayId, - int32_t* vsyncPeriod) override; - ndk::ScopedAStatus getDisplayedContentSample( - int64_t displayId, int64_t maxFrames, int64_t timestamp, - DisplayContentSample* samples) override; - ndk::ScopedAStatus getDisplayedContentSamplingAttributes( - int64_t displayId, DisplayContentSamplingAttributes* attrs) override; - ndk::ScopedAStatus getDisplayPhysicalOrientation( - int64_t displayId, common::Transform* orientation) override; - ndk::ScopedAStatus getHdrCapabilities(int64_t displayId, - HdrCapabilities* caps) override; - ndk::ScopedAStatus getOverlaySupport(OverlayProperties* properties) override; - ndk::ScopedAStatus getMaxVirtualDisplayCount(int32_t* count) override; - ndk::ScopedAStatus getPerFrameMetadataKeys( - int64_t displayId, std::vector<PerFrameMetadataKey>* keys) override; - ndk::ScopedAStatus getReadbackBufferAttributes( - int64_t displayId, ReadbackBufferAttributes* attrs) override; - ndk::ScopedAStatus getReadbackBufferFence( - int64_t displayId, ndk::ScopedFileDescriptor* acquireFence) override; - ndk::ScopedAStatus getRenderIntents( - int64_t displayId, ColorMode mode, - std::vector<RenderIntent>* intents) override; - ndk::ScopedAStatus getSupportedContentTypes( - int64_t displayId, std::vector<ContentType>* types) override; - ndk::ScopedAStatus getDisplayDecorationSupport( - int64_t displayId, - std::optional<common::DisplayDecorationSupport>* support) override; - ndk::ScopedAStatus registerCallback( - const std::shared_ptr<IComposerCallback>& callback) override; - ndk::ScopedAStatus setActiveConfig(int64_t displayId, - int32_t config) override; - ndk::ScopedAStatus setActiveConfigWithConstraints( - int64_t displayId, int32_t config, - const VsyncPeriodChangeConstraints& constraints, - VsyncPeriodChangeTimeline* timeline) override; - ndk::ScopedAStatus setBootDisplayConfig(int64_t displayId, - int32_t config) override; - ndk::ScopedAStatus clearBootDisplayConfig(int64_t displayId) override; - ndk::ScopedAStatus getPreferredBootDisplayConfig(int64_t displayId, - int32_t* config) override; - ndk::ScopedAStatus getHdrConversionCapabilities( - std::vector<aidl::android::hardware::graphics::common::HdrConversionCapability>*) override; - ndk::ScopedAStatus setHdrConversionStrategy( - const aidl::android::hardware::graphics::common::HdrConversionStrategy& conversionStrategy, - aidl::android::hardware::graphics::common::Hdr* preferredHdrOutputType) override; - ndk::ScopedAStatus setAutoLowLatencyMode(int64_t displayId, bool on) override; - ndk::ScopedAStatus setClientTargetSlotCount(int64_t displayId, - int32_t count) override; - ndk::ScopedAStatus setColorMode(int64_t displayId, ColorMode mode, - RenderIntent intent) override; - ndk::ScopedAStatus setContentType(int64_t displayId, - ContentType type) override; - ndk::ScopedAStatus setDisplayedContentSamplingEnabled( - int64_t displayId, bool enable, FormatColorComponent componentMask, - int64_t maxFrames) override; - ndk::ScopedAStatus setPowerMode(int64_t displayId, PowerMode mode) override; - ndk::ScopedAStatus setReadbackBuffer( - int64_t displayId, - const aidl::android::hardware::common::NativeHandle& buffer, - const ndk::ScopedFileDescriptor& releaseFence) override; - ndk::ScopedAStatus setVsyncEnabled(int64_t displayId, bool enabled) override; - ndk::ScopedAStatus setIdleTimerEnabled(int64_t displayId, - int32_t timeoutMs) override; - ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t displayId, - bool enabled) override; - - protected: - ndk::SpAIBinder createBinder() override; - - private: - class CommandResultWriter; - - void executeDisplayCommand(const DisplayCommand& displayCommand); - void executeLayerCommand(Display* display, const LayerCommand& layerCommand); - - void executeDisplayCommandSetColorTransform(Display* display, - const std::vector<float>& matrix); - void executeDisplayCommandSetBrightness(Display* display, - const DisplayBrightness& brightness); - void executeDisplayCommandSetClientTarget(Display* display, - const ClientTarget& command); - void executeDisplayCommandSetOutputBuffer(Display* display, - const Buffer& buffer); - void executeDisplayCommandValidateDisplay( - Display* display, - const std::optional<ClockMonotonicTimestamp> expectedPresentTime); - void executeDisplayCommandAcceptDisplayChanges(Display* display); - void executeDisplayCommandPresentOrValidateDisplay( - Display* display, - const std::optional<ClockMonotonicTimestamp> expectedPresentTime); - void executeDisplayCommandPresentDisplay(Display* display); - - void executeLayerCommandSetLayerCursorPosition( - Display* display, Layer* layer, const common::Point& cursorPosition); - void executeLayerCommandSetLayerBuffer(Display* display, Layer* layer, - const Buffer& buffer); - void executeLayerCommandSetLayerSurfaceDamage( - Display* display, Layer* layer, - const std::vector<std::optional<common::Rect>>& damage); - void executeLayerCommandSetLayerBlendMode( - Display* display, Layer* layer, const ParcelableBlendMode& blendMode); - void executeLayerCommandSetLayerColor(Display* display, Layer* layer, - const Color& color); - void executeLayerCommandSetLayerComposition( - Display* display, Layer* layer, const ParcelableComposition& composition); - void executeLayerCommandSetLayerDataspace( - Display* display, Layer* layer, const ParcelableDataspace& dataspace); - void executeLayerCommandSetLayerDisplayFrame(Display* display, Layer* layer, - const common::Rect& rect); - void executeLayerCommandSetLayerPlaneAlpha(Display* display, Layer* layer, - const PlaneAlpha& planeAlpha); - void executeLayerCommandSetLayerSidebandStream( - Display* display, Layer* layer, - const aidl::android::hardware::common::NativeHandle& sidebandStream); - void executeLayerCommandSetLayerSourceCrop(Display* display, Layer* layer, - const common::FRect& sourceCrop); - void executeLayerCommandSetLayerTransform( - Display* display, Layer* layer, const ParcelableTransform& transform); - void executeLayerCommandSetLayerVisibleRegion( - Display* display, Layer* layer, - const std::vector<std::optional<common::Rect>>& visibleRegion); - void executeLayerCommandSetLayerZOrder(Display* display, Layer* layer, - const ZOrder& zOrder); - void executeLayerCommandSetLayerPerFrameMetadata( - Display* display, Layer* layer, - const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata); - void executeLayerCommandSetLayerColorTransform( - Display* display, Layer* layer, const std::vector<float>& colorTransform); - void executeLayerCommandSetLayerBrightness(Display* display, Layer* layer, - const LayerBrightness& brightness); - void executeLayerCommandSetLayerPerFrameMetadataBlobs( - Display* display, Layer* layer, - const std::vector<std::optional<PerFrameMetadataBlob>>& - perFrameMetadataBlob); - - // Returns the display with the given id or nullptr if not found. - Display* getDisplay(int64_t displayId); - - // Finds the Cuttlefish/Goldfish specific configuration and initializes the - // displays. - HWC3::Error createDisplaysLocked(); - - // Creates a display with the given properties. - HWC3::Error createDisplayLocked(int64_t displayId, int32_t activeConfigId, - const std::vector<DisplayConfig>& configs); - - HWC3::Error destroyDisplaysLocked(); - - HWC3::Error destroyDisplayLocked(int64_t displayId); - - HWC3::Error handleHotplug(bool connected, // - uint32_t id, // - uint32_t width, // - uint32_t height, // - uint32_t dpiX, // - uint32_t dpiY, // - uint32_t refreshRate); - - std::mutex mStateMutex; - - std::map<int64_t, std::unique_ptr<Display>> mDisplays; - - // The onHotplug(), onVsync(), etc callbacks registered by SurfaceFlinger. - std::shared_ptr<IComposerCallback> mCallbacks; - - std::function<void()> mOnClientDestroyed; - - // Underlying interface for composing layers in the guest using libyuv or in - // the host using opengl. Owned by Device. - FrameComposer* mComposer = nullptr; - - // For the duration of a executeCommands(), the helper used to collect - // individual command results. - std::unique_ptr<CommandResultWriter> mCommandResults; - - // Manages importing and caching gralloc buffers for displays and layers. - std::unique_ptr<ComposerResources> mResources; + public: + ComposerClient(); + virtual ~ComposerClient(); + + HWC3::Error init(); + + void setOnClientDestroyed(std::function<void()> onClientDestroyed) { + mOnClientDestroyed = onClientDestroyed; + } + + // HWC3 interface: + ndk::ScopedAStatus createLayer(int64_t displayId, int32_t bufferSlotCount, + int64_t* layer) override; + ndk::ScopedAStatus createVirtualDisplay(int32_t width, int32_t height, + common::PixelFormat formatHint, + int32_t outputBufferSlotCount, + VirtualDisplay* display) override; + ndk::ScopedAStatus destroyLayer(int64_t displayId, int64_t layer) override; + ndk::ScopedAStatus destroyVirtualDisplay(int64_t displayId) override; + ndk::ScopedAStatus executeCommands(const std::vector<DisplayCommand>& commands, + std::vector<CommandResultPayload>* results) override; + ndk::ScopedAStatus getActiveConfig(int64_t displayId, int32_t* config) override; + ndk::ScopedAStatus getColorModes(int64_t displayId, + std::vector<ColorMode>* colorModes) override; + ndk::ScopedAStatus getDataspaceSaturationMatrix(common::Dataspace dataspace, + std::vector<float>* matrix) override; + ndk::ScopedAStatus getDisplayAttribute(int64_t displayId, int32_t config, + DisplayAttribute attribute, int32_t* value) override; + ndk::ScopedAStatus getDisplayCapabilities(int64_t displayId, + std::vector<DisplayCapability>* caps) override; + ndk::ScopedAStatus getDisplayConfigs(int64_t displayId, std::vector<int32_t>* configs) override; + ndk::ScopedAStatus getDisplayConnectionType(int64_t displayId, + DisplayConnectionType* type) override; + ndk::ScopedAStatus getDisplayIdentificationData(int64_t displayId, + DisplayIdentification* id) override; + ndk::ScopedAStatus getDisplayName(int64_t displayId, std::string* name) override; + ndk::ScopedAStatus getDisplayVsyncPeriod(int64_t displayId, int32_t* vsyncPeriod) override; + ndk::ScopedAStatus getDisplayedContentSample(int64_t displayId, int64_t maxFrames, + int64_t timestamp, + DisplayContentSample* samples) override; + ndk::ScopedAStatus getDisplayedContentSamplingAttributes( + int64_t displayId, DisplayContentSamplingAttributes* attrs) override; + ndk::ScopedAStatus getDisplayPhysicalOrientation(int64_t displayId, + common::Transform* orientation) override; + ndk::ScopedAStatus getHdrCapabilities(int64_t displayId, HdrCapabilities* caps) override; + ndk::ScopedAStatus getOverlaySupport(OverlayProperties* properties) override; + ndk::ScopedAStatus getMaxVirtualDisplayCount(int32_t* count) override; + ndk::ScopedAStatus getPerFrameMetadataKeys(int64_t displayId, + std::vector<PerFrameMetadataKey>* keys) override; + ndk::ScopedAStatus getReadbackBufferAttributes(int64_t displayId, + ReadbackBufferAttributes* attrs) override; + ndk::ScopedAStatus getReadbackBufferFence(int64_t displayId, + ndk::ScopedFileDescriptor* acquireFence) override; + ndk::ScopedAStatus getRenderIntents(int64_t displayId, ColorMode mode, + std::vector<RenderIntent>* intents) override; + ndk::ScopedAStatus getSupportedContentTypes(int64_t displayId, + std::vector<ContentType>* types) override; + ndk::ScopedAStatus getDisplayDecorationSupport( + int64_t displayId, std::optional<common::DisplayDecorationSupport>* support) override; + ndk::ScopedAStatus registerCallback( + const std::shared_ptr<IComposerCallback>& callback) override; + ndk::ScopedAStatus setActiveConfig(int64_t displayId, int32_t config) override; + ndk::ScopedAStatus setActiveConfigWithConstraints( + int64_t displayId, int32_t config, const VsyncPeriodChangeConstraints& constraints, + VsyncPeriodChangeTimeline* timeline) override; + ndk::ScopedAStatus setBootDisplayConfig(int64_t displayId, int32_t config) override; + ndk::ScopedAStatus clearBootDisplayConfig(int64_t displayId) override; + ndk::ScopedAStatus getPreferredBootDisplayConfig(int64_t displayId, int32_t* config) override; + ndk::ScopedAStatus getHdrConversionCapabilities( + std::vector<aidl::android::hardware::graphics::common::HdrConversionCapability>*) override; + ndk::ScopedAStatus setHdrConversionStrategy( + const aidl::android::hardware::graphics::common::HdrConversionStrategy& conversionStrategy, + aidl::android::hardware::graphics::common::Hdr* preferredHdrOutputType) override; + ndk::ScopedAStatus setAutoLowLatencyMode(int64_t displayId, bool on) override; + ndk::ScopedAStatus setClientTargetSlotCount(int64_t displayId, int32_t count) override; + ndk::ScopedAStatus setColorMode(int64_t displayId, ColorMode mode, + RenderIntent intent) override; + ndk::ScopedAStatus setContentType(int64_t displayId, ContentType type) override; + ndk::ScopedAStatus setDisplayedContentSamplingEnabled(int64_t displayId, bool enable, + FormatColorComponent componentMask, + int64_t maxFrames) override; + ndk::ScopedAStatus setPowerMode(int64_t displayId, PowerMode mode) override; + ndk::ScopedAStatus setReadbackBuffer( + int64_t displayId, const aidl::android::hardware::common::NativeHandle& buffer, + const ndk::ScopedFileDescriptor& releaseFence) override; + ndk::ScopedAStatus setVsyncEnabled(int64_t displayId, bool enabled) override; + ndk::ScopedAStatus setIdleTimerEnabled(int64_t displayId, int32_t timeoutMs) override; + ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t displayId, + bool enabled) override; + + protected: + ndk::SpAIBinder createBinder() override; + + private: + class CommandResultWriter; + + void executeDisplayCommand(const DisplayCommand& displayCommand); + void executeLayerCommand(Display* display, const LayerCommand& layerCommand); + + void executeDisplayCommandSetColorTransform(Display* display, const std::vector<float>& matrix); + void executeDisplayCommandSetBrightness(Display* display, const DisplayBrightness& brightness); + void executeDisplayCommandSetClientTarget(Display* display, const ClientTarget& command); + void executeDisplayCommandSetOutputBuffer(Display* display, const Buffer& buffer); + void executeDisplayCommandValidateDisplay( + Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime); + void executeDisplayCommandAcceptDisplayChanges(Display* display); + void executeDisplayCommandPresentOrValidateDisplay( + Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime); + void executeDisplayCommandPresentDisplay(Display* display); + + void executeLayerCommandSetLayerCursorPosition(Display* display, Layer* layer, + const common::Point& cursorPosition); + void executeLayerCommandSetLayerBuffer(Display* display, Layer* layer, const Buffer& buffer); + void executeLayerCommandSetLayerSurfaceDamage( + Display* display, Layer* layer, const std::vector<std::optional<common::Rect>>& damage); + void executeLayerCommandSetLayerBlendMode(Display* display, Layer* layer, + const ParcelableBlendMode& blendMode); + void executeLayerCommandSetLayerColor(Display* display, Layer* layer, const Color& color); + void executeLayerCommandSetLayerComposition(Display* display, Layer* layer, + const ParcelableComposition& composition); + void executeLayerCommandSetLayerDataspace(Display* display, Layer* layer, + const ParcelableDataspace& dataspace); + void executeLayerCommandSetLayerDisplayFrame(Display* display, Layer* layer, + const common::Rect& rect); + void executeLayerCommandSetLayerPlaneAlpha(Display* display, Layer* layer, + const PlaneAlpha& planeAlpha); + void executeLayerCommandSetLayerSidebandStream( + Display* display, Layer* layer, + const aidl::android::hardware::common::NativeHandle& sidebandStream); + void executeLayerCommandSetLayerSourceCrop(Display* display, Layer* layer, + const common::FRect& sourceCrop); + void executeLayerCommandSetLayerTransform(Display* display, Layer* layer, + const ParcelableTransform& transform); + void executeLayerCommandSetLayerVisibleRegion( + Display* display, Layer* layer, + const std::vector<std::optional<common::Rect>>& visibleRegion); + void executeLayerCommandSetLayerZOrder(Display* display, Layer* layer, const ZOrder& zOrder); + void executeLayerCommandSetLayerPerFrameMetadata( + Display* display, Layer* layer, + const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata); + void executeLayerCommandSetLayerColorTransform(Display* display, Layer* layer, + const std::vector<float>& colorTransform); + void executeLayerCommandSetLayerBrightness(Display* display, Layer* layer, + const LayerBrightness& brightness); + void executeLayerCommandSetLayerPerFrameMetadataBlobs( + Display* display, Layer* layer, + const std::vector<std::optional<PerFrameMetadataBlob>>& perFrameMetadataBlob); + + // Returns the display with the given id or nullptr if not found. + Display* getDisplay(int64_t displayId); + + // Finds the Cuttlefish/Goldfish specific configuration and initializes the + // displays. + HWC3::Error createDisplaysLocked(); + + // Creates a display with the given properties. + HWC3::Error createDisplayLocked(int64_t displayId, int32_t activeConfigId, + const std::vector<DisplayConfig>& configs); + + HWC3::Error destroyDisplaysLocked(); + + HWC3::Error destroyDisplayLocked(int64_t displayId); + + HWC3::Error handleHotplug(bool connected, // + uint32_t id, // + uint32_t width, // + uint32_t height, // + uint32_t dpiX, // + uint32_t dpiY, // + uint32_t refreshRate); + + std::mutex mStateMutex; + + std::map<int64_t, std::unique_ptr<Display>> mDisplays; + + // The onHotplug(), onVsync(), etc callbacks registered by SurfaceFlinger. + std::shared_ptr<IComposerCallback> mCallbacks; + + std::function<void()> mOnClientDestroyed; + + // Underlying interface for composing layers in the guest using libyuv or in + // the host using opengl. Owned by Device. + FrameComposer* mComposer = nullptr; + + // For the duration of a executeCommands(), the helper used to collect + // individual command results. + std::unique_ptr<CommandResultWriter> mCommandResults; + + // Manages importing and caching gralloc buffers for displays and layers. + std::unique_ptr<ComposerResources> mResources; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/ComposerResources.cpp b/system/hwc3/ComposerResources.cpp index 35990889..8083b45d 100644 --- a/system/hwc3/ComposerResources.cpp +++ b/system/hwc3/ComposerResources.cpp @@ -21,235 +21,196 @@ namespace aidl::android::hardware::graphics::composer3::impl { namespace { -HWC3::Error toHwc3Error( - ::android::hardware::graphics::composer::V2_1::Error error) { - switch (error) { - case ::android::hardware::graphics::composer::V2_1::Error::NONE: - return HWC3::Error::None; - case ::android::hardware::graphics::composer::V2_1::Error::BAD_CONFIG: - return HWC3::Error::BadConfig; - case ::android::hardware::graphics::composer::V2_1::Error::BAD_DISPLAY: - return HWC3::Error::BadDisplay; - case ::android::hardware::graphics::composer::V2_1::Error::BAD_LAYER: - return HWC3::Error::BadLayer; - case ::android::hardware::graphics::composer::V2_1::Error::BAD_PARAMETER: - return HWC3::Error::BadParameter; - case ::android::hardware::graphics::composer::V2_1::Error::NO_RESOURCES: - return HWC3::Error::NoResources; - case ::android::hardware::graphics::composer::V2_1::Error::NOT_VALIDATED: - return HWC3::Error::NotValidated; - case ::android::hardware::graphics::composer::V2_1::Error::UNSUPPORTED: - return HWC3::Error::Unsupported; - } -} - -::android::hardware::graphics::composer::V2_1::Display toHwc2Display( - int64_t displayId) { - return static_cast<::android::hardware::graphics::composer::V2_1::Display>( - displayId); -} - -::android::hardware::graphics::composer::V2_1::Layer toHwc2Layer( - int64_t layerId) { - return static_cast<::android::hardware::graphics::composer::V2_1::Layer>( - layerId); +HWC3::Error toHwc3Error(::android::hardware::graphics::composer::V2_1::Error error) { + switch (error) { + case ::android::hardware::graphics::composer::V2_1::Error::NONE: + return HWC3::Error::None; + case ::android::hardware::graphics::composer::V2_1::Error::BAD_CONFIG: + return HWC3::Error::BadConfig; + case ::android::hardware::graphics::composer::V2_1::Error::BAD_DISPLAY: + return HWC3::Error::BadDisplay; + case ::android::hardware::graphics::composer::V2_1::Error::BAD_LAYER: + return HWC3::Error::BadLayer; + case ::android::hardware::graphics::composer::V2_1::Error::BAD_PARAMETER: + return HWC3::Error::BadParameter; + case ::android::hardware::graphics::composer::V2_1::Error::NO_RESOURCES: + return HWC3::Error::NoResources; + case ::android::hardware::graphics::composer::V2_1::Error::NOT_VALIDATED: + return HWC3::Error::NotValidated; + case ::android::hardware::graphics::composer::V2_1::Error::UNSUPPORTED: + return HWC3::Error::Unsupported; + } +} + +::android::hardware::graphics::composer::V2_1::Display toHwc2Display(int64_t displayId) { + return static_cast<::android::hardware::graphics::composer::V2_1::Display>(displayId); +} + +::android::hardware::graphics::composer::V2_1::Layer toHwc2Layer(int64_t layerId) { + return static_cast<::android::hardware::graphics::composer::V2_1::Layer>(layerId); } } // namespace -std::unique_ptr<ComposerResourceReleaser> ComposerResources::createReleaser( - bool isBuffer) { - return std::make_unique<ComposerResourceReleaser>(isBuffer); +std::unique_ptr<ComposerResourceReleaser> ComposerResources::createReleaser(bool isBuffer) { + return std::make_unique<ComposerResourceReleaser>(isBuffer); } HWC3::Error ComposerResources::init() { - mImpl = ::android::hardware::graphics::composer::V2_2::hal:: - ComposerResources::create(); - if (!mImpl) { - ALOGE("%s: failed to create underlying ComposerResources.", __FUNCTION__); - return HWC3::Error::NoResources; - } - return HWC3::Error::None; + mImpl = ::android::hardware::graphics::composer::V2_2::hal::ComposerResources::create(); + if (!mImpl) { + ALOGE("%s: failed to create underlying ComposerResources.", __FUNCTION__); + return HWC3::Error::NoResources; + } + return HWC3::Error::None; } void ComposerResources::clear( - ::android::hardware::graphics::composer::V2_2::hal::ComposerResources:: - RemoveDisplay removeDisplay) { - mImpl->clear(removeDisplay); + ::android::hardware::graphics::composer::V2_2::hal::ComposerResources::RemoveDisplay + removeDisplay) { + mImpl->clear(removeDisplay); } bool ComposerResources::hasDisplay(int64_t displayId) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return mImpl->hasDisplay(display); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return mImpl->hasDisplay(display); } HWC3::Error ComposerResources::addPhysicalDisplay(int64_t displayId) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, displayId); - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error(mImpl->addPhysicalDisplay(display)); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, displayId); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->addPhysicalDisplay(display)); } -HWC3::Error ComposerResources::addVirtualDisplay( - int64_t displayId, uint32_t outputBufferCacheSize) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error(mImpl->addVirtualDisplay(display, outputBufferCacheSize)); +HWC3::Error ComposerResources::addVirtualDisplay(int64_t displayId, + uint32_t outputBufferCacheSize) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->addVirtualDisplay(display, outputBufferCacheSize)); } HWC3::Error ComposerResources::removeDisplay(int64_t displayId) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error(mImpl->removeDisplay(display)); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->removeDisplay(display)); } -HWC3::Error ComposerResources::setDisplayClientTargetCacheSize( - int64_t displayId, uint32_t clientTargetCacheSize) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error( - mImpl->setDisplayClientTargetCacheSize(display, clientTargetCacheSize)); +HWC3::Error ComposerResources::setDisplayClientTargetCacheSize(int64_t displayId, + uint32_t clientTargetCacheSize) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->setDisplayClientTargetCacheSize(display, clientTargetCacheSize)); } -HWC3::Error ComposerResources::getDisplayClientTargetCacheSize( - int64_t displayId, size_t* outCacheSize) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error( - mImpl->getDisplayClientTargetCacheSize(display, outCacheSize)); +HWC3::Error ComposerResources::getDisplayClientTargetCacheSize(int64_t displayId, + size_t* outCacheSize) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->getDisplayClientTargetCacheSize(display, outCacheSize)); } -HWC3::Error ComposerResources::getDisplayOutputBufferCacheSize( - int64_t displayId, size_t* outCacheSize) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error( - mImpl->getDisplayOutputBufferCacheSize(display, outCacheSize)); +HWC3::Error ComposerResources::getDisplayOutputBufferCacheSize(int64_t displayId, + size_t* outCacheSize) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->getDisplayOutputBufferCacheSize(display, outCacheSize)); } HWC3::Error ComposerResources::addLayer(int64_t displayId, int64_t layerId, uint32_t bufferCacheSize) { - DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, - layerId); + DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, layerId); - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - ::android::hardware::graphics::composer::V2_1::Layer layer = - toHwc2Layer(layerId); - return toHwc3Error(mImpl->addLayer(display, layer, bufferCacheSize)); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + ::android::hardware::graphics::composer::V2_1::Layer layer = toHwc2Layer(layerId); + return toHwc3Error(mImpl->addLayer(display, layer, bufferCacheSize)); } HWC3::Error ComposerResources::removeLayer(int64_t displayId, int64_t layerId) { - DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, - layerId); + DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, layerId); - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - ::android::hardware::graphics::composer::V2_1::Layer layer = - toHwc2Layer(layerId); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + ::android::hardware::graphics::composer::V2_1::Layer layer = toHwc2Layer(layerId); - return toHwc3Error(mImpl->removeLayer(display, layer)); + return toHwc3Error(mImpl->removeLayer(display, layer)); } -void ComposerResources::setDisplayMustValidateState(int64_t displayId, - bool mustValidate) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - mImpl->setDisplayMustValidateState(display, mustValidate); +void ComposerResources::setDisplayMustValidateState(int64_t displayId, bool mustValidate) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + mImpl->setDisplayMustValidateState(display, mustValidate); } bool ComposerResources::mustValidateDisplay(int64_t displayId) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return mImpl->mustValidateDisplay(display); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return mImpl->mustValidateDisplay(display); } HWC3::Error ComposerResources::getDisplayReadbackBuffer( - int64_t displayId, - const aidl::android::hardware::common::NativeHandle& handle, + int64_t displayId, const aidl::android::hardware::common::NativeHandle& handle, buffer_handle_t* outHandle, ComposerResourceReleaser* releaser) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - return toHwc3Error(mImpl->getDisplayReadbackBuffer( - display, ::android::makeFromAidl(handle), outHandle, - releaser->getReplacedHandle())); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + return toHwc3Error(mImpl->getDisplayReadbackBuffer(display, ::android::makeFromAidl(handle), + outHandle, releaser->getReplacedHandle())); } -HWC3::Error ComposerResources::getDisplayClientTarget( - int64_t displayId, const Buffer& buffer, buffer_handle_t* outHandle, - ComposerResourceReleaser* releaser) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); +HWC3::Error ComposerResources::getDisplayClientTarget(int64_t displayId, const Buffer& buffer, + buffer_handle_t* outHandle, + ComposerResourceReleaser* releaser) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); - const bool useCache = !buffer.handle.has_value(); + const bool useCache = !buffer.handle.has_value(); - buffer_handle_t bufferHandle = nullptr; - if (buffer.handle.has_value()) { - bufferHandle = ::android::makeFromAidl(*buffer.handle); - } + buffer_handle_t bufferHandle = nullptr; + if (buffer.handle.has_value()) { + bufferHandle = ::android::makeFromAidl(*buffer.handle); + } - return toHwc3Error(mImpl->getDisplayClientTarget(display, static_cast<uint32_t>(buffer.slot), - useCache, bufferHandle, outHandle, - releaser->getReplacedHandle())); + return toHwc3Error(mImpl->getDisplayClientTarget(display, static_cast<uint32_t>(buffer.slot), + useCache, bufferHandle, outHandle, + releaser->getReplacedHandle())); } -HWC3::Error ComposerResources::getDisplayOutputBuffer( - int64_t displayId, const Buffer& buffer, buffer_handle_t* outHandle, - ComposerResourceReleaser* releaser) { - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); +HWC3::Error ComposerResources::getDisplayOutputBuffer(int64_t displayId, const Buffer& buffer, + buffer_handle_t* outHandle, + ComposerResourceReleaser* releaser) { + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); - const bool useCache = !buffer.handle.has_value(); + const bool useCache = !buffer.handle.has_value(); - buffer_handle_t bufferHandle = nullptr; - if (buffer.handle.has_value()) { - bufferHandle = ::android::makeFromAidl(*buffer.handle); - } + buffer_handle_t bufferHandle = nullptr; + if (buffer.handle.has_value()) { + bufferHandle = ::android::makeFromAidl(*buffer.handle); + } - return toHwc3Error(mImpl->getDisplayOutputBuffer(display, static_cast<uint32_t>(buffer.slot), - useCache, bufferHandle, outHandle, - releaser->getReplacedHandle())); + return toHwc3Error(mImpl->getDisplayOutputBuffer(display, static_cast<uint32_t>(buffer.slot), + useCache, bufferHandle, outHandle, + releaser->getReplacedHandle())); } -HWC3::Error ComposerResources::getLayerBuffer( - int64_t displayId, int64_t layerId, const Buffer& buffer, - buffer_handle_t* outHandle, ComposerResourceReleaser* releaser) { - DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, - layerId); +HWC3::Error ComposerResources::getLayerBuffer(int64_t displayId, int64_t layerId, + const Buffer& buffer, buffer_handle_t* outHandle, + ComposerResourceReleaser* releaser) { + DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, layerId); - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - ::android::hardware::graphics::composer::V2_1::Layer layer = - toHwc2Layer(layerId); + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + ::android::hardware::graphics::composer::V2_1::Layer layer = toHwc2Layer(layerId); - const bool useCache = !buffer.handle.has_value(); + const bool useCache = !buffer.handle.has_value(); - buffer_handle_t bufferHandle = nullptr; - if (buffer.handle.has_value()) { - bufferHandle = ::android::makeFromAidl(*buffer.handle); - } + buffer_handle_t bufferHandle = nullptr; + if (buffer.handle.has_value()) { + bufferHandle = ::android::makeFromAidl(*buffer.handle); + } - DEBUG_LOG("%s fromCache:%s", __FUNCTION__, (useCache ? "yes" : "no")); - return toHwc3Error(mImpl->getLayerBuffer(display, layer, static_cast<uint32_t>(buffer.slot), - useCache, bufferHandle, outHandle, - releaser->getReplacedHandle())); + DEBUG_LOG("%s fromCache:%s", __FUNCTION__, (useCache ? "yes" : "no")); + return toHwc3Error(mImpl->getLayerBuffer(display, layer, static_cast<uint32_t>(buffer.slot), + useCache, bufferHandle, outHandle, + releaser->getReplacedHandle())); } HWC3::Error ComposerResources::getLayerSidebandStream( - int64_t displayId, int64_t layerId, - const aidl::android::hardware::common::NativeHandle& handle, + int64_t displayId, int64_t layerId, const aidl::android::hardware::common::NativeHandle& handle, buffer_handle_t* outHandle, ComposerResourceReleaser* releaser) { - DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, - layerId); - - ::android::hardware::graphics::composer::V2_1::Display display = - toHwc2Display(displayId); - ::android::hardware::graphics::composer::V2_1::Layer layer = - toHwc2Layer(layerId); - return toHwc3Error(mImpl->getLayerSidebandStream( - display, layer, ::android::makeFromAidl(handle), outHandle, - releaser->getReplacedHandle())); + DEBUG_LOG("%s: display:%" PRId64 " layer:%" PRId64, __FUNCTION__, displayId, layerId); + + ::android::hardware::graphics::composer::V2_1::Display display = toHwc2Display(displayId); + ::android::hardware::graphics::composer::V2_1::Layer layer = toHwc2Layer(layerId); + return toHwc3Error(mImpl->getLayerSidebandStream( + display, layer, ::android::makeFromAidl(handle), outHandle, releaser->getReplacedHandle())); } } // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file diff --git a/system/hwc3/ComposerResources.h b/system/hwc3/ComposerResources.h index faf6a4d0..2f79dc88 100644 --- a/system/hwc3/ComposerResources.h +++ b/system/hwc3/ComposerResources.h @@ -32,86 +32,76 @@ namespace aidl::android::hardware::graphics::composer3::impl { class ComposerResourceReleaser { - public: - ComposerResourceReleaser(bool isBuffer) : mReplacedHandle(isBuffer) {} - virtual ~ComposerResourceReleaser() = default; - - ::android::hardware::graphics::composer::V2_2::hal::ComposerResources:: - ReplacedHandle* - getReplacedHandle() { - return &mReplacedHandle; - } - - private: - ::android::hardware::graphics::composer::V2_2::hal::ComposerResources:: - ReplacedHandle mReplacedHandle; + public: + ComposerResourceReleaser(bool isBuffer) : mReplacedHandle(isBuffer) {} + virtual ~ComposerResourceReleaser() = default; + + ::android::hardware::graphics::composer::V2_2::hal::ComposerResources::ReplacedHandle* + getReplacedHandle() { + return &mReplacedHandle; + } + + private: + ::android::hardware::graphics::composer::V2_2::hal::ComposerResources::ReplacedHandle + mReplacedHandle; }; class ComposerResources { - public: - ComposerResources() = default; + public: + ComposerResources() = default; - HWC3::Error init(); + HWC3::Error init(); - std::unique_ptr<ComposerResourceReleaser> createReleaser(bool isBuffer); + std::unique_ptr<ComposerResourceReleaser> createReleaser(bool isBuffer); - void clear(::android::hardware::graphics::composer::V2_2::hal:: - ComposerResources::RemoveDisplay removeDisplay); + void clear(::android::hardware::graphics::composer::V2_2::hal::ComposerResources::RemoveDisplay + removeDisplay); - bool hasDisplay(int64_t display); + bool hasDisplay(int64_t display); - HWC3::Error addPhysicalDisplay(int64_t display); + HWC3::Error addPhysicalDisplay(int64_t display); - HWC3::Error addVirtualDisplay(int64_t displayId, - uint32_t outputBufferCacheSize); + HWC3::Error addVirtualDisplay(int64_t displayId, uint32_t outputBufferCacheSize); - HWC3::Error removeDisplay(int64_t display); + HWC3::Error removeDisplay(int64_t display); - HWC3::Error setDisplayClientTargetCacheSize(int64_t displayId, - uint32_t clientTargetCacheSize); + HWC3::Error setDisplayClientTargetCacheSize(int64_t displayId, uint32_t clientTargetCacheSize); - HWC3::Error getDisplayClientTargetCacheSize(int64_t displayId, - size_t* outCacheSize); + HWC3::Error getDisplayClientTargetCacheSize(int64_t displayId, size_t* outCacheSize); - HWC3::Error getDisplayOutputBufferCacheSize(int64_t displayId, - size_t* outCacheSize); + HWC3::Error getDisplayOutputBufferCacheSize(int64_t displayId, size_t* outCacheSize); - HWC3::Error addLayer(int64_t displayId, int64_t layerId, - uint32_t bufferCacheSize); + HWC3::Error addLayer(int64_t displayId, int64_t layerId, uint32_t bufferCacheSize); - HWC3::Error removeLayer(int64_t displayId, int64_t layer); + HWC3::Error removeLayer(int64_t displayId, int64_t layer); - void setDisplayMustValidateState(int64_t displayId, bool mustValidate); + void setDisplayMustValidateState(int64_t displayId, bool mustValidate); - bool mustValidateDisplay(int64_t displayId); + bool mustValidateDisplay(int64_t displayId); - HWC3::Error getDisplayReadbackBuffer( - int64_t displayId, - const aidl::android::hardware::common::NativeHandle& handle, - buffer_handle_t* outHandle, ComposerResourceReleaser* bufReleaser); + HWC3::Error getDisplayReadbackBuffer( + int64_t displayId, const aidl::android::hardware::common::NativeHandle& handle, + buffer_handle_t* outHandle, ComposerResourceReleaser* bufReleaser); - HWC3::Error getDisplayClientTarget(int64_t displayId, const Buffer& buffer, - buffer_handle_t* outHandle, - ComposerResourceReleaser* bufReleaser); + HWC3::Error getDisplayClientTarget(int64_t displayId, const Buffer& buffer, + buffer_handle_t* outHandle, + ComposerResourceReleaser* bufReleaser); - HWC3::Error getDisplayOutputBuffer(int64_t displayId, const Buffer& buffer, - buffer_handle_t* outHandle, - ComposerResourceReleaser* bufReleaser); + HWC3::Error getDisplayOutputBuffer(int64_t displayId, const Buffer& buffer, + buffer_handle_t* outHandle, + ComposerResourceReleaser* bufReleaser); - HWC3::Error getLayerBuffer(int64_t displayId, int64_t layerId, - const Buffer& buffer, - buffer_handle_t* outBufferHandle, - ComposerResourceReleaser* bufReleaser); + HWC3::Error getLayerBuffer(int64_t displayId, int64_t layerId, const Buffer& buffer, + buffer_handle_t* outBufferHandle, + ComposerResourceReleaser* bufReleaser); - HWC3::Error getLayerSidebandStream( - int64_t displayId, int64_t layerId, - const aidl::android::hardware::common::NativeHandle& rawHandle, - buffer_handle_t* outStreamHandle, ComposerResourceReleaser* bufReleaser); + HWC3::Error getLayerSidebandStream( + int64_t displayId, int64_t layerId, + const aidl::android::hardware::common::NativeHandle& rawHandle, + buffer_handle_t* outStreamHandle, ComposerResourceReleaser* bufReleaser); - private: - std::unique_ptr< - ::android::hardware::graphics::composer::V2_2::hal::ComposerResources> - mImpl; + private: + std::unique_ptr< ::android::hardware::graphics::composer::V2_2::hal::ComposerResources> mImpl; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Device.cpp b/system/hwc3/Device.cpp index 894d48b4..04933ab4 100644 --- a/system/hwc3/Device.cpp +++ b/system/hwc3/Device.cpp @@ -26,147 +26,140 @@ #include "HostFrameComposer.h" #include "NoOpFrameComposer.h" -ANDROID_SINGLETON_STATIC_INSTANCE( - aidl::android::hardware::graphics::composer3::impl::Device); +ANDROID_SINGLETON_STATIC_INSTANCE(aidl::android::hardware::graphics::composer3::impl::Device); namespace aidl::android::hardware::graphics::composer3::impl { namespace { bool shouldUseGuestComposer() { - return ::android::base::GetProperty("ro.hardware.vulkan", "") == "pastel"; + return ::android::base::GetProperty("ro.hardware.vulkan", "") == "pastel"; } -std::string getPmemPath() { - return ::android::base::GetProperty("ro.vendor.hwcomposer.pmem", ""); -} +std::string getPmemPath() { return ::android::base::GetProperty("ro.vendor.hwcomposer.pmem", ""); } HWC3::Error loadPersistentKeyValues(Json::Value* dictionary) { - *dictionary = Json::Value(Json::ValueType::objectValue); - - const std::string path = getPmemPath(); - if (path.empty()) { - ALOGE("%s: persistent key-value store path not available.", __FUNCTION__); - return HWC3::Error::NoResources; - } - - std::string content; - if (!::android::base::ReadFileToString(path, &content)) { - ALOGE("%s: failed to read key-value store from %s", __FUNCTION__, - path.c_str()); - return HWC3::Error::NoResources; - } - - if (content.empty() || content[0] == '\0') { - return HWC3::Error::None; - } + *dictionary = Json::Value(Json::ValueType::objectValue); + + const std::string path = getPmemPath(); + if (path.empty()) { + ALOGE("%s: persistent key-value store path not available.", __FUNCTION__); + return HWC3::Error::NoResources; + } + + std::string content; + if (!::android::base::ReadFileToString(path, &content)) { + ALOGE("%s: failed to read key-value store from %s", __FUNCTION__, path.c_str()); + return HWC3::Error::NoResources; + } + + if (content.empty() || content[0] == '\0') { + return HWC3::Error::None; + } - Json::Reader reader; - if (!reader.parse(content, *dictionary)) { - const std::string error = reader.getFormattedErrorMessages(); - ALOGE("%s: failed to parse key-value store from %s:%s", __FUNCTION__, - path.c_str(), error.c_str()); - return HWC3::Error::NoResources; - } + Json::Reader reader; + if (!reader.parse(content, *dictionary)) { + const std::string error = reader.getFormattedErrorMessages(); + ALOGE("%s: failed to parse key-value store from %s:%s", __FUNCTION__, path.c_str(), + error.c_str()); + return HWC3::Error::NoResources; + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error savePersistentKeyValues(const Json::Value& dictionary) { - const std::string path = getPmemPath(); - if (path.empty()) { - ALOGE("%s: persistent key-value store path not available.", __FUNCTION__); - return HWC3::Error::NoResources; - } - - const std::string contents = dictionary.toStyledString(); - if (!::android::base::WriteStringToFile(contents, path)) { - ALOGE("%s: failed to write key-value store to %s", __FUNCTION__, - path.c_str()); - return HWC3::Error::NoResources; - } - - return HWC3::Error::None; + const std::string path = getPmemPath(); + if (path.empty()) { + ALOGE("%s: persistent key-value store path not available.", __FUNCTION__); + return HWC3::Error::NoResources; + } + + const std::string contents = dictionary.toStyledString(); + if (!::android::base::WriteStringToFile(contents, path)) { + ALOGE("%s: failed to write key-value store to %s", __FUNCTION__, path.c_str()); + return HWC3::Error::NoResources; + } + + return HWC3::Error::None; } } // namespace HWC3::Error Device::getComposer(FrameComposer** outComposer) { - std::unique_lock<std::mutex> lock(mMutex); - - if (mComposer == nullptr) { - if (IsInNoOpCompositionMode()) { - DEBUG_LOG("%s: using NoOpFrameComposer", __FUNCTION__); - mComposer = std::make_unique<NoOpFrameComposer>(); - } else if (IsInClientCompositionMode()) { - DEBUG_LOG("%s: using ClientFrameComposer", __FUNCTION__); - mComposer = std::make_unique<ClientFrameComposer>(); - } else if (shouldUseGuestComposer()) { - DEBUG_LOG("%s: using GuestFrameComposer", __FUNCTION__); - mComposer = std::make_unique<GuestFrameComposer>(); - } else { - DEBUG_LOG("%s: using HostFrameComposer", __FUNCTION__); - mComposer = std::make_unique<HostFrameComposer>(); - } - if (!mComposer) { - ALOGE("%s failed to allocate FrameComposer", __FUNCTION__); - return HWC3::Error::NoResources; + std::unique_lock<std::mutex> lock(mMutex); + + if (mComposer == nullptr) { + if (IsInNoOpCompositionMode()) { + DEBUG_LOG("%s: using NoOpFrameComposer", __FUNCTION__); + mComposer = std::make_unique<NoOpFrameComposer>(); + } else if (IsInClientCompositionMode()) { + DEBUG_LOG("%s: using ClientFrameComposer", __FUNCTION__); + mComposer = std::make_unique<ClientFrameComposer>(); + } else if (shouldUseGuestComposer()) { + DEBUG_LOG("%s: using GuestFrameComposer", __FUNCTION__); + mComposer = std::make_unique<GuestFrameComposer>(); + } else { + DEBUG_LOG("%s: using HostFrameComposer", __FUNCTION__); + mComposer = std::make_unique<HostFrameComposer>(); + } + if (!mComposer) { + ALOGE("%s failed to allocate FrameComposer", __FUNCTION__); + return HWC3::Error::NoResources; + } + + HWC3::Error error = mComposer->init(); + if (error != HWC3::Error::None) { + ALOGE("%s failed to init FrameComposer", __FUNCTION__); + return error; + } } - HWC3::Error error = mComposer->init(); - if (error != HWC3::Error::None) { - ALOGE("%s failed to init FrameComposer", __FUNCTION__); - return error; - } - } - - *outComposer = mComposer.get(); - return HWC3::Error::None; + *outComposer = mComposer.get(); + return HWC3::Error::None; } -HWC3::Error Device::getPersistentKeyValue(const std::string& key, - const std::string& defaultValue, +HWC3::Error Device::getPersistentKeyValue(const std::string& key, const std::string& defaultValue, std::string* outValue) { - std::unique_lock<std::mutex> lock(mMutex); + std::unique_lock<std::mutex> lock(mMutex); - Json::Value dictionary; + Json::Value dictionary; - HWC3::Error error = loadPersistentKeyValues(&dictionary); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to load pmem json", __FUNCTION__); - return error; - } + HWC3::Error error = loadPersistentKeyValues(&dictionary); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to load pmem json", __FUNCTION__); + return error; + } - if (!dictionary.isMember(key)) { - *outValue = defaultValue; - return HWC3::Error::None; - } + if (!dictionary.isMember(key)) { + *outValue = defaultValue; + return HWC3::Error::None; + } - *outValue = defaultValue; + *outValue = defaultValue; - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error Device::setPersistentKeyValue(const std::string& key, - const std::string& value) { - std::unique_lock<std::mutex> lock(mMutex); +HWC3::Error Device::setPersistentKeyValue(const std::string& key, const std::string& value) { + std::unique_lock<std::mutex> lock(mMutex); - Json::Value dictionary; + Json::Value dictionary; - HWC3::Error error = loadPersistentKeyValues(&dictionary); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to load pmem json", __FUNCTION__); - return error; - } + HWC3::Error error = loadPersistentKeyValues(&dictionary); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to load pmem json", __FUNCTION__); + return error; + } - dictionary[key] = value; + dictionary[key] = value; - error = savePersistentKeyValues(dictionary); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to save pmem json", __FUNCTION__); - return error; - } + error = savePersistentKeyValues(dictionary); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to save pmem json", __FUNCTION__); + return error; + } - return HWC3::Error::None; + return HWC3::Error::None; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Device.h b/system/hwc3/Device.h index 6a3d0641..443786ab 100644 --- a/system/hwc3/Device.h +++ b/system/hwc3/Device.h @@ -31,24 +31,22 @@ class FrameComposer; // Provides resources that are stable for the duration of the virtual // device. class Device : public ::android::Singleton<Device> { - public: - virtual ~Device() = default; + public: + virtual ~Device() = default; - HWC3::Error getComposer(FrameComposer** outComposer); + HWC3::Error getComposer(FrameComposer** outComposer); - HWC3::Error getPersistentKeyValue(const std::string& key, - const std::string& defaultVal, - std::string* outValue); + HWC3::Error getPersistentKeyValue(const std::string& key, const std::string& defaultVal, + std::string* outValue); - HWC3::Error setPersistentKeyValue(const std::string& key, - const std::string& outValue); + HWC3::Error setPersistentKeyValue(const std::string& key, const std::string& outValue); - private: - friend class Singleton<Device>; - Device() = default; + private: + friend class Singleton<Device>; + Device() = default; - std::mutex mMutex; - std::unique_ptr<FrameComposer> mComposer; + std::mutex mMutex; + std::unique_ptr<FrameComposer> mComposer; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Display.cpp b/system/hwc3/Display.cpp index 8e6cfc85..7fef3bbc 100644 --- a/system/hwc3/Display.cpp +++ b/system/hwc3/Display.cpp @@ -37,1017 +37,959 @@ namespace aidl::android::hardware::graphics::composer3::impl { namespace { bool isValidColorMode(ColorMode mode) { - switch (mode) { - case ColorMode::NATIVE: - case ColorMode::STANDARD_BT601_625: - case ColorMode::STANDARD_BT601_625_UNADJUSTED: - case ColorMode::STANDARD_BT601_525: - case ColorMode::STANDARD_BT601_525_UNADJUSTED: - case ColorMode::STANDARD_BT709: - case ColorMode::DCI_P3: - case ColorMode::SRGB: - case ColorMode::ADOBE_RGB: - case ColorMode::DISPLAY_P3: - case ColorMode::BT2020: - case ColorMode::BT2100_PQ: - case ColorMode::BT2100_HLG: - case ColorMode::DISPLAY_BT2020: - return true; - default: - return false; - } + switch (mode) { + case ColorMode::NATIVE: + case ColorMode::STANDARD_BT601_625: + case ColorMode::STANDARD_BT601_625_UNADJUSTED: + case ColorMode::STANDARD_BT601_525: + case ColorMode::STANDARD_BT601_525_UNADJUSTED: + case ColorMode::STANDARD_BT709: + case ColorMode::DCI_P3: + case ColorMode::SRGB: + case ColorMode::ADOBE_RGB: + case ColorMode::DISPLAY_P3: + case ColorMode::BT2020: + case ColorMode::BT2100_PQ: + case ColorMode::BT2100_HLG: + case ColorMode::DISPLAY_BT2020: + return true; + default: + return false; + } } bool isValidRenderIntent(RenderIntent intent) { - switch (intent) { - case RenderIntent::COLORIMETRIC: - case RenderIntent::ENHANCE: - case RenderIntent::TONE_MAP_COLORIMETRIC: - case RenderIntent::TONE_MAP_ENHANCE: - return true; - default: - return false; - } + switch (intent) { + case RenderIntent::COLORIMETRIC: + case RenderIntent::ENHANCE: + case RenderIntent::TONE_MAP_COLORIMETRIC: + case RenderIntent::TONE_MAP_ENHANCE: + return true; + default: + return false; + } } bool isValidPowerMode(PowerMode mode) { - switch (mode) { - case PowerMode::OFF: - case PowerMode::DOZE: - case PowerMode::DOZE_SUSPEND: - case PowerMode::ON: - case PowerMode::ON_SUSPEND: - return true; - default: - return false; - } + switch (mode) { + case PowerMode::OFF: + case PowerMode::DOZE: + case PowerMode::DOZE_SUSPEND: + case PowerMode::ON: + case PowerMode::ON_SUSPEND: + return true; + default: + return false; + } } } // namespace Display::Display(FrameComposer* composer, int64_t id) : mComposer(composer), mId(id), mVsyncThread(id) { - setLegacyEdid(); + setLegacyEdid(); } Display::~Display() {} -HWC3::Error Display::init(const std::vector<DisplayConfig>& configs, - int32_t activeConfigId, +HWC3::Error Display::init(const std::vector<DisplayConfig>& configs, int32_t activeConfigId, const std::optional<std::vector<uint8_t>>& edid) { - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - for (const DisplayConfig& config : configs) { - mConfigs.emplace(config.getId(), config); - } + for (const DisplayConfig& config : configs) { + mConfigs.emplace(config.getId(), config); + } - mActiveConfigId = activeConfigId; + mActiveConfigId = activeConfigId; - auto bootConfigIdOpt = getBootConfigId(); - if (bootConfigIdOpt) { - mActiveConfigId = *bootConfigIdOpt; - } + auto bootConfigIdOpt = getBootConfigId(); + if (bootConfigIdOpt) { + mActiveConfigId = *bootConfigIdOpt; + } - if (edid.has_value()) { - mEdid = *edid; - } + if (edid.has_value()) { + mEdid = *edid; + } - auto it = mConfigs.find(activeConfigId); - if (it == mConfigs.end()) { - ALOGE("%s: display:%" PRId64 "missing config:%" PRId32, __FUNCTION__, mId, - activeConfigId); - return HWC3::Error::NoResources; - } + auto it = mConfigs.find(activeConfigId); + if (it == mConfigs.end()) { + ALOGE("%s: display:%" PRId64 "missing config:%" PRId32, __FUNCTION__, mId, activeConfigId); + return HWC3::Error::NoResources; + } - const auto& activeConfig = it->second; - const auto activeConfigString = activeConfig.toString(); - ALOGD("%s display:%" PRId64 " with config:%s", __FUNCTION__, mId, - activeConfigString.c_str()); + const auto& activeConfig = it->second; + const auto activeConfigString = activeConfig.toString(); + ALOGD("%s display:%" PRId64 " with config:%s", __FUNCTION__, mId, activeConfigString.c_str()); - mVsyncThread.start(activeConfig.getVsyncPeriod()); + mVsyncThread.start(activeConfig.getVsyncPeriod()); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error Display::updateParameters( - uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY, - uint32_t refreshRateHz, const std::optional<std::vector<uint8_t>>& edid) { - DEBUG_LOG("%s: updating display:%" PRId64 - " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d", - __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz); - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - auto it = mConfigs.find(*mActiveConfigId); - if (it == mConfigs.end()) { - ALOGE("%s: failed to find config %" PRId32, __func__, *mActiveConfigId); - return HWC3::Error::NoResources; - } - DisplayConfig& config = it->second; - config.setAttribute(DisplayAttribute::VSYNC_PERIOD, HertzToPeriodNanos(refreshRateHz)); - config.setAttribute(DisplayAttribute::WIDTH, static_cast<int32_t>(width)); - config.setAttribute(DisplayAttribute::HEIGHT, static_cast<int32_t>(height)); - config.setAttribute(DisplayAttribute::DPI_X, static_cast<int32_t>(dpiX)); - config.setAttribute(DisplayAttribute::DPI_Y, static_cast<int32_t>(dpiY)); - - if (edid.has_value()) { - mEdid = *edid; - } - - return HWC3::Error::None; +HWC3::Error Display::updateParameters(uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY, + uint32_t refreshRateHz, + const std::optional<std::vector<uint8_t>>& edid) { + DEBUG_LOG("%s: updating display:%" PRId64 + " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d", + __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + auto it = mConfigs.find(*mActiveConfigId); + if (it == mConfigs.end()) { + ALOGE("%s: failed to find config %" PRId32, __func__, *mActiveConfigId); + return HWC3::Error::NoResources; + } + DisplayConfig& config = it->second; + config.setAttribute(DisplayAttribute::VSYNC_PERIOD, HertzToPeriodNanos(refreshRateHz)); + config.setAttribute(DisplayAttribute::WIDTH, static_cast<int32_t>(width)); + config.setAttribute(DisplayAttribute::HEIGHT, static_cast<int32_t>(height)); + config.setAttribute(DisplayAttribute::DPI_X, static_cast<int32_t>(dpiX)); + config.setAttribute(DisplayAttribute::DPI_Y, static_cast<int32_t>(dpiY)); + + if (edid.has_value()) { + mEdid = *edid; + } + + return HWC3::Error::None; } HWC3::Error Display::createLayer(int64_t* outLayerId) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - auto layer = std::make_unique<Layer>(); + auto layer = std::make_unique<Layer>(); - const int64_t layerId = layer->getId(); - DEBUG_LOG("%s: created layer:%" PRId64, __FUNCTION__, layerId); + const int64_t layerId = layer->getId(); + DEBUG_LOG("%s: created layer:%" PRId64, __FUNCTION__, layerId); - mLayers.emplace(layerId, std::move(layer)); + mLayers.emplace(layerId, std::move(layer)); - *outLayerId = layerId; + *outLayerId = layerId; - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::destroyLayer(int64_t layerId) { - DEBUG_LOG("%s: destroy layer:%" PRId64, __FUNCTION__, layerId); + DEBUG_LOG("%s: destroy layer:%" PRId64, __FUNCTION__, layerId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - auto it = mLayers.find(layerId); - if (it == mLayers.end()) { - ALOGE("%s display:%" PRId64 " has no such layer:%." PRId64, __FUNCTION__, - mId, layerId); - return HWC3::Error::BadLayer; - } + auto it = mLayers.find(layerId); + if (it == mLayers.end()) { + ALOGE("%s display:%" PRId64 " has no such layer:%." PRId64, __FUNCTION__, mId, layerId); + return HWC3::Error::BadLayer; + } - mOrderedLayers.erase(std::remove_if(mOrderedLayers.begin(), // - mOrderedLayers.end(), // - [layerId](Layer* layer) { - return layer->getId() == layerId; - }), - mOrderedLayers.end()); + mOrderedLayers.erase( + std::remove_if(mOrderedLayers.begin(), // + mOrderedLayers.end(), // + [layerId](Layer* layer) { return layer->getId() == layerId; }), + mOrderedLayers.end()); - mLayers.erase(it); + mLayers.erase(it); - DEBUG_LOG("%s: destroyed layer:%" PRId64, __FUNCTION__, layerId); - return HWC3::Error::None; + DEBUG_LOG("%s: destroyed layer:%" PRId64, __FUNCTION__, layerId); + return HWC3::Error::None; } HWC3::Error Display::getActiveConfig(int32_t* outConfig) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - if (!mActiveConfigId) { - ALOGW("%s: display:%" PRId64 " has no active config.", __FUNCTION__, mId); - return HWC3::Error::BadConfig; - } + if (!mActiveConfigId) { + ALOGW("%s: display:%" PRId64 " has no active config.", __FUNCTION__, mId); + return HWC3::Error::BadConfig; + } - *outConfig = *mActiveConfigId; - return HWC3::Error::None; + *outConfig = *mActiveConfigId; + return HWC3::Error::None; } -HWC3::Error Display::getDisplayAttribute(int32_t configId, - DisplayAttribute attribute, +HWC3::Error Display::getDisplayAttribute(int32_t configId, DisplayAttribute attribute, int32_t* outValue) { - auto attributeString = toString(attribute); - DEBUG_LOG("%s: display:%" PRId64 " attribute:%s", __FUNCTION__, mId, - attributeString.c_str()); - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - auto it = mConfigs.find(configId); - if (it == mConfigs.end()) { - ALOGW("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId, - configId); - return HWC3::Error::BadConfig; - } - - const DisplayConfig& config = it->second; - *outValue = config.getAttribute(attribute); - DEBUG_LOG("%s: display:%" PRId64 " attribute:%s value is %" PRIi32, - __FUNCTION__, mId, attributeString.c_str(), *outValue); - return HWC3::Error::None; + auto attributeString = toString(attribute); + DEBUG_LOG("%s: display:%" PRId64 " attribute:%s", __FUNCTION__, mId, attributeString.c_str()); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + auto it = mConfigs.find(configId); + if (it == mConfigs.end()) { + ALOGW("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId, configId); + return HWC3::Error::BadConfig; + } + + const DisplayConfig& config = it->second; + *outValue = config.getAttribute(attribute); + DEBUG_LOG("%s: display:%" PRId64 " attribute:%s value is %" PRIi32, __FUNCTION__, mId, + attributeString.c_str(), *outValue); + return HWC3::Error::None; } HWC3::Error Display::getColorModes(std::vector<ColorMode>* outModes) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - outModes->clear(); - outModes->insert(outModes->end(), mColorModes.begin(), mColorModes.end()); + outModes->clear(); + outModes->insert(outModes->end(), mColorModes.begin(), mColorModes.end()); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error Display::getDisplayCapabilities( - std::vector<DisplayCapability>* outCapabilities) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getDisplayCapabilities(std::vector<DisplayCapability>* outCapabilities) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - outCapabilities->clear(); - outCapabilities->push_back(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM); + outCapabilities->clear(); + outCapabilities->push_back(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::getDisplayConfigs(std::vector<int32_t>* outConfigIds) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - outConfigIds->clear(); - outConfigIds->reserve(mConfigs.size()); - for (const auto& [configId, _] : mConfigs) { - outConfigIds->push_back(configId); - } + outConfigIds->clear(); + outConfigIds->reserve(mConfigs.size()); + for (const auto& [configId, _] : mConfigs) { + outConfigIds->push_back(configId); + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::getDisplayConnectionType(DisplayConnectionType* outType) { - if (IsCuttlefishFoldable() || IsAutoDevice()) { - // Android Auto OS needs to set all displays to INTERNAL since they're used - // for the passenger displays. - // Workaround to force all displays to INTERNAL for cf_x86_64_foldable. - // TODO(b/193568008): Allow configuring internal/external per display. - *outType = DisplayConnectionType::INTERNAL; - } else { - // Other devices default to the first display INTERNAL, others EXTERNAL. - *outType = mId == 0 ? DisplayConnectionType::INTERNAL - : DisplayConnectionType::EXTERNAL; - } - return HWC3::Error::None; + if (IsCuttlefishFoldable() || IsAutoDevice()) { + // Android Auto OS needs to set all displays to INTERNAL since they're used + // for the passenger displays. + // Workaround to force all displays to INTERNAL for cf_x86_64_foldable. + // TODO(b/193568008): Allow configuring internal/external per display. + *outType = DisplayConnectionType::INTERNAL; + } else { + // Other devices default to the first display INTERNAL, others EXTERNAL. + *outType = mId == 0 ? DisplayConnectionType::INTERNAL : DisplayConnectionType::EXTERNAL; + } + return HWC3::Error::None; } -HWC3::Error Display::getDisplayIdentificationData( - DisplayIdentification* outIdentification) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getDisplayIdentificationData(DisplayIdentification* outIdentification) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - if (outIdentification == nullptr) { - return HWC3::Error::BadParameter; - } + if (outIdentification == nullptr) { + return HWC3::Error::BadParameter; + } - outIdentification->port = static_cast<int8_t>(mId); - outIdentification->data = mEdid; + outIdentification->port = static_cast<int8_t>(mId); + outIdentification->data = mEdid; - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::getDisplayName(std::string* outName) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - *outName = mName; - return HWC3::Error::None; + *outName = mName; + return HWC3::Error::None; } HWC3::Error Display::getDisplayVsyncPeriod(int32_t* outVsyncPeriod) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - if (!mActiveConfigId) { - ALOGE("%s : display:%" PRId64 " no active config", __FUNCTION__, mId); - return HWC3::Error::BadConfig; - } + if (!mActiveConfigId) { + ALOGE("%s : display:%" PRId64 " no active config", __FUNCTION__, mId); + return HWC3::Error::BadConfig; + } - const auto it = mConfigs.find(*mActiveConfigId); - if (it == mConfigs.end()) { - ALOGE("%s : display:%" PRId64 " failed to find active config:%" PRId32, - __FUNCTION__, mId, *mActiveConfigId); - return HWC3::Error::BadConfig; - } - const DisplayConfig& activeConfig = it->second; + const auto it = mConfigs.find(*mActiveConfigId); + if (it == mConfigs.end()) { + ALOGE("%s : display:%" PRId64 " failed to find active config:%" PRId32, __FUNCTION__, mId, + *mActiveConfigId); + return HWC3::Error::BadConfig; + } + const DisplayConfig& activeConfig = it->second; - *outVsyncPeriod = activeConfig.getAttribute(DisplayAttribute::VSYNC_PERIOD); - return HWC3::Error::None; + *outVsyncPeriod = activeConfig.getAttribute(DisplayAttribute::VSYNC_PERIOD); + return HWC3::Error::None; } -HWC3::Error Display::getDisplayedContentSample( - int64_t /*maxFrames*/, int64_t /*timestamp*/, - DisplayContentSample* /*samples*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getDisplayedContentSample(int64_t /*maxFrames*/, int64_t /*timestamp*/, + DisplayContentSample* /*samples*/) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } HWC3::Error Display::getDisplayedContentSamplingAttributes( DisplayContentSamplingAttributes* /*outAttributes*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::getDisplayPhysicalOrientation( - common::Transform* outOrientation) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getDisplayPhysicalOrientation(common::Transform* outOrientation) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - *outOrientation = common::Transform::NONE; + *outOrientation = common::Transform::NONE; - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - // No supported types. - outCapabilities->types.clear(); + // No supported types. + outCapabilities->types.clear(); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error Display::getPerFrameMetadataKeys( - std::vector<PerFrameMetadataKey>* outKeys) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getPerFrameMetadataKeys(std::vector<PerFrameMetadataKey>* outKeys) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - outKeys->clear(); + outKeys->clear(); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::getReadbackBufferAttributes( - ReadbackBufferAttributes* outAttributes) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getReadbackBufferAttributes(ReadbackBufferAttributes* outAttributes) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - outAttributes->format = common::PixelFormat::RGBA_8888; - outAttributes->dataspace = common::Dataspace::UNKNOWN; + outAttributes->format = common::PixelFormat::RGBA_8888; + outAttributes->dataspace = common::Dataspace::UNKNOWN; - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::getReadbackBufferFence( - ndk::ScopedFileDescriptor* /*outAcquireFence*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getReadbackBufferFence(ndk::ScopedFileDescriptor* /*outAcquireFence*/) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::getRenderIntents(ColorMode mode, - std::vector<RenderIntent>* outIntents) { - const auto modeString = toString(mode); - DEBUG_LOG("%s: display:%" PRId64 "for mode:%s", __FUNCTION__, mId, - modeString.c_str()); +HWC3::Error Display::getRenderIntents(ColorMode mode, std::vector<RenderIntent>* outIntents) { + const auto modeString = toString(mode); + DEBUG_LOG("%s: display:%" PRId64 "for mode:%s", __FUNCTION__, mId, modeString.c_str()); - outIntents->clear(); + outIntents->clear(); - if (!isValidColorMode(mode)) { - DEBUG_LOG("%s: display:%" PRId64 "invalid mode:%s", __FUNCTION__, mId, - modeString.c_str()); - return HWC3::Error::BadParameter; - } + if (!isValidColorMode(mode)) { + DEBUG_LOG("%s: display:%" PRId64 "invalid mode:%s", __FUNCTION__, mId, modeString.c_str()); + return HWC3::Error::BadParameter; + } - outIntents->push_back(RenderIntent::COLORIMETRIC); + outIntents->push_back(RenderIntent::COLORIMETRIC); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error Display::getSupportedContentTypes( - std::vector<ContentType>* outTypes) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::getSupportedContentTypes(std::vector<ContentType>* outTypes) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - outTypes->clear(); + outTypes->clear(); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::getDecorationSupport( std::optional<common::DisplayDecorationSupport>* outSupport) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - outSupport->reset(); + outSupport->reset(); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::registerCallback( - const std::shared_ptr<IComposerCallback>& callback) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::registerCallback(const std::shared_ptr<IComposerCallback>& callback) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - mVsyncThread.setCallbacks(callback); + mVsyncThread.setCallbacks(callback); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } HWC3::Error Display::setActiveConfig(int32_t configId) { - DEBUG_LOG("%s: display:%" PRId64 " setting active config to %" PRId32, - __FUNCTION__, mId, configId); + DEBUG_LOG("%s: display:%" PRId64 " setting active config to %" PRId32, __FUNCTION__, mId, + configId); - VsyncPeriodChangeConstraints constraints; - constraints.desiredTimeNanos = 0; - constraints.seamlessRequired = false; + VsyncPeriodChangeConstraints constraints; + constraints.desiredTimeNanos = 0; + constraints.seamlessRequired = false; - VsyncPeriodChangeTimeline timeline; + VsyncPeriodChangeTimeline timeline; - return setActiveConfigWithConstraints(configId, constraints, &timeline); + return setActiveConfigWithConstraints(configId, constraints, &timeline); } -HWC3::Error Display::setActiveConfigWithConstraints( - int32_t configId, const VsyncPeriodChangeConstraints& constraints, - VsyncPeriodChangeTimeline* outTimeline) { - DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId, - configId); +HWC3::Error Display::setActiveConfigWithConstraints(int32_t configId, + const VsyncPeriodChangeConstraints& constraints, + VsyncPeriodChangeTimeline* outTimeline) { + DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId, configId); - if (outTimeline == nullptr) { - return HWC3::Error::BadParameter; - } + if (outTimeline == nullptr) { + return HWC3::Error::BadParameter; + } - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - if (mActiveConfigId == configId) { - return HWC3::Error::None; - } - - DisplayConfig* newConfig = getConfig(configId); - if (newConfig == nullptr) { - ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId, - configId); - return HWC3::Error::BadConfig; - } - - if (constraints.seamlessRequired) { - if (mActiveConfigId) { - DisplayConfig* oldConfig = getConfig(*mActiveConfigId); - if (oldConfig == nullptr) { - ALOGE("%s: display:%" PRId64 " missing config:%" PRId32, __FUNCTION__, - mId, *mActiveConfigId); + if (mActiveConfigId == configId) { + return HWC3::Error::None; + } + + DisplayConfig* newConfig = getConfig(configId); + if (newConfig == nullptr) { + ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId, configId); + return HWC3::Error::BadConfig; + } + + if (constraints.seamlessRequired) { + if (mActiveConfigId) { + DisplayConfig* oldConfig = getConfig(*mActiveConfigId); + if (oldConfig == nullptr) { + ALOGE("%s: display:%" PRId64 " missing config:%" PRId32, __FUNCTION__, mId, + *mActiveConfigId); + return HWC3::Error::NoResources; + } + + const int32_t newConfigGroup = newConfig->getConfigGroup(); + const int32_t oldConfigGroup = oldConfig->getConfigGroup(); + if (newConfigGroup != oldConfigGroup) { + DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32 + " seamless not supported between different config groups " + "old:%d vs new:%d", + __FUNCTION__, mId, configId, oldConfigGroup, newConfigGroup); + return HWC3::Error::SeamlessNotAllowed; + } + } + } + + mActiveConfigId = configId; + + if (mComposer == nullptr) { + ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId); return HWC3::Error::NoResources; - } - - const int32_t newConfigGroup = newConfig->getConfigGroup(); - const int32_t oldConfigGroup = oldConfig->getConfigGroup(); - if (newConfigGroup != oldConfigGroup) { - DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32 - " seamless not supported between different config groups " - "old:%d vs new:%d", - __FUNCTION__, mId, configId, oldConfigGroup, newConfigGroup); - return HWC3::Error::SeamlessNotAllowed; - } } - } - - mActiveConfigId = configId; - - if (mComposer == nullptr) { - ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId); - return HWC3::Error::NoResources; - } - - HWC3::Error error = mComposer->onActiveConfigChange(this); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " composer failed to handle config change", - __FUNCTION__, mId); - return error; - } - - int32_t vsyncPeriod; - error = getDisplayVsyncPeriod(&vsyncPeriod); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " composer failed to handle config change", - __FUNCTION__, mId); - return error; - } - - return mVsyncThread.scheduleVsyncUpdate(vsyncPeriod, constraints, - outTimeline); + + HWC3::Error error = mComposer->onActiveConfigChange(this); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " composer failed to handle config change", __FUNCTION__, mId); + return error; + } + + int32_t vsyncPeriod; + error = getDisplayVsyncPeriod(&vsyncPeriod); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " composer failed to handle config change", __FUNCTION__, mId); + return error; + } + + return mVsyncThread.scheduleVsyncUpdate(vsyncPeriod, constraints, outTimeline); } std::optional<int32_t> Display::getBootConfigId() { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - std::string val; - HWC3::Error error = Device::getInstance().getPersistentKeyValue( - std::to_string(mId), "", &val); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " failed to get persistent boot config", - __FUNCTION__, mId); - return std::nullopt; - } - - if (val.empty()) { - return std::nullopt; - } - - int32_t configId = 0; - if (!::android::base::ParseInt(val, &configId)) { - ALOGE("%s: display:%" PRId64 - " failed to parse persistent boot config from: %s", - __FUNCTION__, mId, val.c_str()); - return std::nullopt; - } - - if (!hasConfig(configId)) { - ALOGE("%s: display:%" PRId64 " invalid persistent boot config:%" PRId32, - __FUNCTION__, mId, configId); - return std::nullopt; - } - - return configId; + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + std::string val; + HWC3::Error error = Device::getInstance().getPersistentKeyValue(std::to_string(mId), "", &val); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " failed to get persistent boot config", __FUNCTION__, mId); + return std::nullopt; + } + + if (val.empty()) { + return std::nullopt; + } + + int32_t configId = 0; + if (!::android::base::ParseInt(val, &configId)) { + ALOGE("%s: display:%" PRId64 " failed to parse persistent boot config from: %s", + __FUNCTION__, mId, val.c_str()); + return std::nullopt; + } + + if (!hasConfig(configId)) { + ALOGE("%s: display:%" PRId64 " invalid persistent boot config:%" PRId32, __FUNCTION__, mId, + configId); + return std::nullopt; + } + + return configId; } HWC3::Error Display::setBootConfig(int32_t configId) { - DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId, - configId); - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - DisplayConfig* newConfig = getConfig(configId); - if (newConfig == nullptr) { - ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId, - configId); - return HWC3::Error::BadConfig; - } - - const std::string key = std::to_string(mId); - const std::string val = std::to_string(configId); - HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " failed to save persistent boot config", - __FUNCTION__, mId); - return error; - } - - return HWC3::Error::None; + DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId, configId); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + DisplayConfig* newConfig = getConfig(configId); + if (newConfig == nullptr) { + ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId, configId); + return HWC3::Error::BadConfig; + } + + const std::string key = std::to_string(mId); + const std::string val = std::to_string(configId); + HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " failed to save persistent boot config", __FUNCTION__, mId); + return error; + } + + return HWC3::Error::None; } HWC3::Error Display::clearBootConfig() { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - const std::string key = std::to_string(mId); - const std::string val = ""; - HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " failed to save persistent boot config", - __FUNCTION__, mId); - return error; - } + const std::string key = std::to_string(mId); + const std::string val = ""; + HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " failed to save persistent boot config", __FUNCTION__, mId); + return error; + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::getPreferredBootConfig(int32_t* outConfigId) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - std::vector<int32_t> configIds; - for (const auto [configId, _] : mConfigs) { - configIds.push_back(configId); - } - *outConfigId = *std::min_element(configIds.begin(), configIds.end()); + std::vector<int32_t> configIds; + for (const auto [configId, _] : mConfigs) { + configIds.push_back(configId); + } + *outConfigId = *std::min_element(configIds.begin(), configIds.end()); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::setAutoLowLatencyMode(bool /*on*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } HWC3::Error Display::setColorMode(ColorMode mode, RenderIntent intent) { - const std::string modeString = toString(mode); - const std::string intentString = toString(intent); - DEBUG_LOG("%s: display:%" PRId64 " setting color mode:%s intent:%s", - __FUNCTION__, mId, modeString.c_str(), intentString.c_str()); - - if (!isValidColorMode(mode)) { - ALOGE("%s: display:%" PRId64 " invalid color mode:%s", __FUNCTION__, mId, - modeString.c_str()); - return HWC3::Error::BadParameter; - } - - if (!isValidRenderIntent(intent)) { - ALOGE("%s: display:%" PRId64 " invalid intent:%s", __FUNCTION__, mId, - intentString.c_str()); - return HWC3::Error::BadParameter; - } - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - if (mColorModes.count(mode) == 0) { - ALOGE("%s: display %" PRId64 " mode %s not supported", __FUNCTION__, mId, - modeString.c_str()); - return HWC3::Error::Unsupported; - } + const std::string modeString = toString(mode); + const std::string intentString = toString(intent); + DEBUG_LOG("%s: display:%" PRId64 " setting color mode:%s intent:%s", __FUNCTION__, mId, + modeString.c_str(), intentString.c_str()); + + if (!isValidColorMode(mode)) { + ALOGE("%s: display:%" PRId64 " invalid color mode:%s", __FUNCTION__, mId, + modeString.c_str()); + return HWC3::Error::BadParameter; + } + + if (!isValidRenderIntent(intent)) { + ALOGE("%s: display:%" PRId64 " invalid intent:%s", __FUNCTION__, mId, intentString.c_str()); + return HWC3::Error::BadParameter; + } + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + if (mColorModes.count(mode) == 0) { + ALOGE("%s: display %" PRId64 " mode %s not supported", __FUNCTION__, mId, + modeString.c_str()); + return HWC3::Error::Unsupported; + } - mActiveColorMode = mode; - return HWC3::Error::None; + mActiveColorMode = mode; + return HWC3::Error::None; } HWC3::Error Display::setContentType(ContentType contentType) { - auto contentTypeString = toString(contentType); - DEBUG_LOG("%s: display:%" PRId64 " content type:%s", __FUNCTION__, mId, - contentTypeString.c_str()); + auto contentTypeString = toString(contentType); + DEBUG_LOG("%s: display:%" PRId64 " content type:%s", __FUNCTION__, mId, + contentTypeString.c_str()); - if (contentType != ContentType::NONE) { - return HWC3::Error::Unsupported; - } + if (contentType != ContentType::NONE) { + return HWC3::Error::Unsupported; + } - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error Display::setDisplayedContentSamplingEnabled( - bool /*enable*/, FormatColorComponent /*componentMask*/, - int64_t /*maxFrames*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::setDisplayedContentSamplingEnabled(bool /*enable*/, + FormatColorComponent /*componentMask*/, + int64_t /*maxFrames*/) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } HWC3::Error Display::setPowerMode(PowerMode mode) { - auto modeString = toString(mode); - DEBUG_LOG("%s: display:%" PRId64 " to mode:%s", __FUNCTION__, mId, - modeString.c_str()); - - if (!isValidPowerMode(mode)) { - ALOGE("%s: display:%" PRId64 " invalid mode:%s", __FUNCTION__, mId, - modeString.c_str()); - return HWC3::Error::BadParameter; - } - - if (mode == PowerMode::DOZE || mode == PowerMode::DOZE_SUSPEND || - mode == PowerMode::ON_SUSPEND) { - ALOGE("%s display %" PRId64 " mode:%s not supported", __FUNCTION__, mId, - modeString.c_str()); - return HWC3::Error::Unsupported; - } - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - if (IsCuttlefish()) { - if (int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); fd != -1) { - std::ostringstream stream; - stream << "VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED display=" << mId - << " mode=" << modeString << std::endl; - std::string message = stream.str(); - write(fd, message.c_str(), message.length()); - close(fd); + auto modeString = toString(mode); + DEBUG_LOG("%s: display:%" PRId64 " to mode:%s", __FUNCTION__, mId, modeString.c_str()); + + if (!isValidPowerMode(mode)) { + ALOGE("%s: display:%" PRId64 " invalid mode:%s", __FUNCTION__, mId, modeString.c_str()); + return HWC3::Error::BadParameter; } - } - mPowerMode = mode; - return HWC3::Error::None; + if (mode == PowerMode::DOZE || mode == PowerMode::DOZE_SUSPEND || + mode == PowerMode::ON_SUSPEND) { + ALOGE("%s display %" PRId64 " mode:%s not supported", __FUNCTION__, mId, + modeString.c_str()); + return HWC3::Error::Unsupported; + } + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + if (IsCuttlefish()) { + if (int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); fd != -1) { + std::ostringstream stream; + stream << "VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED display=" << mId + << " mode=" << modeString << std::endl; + std::string message = stream.str(); + write(fd, message.c_str(), message.length()); + close(fd); + } + } + + mPowerMode = mode; + return HWC3::Error::None; } HWC3::Error Display::setReadbackBuffer(const buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - mReadbackBuffer.set(buffer, fence); + mReadbackBuffer.set(buffer, fence); - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } HWC3::Error Display::setVsyncEnabled(bool enabled) { - DEBUG_LOG("%s: display:%" PRId64 " setting vsync %s", __FUNCTION__, mId, - (enabled ? "on" : "off")); + DEBUG_LOG("%s: display:%" PRId64 " setting vsync %s", __FUNCTION__, mId, + (enabled ? "on" : "off")); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - return mVsyncThread.setVsyncEnabled(enabled); + return mVsyncThread.setVsyncEnabled(enabled); } HWC3::Error Display::setIdleTimerEnabled(int32_t timeoutMs) { - DEBUG_LOG("%s: display:%" PRId64 " timeout:%" PRId32, __FUNCTION__, mId, - timeoutMs); + DEBUG_LOG("%s: display:%" PRId64 " timeout:%" PRId32, __FUNCTION__, mId, timeoutMs); - (void)timeoutMs; + (void)timeoutMs; - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::setColorTransform( - const std::vector<float>& transformMatrix) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::setColorTransform(const std::vector<float>& transformMatrix) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - if (transformMatrix.size() < 16) { - ALOGE("%s: display:%" PRId64 " has non 4x4 matrix, size:%zu", __FUNCTION__, - mId, transformMatrix.size()); - return HWC3::Error::BadParameter; - } + if (transformMatrix.size() < 16) { + ALOGE("%s: display:%" PRId64 " has non 4x4 matrix, size:%zu", __FUNCTION__, mId, + transformMatrix.size()); + return HWC3::Error::BadParameter; + } - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - auto& colorTransform = mColorTransform.emplace(); - std::copy_n(transformMatrix.data(), colorTransform.size(), - colorTransform.begin()); + auto& colorTransform = mColorTransform.emplace(); + std::copy_n(transformMatrix.data(), colorTransform.size(), colorTransform.begin()); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::setBrightness(float brightness) { - DEBUG_LOG("%s: display:%" PRId64 " brightness:%f", __FUNCTION__, mId, - brightness); + DEBUG_LOG("%s: display:%" PRId64 " brightness:%f", __FUNCTION__, mId, brightness); - if (brightness < 0.0f) { - ALOGE("%s: display:%" PRId64 " invalid brightness:%f", __FUNCTION__, mId, - brightness); - return HWC3::Error::BadParameter; - } + if (brightness < 0.0f) { + ALOGE("%s: display:%" PRId64 " invalid brightness:%f", __FUNCTION__, mId, brightness); + return HWC3::Error::BadParameter; + } - return HWC3::Error::Unsupported; + return HWC3::Error::Unsupported; } -HWC3::Error Display::setClientTarget( - buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence, - common::Dataspace /*dataspace*/, - const std::vector<common::Rect>& /*damage*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::setClientTarget(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence, + common::Dataspace /*dataspace*/, + const std::vector<common::Rect>& /*damage*/) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - mClientTarget.set(buffer, fence); + mClientTarget.set(buffer, fence); - mComposer->onDisplayClientTargetSet(this); - return HWC3::Error::None; + mComposer->onDisplayClientTargetSet(this); + return HWC3::Error::None; } -HWC3::Error Display::setOutputBuffer( - buffer_handle_t /*buffer*/, const ndk::ScopedFileDescriptor& /*fence*/) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); +HWC3::Error Display::setOutputBuffer(buffer_handle_t /*buffer*/, + const ndk::ScopedFileDescriptor& /*fence*/) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - // TODO: for virtual display - return HWC3::Error::None; + // TODO: for virtual display + return HWC3::Error::None; } HWC3::Error Display::setExpectedPresentTime( const std::optional<ClockMonotonicTimestamp>& expectedPresentTime) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - if (!expectedPresentTime.has_value()) { - return HWC3::Error::None; - } + if (!expectedPresentTime.has_value()) { + return HWC3::Error::None; + } - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - mExpectedPresentTime.emplace( - asTimePoint(expectedPresentTime->timestampNanos)); + mExpectedPresentTime.emplace(asTimePoint(expectedPresentTime->timestampNanos)); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Display::validate(DisplayChanges* outChanges) { - ATRACE_CALL(); - - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - - std::unique_lock<std::recursive_mutex> lock(mStateMutex); - - mPendingChanges.reset(); - - mOrderedLayers.clear(); - mOrderedLayers.reserve(mLayers.size()); - for (auto& [_, layerPtr] : mLayers) { - mOrderedLayers.push_back(layerPtr.get()); - } - std::sort(mOrderedLayers.begin(), mOrderedLayers.end(), - [](const Layer* layerA, const Layer* layerB) { - const auto zA = layerA->getZOrder(); - const auto zB = layerB->getZOrder(); - if (zA != zB) { - return zA < zB; - } - return layerA->getId() < layerB->getId(); - }); - - if (mComposer == nullptr) { - ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId); - return HWC3::Error::NoResources; - } - - HWC3::Error error = mComposer->validateDisplay(this, &mPendingChanges); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRId64 " failed to validate", __FUNCTION__, mId); - return error; - } - - if (mPendingChanges.hasAnyChanges()) { - mPresentFlowState = PresentFlowState::WAITING_FOR_ACCEPT; - DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_ACCEPT", __FUNCTION__, - mId); - } else { - mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT; - DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__, - mId); - } + ATRACE_CALL(); - *outChanges = mPendingChanges; - return HWC3::Error::None; -} + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); -HWC3::Error Display::acceptChanges() { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + std::unique_lock<std::recursive_mutex> lock(mStateMutex); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + mPendingChanges.reset(); - switch (mPresentFlowState) { - case PresentFlowState::WAITING_FOR_VALIDATE: { - ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId); - return HWC3::Error::NotValidated; + mOrderedLayers.clear(); + mOrderedLayers.reserve(mLayers.size()); + for (auto& [_, layerPtr] : mLayers) { + mOrderedLayers.push_back(layerPtr.get()); } - case PresentFlowState::WAITING_FOR_ACCEPT: - case PresentFlowState::WAITING_FOR_PRESENT: { - break; + std::sort(mOrderedLayers.begin(), mOrderedLayers.end(), + [](const Layer* layerA, const Layer* layerB) { + const auto zA = layerA->getZOrder(); + const auto zB = layerB->getZOrder(); + if (zA != zB) { + return zA < zB; + } + return layerA->getId() < layerB->getId(); + }); + + if (mComposer == nullptr) { + ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId); + return HWC3::Error::NoResources; } - } - - if (mPendingChanges.compositionChanges) { - const ChangedCompositionTypes& compositionChanges = - *mPendingChanges.compositionChanges; - for (const ChangedCompositionLayer& compositionChange : - compositionChanges.layers) { - const auto layerId = compositionChange.layer; - const auto layerComposition = compositionChange.composition; - auto* layer = getLayer(layerId); - if (layer == nullptr) { - ALOGE("%s: display:%" PRId64 " layer:%" PRId64 - " dropped before acceptChanges()?", - __FUNCTION__, mId, layerId); - continue; - } - - layer->setCompositionType(layerComposition); + + HWC3::Error error = mComposer->validateDisplay(this, &mPendingChanges); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRId64 " failed to validate", __FUNCTION__, mId); + return error; } - } - mPendingChanges.reset(); - mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT; - DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__, - mId); + if (mPendingChanges.hasAnyChanges()) { + mPresentFlowState = PresentFlowState::WAITING_FOR_ACCEPT; + DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_ACCEPT", __FUNCTION__, mId); + } else { + mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT; + DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__, mId); + } - return HWC3::Error::None; + *outChanges = mPendingChanges; + return HWC3::Error::None; } -HWC3::Error Display::present( - ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) { - ATRACE_CALL(); +HWC3::Error Display::acceptChanges() { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + switch (mPresentFlowState) { + case PresentFlowState::WAITING_FOR_VALIDATE: { + ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId); + return HWC3::Error::NotValidated; + } + case PresentFlowState::WAITING_FOR_ACCEPT: + case PresentFlowState::WAITING_FOR_PRESENT: { + break; + } + } - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + if (mPendingChanges.compositionChanges) { + const ChangedCompositionTypes& compositionChanges = *mPendingChanges.compositionChanges; + for (const ChangedCompositionLayer& compositionChange : compositionChanges.layers) { + const auto layerId = compositionChange.layer; + const auto layerComposition = compositionChange.composition; + auto* layer = getLayer(layerId); + if (layer == nullptr) { + ALOGE("%s: display:%" PRId64 " layer:%" PRId64 " dropped before acceptChanges()?", + __FUNCTION__, mId, layerId); + continue; + } + + layer->setCompositionType(layerComposition); + } + } + mPendingChanges.reset(); - outDisplayFence->reset(); - outLayerFences->clear(); + mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT; + DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__, mId); - std::unique_lock<std::recursive_mutex> lock(mStateMutex); + return HWC3::Error::None; +} - switch (mPresentFlowState) { - case PresentFlowState::WAITING_FOR_VALIDATE: { - ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId); - return HWC3::Error::NotValidated; - } - case PresentFlowState::WAITING_FOR_ACCEPT: { - ALOGE("%s: display %" PRId64 " failed, changes not accepted", - __FUNCTION__, mId); - return HWC3::Error::NotValidated; - } - case PresentFlowState::WAITING_FOR_PRESENT: { - break; +HWC3::Error Display::present( + ::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) { + ATRACE_CALL(); + + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + + outDisplayFence->reset(); + outLayerFences->clear(); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + switch (mPresentFlowState) { + case PresentFlowState::WAITING_FOR_VALIDATE: { + ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId); + return HWC3::Error::NotValidated; + } + case PresentFlowState::WAITING_FOR_ACCEPT: { + ALOGE("%s: display %" PRId64 " failed, changes not accepted", __FUNCTION__, mId); + return HWC3::Error::NotValidated; + } + case PresentFlowState::WAITING_FOR_PRESENT: { + break; + } } - } - mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE; - DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_VALIDATE", __FUNCTION__, - mId); + mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE; + DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_VALIDATE", __FUNCTION__, mId); - if (mComposer == nullptr) { - ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId); - return HWC3::Error::NoResources; - } + if (mComposer == nullptr) { + ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId); + return HWC3::Error::NoResources; + } - return mComposer->presentDisplay(this, outDisplayFence, outLayerFences); + return mComposer->presentDisplay(this, outDisplayFence, outLayerFences); } bool Display::hasConfig(int32_t configId) const { - return mConfigs.find(configId) != mConfigs.end(); + return mConfigs.find(configId) != mConfigs.end(); } DisplayConfig* Display::getConfig(int32_t configId) { - auto it = mConfigs.find(configId); - if (it != mConfigs.end()) { - return &it->second; - } - return nullptr; + auto it = mConfigs.find(configId); + if (it != mConfigs.end()) { + return &it->second; + } + return nullptr; } HWC3::Error Display::setEdid(std::vector<uint8_t> edid) { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - mEdid = edid; - return HWC3::Error::None; + mEdid = edid; + return HWC3::Error::None; } void Display::setLegacyEdid() { - // thess EDIDs are carefully generated according to the EDID spec version 1.3, - // more info can be found from the following file: - // frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp - // approved pnp ids can be found here: https://uefi.org/pnp_id_list - // pnp id: GGL, name: EMU_display_0, last byte is checksum - // display id is local:8141603649153536 - static constexpr const std::array<uint8_t, 128> kEdid0 = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, - 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00, - 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, - 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b}; - - // pnp id: GGL, name: EMU_display_1 - // display id is local:8140900251843329 - static constexpr const std::array<uint8_t, 128> kEdid1 = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, - 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00, - 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, - 0x2d, 0x40, 0x58, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b}; - - // pnp id: GGL, name: EMU_display_2 - // display id is local:8140940453066754 - static constexpr const std::array<uint8_t, 128> kEdid2 = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, - 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00, - 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, - 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49}; - - mEdid.clear(); - switch (mId) { - case 0: { - mEdid.insert(mEdid.end(), kEdid0.begin(), kEdid0.end()); - break; - } - case 1: { - mEdid.insert(mEdid.end(), kEdid1.begin(), kEdid1.end()); - break; + // thess EDIDs are carefully generated according to the EDID spec version 1.3, + // more info can be found from the following file: + // frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp + // approved pnp ids can be found here: https://uefi.org/pnp_id_list + // pnp id: GGL, name: EMU_display_0, last byte is checksum + // display id is local:8141603649153536 + static constexpr const std::array<uint8_t, 128> kEdid0 = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, + 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b}; + + // pnp id: GGL, name: EMU_display_1 + // display id is local:8140900251843329 + static constexpr const std::array<uint8_t, 128> kEdid1 = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, + 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b}; + + // pnp id: GGL, name: EMU_display_2 + // display id is local:8140940453066754 + static constexpr const std::array<uint8_t, 128> kEdid2 = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, + 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49}; + + mEdid.clear(); + switch (mId) { + case 0: { + mEdid.insert(mEdid.end(), kEdid0.begin(), kEdid0.end()); + break; + } + case 1: { + mEdid.insert(mEdid.end(), kEdid1.begin(), kEdid1.end()); + break; + } + case 2: { + mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end()); + break; + } + default: { + mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end()); + const size_t size = mEdid.size(); + // Update the name to EMU_display_<mID> + mEdid[size - 3] = '0' + (uint8_t)mId; + // Update the checksum byte + uint8_t checksum = -(uint8_t)std::accumulate(mEdid.data(), mEdid.data() + size - 1, + static_cast<uint8_t>(0)); + mEdid[size - 1] = checksum; + break; + } } - case 2: { - mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end()); - break; - } - default: { - mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end()); - const size_t size = mEdid.size(); - // Update the name to EMU_display_<mID> - mEdid[size - 3] = '0' + (uint8_t)mId; - // Update the checksum byte - uint8_t checksum = -(uint8_t)std::accumulate( - mEdid.data(), mEdid.data() + size - 1, static_cast<uint8_t>(0)); - mEdid[size - 1] = checksum; - break; - } - } } Layer* Display::getLayer(int64_t layerId) { - auto it = mLayers.find(layerId); - if (it == mLayers.end()) { - ALOGE("%s Unknown layer:%" PRId64, __FUNCTION__, layerId); - return nullptr; - } + auto it = mLayers.find(layerId); + if (it == mLayers.end()) { + ALOGE("%s Unknown layer:%" PRId64, __FUNCTION__, layerId); + return nullptr; + } - return it->second.get(); + return it->second.get(); } buffer_handle_t Display::waitAndGetClientTargetBuffer() { - DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); - - ::android::base::unique_fd fence = mClientTarget.getFence(); - if (fence.ok()) { - int err = sync_wait(fence.get(), 3000); - if (err < 0 && errno == ETIME) { - ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__, - fence.get()); + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + + ::android::base::unique_fd fence = mClientTarget.getFence(); + if (fence.ok()) { + int err = sync_wait(fence.get(), 3000); + if (err < 0 && errno == ETIME) { + ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__, fence.get()); + } } - } - return mClientTarget.getBuffer(); + return mClientTarget.getBuffer(); } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Display.h b/system/hwc3/Display.h index 707bc19e..8ed6f919 100644 --- a/system/hwc3/Display.h +++ b/system/hwc3/Display.h @@ -57,144 +57,134 @@ namespace aidl::android::hardware::graphics::composer3::impl { class FrameComposer; class Display { - public: - Display(FrameComposer* composer, int64_t id); - ~Display(); - - Display(const Display& display) = delete; - Display& operator=(const Display& display) = delete; - - Display(Display&& display) = delete; - Display& operator=(Display&& display) = delete; - - HWC3::Error init( - const std::vector<DisplayConfig>& configs, int32_t activeConfigId, - const std::optional<std::vector<uint8_t>>& edid = std::nullopt); - - HWC3::Error updateParameters( - uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY, - uint32_t refreshRateHz, - const std::optional<std::vector<uint8_t>>& edid = std::nullopt); - - // HWComposer3 interface. - HWC3::Error createLayer(int64_t* outLayerId); - HWC3::Error destroyLayer(int64_t layerId); - HWC3::Error getActiveConfig(int32_t* outConfigId); - HWC3::Error getDisplayAttribute(int32_t configId, DisplayAttribute attribute, - int32_t* outValue); - HWC3::Error getColorModes(std::vector<ColorMode>* outColorModes); - HWC3::Error getDisplayCapabilities(std::vector<DisplayCapability>* caps); - HWC3::Error getDisplayConfigs(std::vector<int32_t>* configs); - HWC3::Error getDisplayConnectionType(DisplayConnectionType* outType); - HWC3::Error getDisplayIdentificationData( - DisplayIdentification* outIdentification); - HWC3::Error getDisplayName(std::string* outName); - HWC3::Error getDisplayVsyncPeriod(int32_t* outVsyncPeriod); - HWC3::Error getDisplayedContentSample(int64_t maxFrames, int64_t timestamp, - DisplayContentSample* samples); - HWC3::Error getDisplayedContentSamplingAttributes( - DisplayContentSamplingAttributes* outAttributes); - HWC3::Error getDisplayPhysicalOrientation(common::Transform* outOrientation); - HWC3::Error getHdrCapabilities(HdrCapabilities* outCapabilities); - HWC3::Error getPerFrameMetadataKeys( - std::vector<PerFrameMetadataKey>* outKeys); - HWC3::Error getReadbackBufferAttributes(ReadbackBufferAttributes* attrs); - HWC3::Error getReadbackBufferFence(ndk::ScopedFileDescriptor* acquireFence); - HWC3::Error getRenderIntents(ColorMode mode, - std::vector<RenderIntent>* intents); - HWC3::Error getSupportedContentTypes(std::vector<ContentType>* types); - HWC3::Error getDecorationSupport( - std::optional<common::DisplayDecorationSupport>* support); - HWC3::Error registerCallback( - const std::shared_ptr<IComposerCallback>& callback); - HWC3::Error setActiveConfig(int32_t configId); - HWC3::Error setActiveConfigWithConstraints( - int32_t config, const VsyncPeriodChangeConstraints& constraints, - VsyncPeriodChangeTimeline* outTimeline); - HWC3::Error setBootConfig(int32_t configId); - HWC3::Error clearBootConfig(); - HWC3::Error getPreferredBootConfig(int32_t* outConfigId); - HWC3::Error setAutoLowLatencyMode(bool on); - HWC3::Error setColorMode(ColorMode mode, RenderIntent intent); - HWC3::Error setContentType(ContentType contentType); - HWC3::Error setDisplayedContentSamplingEnabled( - bool enable, FormatColorComponent componentMask, int64_t maxFrames); - HWC3::Error setPowerMode(PowerMode mode); - HWC3::Error setReadbackBuffer(const buffer_handle_t buffer, - const ndk::ScopedFileDescriptor& releaseFence); - HWC3::Error setVsyncEnabled(bool enabled); - HWC3::Error setIdleTimerEnabled(int32_t timeoutMs); - HWC3::Error setColorTransform(const std::vector<float>& transform); - HWC3::Error setBrightness(float brightness); - HWC3::Error setClientTarget(buffer_handle_t buffer, - const ndk::ScopedFileDescriptor& fence, - common::Dataspace dataspace, - const std::vector<common::Rect>& damage); - HWC3::Error setOutputBuffer(buffer_handle_t buffer, - const ndk::ScopedFileDescriptor& fence); - HWC3::Error setExpectedPresentTime( - const std::optional<ClockMonotonicTimestamp>& expectedPresentTime); - HWC3::Error validate(DisplayChanges* outChanges); - HWC3::Error acceptChanges(); - HWC3::Error present( - ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences); - - // Non HWCComposer3 interface. - int64_t getId() const { return mId; } - - Layer* getLayer(int64_t layerHandle); - - HWC3::Error setEdid(std::vector<uint8_t> edid); - - bool hasColorTransform() const { return mColorTransform.has_value(); } - std::array<float, 16> getColorTransform() const { return *mColorTransform; } - - FencedBuffer& getClientTarget() { return mClientTarget; } - buffer_handle_t waitAndGetClientTargetBuffer(); - - const std::vector<Layer*>& getOrderedLayers() { return mOrderedLayers; } - - private: - bool hasConfig(int32_t configId) const; - DisplayConfig* getConfig(int32_t configId); - - std::optional<int32_t> getBootConfigId(); - - void setLegacyEdid(); - - // The state of this display should only be modified from - // SurfaceFlinger's main loop, with the exception of when dump is - // called. To prevent a bad state from crashing us during a dump - // call, all public calls into Display must acquire this mutex. - mutable std::recursive_mutex mStateMutex; - - FrameComposer* mComposer = nullptr; - const int64_t mId; - std::string mName; - PowerMode mPowerMode = PowerMode::OFF; - VsyncThread mVsyncThread; - FencedBuffer mClientTarget; - FencedBuffer mReadbackBuffer; - // Will only be non-null after the Display has been validated and - // before it has been accepted. - enum class PresentFlowState { - WAITING_FOR_VALIDATE, - WAITING_FOR_ACCEPT, - WAITING_FOR_PRESENT, - }; - PresentFlowState mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE; - DisplayChanges mPendingChanges; - std::optional<TimePoint> mExpectedPresentTime; - std::unordered_map<int64_t, std::unique_ptr<Layer>> mLayers; - // Ordered layers available after validate(). - std::vector<Layer*> mOrderedLayers; - std::optional<int32_t> mActiveConfigId; - std::unordered_map<int32_t, DisplayConfig> mConfigs; - std::unordered_set<ColorMode> mColorModes = {ColorMode::NATIVE}; - ColorMode mActiveColorMode = ColorMode::NATIVE; - std::optional<std::array<float, 16>> mColorTransform; - std::vector<uint8_t> mEdid; + public: + Display(FrameComposer* composer, int64_t id); + ~Display(); + + Display(const Display& display) = delete; + Display& operator=(const Display& display) = delete; + + Display(Display&& display) = delete; + Display& operator=(Display&& display) = delete; + + HWC3::Error init(const std::vector<DisplayConfig>& configs, int32_t activeConfigId, + const std::optional<std::vector<uint8_t>>& edid = std::nullopt); + + HWC3::Error updateParameters(uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY, + uint32_t refreshRateHz, + const std::optional<std::vector<uint8_t>>& edid = std::nullopt); + + // HWComposer3 interface. + HWC3::Error createLayer(int64_t* outLayerId); + HWC3::Error destroyLayer(int64_t layerId); + HWC3::Error getActiveConfig(int32_t* outConfigId); + HWC3::Error getDisplayAttribute(int32_t configId, DisplayAttribute attribute, + int32_t* outValue); + HWC3::Error getColorModes(std::vector<ColorMode>* outColorModes); + HWC3::Error getDisplayCapabilities(std::vector<DisplayCapability>* caps); + HWC3::Error getDisplayConfigs(std::vector<int32_t>* configs); + HWC3::Error getDisplayConnectionType(DisplayConnectionType* outType); + HWC3::Error getDisplayIdentificationData(DisplayIdentification* outIdentification); + HWC3::Error getDisplayName(std::string* outName); + HWC3::Error getDisplayVsyncPeriod(int32_t* outVsyncPeriod); + HWC3::Error getDisplayedContentSample(int64_t maxFrames, int64_t timestamp, + DisplayContentSample* samples); + HWC3::Error getDisplayedContentSamplingAttributes( + DisplayContentSamplingAttributes* outAttributes); + HWC3::Error getDisplayPhysicalOrientation(common::Transform* outOrientation); + HWC3::Error getHdrCapabilities(HdrCapabilities* outCapabilities); + HWC3::Error getPerFrameMetadataKeys(std::vector<PerFrameMetadataKey>* outKeys); + HWC3::Error getReadbackBufferAttributes(ReadbackBufferAttributes* attrs); + HWC3::Error getReadbackBufferFence(ndk::ScopedFileDescriptor* acquireFence); + HWC3::Error getRenderIntents(ColorMode mode, std::vector<RenderIntent>* intents); + HWC3::Error getSupportedContentTypes(std::vector<ContentType>* types); + HWC3::Error getDecorationSupport(std::optional<common::DisplayDecorationSupport>* support); + HWC3::Error registerCallback(const std::shared_ptr<IComposerCallback>& callback); + HWC3::Error setActiveConfig(int32_t configId); + HWC3::Error setActiveConfigWithConstraints(int32_t config, + const VsyncPeriodChangeConstraints& constraints, + VsyncPeriodChangeTimeline* outTimeline); + HWC3::Error setBootConfig(int32_t configId); + HWC3::Error clearBootConfig(); + HWC3::Error getPreferredBootConfig(int32_t* outConfigId); + HWC3::Error setAutoLowLatencyMode(bool on); + HWC3::Error setColorMode(ColorMode mode, RenderIntent intent); + HWC3::Error setContentType(ContentType contentType); + HWC3::Error setDisplayedContentSamplingEnabled(bool enable, FormatColorComponent componentMask, + int64_t maxFrames); + HWC3::Error setPowerMode(PowerMode mode); + HWC3::Error setReadbackBuffer(const buffer_handle_t buffer, + const ndk::ScopedFileDescriptor& releaseFence); + HWC3::Error setVsyncEnabled(bool enabled); + HWC3::Error setIdleTimerEnabled(int32_t timeoutMs); + HWC3::Error setColorTransform(const std::vector<float>& transform); + HWC3::Error setBrightness(float brightness); + HWC3::Error setClientTarget(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence, + common::Dataspace dataspace, + const std::vector<common::Rect>& damage); + HWC3::Error setOutputBuffer(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence); + HWC3::Error setExpectedPresentTime( + const std::optional<ClockMonotonicTimestamp>& expectedPresentTime); + HWC3::Error validate(DisplayChanges* outChanges); + HWC3::Error acceptChanges(); + HWC3::Error present(::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences); + + // Non HWCComposer3 interface. + int64_t getId() const { return mId; } + + Layer* getLayer(int64_t layerHandle); + + HWC3::Error setEdid(std::vector<uint8_t> edid); + + bool hasColorTransform() const { return mColorTransform.has_value(); } + std::array<float, 16> getColorTransform() const { return *mColorTransform; } + + FencedBuffer& getClientTarget() { return mClientTarget; } + buffer_handle_t waitAndGetClientTargetBuffer(); + + const std::vector<Layer*>& getOrderedLayers() { return mOrderedLayers; } + + private: + bool hasConfig(int32_t configId) const; + DisplayConfig* getConfig(int32_t configId); + + std::optional<int32_t> getBootConfigId(); + + void setLegacyEdid(); + + // The state of this display should only be modified from + // SurfaceFlinger's main loop, with the exception of when dump is + // called. To prevent a bad state from crashing us during a dump + // call, all public calls into Display must acquire this mutex. + mutable std::recursive_mutex mStateMutex; + + FrameComposer* mComposer = nullptr; + const int64_t mId; + std::string mName; + PowerMode mPowerMode = PowerMode::OFF; + VsyncThread mVsyncThread; + FencedBuffer mClientTarget; + FencedBuffer mReadbackBuffer; + // Will only be non-null after the Display has been validated and + // before it has been accepted. + enum class PresentFlowState { + WAITING_FOR_VALIDATE, + WAITING_FOR_ACCEPT, + WAITING_FOR_PRESENT, + }; + PresentFlowState mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE; + DisplayChanges mPendingChanges; + std::optional<TimePoint> mExpectedPresentTime; + std::unordered_map<int64_t, std::unique_ptr<Layer>> mLayers; + // Ordered layers available after validate(). + std::vector<Layer*> mOrderedLayers; + std::optional<int32_t> mActiveConfigId; + std::unordered_map<int32_t, DisplayConfig> mConfigs; + std::unordered_set<ColorMode> mColorModes = {ColorMode::NATIVE}; + ColorMode mActiveColorMode = ColorMode::NATIVE; + std::optional<std::array<float, 16>> mColorTransform; + std::vector<uint8_t> mEdid; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/DisplayChanges.h b/system/hwc3/DisplayChanges.h index 2745a4d6..7c4b5d18 100644 --- a/system/hwc3/DisplayChanges.h +++ b/system/hwc3/DisplayChanges.h @@ -26,32 +26,32 @@ namespace aidl::android::hardware::graphics::composer3::impl { struct DisplayChanges { - std::optional<ChangedCompositionTypes> compositionChanges; - std::optional<DisplayRequest> displayRequestChanges; - - void addLayerCompositionChange(int64_t displayId, int64_t layerId, - Composition layerComposition) { - if (!compositionChanges) { - compositionChanges.emplace(); - compositionChanges->display = displayId; + std::optional<ChangedCompositionTypes> compositionChanges; + std::optional<DisplayRequest> displayRequestChanges; + + void addLayerCompositionChange(int64_t displayId, int64_t layerId, + Composition layerComposition) { + if (!compositionChanges) { + compositionChanges.emplace(); + compositionChanges->display = displayId; + } + + ChangedCompositionLayer compositionChange; + compositionChange.layer = layerId; + compositionChange.composition = layerComposition; + compositionChanges->layers.emplace_back(std::move(compositionChange)); } - ChangedCompositionLayer compositionChange; - compositionChange.layer = layerId; - compositionChange.composition = layerComposition; - compositionChanges->layers.emplace_back(std::move(compositionChange)); - } + void clearLayerCompositionChanges() { compositionChanges.reset(); } - void clearLayerCompositionChanges() { compositionChanges.reset(); } - - bool hasAnyChanges() const { - return compositionChanges.has_value() || displayRequestChanges.has_value(); - } + bool hasAnyChanges() const { + return compositionChanges.has_value() || displayRequestChanges.has_value(); + } - void reset() { - compositionChanges.reset(); - displayRequestChanges.reset(); - } + void reset() { + compositionChanges.reset(); + displayRequestChanges.reset(); + } }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/DisplayConfig.cpp b/system/hwc3/DisplayConfig.cpp index 36050107..c17fa952 100644 --- a/system/hwc3/DisplayConfig.cpp +++ b/system/hwc3/DisplayConfig.cpp @@ -23,110 +23,108 @@ namespace { template <class T> inline void hashCombine(size_t& hash, const T& value) { - std::hash<T> hasher; - hash ^= hasher(value) + 0x9e3779b9 + (hash << 6) + (hash >> 2); + std::hash<T> hasher; + hash ^= hasher(value) + 0x9e3779b9 + (hash << 6) + (hash >> 2); } } // namespace void DisplayConfig::setAttribute(DisplayAttribute attribute, int32_t value) { - if (attribute == DisplayAttribute::WIDTH) { - mWidth = value; - } - if (attribute == DisplayAttribute::HEIGHT) { - mHeight = value; - } - if (attribute == DisplayAttribute::DPI_X) { - mDpiX = value; - } - if (attribute == DisplayAttribute::DPI_Y) { - mDpiY = value; - } - if (attribute == DisplayAttribute::VSYNC_PERIOD) { - mVsyncPeriodNanos = value; - } - if (attribute == DisplayAttribute::CONFIG_GROUP) { - mConfigGroup = value; - } + if (attribute == DisplayAttribute::WIDTH) { + mWidth = value; + } + if (attribute == DisplayAttribute::HEIGHT) { + mHeight = value; + } + if (attribute == DisplayAttribute::DPI_X) { + mDpiX = value; + } + if (attribute == DisplayAttribute::DPI_Y) { + mDpiY = value; + } + if (attribute == DisplayAttribute::VSYNC_PERIOD) { + mVsyncPeriodNanos = value; + } + if (attribute == DisplayAttribute::CONFIG_GROUP) { + mConfigGroup = value; + } } int32_t DisplayConfig::getAttribute(DisplayAttribute attribute) const { - if (attribute == DisplayAttribute::WIDTH) { - return mWidth; - } - if (attribute == DisplayAttribute::HEIGHT) { - return mHeight; - } - if (attribute == DisplayAttribute::DPI_X) { - // From hwcomposer2.h, HWC2_ATTRIBUTE_DPI_X returns "Dots per thousand - // inches (DPI * 1000)". - return getDotsPerThousandInchesX(); - } - if (attribute == DisplayAttribute::DPI_Y) { - // From hwcomposer2.h, HWC2_ATTRIBUTE_DPI_Y returns "Dots per thousand - // inches (DPI * 1000)" - return getDotsPerThousandInchesY(); - } - if (attribute == DisplayAttribute::VSYNC_PERIOD) { - return mVsyncPeriodNanos; - } - if (attribute == DisplayAttribute::CONFIG_GROUP) { - return mConfigGroup; - } - return -1; + if (attribute == DisplayAttribute::WIDTH) { + return mWidth; + } + if (attribute == DisplayAttribute::HEIGHT) { + return mHeight; + } + if (attribute == DisplayAttribute::DPI_X) { + // From hwcomposer2.h, HWC2_ATTRIBUTE_DPI_X returns "Dots per thousand + // inches (DPI * 1000)". + return getDotsPerThousandInchesX(); + } + if (attribute == DisplayAttribute::DPI_Y) { + // From hwcomposer2.h, HWC2_ATTRIBUTE_DPI_Y returns "Dots per thousand + // inches (DPI * 1000)" + return getDotsPerThousandInchesY(); + } + if (attribute == DisplayAttribute::VSYNC_PERIOD) { + return mVsyncPeriodNanos; + } + if (attribute == DisplayAttribute::CONFIG_GROUP) { + return mConfigGroup; + } + return -1; } std::string DisplayConfig::toString() const { - std::string output; - output += " id: " + std::to_string(mId); - output += " w:" + std::to_string(mWidth); - output += " h:" + std::to_string(mHeight); - output += " dpi-x:" + std::to_string(mDpiX); - output += " dpi-y:" + std::to_string(mDpiY); - output += " vsync:" + std::to_string(1e9 / mVsyncPeriodNanos); - output += " config-group:" + std::to_string(mConfigGroup); - return output; + std::string output; + output += " id: " + std::to_string(mId); + output += " w:" + std::to_string(mWidth); + output += " h:" + std::to_string(mHeight); + output += " dpi-x:" + std::to_string(mDpiX); + output += " dpi-y:" + std::to_string(mDpiY); + output += " vsync:" + std::to_string(1e9 / mVsyncPeriodNanos); + output += " config-group:" + std::to_string(mConfigGroup); + return output; } /*static*/ void DisplayConfig::addConfigGroups(std::vector<DisplayConfig>* configs) { - // From /hardware/interfaces/graphics/composer/2.4/IComposerClient.hal: - // "Configurations which share the same config group are similar in all - // attributes except for the vsync period." - struct ConfigForGroupHash { - size_t operator()(const DisplayConfig& config) const { - size_t hash = 0; - hashCombine(hash, config.mWidth); - hashCombine(hash, config.mHeight); - hashCombine(hash, config.mDpiX); - hashCombine(hash, config.mDpiY); - return hash; - } - }; - struct ConfigForGroupEq { - size_t operator()(const DisplayConfig& a, const DisplayConfig& b) const { - if (a.mWidth != b.mWidth) { - return a.mWidth < b.mWidth; - } - if (a.mHeight != b.mHeight) { - return a.mHeight < b.mHeight; - } - if (a.mDpiX != b.mDpiX) { - return a.mDpiX < b.mDpiX; - } - return a.mDpiY < b.mDpiY; - } - }; + // From /hardware/interfaces/graphics/composer/2.4/IComposerClient.hal: + // "Configurations which share the same config group are similar in all + // attributes except for the vsync period." + struct ConfigForGroupHash { + size_t operator()(const DisplayConfig& config) const { + size_t hash = 0; + hashCombine(hash, config.mWidth); + hashCombine(hash, config.mHeight); + hashCombine(hash, config.mDpiX); + hashCombine(hash, config.mDpiY); + return hash; + } + }; + struct ConfigForGroupEq { + size_t operator()(const DisplayConfig& a, const DisplayConfig& b) const { + if (a.mWidth != b.mWidth) { + return a.mWidth < b.mWidth; + } + if (a.mHeight != b.mHeight) { + return a.mHeight < b.mHeight; + } + if (a.mDpiX != b.mDpiX) { + return a.mDpiX < b.mDpiX; + } + return a.mDpiY < b.mDpiY; + } + }; - std::unordered_map<DisplayConfig, int32_t, ConfigForGroupHash, - ConfigForGroupEq> - configToConfigGroup; + std::unordered_map<DisplayConfig, int32_t, ConfigForGroupHash, ConfigForGroupEq> + configToConfigGroup; - for (auto& config : *configs) { - auto [it, inserted] = - configToConfigGroup.try_emplace(config, configToConfigGroup.size()); - config.setConfigGroup(it->second); - } + for (auto& config : *configs) { + auto [it, inserted] = configToConfigGroup.try_emplace(config, configToConfigGroup.size()); + config.setConfigGroup(it->second); + } } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/DisplayConfig.h b/system/hwc3/DisplayConfig.h index 7130fff4..1abd992c 100644 --- a/system/hwc3/DisplayConfig.h +++ b/system/hwc3/DisplayConfig.h @@ -26,63 +26,63 @@ namespace aidl::android::hardware::graphics::composer3::impl { class DisplayConfig { - public: - DisplayConfig(int32_t configId) : mId(configId) {} + public: + DisplayConfig(int32_t configId) : mId(configId) {} - DisplayConfig(int32_t configId, int32_t width, int32_t height, int32_t dpiX, - int32_t dpiY, int32_t vsyncPeriodNanos) - : mId(configId), - mWidth(width), - mHeight(height), - mDpiX(dpiX), - mDpiY(dpiY), - mVsyncPeriodNanos(vsyncPeriodNanos) {} + DisplayConfig(int32_t configId, int32_t width, int32_t height, int32_t dpiX, int32_t dpiY, + int32_t vsyncPeriodNanos) + : mId(configId), + mWidth(width), + mHeight(height), + mDpiX(dpiX), + mDpiY(dpiY), + mVsyncPeriodNanos(vsyncPeriodNanos) {} - DisplayConfig(const DisplayConfig& other) = default; - DisplayConfig& operator=(DisplayConfig& other) = default; + DisplayConfig(const DisplayConfig& other) = default; + DisplayConfig& operator=(DisplayConfig& other) = default; - DisplayConfig(DisplayConfig&& other) = default; - DisplayConfig& operator=(DisplayConfig&& other) = default; + DisplayConfig(DisplayConfig&& other) = default; + DisplayConfig& operator=(DisplayConfig&& other) = default; - int32_t getId() const { return mId; } - void setId(int32_t id) { mId = id; } + int32_t getId() const { return mId; } + void setId(int32_t id) { mId = id; } - int32_t getAttribute(DisplayAttribute attribute) const; - void setAttribute(DisplayAttribute attribute, int32_t value); + int32_t getAttribute(DisplayAttribute attribute) const; + void setAttribute(DisplayAttribute attribute, int32_t value); - int32_t getWidth() const { return mWidth; } - void setWidth(int32_t width) { mWidth = width; } + int32_t getWidth() const { return mWidth; } + void setWidth(int32_t width) { mWidth = width; } - int32_t getHeight() const { return mHeight; } - void getHeight(int32_t height) { mHeight = height; } + int32_t getHeight() const { return mHeight; } + void getHeight(int32_t height) { mHeight = height; } - int32_t getDpiX() const { return mDpiX; } - void setDpiX(int32_t dpi) { mDpiX = dpi; } + int32_t getDpiX() const { return mDpiX; } + void setDpiX(int32_t dpi) { mDpiX = dpi; } - int32_t getDpiY() const { return mDpiY; } - void setDpiY(int32_t dpi) { mDpiY = dpi; } + int32_t getDpiY() const { return mDpiY; } + void setDpiY(int32_t dpi) { mDpiY = dpi; } - int32_t getDotsPerThousandInchesX() const { return mDpiX * 1000; } - int32_t getDotsPerThousandInchesY() const { return mDpiY * 1000; } + int32_t getDotsPerThousandInchesX() const { return mDpiX * 1000; } + int32_t getDotsPerThousandInchesY() const { return mDpiY * 1000; } - int32_t getVsyncPeriod() const { return mVsyncPeriodNanos; } - void setVsyncPeriod(int32_t vsync) { mVsyncPeriodNanos = vsync; } + int32_t getVsyncPeriod() const { return mVsyncPeriodNanos; } + void setVsyncPeriod(int32_t vsync) { mVsyncPeriodNanos = vsync; } - int32_t getConfigGroup() const { return mConfigGroup; } - void setConfigGroup(int32_t group) { mConfigGroup = group; } + int32_t getConfigGroup() const { return mConfigGroup; } + void setConfigGroup(int32_t group) { mConfigGroup = group; } - std::string toString() const; + std::string toString() const; - static void addConfigGroups(std::vector<DisplayConfig>* configs); + static void addConfigGroups(std::vector<DisplayConfig>* configs); - private: - int32_t mId; - int32_t mWidth; - int32_t mHeight; - int32_t mDpiX; - int32_t mDpiY; - int32_t mVsyncPeriodNanos; - int32_t mConfigGroup; + private: + int32_t mId; + int32_t mWidth; + int32_t mHeight; + int32_t mDpiX; + int32_t mDpiY; + int32_t mVsyncPeriodNanos; + int32_t mConfigGroup; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/DisplayFinder.cpp b/system/hwc3/DisplayFinder.cpp index 9ee68374..0dd59224 100644 --- a/system/hwc3/DisplayFinder.cpp +++ b/system/hwc3/DisplayFinder.cpp @@ -43,215 +43,203 @@ static uint32_t getVsyncHzFromProperty() { return static_cast<uint32_t>(vsyncPeriod); } -HWC3::Error findGoldfishPrimaryDisplay( - std::vector<DisplayMultiConfigs>* outDisplays) { - DEBUG_LOG("%s", __FUNCTION__); - - DEFINE_AND_VALIDATE_HOST_CONNECTION - hostCon->lock(); - const int32_t vsyncPeriodNanos = HertzToPeriodNanos(getVsyncHzFromProperty()); - DisplayMultiConfigs display; - display.displayId = 0; - if (rcEnc->hasHWCMultiConfigs()) { - int count = rcEnc->rcGetFBDisplayConfigsCount(rcEnc); - if (count <= 0) { - ALOGE("%s failed to allocate primary display, config count %d", __func__, - count); - return HWC3::Error::NoResources; - } - display.activeConfigId = rcEnc->rcGetFBDisplayActiveConfig(rcEnc); - for (int configId = 0; configId < count; configId++) { - display.configs.push_back(DisplayConfig( - configId, // - rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_WIDTH), // - rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_HEIGHT), // - rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_XDPI), // - rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_YDPI), // - vsyncPeriodNanos // - )); +HWC3::Error findGoldfishPrimaryDisplay(std::vector<DisplayMultiConfigs>* outDisplays) { + DEBUG_LOG("%s", __FUNCTION__); + + DEFINE_AND_VALIDATE_HOST_CONNECTION + hostCon->lock(); + const int32_t vsyncPeriodNanos = HertzToPeriodNanos(getVsyncHzFromProperty()); + DisplayMultiConfigs display; + display.displayId = 0; + if (rcEnc->hasHWCMultiConfigs()) { + int count = rcEnc->rcGetFBDisplayConfigsCount(rcEnc); + if (count <= 0) { + ALOGE("%s failed to allocate primary display, config count %d", __func__, count); + return HWC3::Error::NoResources; + } + display.activeConfigId = rcEnc->rcGetFBDisplayActiveConfig(rcEnc); + for (int configId = 0; configId < count; configId++) { + display.configs.push_back(DisplayConfig( + configId, // + rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_WIDTH), // + rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_HEIGHT), // + rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_XDPI), // + rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_YDPI), // + vsyncPeriodNanos // + )); + } + } else { + display.activeConfigId = 0; + display.configs.push_back(DisplayConfig(0, // + rcEnc->rcGetFBParam(rcEnc, FB_WIDTH), // + rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT), // + rcEnc->rcGetFBParam(rcEnc, FB_XDPI), // + rcEnc->rcGetFBParam(rcEnc, FB_YDPI), // + vsyncPeriodNanos // + )); } - } else { - display.activeConfigId = 0; - display.configs.push_back(DisplayConfig( - 0, // - rcEnc->rcGetFBParam(rcEnc, FB_WIDTH), // - rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT), // - rcEnc->rcGetFBParam(rcEnc, FB_XDPI), // - rcEnc->rcGetFBParam(rcEnc, FB_YDPI), // - vsyncPeriodNanos // - )); - } - hostCon->unlock(); - - outDisplays->push_back(display); - - return HWC3::Error::None; -} + hostCon->unlock(); -void parseExternalDisplaysFromProperties(std::vector<int>& outPropIntParts) { + outDisplays->push_back(display); - static constexpr const char* kExternalDisplayProp[] = { - "hwservicemanager.external.displays", - "ro.boot.qemu.external.displays", - }; - - for (auto propName: kExternalDisplayProp) { - const std::string propVal = ::android::base::GetProperty(propName, ""); - if (propVal.empty()) { - DEBUG_LOG("%s: prop name is: %s, prop value is: empty", __FUNCTION__, - propName); - continue; - } - DEBUG_LOG("%s: prop name is: %s, prop value is: %s", __FUNCTION__, - propName, propVal.c_str()); - - const std::vector<std::string> propStringParts = - ::android::base::Split(propVal, ","); - if (propStringParts.size() % 5 != 0) { - ALOGE("%s: Invalid syntax for system prop %s which is %s", __FUNCTION__, - propName, propVal.c_str()); - continue; - } - std::vector<int> propIntParts; - for (const std::string& propStringPart : propStringParts) { - int propIntPart; - if (!::android::base::ParseInt(propStringPart, &propIntPart)) { - ALOGE("%s: Invalid syntax for system prop %s which is %s", __FUNCTION__, - propName, propVal.c_str()); - break; - } - propIntParts.push_back(propIntPart); - } - if (propIntParts.empty() || propIntParts.size() % 5 != 0) { - continue; - } - outPropIntParts.insert(outPropIntParts.end(), propIntParts.begin(), propIntParts.end()); - } + return HWC3::Error::None; } -HWC3::Error findGoldfishSecondaryDisplays( - std::vector<DisplayMultiConfigs>* outDisplays) { - DEBUG_LOG("%s", __FUNCTION__); - - - std::vector<int> propIntParts; - parseExternalDisplaysFromProperties(propIntParts); - - int64_t secondaryDisplayId = 1; - while (!propIntParts.empty()) { - DisplayMultiConfigs display; - display.displayId = secondaryDisplayId; - display.activeConfigId = 0; - display.configs.push_back(DisplayConfig( - 0, // - /*width=*/propIntParts[1], // - /*heighth=*/propIntParts[2], // - /*dpiXh=*/propIntParts[3], // - /*dpiYh=*/propIntParts[3], // - /*vsyncPeriod=*/HertzToPeriodNanos(160) // - )); - outDisplays->push_back(display); - - ++secondaryDisplayId; +void parseExternalDisplaysFromProperties(std::vector<int>& outPropIntParts) { + static constexpr const char* kExternalDisplayProp[] = { + "hwservicemanager.external.displays", + "ro.boot.qemu.external.displays", + }; + + for (auto propName : kExternalDisplayProp) { + const std::string propVal = ::android::base::GetProperty(propName, ""); + if (propVal.empty()) { + DEBUG_LOG("%s: prop name is: %s, prop value is: empty", __FUNCTION__, propName); + continue; + } + DEBUG_LOG("%s: prop name is: %s, prop value is: %s", __FUNCTION__, propName, + propVal.c_str()); + + const std::vector<std::string> propStringParts = ::android::base::Split(propVal, ","); + if (propStringParts.size() % 5 != 0) { + ALOGE("%s: Invalid syntax for system prop %s which is %s", __FUNCTION__, propName, + propVal.c_str()); + continue; + } + std::vector<int> propIntParts; + for (const std::string& propStringPart : propStringParts) { + int propIntPart; + if (!::android::base::ParseInt(propStringPart, &propIntPart)) { + ALOGE("%s: Invalid syntax for system prop %s which is %s", __FUNCTION__, propName, + propVal.c_str()); + break; + } + propIntParts.push_back(propIntPart); + } + if (propIntParts.empty() || propIntParts.size() % 5 != 0) { + continue; + } + outPropIntParts.insert(outPropIntParts.end(), propIntParts.begin(), propIntParts.end()); + } +} - propIntParts.erase(propIntParts.begin(), propIntParts.begin() + 5); - } +HWC3::Error findGoldfishSecondaryDisplays(std::vector<DisplayMultiConfigs>* outDisplays) { + DEBUG_LOG("%s", __FUNCTION__); + + std::vector<int> propIntParts; + parseExternalDisplaysFromProperties(propIntParts); + + int64_t secondaryDisplayId = 1; + while (!propIntParts.empty()) { + DisplayMultiConfigs display; + display.displayId = secondaryDisplayId; + display.activeConfigId = 0; + display.configs.push_back(DisplayConfig(0, // + /*width=*/propIntParts[1], // + /*heighth=*/propIntParts[2], // + /*dpiXh=*/propIntParts[3], // + /*dpiYh=*/propIntParts[3], // + /*vsyncPeriod=*/HertzToPeriodNanos(160) // + )); + outDisplays->push_back(display); + + ++secondaryDisplayId; + + propIntParts.erase(propIntParts.begin(), propIntParts.begin() + 5); + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error findGoldfishDisplays(std::vector<DisplayMultiConfigs>* outDisplays) { - HWC3::Error error = findGoldfishPrimaryDisplay(outDisplays); - if (error != HWC3::Error::None) { - ALOGE("%s failed to find Goldfish primary display", __FUNCTION__); - return error; - } + HWC3::Error error = findGoldfishPrimaryDisplay(outDisplays); + if (error != HWC3::Error::None) { + ALOGE("%s failed to find Goldfish primary display", __FUNCTION__); + return error; + } - error = findGoldfishSecondaryDisplays(outDisplays); - if (error != HWC3::Error::None) { - ALOGE("%s failed to find Goldfish secondary displays", __FUNCTION__); - } + error = findGoldfishSecondaryDisplays(outDisplays); + if (error != HWC3::Error::None) { + ALOGE("%s failed to find Goldfish secondary displays", __FUNCTION__); + } - return error; + return error; } // This is currently only used for Gem5 bring-up where virtio-gpu and drm // are not currently available. For now, just return a placeholder display. HWC3::Error findNoOpDisplays(std::vector<DisplayMultiConfigs>* outDisplays) { - outDisplays->push_back(DisplayMultiConfigs{ - .displayId = 0, - .activeConfigId = 0, - .configs = {DisplayConfig(0, - /*width=*/720, // - /*heighth=*/1280, // - /*dpiXh=*/320, // - /*dpiYh=*/320, // - /*vsyncPeriod=*/HertzToPeriodNanos(30) // - )}, - }); - - return HWC3::Error::None; + outDisplays->push_back(DisplayMultiConfigs{ + .displayId = 0, + .activeConfigId = 0, + .configs = {DisplayConfig(0, + /*width=*/720, // + /*heighth=*/1280, // + /*dpiXh=*/320, // + /*dpiYh=*/320, // + /*vsyncPeriod=*/HertzToPeriodNanos(30) // + )}, + }); + + return HWC3::Error::None; } -HWC3::Error findDrmDisplays(const DrmClient& drm, - std::vector<DisplayMultiConfigs>* outDisplays) { - outDisplays->clear(); +HWC3::Error findDrmDisplays(const DrmClient& drm, std::vector<DisplayMultiConfigs>* outDisplays) { + outDisplays->clear(); - std::vector<DrmClient::DisplayConfig> drmDisplayConfigs; + std::vector<DrmClient::DisplayConfig> drmDisplayConfigs; - HWC3::Error error = drm.getDisplayConfigs(&drmDisplayConfigs); - if (error != HWC3::Error::None) { - ALOGE("%s failed to find displays from DRM.", __FUNCTION__); - return error; - } + HWC3::Error error = drm.getDisplayConfigs(&drmDisplayConfigs); + if (error != HWC3::Error::None) { + ALOGE("%s failed to find displays from DRM.", __FUNCTION__); + return error; + } - for (const DrmClient::DisplayConfig drmDisplayConfig : drmDisplayConfigs) { - outDisplays->push_back(DisplayMultiConfigs{ - .displayId = drmDisplayConfig.id, - .activeConfigId = static_cast<int32_t>(drmDisplayConfig.id), - .configs = - { - DisplayConfig(static_cast<int32_t>(drmDisplayConfig.id), - static_cast<int32_t>(drmDisplayConfig.width), - static_cast<int32_t>(drmDisplayConfig.height), - static_cast<int32_t>(drmDisplayConfig.dpiX), - static_cast<int32_t>(drmDisplayConfig.dpiY), - HertzToPeriodNanos(drmDisplayConfig.refreshRateHz)), - }, - }); - } + for (const DrmClient::DisplayConfig drmDisplayConfig : drmDisplayConfigs) { + outDisplays->push_back(DisplayMultiConfigs{ + .displayId = drmDisplayConfig.id, + .activeConfigId = static_cast<int32_t>(drmDisplayConfig.id), + .configs = + { + DisplayConfig(static_cast<int32_t>(drmDisplayConfig.id), + static_cast<int32_t>(drmDisplayConfig.width), + static_cast<int32_t>(drmDisplayConfig.height), + static_cast<int32_t>(drmDisplayConfig.dpiX), + static_cast<int32_t>(drmDisplayConfig.dpiY), + HertzToPeriodNanos(drmDisplayConfig.refreshRateHz)), + }, + }); + } - return HWC3::Error::None; + return HWC3::Error::None; } } // namespace -HWC3::Error findDisplays(const DrmClient* drm, - std::vector<DisplayMultiConfigs>* outDisplays) { - HWC3::Error error = HWC3::Error::None; - if (IsInGem5DisplayFinderMode() || IsInNoOpDisplayFinderMode()) { - error = findNoOpDisplays(outDisplays); - } else if (IsInDrmDisplayFinderMode()) { - if (drm == nullptr) { - ALOGE("%s asked to find displays from DRM, but DRM not available.", - __FUNCTION__); - return HWC3::Error::NoResources; +HWC3::Error findDisplays(const DrmClient* drm, std::vector<DisplayMultiConfigs>* outDisplays) { + HWC3::Error error = HWC3::Error::None; + if (IsInGem5DisplayFinderMode() || IsInNoOpDisplayFinderMode()) { + error = findNoOpDisplays(outDisplays); + } else if (IsInDrmDisplayFinderMode()) { + if (drm == nullptr) { + ALOGE("%s asked to find displays from DRM, but DRM not available.", __FUNCTION__); + return HWC3::Error::NoResources; + } + error = findDrmDisplays(*drm, outDisplays); + } else { + error = findGoldfishDisplays(outDisplays); } - error = findDrmDisplays(*drm, outDisplays); - } else { - error = findGoldfishDisplays(outDisplays); - } - if (error != HWC3::Error::None) { - ALOGE("%s failed to find displays", __FUNCTION__); - return error; - } + if (error != HWC3::Error::None) { + ALOGE("%s failed to find displays", __FUNCTION__); + return error; + } - for (auto& display : *outDisplays) { - DisplayConfig::addConfigGroups(&display.configs); - } + for (auto& display : *outDisplays) { + DisplayConfig::addConfigGroups(&display.configs); + } - return HWC3::Error::None; + return HWC3::Error::None; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/DisplayFinder.h b/system/hwc3/DisplayFinder.h index f66eedfb..c124c805 100644 --- a/system/hwc3/DisplayFinder.h +++ b/system/hwc3/DisplayFinder.h @@ -27,16 +27,15 @@ namespace aidl::android::hardware::graphics::composer3::impl { struct DisplayMultiConfigs { - int64_t displayId; - int32_t activeConfigId; - // Modes that this display can be configured to use. - std::vector<DisplayConfig> configs; + int64_t displayId; + int32_t activeConfigId; + // Modes that this display can be configured to use. + std::vector<DisplayConfig> configs; }; void parseExternalDisplaysFromProperties(std::vector<int>& outPropIntParts); -HWC3::Error findDisplays(const DrmClient* drm, - std::vector<DisplayMultiConfigs>* outDisplays); +HWC3::Error findDisplays(const DrmClient* drm, std::vector<DisplayMultiConfigs>* outDisplays); } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/DrmClient.cpp b/system/hwc3/DrmClient.cpp index 2f0fb732..a55e94bd 100644 --- a/system/hwc3/DrmClient.cpp +++ b/system/hwc3/DrmClient.cpp @@ -31,34 +31,33 @@ DrmClient::~DrmClient() { } ::android::base::unique_fd DrmClient::OpenVirtioGpuDrmFd() { - for (int i = 0; i < 10; i++) { - const std::string path = "/dev/dri/card" + std::to_string(i); - DEBUG_LOG("%s: trying to open DRM device at %s", - __FUNCTION__, path.c_str()); + for (int i = 0; i < 10; i++) { + const std::string path = "/dev/dri/card" + std::to_string(i); + DEBUG_LOG("%s: trying to open DRM device at %s", __FUNCTION__, path.c_str()); - ::android::base::unique_fd fd(open(path.c_str(), O_RDWR | O_CLOEXEC)); + ::android::base::unique_fd fd(open(path.c_str(), O_RDWR | O_CLOEXEC)); - if (fd < 0) { - ALOGE("%s: failed to open drm device %s: %s", - __FUNCTION__, path.c_str(), strerror(errno)); - continue; - } + if (fd < 0) { + ALOGE("%s: failed to open drm device %s: %s", __FUNCTION__, path.c_str(), + strerror(errno)); + continue; + } - auto version = drmGetVersion(fd.get()); - const std::string name = version->name; - drmFreeVersion(version); + auto version = drmGetVersion(fd.get()); + const std::string name = version->name; + drmFreeVersion(version); - DEBUG_LOG("%s: The DRM device at %s is \"%s\"", - __FUNCTION__, path.c_str(), name.c_str()); - if (name.find("virtio") != std::string::npos) { - return fd; + DEBUG_LOG("%s: The DRM device at %s is \"%s\"", __FUNCTION__, path.c_str(), name.c_str()); + if (name.find("virtio") != std::string::npos) { + return fd; + } } - } - ALOGE("Failed to find virtio-gpu DRM node. Ranchu HWComposer " + ALOGE( + "Failed to find virtio-gpu DRM node. Ranchu HWComposer " "is only expected to be used with \"virtio_gpu\""); - return ::android::base::unique_fd(-1); + return ::android::base::unique_fd(-1); } HWC3::Error DrmClient::init() { diff --git a/system/hwc3/FencedBuffer.h b/system/hwc3/FencedBuffer.h index 50e85349..03f71f42 100644 --- a/system/hwc3/FencedBuffer.h +++ b/system/hwc3/FencedBuffer.h @@ -24,35 +24,34 @@ namespace aidl::android::hardware::graphics::composer3::impl { class FencedBuffer { - public: - FencedBuffer() : mBuffer(nullptr) {} + public: + FencedBuffer() : mBuffer(nullptr) {} - void set(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence) { - mBuffer = buffer; - mFence = GetUniqueFd(fence); - } + void set(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence) { + mBuffer = buffer; + mFence = GetUniqueFd(fence); + } + + buffer_handle_t getBuffer() const { return mBuffer; } - buffer_handle_t getBuffer() const { return mBuffer; } + ::android::base::unique_fd getFence() const { + if (mFence.ok()) { + return ::android::base::unique_fd(dup(mFence.get())); + } else { + return ::android::base::unique_fd(); + } + } - ::android::base::unique_fd getFence() const { - if (mFence.ok()) { - return ::android::base::unique_fd(dup(mFence.get())); - } else { - return ::android::base::unique_fd(); + private: + static ::android::base::unique_fd GetUniqueFd(const ndk::ScopedFileDescriptor& in) { + auto& sfd = const_cast<ndk::ScopedFileDescriptor&>(in); + ::android::base::unique_fd ret(sfd.get()); + *sfd.getR() = -1; + return ret; } - } - - private: - static ::android::base::unique_fd GetUniqueFd( - const ndk::ScopedFileDescriptor& in) { - auto& sfd = const_cast<ndk::ScopedFileDescriptor&>(in); - ::android::base::unique_fd ret(sfd.get()); - *sfd.getR() = -1; - return ret; - } - - buffer_handle_t mBuffer; - ::android::base::unique_fd mFence; + + buffer_handle_t mBuffer; + ::android::base::unique_fd mFence; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/FrameComposer.h b/system/hwc3/FrameComposer.h index 70e0f00a..5e54561b 100644 --- a/system/hwc3/FrameComposer.h +++ b/system/hwc3/FrameComposer.h @@ -33,46 +33,42 @@ namespace aidl::android::hardware::graphics::composer3::impl { class Display; class FrameComposer { - public: - virtual ~FrameComposer() {} + public: + virtual ~FrameComposer() {} - virtual HWC3::Error init() = 0; + virtual HWC3::Error init() = 0; - using HotplugCallback = std::function<void(bool /*connected*/, // - uint32_t /*id*/, // - uint32_t /*width*/, // - uint32_t /*height*/, // - uint32_t /*dpiX*/, // - uint32_t /*dpiY*/, // - uint32_t /*refreshRate*/)>; + using HotplugCallback = std::function<void(bool /*connected*/, // + uint32_t /*id*/, // + uint32_t /*width*/, // + uint32_t /*height*/, // + uint32_t /*dpiX*/, // + uint32_t /*dpiY*/, // + uint32_t /*refreshRate*/)>; - virtual HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) = 0; + virtual HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) = 0; - virtual HWC3::Error unregisterOnHotplugCallback() = 0; + virtual HWC3::Error unregisterOnHotplugCallback() = 0; - virtual HWC3::Error onDisplayCreate(Display* display) = 0; + virtual HWC3::Error onDisplayCreate(Display* display) = 0; - virtual HWC3::Error onDisplayDestroy(Display* display) = 0; + virtual HWC3::Error onDisplayDestroy(Display* display) = 0; - virtual HWC3::Error onDisplayClientTargetSet(Display* display) = 0; + virtual HWC3::Error onDisplayClientTargetSet(Display* display) = 0; - // Determines if this composer can compose the given layers and requests - // changes for layers that can't not be composed. - virtual HWC3::Error validateDisplay(Display* display, - DisplayChanges* outChanges) = 0; + // Determines if this composer can compose the given layers and requests + // changes for layers that can't not be composed. + virtual HWC3::Error validateDisplay(Display* display, DisplayChanges* outChanges) = 0; - // Performs the actual composition of layers and presents the composed result - // to the display. - virtual HWC3::Error presentDisplay( - Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* - outLayerFences) = 0; + // Performs the actual composition of layers and presents the composed result + // to the display. + virtual HWC3::Error presentDisplay( + Display* display, ::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) = 0; - virtual HWC3::Error onActiveConfigChange(Display* display) = 0; + virtual HWC3::Error onActiveConfigChange(Display* display) = 0; - virtual const DrmClient* getDrmPresenter() const { - return nullptr; - } + virtual const DrmClient* getDrmPresenter() const { return nullptr; } }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Gralloc.cpp b/system/hwc3/Gralloc.cpp index e609da79..1b364cd5 100644 --- a/system/hwc3/Gralloc.cpp +++ b/system/hwc3/Gralloc.cpp @@ -32,213 +32,211 @@ using aidl::android::hardware::graphics::common::BufferUsage; using aidl::android::hardware::graphics::common::PlaneLayout; using aidl::android::hardware::graphics::common::PlaneLayoutComponent; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; +using android::GraphicBufferMapper; using android::OK; using android::Rect; using android::status_t; -using android::GraphicBufferMapper; namespace aidl::android::hardware::graphics::composer3::impl { std::optional<uint32_t> Gralloc::GetWidth(buffer_handle_t buffer) { - uint64_t width = 0; - status_t status = GraphicBufferMapper::get().getWidth(buffer, &width); - if (status != OK) { - return std::nullopt; - } + uint64_t width = 0; + status_t status = GraphicBufferMapper::get().getWidth(buffer, &width); + if (status != OK) { + return std::nullopt; + } - if (width > std::numeric_limits<uint32_t>::max()) { - ALOGE("%s Width too large to cast to uint32_t: %ld", __FUNCTION__, width); - return std::nullopt; - } - return static_cast<uint32_t>(width); + if (width > std::numeric_limits<uint32_t>::max()) { + ALOGE("%s Width too large to cast to uint32_t: %ld", __FUNCTION__, width); + return std::nullopt; + } + return static_cast<uint32_t>(width); } std::optional<uint32_t> Gralloc::GetHeight(buffer_handle_t buffer) { - uint64_t height = 0; - status_t status = GraphicBufferMapper::get().getHeight(buffer, &height); - if (status != OK) { - return std::nullopt; - } + uint64_t height = 0; + status_t status = GraphicBufferMapper::get().getHeight(buffer, &height); + if (status != OK) { + return std::nullopt; + } - if (height > std::numeric_limits<uint32_t>::max()) { - ALOGE("%s Height too large to cast to uint32_t: %ld", __FUNCTION__, height); - return std::nullopt; - } - return static_cast<uint32_t>(height); + if (height > std::numeric_limits<uint32_t>::max()) { + ALOGE("%s Height too large to cast to uint32_t: %ld", __FUNCTION__, height); + return std::nullopt; + } + return static_cast<uint32_t>(height); } std::optional<uint32_t> Gralloc::GetDrmFormat(buffer_handle_t buffer) { - uint32_t format = 0; - status_t status = GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &format); - if (status != OK) { - return std::nullopt; - } + uint32_t format = 0; + status_t status = GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &format); + if (status != OK) { + return std::nullopt; + } - return format; + return format; } -std::optional<std::vector<PlaneLayout>> Gralloc::GetPlaneLayouts( - buffer_handle_t buffer) { - std::vector<PlaneLayout> layouts; - status_t status = GraphicBufferMapper::get().getPlaneLayouts( - buffer, &layouts); - if (status != OK) { - return std::nullopt; - } +std::optional<std::vector<PlaneLayout>> Gralloc::GetPlaneLayouts(buffer_handle_t buffer) { + std::vector<PlaneLayout> layouts; + status_t status = GraphicBufferMapper::get().getPlaneLayouts(buffer, &layouts); + if (status != OK) { + return std::nullopt; + } - return layouts; + return layouts; } -std::optional<uint32_t> Gralloc::GetMonoPlanarStrideBytes( - buffer_handle_t buffer) { - auto plane_layouts_opt = GetPlaneLayouts(buffer); - if (!plane_layouts_opt) { - return std::nullopt; - } +std::optional<uint32_t> Gralloc::GetMonoPlanarStrideBytes(buffer_handle_t buffer) { + auto plane_layouts_opt = GetPlaneLayouts(buffer); + if (!plane_layouts_opt) { + return std::nullopt; + } - std::vector<PlaneLayout>& plane_layouts = *plane_layouts_opt; - if (plane_layouts.size() != 1) { - return std::nullopt; - } + std::vector<PlaneLayout>& plane_layouts = *plane_layouts_opt; + if (plane_layouts.size() != 1) { + return std::nullopt; + } - if (plane_layouts[0].strideInBytes > std::numeric_limits<uint32_t>::max()) { - ALOGE("%s strideInBytes too large to cast to uint32_t: %ld", __FUNCTION__, plane_layouts[0].strideInBytes); - return std::nullopt; - } - return static_cast<uint32_t>(plane_layouts[0].strideInBytes); + if (plane_layouts[0].strideInBytes > std::numeric_limits<uint32_t>::max()) { + ALOGE("%s strideInBytes too large to cast to uint32_t: %ld", __FUNCTION__, + plane_layouts[0].strideInBytes); + return std::nullopt; + } + return static_cast<uint32_t>(plane_layouts[0].strideInBytes); } std::optional<GrallocBuffer> Gralloc::Import(buffer_handle_t buffer) { - buffer_handle_t imported_buffer; + buffer_handle_t imported_buffer; - status_t status = - GraphicBufferMapper::get().importBufferNoValidate(buffer, &imported_buffer); + status_t status = GraphicBufferMapper::get().importBufferNoValidate(buffer, &imported_buffer); - if (status != OK) { - ALOGE("%s failed to import buffer: %d", __FUNCTION__, status); - return std::nullopt; - } - return GrallocBuffer(this, imported_buffer); + if (status != OK) { + ALOGE("%s failed to import buffer: %d", __FUNCTION__, status); + return std::nullopt; + } + return GrallocBuffer(this, imported_buffer); } void Gralloc::Release(buffer_handle_t buffer) { - status_t status = GraphicBufferMapper::get().freeBuffer(buffer); + status_t status = GraphicBufferMapper::get().freeBuffer(buffer); - if (status != OK) { - ALOGE("%s failed to release buffer: %d", __FUNCTION__, status); - } + if (status != OK) { + ALOGE("%s failed to release buffer: %d", __FUNCTION__, status); + } } std::optional<void*> Gralloc::Lock(buffer_handle_t buffer) { - const auto buffer_usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) | - static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN); + const auto buffer_usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) | + static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN); - auto width_opt = GetWidth(buffer); - if (!width_opt) { - return std::nullopt; - } + auto width_opt = GetWidth(buffer); + if (!width_opt) { + return std::nullopt; + } - auto height_opt = GetHeight(buffer); - if (!height_opt) { - return std::nullopt; - } + auto height_opt = GetHeight(buffer); + if (!height_opt) { + return std::nullopt; + } - Rect buffer_region; - buffer_region.left = 0; - buffer_region.top = 0; - // width = right - left - buffer_region.right = static_cast<int32_t>(*width_opt); - // height = bottom - top - buffer_region.bottom = static_cast<int32_t>(*height_opt); + Rect buffer_region; + buffer_region.left = 0; + buffer_region.top = 0; + // width = right - left + buffer_region.right = static_cast<int32_t>(*width_opt); + // height = bottom - top + buffer_region.bottom = static_cast<int32_t>(*height_opt); - void* data = nullptr; + void* data = nullptr; - status_t status = - GraphicBufferMapper::get().lock(buffer, buffer_usage, buffer_region, &data); + status_t status = GraphicBufferMapper::get().lock(buffer, buffer_usage, buffer_region, &data); - if (status != OK) { - ALOGE("%s failed to lock buffer: %d", __FUNCTION__, status); - return std::nullopt; - } + if (status != OK) { + ALOGE("%s failed to lock buffer: %d", __FUNCTION__, status); + return std::nullopt; + } - return data; + return data; } std::optional<android_ycbcr> Gralloc::LockYCbCr(buffer_handle_t buffer) { - auto format_opt = GetDrmFormat(buffer); - if (!format_opt) { - ALOGE("%s failed to check format of buffer", __FUNCTION__); - return std::nullopt; - } + auto format_opt = GetDrmFormat(buffer); + if (!format_opt) { + ALOGE("%s failed to check format of buffer", __FUNCTION__); + return std::nullopt; + } - if (*format_opt != DRM_FORMAT_NV12 && *format_opt != DRM_FORMAT_NV21 && - *format_opt != DRM_FORMAT_YVU420) { - ALOGE("%s called on non-ycbcr buffer", __FUNCTION__); - return std::nullopt; - } + if (*format_opt != DRM_FORMAT_NV12 && *format_opt != DRM_FORMAT_NV21 && + *format_opt != DRM_FORMAT_YVU420) { + ALOGE("%s called on non-ycbcr buffer", __FUNCTION__); + return std::nullopt; + } - auto lock_opt = Lock(buffer); - if (!lock_opt) { - ALOGE("%s failed to lock buffer", __FUNCTION__); - return std::nullopt; - } + auto lock_opt = Lock(buffer); + if (!lock_opt) { + ALOGE("%s failed to lock buffer", __FUNCTION__); + return std::nullopt; + } - auto plane_layouts_opt = GetPlaneLayouts(buffer); - if (!plane_layouts_opt) { - ALOGE("%s failed to get plane layouts", __FUNCTION__); - return std::nullopt; - } - - android_ycbcr buffer_ycbcr; - buffer_ycbcr.y = nullptr; - buffer_ycbcr.cb = nullptr; - buffer_ycbcr.cr = nullptr; - buffer_ycbcr.ystride = 0; - buffer_ycbcr.cstride = 0; - buffer_ycbcr.chroma_step = 0; - - for (const auto& plane_layout : *plane_layouts_opt) { - for (const auto& plane_layout_component : plane_layout.components) { - const auto& type = plane_layout_component.type; - - if (!::android::gralloc4::isStandardPlaneLayoutComponentType(type)) { - continue; - } - - auto* component_data = reinterpret_cast<uint8_t*>(*lock_opt) + - plane_layout.offsetInBytes + - plane_layout_component.offsetInBits / 8; - - switch (static_cast<PlaneLayoutComponentType>(type.value)) { - case PlaneLayoutComponentType::Y: - buffer_ycbcr.y = component_data; - buffer_ycbcr.ystride = static_cast<size_t>(plane_layout.strideInBytes); - break; - case PlaneLayoutComponentType::CB: - buffer_ycbcr.cb = component_data; - buffer_ycbcr.cstride = static_cast<size_t>(plane_layout.strideInBytes); - buffer_ycbcr.chroma_step = static_cast<size_t>(plane_layout.sampleIncrementInBits / 8); - break; - case PlaneLayoutComponentType::CR: - buffer_ycbcr.cr = component_data; - buffer_ycbcr.cstride = static_cast<size_t>(plane_layout.strideInBytes); - buffer_ycbcr.chroma_step = static_cast<size_t>(plane_layout.sampleIncrementInBits / 8); - break; - default: - break; - } + auto plane_layouts_opt = GetPlaneLayouts(buffer); + if (!plane_layouts_opt) { + ALOGE("%s failed to get plane layouts", __FUNCTION__); + return std::nullopt; } - } - return buffer_ycbcr; + android_ycbcr buffer_ycbcr; + buffer_ycbcr.y = nullptr; + buffer_ycbcr.cb = nullptr; + buffer_ycbcr.cr = nullptr; + buffer_ycbcr.ystride = 0; + buffer_ycbcr.cstride = 0; + buffer_ycbcr.chroma_step = 0; + + for (const auto& plane_layout : *plane_layouts_opt) { + for (const auto& plane_layout_component : plane_layout.components) { + const auto& type = plane_layout_component.type; + + if (!::android::gralloc4::isStandardPlaneLayoutComponentType(type)) { + continue; + } + + auto* component_data = reinterpret_cast<uint8_t*>(*lock_opt) + + plane_layout.offsetInBytes + + plane_layout_component.offsetInBits / 8; + + switch (static_cast<PlaneLayoutComponentType>(type.value)) { + case PlaneLayoutComponentType::Y: + buffer_ycbcr.y = component_data; + buffer_ycbcr.ystride = static_cast<size_t>(plane_layout.strideInBytes); + break; + case PlaneLayoutComponentType::CB: + buffer_ycbcr.cb = component_data; + buffer_ycbcr.cstride = static_cast<size_t>(plane_layout.strideInBytes); + buffer_ycbcr.chroma_step = + static_cast<size_t>(plane_layout.sampleIncrementInBits / 8); + break; + case PlaneLayoutComponentType::CR: + buffer_ycbcr.cr = component_data; + buffer_ycbcr.cstride = static_cast<size_t>(plane_layout.strideInBytes); + buffer_ycbcr.chroma_step = + static_cast<size_t>(plane_layout.sampleIncrementInBits / 8); + break; + default: + break; + } + } + } + + return buffer_ycbcr; } void Gralloc::Unlock(buffer_handle_t buffer) { - status_t status = GraphicBufferMapper::get().unlock(buffer); + status_t status = GraphicBufferMapper::get().unlock(buffer); - if (status != OK) { - ALOGE("%s failed to unlock buffer %d", __FUNCTION__, status); - } + if (status != OK) { + ALOGE("%s failed to unlock buffer %d", __FUNCTION__, status); + } } GrallocBuffer::GrallocBuffer(Gralloc* gralloc, buffer_handle_t buffer) @@ -249,86 +247,86 @@ GrallocBuffer::~GrallocBuffer() { Release(); } GrallocBuffer::GrallocBuffer(GrallocBuffer&& rhs) { *this = std::move(rhs); } GrallocBuffer& GrallocBuffer::operator=(GrallocBuffer&& rhs) { - gralloc_ = rhs.gralloc_; - buffer_ = rhs.buffer_; - rhs.gralloc_ = nullptr; - rhs.buffer_ = nullptr; - return *this; + gralloc_ = rhs.gralloc_; + buffer_ = rhs.buffer_; + rhs.gralloc_ = nullptr; + rhs.buffer_ = nullptr; + return *this; } void GrallocBuffer::Release() { - if (gralloc_ && buffer_) { - gralloc_->Release(buffer_); - gralloc_ = nullptr; - buffer_ = nullptr; - } + if (gralloc_ && buffer_) { + gralloc_->Release(buffer_); + gralloc_ = nullptr; + buffer_ = nullptr; + } } std::optional<GrallocBufferView> GrallocBuffer::Lock() { - if (gralloc_ && buffer_) { - auto format_opt = GetDrmFormat(); - if (!format_opt) { - ALOGE("%s failed to check format of buffer", __FUNCTION__); - return std::nullopt; + if (gralloc_ && buffer_) { + auto format_opt = GetDrmFormat(); + if (!format_opt) { + ALOGE("%s failed to check format of buffer", __FUNCTION__); + return std::nullopt; + } + if (*format_opt != DRM_FORMAT_NV12 && *format_opt != DRM_FORMAT_NV21 && + *format_opt != DRM_FORMAT_YVU420) { + auto locked_opt = gralloc_->Lock(buffer_); + if (!locked_opt) { + return std::nullopt; + } + return GrallocBufferView(this, *locked_opt); + } else { + auto locked_ycbcr_opt = gralloc_->LockYCbCr(buffer_); + if (!locked_ycbcr_opt) { + ALOGE("%s failed to lock ycbcr buffer", __FUNCTION__); + return std::nullopt; + } + return GrallocBufferView(this, *locked_ycbcr_opt); + } } - if (*format_opt != DRM_FORMAT_NV12 && *format_opt != DRM_FORMAT_NV21 && - *format_opt != DRM_FORMAT_YVU420) { - auto locked_opt = gralloc_->Lock(buffer_); - if (!locked_opt) { - return std::nullopt; - } - return GrallocBufferView(this, *locked_opt); - } else { - auto locked_ycbcr_opt = gralloc_->LockYCbCr(buffer_); - if (!locked_ycbcr_opt) { - ALOGE("%s failed to lock ycbcr buffer", __FUNCTION__); - return std::nullopt; - } - return GrallocBufferView(this, *locked_ycbcr_opt); - } - } - return std::nullopt; + return std::nullopt; } void GrallocBuffer::Unlock() { - if (gralloc_ && buffer_) { - gralloc_->Unlock(buffer_); - } + if (gralloc_ && buffer_) { + gralloc_->Unlock(buffer_); + } } std::optional<uint32_t> GrallocBuffer::GetWidth() { - if (gralloc_ && buffer_) { - return gralloc_->GetWidth(buffer_); - } - return std::nullopt; + if (gralloc_ && buffer_) { + return gralloc_->GetWidth(buffer_); + } + return std::nullopt; } std::optional<uint32_t> GrallocBuffer::GetHeight() { - if (gralloc_ && buffer_) { - return gralloc_->GetHeight(buffer_); - } - return std::nullopt; + if (gralloc_ && buffer_) { + return gralloc_->GetHeight(buffer_); + } + return std::nullopt; } std::optional<uint32_t> GrallocBuffer::GetDrmFormat() { - if (gralloc_ && buffer_) { - return gralloc_->GetDrmFormat(buffer_); - } - return std::nullopt; + if (gralloc_ && buffer_) { + return gralloc_->GetDrmFormat(buffer_); + } + return std::nullopt; } std::optional<std::vector<PlaneLayout>> GrallocBuffer::GetPlaneLayouts() { - if (gralloc_ && buffer_) { - return gralloc_->GetPlaneLayouts(buffer_); - } - return std::nullopt; + if (gralloc_ && buffer_) { + return gralloc_->GetPlaneLayouts(buffer_); + } + return std::nullopt; } std::optional<uint32_t> GrallocBuffer::GetMonoPlanarStrideBytes() { - if (gralloc_ && buffer_) { - return gralloc_->GetMonoPlanarStrideBytes(buffer_); - } - return std::nullopt; + if (gralloc_ && buffer_) { + return gralloc_->GetMonoPlanarStrideBytes(buffer_); + } + return std::nullopt; } GrallocBufferView::GrallocBufferView(GrallocBuffer* buffer, void* raw) @@ -338,26 +336,22 @@ GrallocBufferView::GrallocBufferView(GrallocBuffer* buffer, android_ycbcr raw) : gralloc_buffer_(buffer), locked_ycbcr_(raw) {} GrallocBufferView::~GrallocBufferView() { - if (gralloc_buffer_) { - gralloc_buffer_->Unlock(); - } + if (gralloc_buffer_) { + gralloc_buffer_->Unlock(); + } } -GrallocBufferView::GrallocBufferView(GrallocBufferView&& rhs) { - *this = std::move(rhs); -} +GrallocBufferView::GrallocBufferView(GrallocBufferView&& rhs) { *this = std::move(rhs); } GrallocBufferView& GrallocBufferView::operator=(GrallocBufferView&& rhs) { - std::swap(gralloc_buffer_, rhs.gralloc_buffer_); - std::swap(locked_, rhs.locked_); - std::swap(locked_ycbcr_, rhs.locked_ycbcr_); - return *this; + std::swap(gralloc_buffer_, rhs.gralloc_buffer_); + std::swap(locked_, rhs.locked_); + std::swap(locked_ycbcr_, rhs.locked_ycbcr_); + return *this; } const std::optional<void*> GrallocBufferView::Get() const { return locked_; } -const std::optional<android_ycbcr>& GrallocBufferView::GetYCbCr() const { - return locked_ycbcr_; -} +const std::optional<android_ycbcr>& GrallocBufferView::GetYCbCr() const { return locked_ycbcr_; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Gralloc.h b/system/hwc3/Gralloc.h index b3c6c6c9..a759089c 100644 --- a/system/hwc3/Gralloc.h +++ b/system/hwc3/Gralloc.h @@ -33,116 +33,114 @@ class GrallocBuffer; // An RAII object that will Unlock() a GrallocBuffer upon destruction. class GrallocBufferView { - public: - virtual ~GrallocBufferView(); + public: + virtual ~GrallocBufferView(); - GrallocBufferView(const GrallocBufferView& rhs) = delete; - GrallocBufferView& operator=(const GrallocBufferView& rhs) = delete; + GrallocBufferView(const GrallocBufferView& rhs) = delete; + GrallocBufferView& operator=(const GrallocBufferView& rhs) = delete; - GrallocBufferView(GrallocBufferView&& rhs); - GrallocBufferView& operator=(GrallocBufferView&& rhs); + GrallocBufferView(GrallocBufferView&& rhs); + GrallocBufferView& operator=(GrallocBufferView&& rhs); - const std::optional<void*> Get() const; + const std::optional<void*> Get() const; - const std::optional<android_ycbcr>& GetYCbCr() const; + const std::optional<android_ycbcr>& GetYCbCr() const; - private: - friend class GrallocBuffer; - GrallocBufferView(GrallocBuffer* buffer, void* raw); - GrallocBufferView(GrallocBuffer* buffer, android_ycbcr raw); + private: + friend class GrallocBuffer; + GrallocBufferView(GrallocBuffer* buffer, void* raw); + GrallocBufferView(GrallocBuffer* buffer, android_ycbcr raw); - // The GrallocBuffer that should be unlocked upon destruction of this object. - GrallocBuffer* gralloc_buffer_ = nullptr; + // The GrallocBuffer that should be unlocked upon destruction of this object. + GrallocBuffer* gralloc_buffer_ = nullptr; - std::optional<void*> locked_; - std::optional<android_ycbcr> locked_ycbcr_; + std::optional<void*> locked_; + std::optional<android_ycbcr> locked_ycbcr_; }; // A gralloc 4.0 buffer that has been imported in the current process and // that will be released upon destruction. Users must ensure that the Gralloc // instance that this buffer is created with out lives this buffer. class GrallocBuffer { - public: - GrallocBuffer(Gralloc* gralloc, buffer_handle_t buffer); - virtual ~GrallocBuffer(); + public: + GrallocBuffer(Gralloc* gralloc, buffer_handle_t buffer); + virtual ~GrallocBuffer(); - GrallocBuffer(const GrallocBuffer& rhs) = delete; - GrallocBuffer& operator=(const GrallocBuffer& rhs) = delete; + GrallocBuffer(const GrallocBuffer& rhs) = delete; + GrallocBuffer& operator=(const GrallocBuffer& rhs) = delete; - GrallocBuffer(GrallocBuffer&& rhs); - GrallocBuffer& operator=(GrallocBuffer&& rhs); + GrallocBuffer(GrallocBuffer&& rhs); + GrallocBuffer& operator=(GrallocBuffer&& rhs); - // Locks the buffer for reading and returns a view if successful. - std::optional<GrallocBufferView> Lock(); + // Locks the buffer for reading and returns a view if successful. + std::optional<GrallocBufferView> Lock(); - std::optional<uint32_t> GetWidth(); - std::optional<uint32_t> GetHeight(); - std::optional<uint32_t> GetDrmFormat(); + std::optional<uint32_t> GetWidth(); + std::optional<uint32_t> GetHeight(); + std::optional<uint32_t> GetDrmFormat(); - // Returns the stride of the buffer if it is a single plane buffer or fails - // and returns nullopt if the buffer is for a multi plane buffer. - std::optional<uint32_t> GetMonoPlanarStrideBytes(); + // Returns the stride of the buffer if it is a single plane buffer or fails + // and returns nullopt if the buffer is for a multi plane buffer. + std::optional<uint32_t> GetMonoPlanarStrideBytes(); - std::optional< - std::vector<aidl::android::hardware::graphics::common::PlaneLayout>> - GetPlaneLayouts(); + std::optional<std::vector<aidl::android::hardware::graphics::common::PlaneLayout>> + GetPlaneLayouts(); - private: - // Internal visibility for Unlock(). - friend class GrallocBufferView; + private: + // Internal visibility for Unlock(). + friend class GrallocBufferView; - // Unlocks the buffer from reading. - void Unlock(); + // Unlocks the buffer from reading. + void Unlock(); - void Release(); + void Release(); - Gralloc* gralloc_ = nullptr; - buffer_handle_t buffer_ = nullptr; + Gralloc* gralloc_ = nullptr; + buffer_handle_t buffer_ = nullptr; }; class Gralloc { - public: - virtual ~Gralloc() = default; + public: + virtual ~Gralloc() = default; - // Imports the given buffer handle into the current process and returns an - // imported buffer which can be used for reading. Users must ensure that the - // Gralloc instance outlives any GrallocBuffers. - std::optional<GrallocBuffer> Import(buffer_handle_t buffer); + // Imports the given buffer handle into the current process and returns an + // imported buffer which can be used for reading. Users must ensure that the + // Gralloc instance outlives any GrallocBuffers. + std::optional<GrallocBuffer> Import(buffer_handle_t buffer); - private: - // The below functions are made available only to GrallocBuffer so that - // users only call gralloc functions on *imported* buffers. - friend class GrallocBuffer; + private: + // The below functions are made available only to GrallocBuffer so that + // users only call gralloc functions on *imported* buffers. + friend class GrallocBuffer; - // See GrallocBuffer::Release. - void Release(buffer_handle_t buffer); + // See GrallocBuffer::Release. + void Release(buffer_handle_t buffer); - // See GrallocBuffer::Lock. - std::optional<void*> Lock(buffer_handle_t buffer); + // See GrallocBuffer::Lock. + std::optional<void*> Lock(buffer_handle_t buffer); - // See GrallocBuffer::LockYCbCr. - std::optional<android_ycbcr> LockYCbCr(buffer_handle_t buffer); + // See GrallocBuffer::LockYCbCr. + std::optional<android_ycbcr> LockYCbCr(buffer_handle_t buffer); - // See GrallocBuffer::Unlock. - void Unlock(buffer_handle_t buffer); + // See GrallocBuffer::Unlock. + void Unlock(buffer_handle_t buffer); - // See GrallocBuffer::GetWidth. - std::optional<uint32_t> GetWidth(buffer_handle_t buffer); + // See GrallocBuffer::GetWidth. + std::optional<uint32_t> GetWidth(buffer_handle_t buffer); - // See GrallocBuffer::GetHeight. - std::optional<uint32_t> GetHeight(buffer_handle_t buffer); + // See GrallocBuffer::GetHeight. + std::optional<uint32_t> GetHeight(buffer_handle_t buffer); - // See GrallocBuffer::GetDrmFormat. - std::optional<uint32_t> GetDrmFormat(buffer_handle_t buffer); + // See GrallocBuffer::GetDrmFormat. + std::optional<uint32_t> GetDrmFormat(buffer_handle_t buffer); - // See GrallocBuffer::GetPlaneLayouts. - std::optional< - std::vector<aidl::android::hardware::graphics::common::PlaneLayout>> - GetPlaneLayouts(buffer_handle_t buffer); + // See GrallocBuffer::GetPlaneLayouts. + std::optional<std::vector<aidl::android::hardware::graphics::common::PlaneLayout>> + GetPlaneLayouts(buffer_handle_t buffer); - // Returns the stride of the buffer if it is a single plane buffer or fails - // and returns nullopt if the buffer is for a multi plane buffer. - std::optional<uint32_t> GetMonoPlanarStrideBytes(buffer_handle_t); + // Returns the stride of the buffer if it is a single plane buffer or fails + // and returns nullopt if the buffer is for a multi plane buffer. + std::optional<uint32_t> GetMonoPlanarStrideBytes(buffer_handle_t); }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/GuestFrameComposer.cpp b/system/hwc3/GuestFrameComposer.cpp index bc51050d..f4333fc1 100644 --- a/system/hwc3/GuestFrameComposer.cpp +++ b/system/hwc3/GuestFrameComposer.cpp @@ -43,55 +43,54 @@ uint32_t AlignToPower2(uint32_t val, uint8_t align_log) { } bool LayerNeedsScaling(const Layer& layer) { - common::Rect crop = layer.getSourceCropInt(); - common::Rect frame = layer.getDisplayFrame(); + common::Rect crop = layer.getSourceCropInt(); + common::Rect frame = layer.getDisplayFrame(); - int fromW = crop.right - crop.left; - int fromH = crop.bottom - crop.top; - int toW = frame.right - frame.left; - int toH = frame.bottom - frame.top; + int fromW = crop.right - crop.left; + int fromH = crop.bottom - crop.top; + int toW = frame.right - frame.left; + int toH = frame.bottom - frame.top; - bool not_rot_scale = fromW != toW || fromH != toH; - bool rot_scale = fromW != toH || fromH != toW; + bool not_rot_scale = fromW != toW || fromH != toH; + bool rot_scale = fromW != toH || fromH != toW; - bool needs_rot = static_cast<int32_t>(layer.getTransform()) & - static_cast<int32_t>(common::Transform::ROT_90); + bool needs_rot = static_cast<int32_t>(layer.getTransform()) & + static_cast<int32_t>(common::Transform::ROT_90); - return needs_rot ? rot_scale : not_rot_scale; + return needs_rot ? rot_scale : not_rot_scale; } bool LayerNeedsBlending(const Layer& layer) { - return layer.getBlendMode() != common::BlendMode::NONE; + return layer.getBlendMode() != common::BlendMode::NONE; } bool LayerNeedsAttenuation(const Layer& layer) { - return layer.getBlendMode() == common::BlendMode::COVERAGE; + return layer.getBlendMode() == common::BlendMode::COVERAGE; } struct BufferSpec; -typedef int (*ConverterFunction)(const BufferSpec& src, const BufferSpec& dst, - bool v_flip); +typedef int (*ConverterFunction)(const BufferSpec& src, const BufferSpec& dst, bool v_flip); int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool vFlip); int ConvertFromRGB565(const BufferSpec& src, const BufferSpec& dst, bool vFlip); int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool vFlip); ConverterFunction GetConverterForDrmFormat(uint32_t drmFormat) { - switch (drmFormat) { - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_XBGR8888: - return &DoCopy; - case DRM_FORMAT_RGB565: - return &ConvertFromRGB565; - case DRM_FORMAT_YVU420: - return &ConvertFromYV12; - } - DEBUG_LOG("Unsupported drm format: %d(%s), returning null converter", - drmFormat, GetDrmFormatString(drmFormat)); - return nullptr; + switch (drmFormat) { + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XBGR8888: + return &DoCopy; + case DRM_FORMAT_RGB565: + return &ConvertFromRGB565; + case DRM_FORMAT_YVU420: + return &ConvertFromYV12; + } + DEBUG_LOG("Unsupported drm format: %d(%s), returning null converter", drmFormat, + GetDrmFormatString(drmFormat)); + return nullptr; } bool IsDrmFormatSupported(uint32_t drmFormat) { - return GetConverterForDrmFormat(drmFormat) != nullptr; + return GetConverterForDrmFormat(drmFormat) != nullptr; } // Libyuv's convert functions only allow the combination of any rotation @@ -102,1058 +101,1019 @@ bool IsDrmFormatSupported(uint32_t drmFormat) { // insight). The following code allows to turn a horizontal flip into a 180 // degrees rotation and a vertical flip. libyuv::RotationMode GetRotationFromTransform(common::Transform transform) { - uint32_t rotation = 0; - rotation += (static_cast<int32_t>(transform) & - static_cast<int32_t>(common::Transform::ROT_90)) - ? 1 - : 0; // 1 * ROT90 bit - rotation += (static_cast<int32_t>(transform) & - static_cast<int32_t>(common::Transform::FLIP_H)) - ? 2 - : 0; // 2 * VFLIP bit - return static_cast<libyuv::RotationMode>(90 * rotation); + uint32_t rotation = 0; + rotation += (static_cast<int32_t>(transform) & static_cast<int32_t>(common::Transform::ROT_90)) + ? 1 + : 0; // 1 * ROT90 bit + rotation += (static_cast<int32_t>(transform) & static_cast<int32_t>(common::Transform::FLIP_H)) + ? 2 + : 0; // 2 * VFLIP bit + return static_cast<libyuv::RotationMode>(90 * rotation); } bool GetVFlipFromTransform(common::Transform transform) { - // vertical flip xor horizontal flip - bool hasVFlip = static_cast<int32_t>(transform) & - static_cast<int32_t>(common::Transform::FLIP_V); - bool hasHFlip = static_cast<int32_t>(transform) & - static_cast<int32_t>(common::Transform::FLIP_H); - return hasVFlip ^ hasHFlip; + // vertical flip xor horizontal flip + bool hasVFlip = + static_cast<int32_t>(transform) & static_cast<int32_t>(common::Transform::FLIP_V); + bool hasHFlip = + static_cast<int32_t>(transform) & static_cast<int32_t>(common::Transform::FLIP_H); + return hasVFlip ^ hasHFlip; } struct BufferSpec { - uint8_t* buffer; - std::optional<android_ycbcr> buffer_ycbcr; - uint32_t width; - uint32_t height; - uint32_t cropX; - uint32_t cropY; - uint32_t cropWidth; - uint32_t cropHeight; - uint32_t drmFormat; - uint32_t strideBytes; - uint32_t sampleBytes; - - BufferSpec() = default; - - BufferSpec(uint8_t* buffer, std::optional<android_ycbcr> buffer_ycbcr, uint32_t width, - uint32_t height, uint32_t cropX, uint32_t cropY, uint32_t cropWidth, - uint32_t cropHeight, uint32_t drmFormat, uint32_t strideBytes, uint32_t sampleBytes) - : buffer(buffer), - buffer_ycbcr(buffer_ycbcr), - width(width), - height(height), - cropX(cropX), - cropY(cropY), - cropWidth(cropWidth), - cropHeight(cropHeight), - drmFormat(drmFormat), - strideBytes(strideBytes), - sampleBytes(sampleBytes) {} - - BufferSpec(uint8_t* buffer, uint32_t width, uint32_t height, uint32_t strideBytes) - : BufferSpec(buffer, - /*buffer_ycbcr=*/std::nullopt, width, height, - /*cropX=*/0, - /*cropY=*/0, - /*cropWidth=*/width, - /*cropHeight=*/height, - /*drmFormat=*/DRM_FORMAT_ABGR8888, strideBytes, - /*sampleBytes=*/4) {} + uint8_t* buffer; + std::optional<android_ycbcr> buffer_ycbcr; + uint32_t width; + uint32_t height; + uint32_t cropX; + uint32_t cropY; + uint32_t cropWidth; + uint32_t cropHeight; + uint32_t drmFormat; + uint32_t strideBytes; + uint32_t sampleBytes; + + BufferSpec() = default; + + BufferSpec(uint8_t* buffer, std::optional<android_ycbcr> buffer_ycbcr, uint32_t width, + uint32_t height, uint32_t cropX, uint32_t cropY, uint32_t cropWidth, + uint32_t cropHeight, uint32_t drmFormat, uint32_t strideBytes, uint32_t sampleBytes) + : buffer(buffer), + buffer_ycbcr(buffer_ycbcr), + width(width), + height(height), + cropX(cropX), + cropY(cropY), + cropWidth(cropWidth), + cropHeight(cropHeight), + drmFormat(drmFormat), + strideBytes(strideBytes), + sampleBytes(sampleBytes) {} + + BufferSpec(uint8_t* buffer, uint32_t width, uint32_t height, uint32_t strideBytes) + : BufferSpec(buffer, + /*buffer_ycbcr=*/std::nullopt, width, height, + /*cropX=*/0, + /*cropY=*/0, + /*cropWidth=*/width, + /*cropHeight=*/height, + /*drmFormat=*/DRM_FORMAT_ABGR8888, strideBytes, + /*sampleBytes=*/4) {} }; int DoFill(const BufferSpec& dst, const Color& color) { - ATRACE_CALL(); + ATRACE_CALL(); - const uint8_t r = static_cast<uint8_t>(color.r * 255.0f); - const uint8_t g = static_cast<uint8_t>(color.g * 255.0f); - const uint8_t b = static_cast<uint8_t>(color.b * 255.0f); - const uint8_t a = static_cast<uint8_t>(color.a * 255.0f); + const uint8_t r = static_cast<uint8_t>(color.r * 255.0f); + const uint8_t g = static_cast<uint8_t>(color.g * 255.0f); + const uint8_t b = static_cast<uint8_t>(color.b * 255.0f); + const uint8_t a = static_cast<uint8_t>(color.a * 255.0f); - const uint32_t rgba = static_cast<uint32_t>(r) | static_cast<uint32_t>(g) << 8 | - static_cast<uint32_t>(b) << 16 | static_cast<uint32_t>(a) << 24; + const uint32_t rgba = static_cast<uint32_t>(r) | static_cast<uint32_t>(g) << 8 | + static_cast<uint32_t>(b) << 16 | static_cast<uint32_t>(a) << 24; - // Point to the upper left corner of the crop rectangle. - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + // Point to the upper left corner of the crop rectangle. + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - libyuv::SetPlane(dstBuffer, static_cast<int>(dst.strideBytes), static_cast<int>(dst.cropWidth), - static_cast<int>(dst.cropHeight), rgba); - return 0; + libyuv::SetPlane(dstBuffer, static_cast<int>(dst.strideBytes), static_cast<int>(dst.cropWidth), + static_cast<int>(dst.cropHeight), rgba); + return 0; } -int ConvertFromRGB565(const BufferSpec& src, const BufferSpec& dst, - bool vFlip) { - ATRACE_CALL(); - - // Point to the upper left corner of the crop rectangle - uint8_t* srcBuffer = - src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; - const int srcStrideBytes = static_cast<int>(src.strideBytes); - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - - int width = static_cast<int>(src.cropWidth); - int height = static_cast<int>(src.cropHeight); - if (vFlip) { - height = -height; - } - - return libyuv::RGB565ToARGB(srcBuffer, srcStrideBytes, // - dstBuffer, dstStrideBytes, // - width, height); +int ConvertFromRGB565(const BufferSpec& src, const BufferSpec& dst, bool vFlip) { + ATRACE_CALL(); + + // Point to the upper left corner of the crop rectangle + uint8_t* srcBuffer = src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; + const int srcStrideBytes = static_cast<int>(src.strideBytes); + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + + int width = static_cast<int>(src.cropWidth); + int height = static_cast<int>(src.cropHeight); + if (vFlip) { + height = -height; + } + + return libyuv::RGB565ToARGB(srcBuffer, srcStrideBytes, // + dstBuffer, dstStrideBytes, // + width, height); } int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool vFlip) { - ATRACE_CALL(); - - // The following calculation of plane offsets and alignments are based on - // swiftshader's Sampler::setTextureLevel() implementation - // (Renderer/Sampler.cpp:225) - - auto& srcBufferYCbCrOpt = src.buffer_ycbcr; - if (!srcBufferYCbCrOpt) { - ALOGE("%s called on non ycbcr buffer", __FUNCTION__); - return -1; - } - auto& srcBufferYCbCr = *srcBufferYCbCrOpt; - - // The libyuv::I420ToARGB() function is for tri-planar. - if (srcBufferYCbCr.chroma_step != 1) { - ALOGE("%s called with bad chroma step", __FUNCTION__); - return -1; - } - - uint8_t* srcY = reinterpret_cast<uint8_t*>(srcBufferYCbCr.y); - const int strideYBytes = static_cast<int>(srcBufferYCbCr.ystride); - uint8_t* srcU = reinterpret_cast<uint8_t*>(srcBufferYCbCr.cb); - const int strideUBytes = static_cast<int>(srcBufferYCbCr.cstride); - uint8_t* srcV = reinterpret_cast<uint8_t*>(srcBufferYCbCr.cr); - const int strideVBytes = static_cast<int>(srcBufferYCbCr.cstride); - - // Adjust for crop - srcY += src.cropY * srcBufferYCbCr.ystride + src.cropX; - srcV += (src.cropY / 2) * srcBufferYCbCr.cstride + (src.cropX / 2); - srcU += (src.cropY / 2) * srcBufferYCbCr.cstride + (src.cropX / 2); - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - - int width = static_cast<int>(dst.cropWidth); - int height = static_cast<int>(dst.cropHeight); - - if (vFlip) { - height = -height; - } - - // YV12 is the same as I420, with the U and V planes swapped - return libyuv::I420ToARGB(srcY, strideYBytes, // - srcV, strideVBytes, // - srcU, strideUBytes, // - dstBuffer, dstStrideBytes, width, height); + ATRACE_CALL(); + + // The following calculation of plane offsets and alignments are based on + // swiftshader's Sampler::setTextureLevel() implementation + // (Renderer/Sampler.cpp:225) + + auto& srcBufferYCbCrOpt = src.buffer_ycbcr; + if (!srcBufferYCbCrOpt) { + ALOGE("%s called on non ycbcr buffer", __FUNCTION__); + return -1; + } + auto& srcBufferYCbCr = *srcBufferYCbCrOpt; + + // The libyuv::I420ToARGB() function is for tri-planar. + if (srcBufferYCbCr.chroma_step != 1) { + ALOGE("%s called with bad chroma step", __FUNCTION__); + return -1; + } + + uint8_t* srcY = reinterpret_cast<uint8_t*>(srcBufferYCbCr.y); + const int strideYBytes = static_cast<int>(srcBufferYCbCr.ystride); + uint8_t* srcU = reinterpret_cast<uint8_t*>(srcBufferYCbCr.cb); + const int strideUBytes = static_cast<int>(srcBufferYCbCr.cstride); + uint8_t* srcV = reinterpret_cast<uint8_t*>(srcBufferYCbCr.cr); + const int strideVBytes = static_cast<int>(srcBufferYCbCr.cstride); + + // Adjust for crop + srcY += src.cropY * srcBufferYCbCr.ystride + src.cropX; + srcV += (src.cropY / 2) * srcBufferYCbCr.cstride + (src.cropX / 2); + srcU += (src.cropY / 2) * srcBufferYCbCr.cstride + (src.cropX / 2); + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + + int width = static_cast<int>(dst.cropWidth); + int height = static_cast<int>(dst.cropHeight); + + if (vFlip) { + height = -height; + } + + // YV12 is the same as I420, with the U and V planes swapped + return libyuv::I420ToARGB(srcY, strideYBytes, // + srcV, strideVBytes, // + srcU, strideUBytes, // + dstBuffer, dstStrideBytes, width, height); } int DoConversion(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - ConverterFunction func = GetConverterForDrmFormat(src.drmFormat); - if (!func) { - // GetConverterForDrmFormat should've logged the issue for us. - return -1; - } - return func(src, dst, v_flip); + ConverterFunction func = GetConverterForDrmFormat(src.drmFormat); + if (!func) { + // GetConverterForDrmFormat should've logged the issue for us. + return -1; + } + return func(src, dst, v_flip); } int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - ATRACE_CALL(); - - // Point to the upper left corner of the crop rectangle - uint8_t* srcBuffer = - src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; - const int srcStrideBytes = static_cast<int>(src.strideBytes); - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - int width = static_cast<int>(src.cropWidth); - int height = static_cast<int>(src.cropHeight); - - if (v_flip) { - height = -height; - } - - // HAL formats are named based on the order of the pixel components on the - // byte stream, while libyuv formats are named based on the order of those - // pixel components in an integer written from left to right. So - // libyuv::FOURCC_ARGB is equivalent to HAL_PIXEL_FORMAT_BGRA_8888. - auto ret = libyuv::ARGBCopy(srcBuffer, srcStrideBytes, // - dstBuffer, dstStrideBytes, // - width, height); - return ret; + ATRACE_CALL(); + + // Point to the upper left corner of the crop rectangle + uint8_t* srcBuffer = src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; + const int srcStrideBytes = static_cast<int>(src.strideBytes); + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + int width = static_cast<int>(src.cropWidth); + int height = static_cast<int>(src.cropHeight); + + if (v_flip) { + height = -height; + } + + // HAL formats are named based on the order of the pixel components on the + // byte stream, while libyuv formats are named based on the order of those + // pixel components in an integer written from left to right. So + // libyuv::FOURCC_ARGB is equivalent to HAL_PIXEL_FORMAT_BGRA_8888. + auto ret = libyuv::ARGBCopy(srcBuffer, srcStrideBytes, // + dstBuffer, dstStrideBytes, // + width, height); + return ret; } -int DoRotation(const BufferSpec& src, const BufferSpec& dst, - libyuv::RotationMode rotation, bool v_flip) { - ATRACE_CALL(); - - // Point to the upper left corner of the crop rectangles - uint8_t* srcBuffer = - src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; - const int srcStrideBytes = static_cast<int>(src.strideBytes); - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - int width = static_cast<int>(src.cropWidth); - int height = static_cast<int>(src.cropHeight); - - if (v_flip) { - height = -height; - } - - return libyuv::ARGBRotate(srcBuffer, srcStrideBytes, // - dstBuffer, dstStrideBytes, // - width, height, rotation); +int DoRotation(const BufferSpec& src, const BufferSpec& dst, libyuv::RotationMode rotation, + bool v_flip) { + ATRACE_CALL(); + + // Point to the upper left corner of the crop rectangles + uint8_t* srcBuffer = src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; + const int srcStrideBytes = static_cast<int>(src.strideBytes); + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + int width = static_cast<int>(src.cropWidth); + int height = static_cast<int>(src.cropHeight); + + if (v_flip) { + height = -height; + } + + return libyuv::ARGBRotate(srcBuffer, srcStrideBytes, // + dstBuffer, dstStrideBytes, // + width, height, rotation); } int DoScaling(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - ATRACE_CALL(); - - // Point to the upper left corner of the crop rectangles - uint8_t* srcBuffer = - src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int srcStrideBytes = static_cast<int>(src.strideBytes); - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - const int srcWidth = static_cast<int>(src.cropWidth); - int srcHeight = static_cast<int>(src.cropHeight); - const int dstWidth = static_cast<int>(dst.cropWidth); - const int dstHeight = static_cast<int>(dst.cropHeight); - - if (v_flip) { - srcHeight = -srcHeight; - } - - return libyuv::ARGBScale(srcBuffer, srcStrideBytes, srcWidth, srcHeight, dstBuffer, - dstStrideBytes, dstWidth, dstHeight, libyuv::kFilterBilinear); + ATRACE_CALL(); + + // Point to the upper left corner of the crop rectangles + uint8_t* srcBuffer = src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int srcStrideBytes = static_cast<int>(src.strideBytes); + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + const int srcWidth = static_cast<int>(src.cropWidth); + int srcHeight = static_cast<int>(src.cropHeight); + const int dstWidth = static_cast<int>(dst.cropWidth); + const int dstHeight = static_cast<int>(dst.cropHeight); + + if (v_flip) { + srcHeight = -srcHeight; + } + + return libyuv::ARGBScale(srcBuffer, srcStrideBytes, srcWidth, srcHeight, dstBuffer, + dstStrideBytes, dstWidth, dstHeight, libyuv::kFilterBilinear); } int DoAttenuation(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - ATRACE_CALL(); - - // Point to the upper left corner of the crop rectangles - uint8_t* srcBuffer = - src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int srcStrideBytes = static_cast<int>(src.strideBytes); - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - const int width = static_cast<int>(dst.cropWidth); - int height = static_cast<int>(dst.cropHeight); - if (v_flip) { - height = -height; - } - - return libyuv::ARGBAttenuate(srcBuffer, srcStrideBytes, // - dstBuffer, dstStrideBytes, // - width, height); + ATRACE_CALL(); + + // Point to the upper left corner of the crop rectangles + uint8_t* srcBuffer = src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int srcStrideBytes = static_cast<int>(src.strideBytes); + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + const int width = static_cast<int>(dst.cropWidth); + int height = static_cast<int>(dst.cropHeight); + if (v_flip) { + height = -height; + } + + return libyuv::ARGBAttenuate(srcBuffer, srcStrideBytes, // + dstBuffer, dstStrideBytes, // + width, height); } int DoBlending(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - ATRACE_CALL(); - - // Point to the upper left corner of the crop rectangles - uint8_t* srcBuffer = - src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; - uint8_t* dstBuffer = - dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; - const int srcStrideBytes = static_cast<int>(src.strideBytes); - const int dstStrideBytes = static_cast<int>(dst.strideBytes); - const int width = static_cast<int>(dst.cropWidth); - int height = static_cast<int>(dst.cropHeight); - if (v_flip) { - height = -height; - } - - // libyuv's ARGB format is hwcomposer's BGRA format, since blending only cares - // for the position of alpha in the pixel and not the position of the colors - // this function is perfectly usable. - return libyuv::ARGBBlend(srcBuffer, srcStrideBytes, // - dstBuffer, dstStrideBytes, // - dstBuffer, dstStrideBytes, // - width, height); + ATRACE_CALL(); + + // Point to the upper left corner of the crop rectangles + uint8_t* srcBuffer = src.buffer + src.cropY * src.strideBytes + src.cropX * src.sampleBytes; + uint8_t* dstBuffer = dst.buffer + dst.cropY * dst.strideBytes + dst.cropX * dst.sampleBytes; + const int srcStrideBytes = static_cast<int>(src.strideBytes); + const int dstStrideBytes = static_cast<int>(dst.strideBytes); + const int width = static_cast<int>(dst.cropWidth); + int height = static_cast<int>(dst.cropHeight); + if (v_flip) { + height = -height; + } + + // libyuv's ARGB format is hwcomposer's BGRA format, since blending only cares + // for the position of alpha in the pixel and not the position of the colors + // this function is perfectly usable. + return libyuv::ARGBBlend(srcBuffer, srcStrideBytes, // + dstBuffer, dstStrideBytes, // + dstBuffer, dstStrideBytes, // + width, height); } -std::optional<BufferSpec> GetBufferSpec(GrallocBuffer& buffer, - GrallocBufferView& bufferView, +std::optional<BufferSpec> GetBufferSpec(GrallocBuffer& buffer, GrallocBufferView& bufferView, const common::Rect& bufferCrop) { - auto bufferFormatOpt = buffer.GetDrmFormat(); - if (!bufferFormatOpt) { - ALOGE("Failed to get gralloc buffer format."); - return std::nullopt; - } - uint32_t bufferFormat = *bufferFormatOpt; - - auto bufferWidthOpt = buffer.GetWidth(); - if (!bufferWidthOpt) { - ALOGE("Failed to get gralloc buffer width."); - return std::nullopt; - } - uint32_t bufferWidth = *bufferWidthOpt; - - auto bufferHeightOpt = buffer.GetHeight(); - if (!bufferHeightOpt) { - ALOGE("Failed to get gralloc buffer height."); - return std::nullopt; - } - uint32_t bufferHeight = *bufferHeightOpt; - - uint8_t* bufferData = nullptr; - uint32_t bufferStrideBytes = 0; - std::optional<android_ycbcr> bufferYCbCrData; - - if (bufferFormat == DRM_FORMAT_NV12 || bufferFormat == DRM_FORMAT_NV21 || - bufferFormat == DRM_FORMAT_YVU420) { - bufferYCbCrData = bufferView.GetYCbCr(); - if (!bufferYCbCrData) { - ALOGE("%s failed to get raw ycbcr from view.", __FUNCTION__); - return std::nullopt; + auto bufferFormatOpt = buffer.GetDrmFormat(); + if (!bufferFormatOpt) { + ALOGE("Failed to get gralloc buffer format."); + return std::nullopt; + } + uint32_t bufferFormat = *bufferFormatOpt; + + auto bufferWidthOpt = buffer.GetWidth(); + if (!bufferWidthOpt) { + ALOGE("Failed to get gralloc buffer width."); + return std::nullopt; } - } else { - auto bufferDataOpt = bufferView.Get(); - if (!bufferDataOpt) { - ALOGE("%s failed to lock gralloc buffer.", __FUNCTION__); - return std::nullopt; + uint32_t bufferWidth = *bufferWidthOpt; + + auto bufferHeightOpt = buffer.GetHeight(); + if (!bufferHeightOpt) { + ALOGE("Failed to get gralloc buffer height."); + return std::nullopt; } - bufferData = reinterpret_cast<uint8_t*>(*bufferDataOpt); + uint32_t bufferHeight = *bufferHeightOpt; + + uint8_t* bufferData = nullptr; + uint32_t bufferStrideBytes = 0; + std::optional<android_ycbcr> bufferYCbCrData; + + if (bufferFormat == DRM_FORMAT_NV12 || bufferFormat == DRM_FORMAT_NV21 || + bufferFormat == DRM_FORMAT_YVU420) { + bufferYCbCrData = bufferView.GetYCbCr(); + if (!bufferYCbCrData) { + ALOGE("%s failed to get raw ycbcr from view.", __FUNCTION__); + return std::nullopt; + } + } else { + auto bufferDataOpt = bufferView.Get(); + if (!bufferDataOpt) { + ALOGE("%s failed to lock gralloc buffer.", __FUNCTION__); + return std::nullopt; + } + bufferData = reinterpret_cast<uint8_t*>(*bufferDataOpt); - auto bufferStrideBytesOpt = buffer.GetMonoPlanarStrideBytes(); - if (!bufferStrideBytesOpt) { - ALOGE("%s failed to get plane stride.", __FUNCTION__); - return std::nullopt; + auto bufferStrideBytesOpt = buffer.GetMonoPlanarStrideBytes(); + if (!bufferStrideBytesOpt) { + ALOGE("%s failed to get plane stride.", __FUNCTION__); + return std::nullopt; + } + bufferStrideBytes = *bufferStrideBytesOpt; } - bufferStrideBytes = *bufferStrideBytesOpt; - } - uint32_t bufferCropX = static_cast<uint32_t>(bufferCrop.left); - uint32_t bufferCropY = static_cast<uint32_t>(bufferCrop.top); - uint32_t bufferCropWidth = static_cast<uint32_t>(bufferCrop.right - bufferCrop.left); - uint32_t bufferCropHeight = static_cast<uint32_t>(bufferCrop.bottom - bufferCrop.top); + uint32_t bufferCropX = static_cast<uint32_t>(bufferCrop.left); + uint32_t bufferCropY = static_cast<uint32_t>(bufferCrop.top); + uint32_t bufferCropWidth = static_cast<uint32_t>(bufferCrop.right - bufferCrop.left); + uint32_t bufferCropHeight = static_cast<uint32_t>(bufferCrop.bottom - bufferCrop.top); - return BufferSpec(bufferData, bufferYCbCrData, bufferWidth, bufferHeight, bufferCropX, - bufferCropY, bufferCropWidth, bufferCropHeight, bufferFormat, bufferStrideBytes, - GetDrmFormatBytesPerPixel(bufferFormat)); + return BufferSpec(bufferData, bufferYCbCrData, bufferWidth, bufferHeight, bufferCropX, + bufferCropY, bufferCropWidth, bufferCropHeight, bufferFormat, + bufferStrideBytes, GetDrmFormatBytesPerPixel(bufferFormat)); } } // namespace HWC3::Error GuestFrameComposer::init() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - HWC3::Error error = mDrmClient.init(); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to initialize DrmClient", __FUNCTION__); - return error; - } + HWC3::Error error = mDrmClient.init(); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to initialize DrmClient", __FUNCTION__); + return error; + } - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error GuestFrameComposer::registerOnHotplugCallback( - const HotplugCallback& cb) { - return mDrmClient.registerOnHotplugCallback(cb); - return HWC3::Error::None; +HWC3::Error GuestFrameComposer::registerOnHotplugCallback(const HotplugCallback& cb) { + return mDrmClient.registerOnHotplugCallback(cb); + return HWC3::Error::None; } HWC3::Error GuestFrameComposer::unregisterOnHotplugCallback() { - return mDrmClient.unregisterOnHotplugCallback(); + return mDrmClient.unregisterOnHotplugCallback(); } HWC3::Error GuestFrameComposer::onDisplayCreate(Display* display) { - const uint32_t displayId = static_cast<uint32_t>(display->getId()); - int32_t displayConfigId; - int32_t displayWidth; - int32_t displayHeight; - - HWC3::Error error = display->getActiveConfig(&displayConfigId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " has no active config", __FUNCTION__, displayId); - return error; - } + const uint32_t displayId = static_cast<uint32_t>(display->getId()); + int32_t displayConfigId; + int32_t displayWidth; + int32_t displayHeight; - error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, - &displayWidth); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to get width", __FUNCTION__, displayId); - return error; - } + HWC3::Error error = display->getActiveConfig(&displayConfigId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " has no active config", __FUNCTION__, displayId); + return error; + } - error = display->getDisplayAttribute( - displayConfigId, DisplayAttribute::HEIGHT, &displayHeight); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId); - return error; - } - - auto it = mDisplayInfos.find(displayId); - if (it != mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu32 " already created?", __FUNCTION__, displayId); - } - - DisplayInfo& displayInfo = mDisplayInfos[displayId]; - - uint32_t bufferStride; - buffer_handle_t bufferHandle; - - auto status = ::android::GraphicBufferAllocator::get().allocate( - static_cast<uint32_t>(displayWidth), // - static_cast<uint32_t>(displayHeight), // - ::android::PIXEL_FORMAT_RGBA_8888, // - /*layerCount=*/1, // - ::android::GraphicBuffer::USAGE_HW_COMPOSER | ::android::GraphicBuffer::USAGE_SW_READ_OFTEN | - ::android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, // - &bufferHandle, // - &bufferStride, // - "RanchuHwc"); - if (status != ::android::OK) { - ALOGE("%s: failed to allocate composition buffer for display:%" PRIu32, __FUNCTION__, - displayId); - return HWC3::Error::NoResources; - } - - displayInfo.compositionResultBuffer = bufferHandle; - - auto [drmBufferCreateError, drmBuffer] = mDrmClient.create(bufferHandle); - if (drmBufferCreateError != HWC3::Error::None) { - ALOGE("%s: failed to create drm buffer for display:%" PRIu32, __FUNCTION__, displayId); - return drmBufferCreateError; - } - displayInfo.compositionResultDrmBuffer = std::move(drmBuffer); - - if (displayId == 0) { - auto [flushError, flushSyncFd] = mDrmClient.flushToDisplay( - displayId, displayInfo.compositionResultDrmBuffer, -1); - if (flushError != HWC3::Error::None) { - ALOGW( - "%s: Initial display flush failed. HWComposer assuming that we are " - "running in QEMU without a display and disabling presenting.", - __FUNCTION__); - mPresentDisabled = true; + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, &displayWidth); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to get width", __FUNCTION__, displayId); + return error; + } + + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::HEIGHT, &displayHeight); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId); + return error; + } + + auto it = mDisplayInfos.find(displayId); + if (it != mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu32 " already created?", __FUNCTION__, displayId); } - } - std::optional<std::vector<uint8_t>> edid = mDrmClient.getEdid(displayId); - if (edid) { - display->setEdid(*edid); - } + DisplayInfo& displayInfo = mDisplayInfos[displayId]; + + uint32_t bufferStride; + buffer_handle_t bufferHandle; + + auto status = ::android::GraphicBufferAllocator::get().allocate( + static_cast<uint32_t>(displayWidth), // + static_cast<uint32_t>(displayHeight), // + ::android::PIXEL_FORMAT_RGBA_8888, // + /*layerCount=*/1, // + ::android::GraphicBuffer::USAGE_HW_COMPOSER | + ::android::GraphicBuffer::USAGE_SW_READ_OFTEN | + ::android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, // + &bufferHandle, // + &bufferStride, // + "RanchuHwc"); + if (status != ::android::OK) { + ALOGE("%s: failed to allocate composition buffer for display:%" PRIu32, __FUNCTION__, + displayId); + return HWC3::Error::NoResources; + } + + displayInfo.compositionResultBuffer = bufferHandle; - return HWC3::Error::None; + auto [drmBufferCreateError, drmBuffer] = mDrmClient.create(bufferHandle); + if (drmBufferCreateError != HWC3::Error::None) { + ALOGE("%s: failed to create drm buffer for display:%" PRIu32, __FUNCTION__, displayId); + return drmBufferCreateError; + } + displayInfo.compositionResultDrmBuffer = std::move(drmBuffer); + + if (displayId == 0) { + auto [flushError, flushSyncFd] = + mDrmClient.flushToDisplay(displayId, displayInfo.compositionResultDrmBuffer, -1); + if (flushError != HWC3::Error::None) { + ALOGW( + "%s: Initial display flush failed. HWComposer assuming that we are " + "running in QEMU without a display and disabling presenting.", + __FUNCTION__); + mPresentDisabled = true; + } + } + + std::optional<std::vector<uint8_t>> edid = mDrmClient.getEdid(displayId); + if (edid) { + display->setEdid(*edid); + } + + return HWC3::Error::None; } HWC3::Error GuestFrameComposer::onDisplayDestroy(Display* display) { - auto displayId = display->getId(); + auto displayId = display->getId(); - auto it = mDisplayInfos.find(displayId); - if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, - displayId); - return HWC3::Error::BadDisplay; - } + auto it = mDisplayInfos.find(displayId); + if (it == mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; + } - DisplayInfo& displayInfo = mDisplayInfos[displayId]; + DisplayInfo& displayInfo = mDisplayInfos[displayId]; - ::android::GraphicBufferAllocator::get().free( - displayInfo.compositionResultBuffer); + ::android::GraphicBufferAllocator::get().free(displayInfo.compositionResultBuffer); - mDisplayInfos.erase(it); + mDisplayInfos.erase(it); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error GuestFrameComposer::onDisplayClientTargetSet(Display*) { - return HWC3::Error::None; -} +HWC3::Error GuestFrameComposer::onDisplayClientTargetSet(Display*) { return HWC3::Error::None; } HWC3::Error GuestFrameComposer::onActiveConfigChange(Display* /*display*/) { - return HWC3::Error::None; + return HWC3::Error::None; }; HWC3::Error GuestFrameComposer::getDisplayConfigsFromSystemProp( std::vector<GuestFrameComposer::DisplayConfig>* configs) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - std::vector<int> propIntParts; - parseExternalDisplaysFromProperties(propIntParts); + std::vector<int> propIntParts; + parseExternalDisplaysFromProperties(propIntParts); - while (!propIntParts.empty()) { - DisplayConfig display_config = { - .width = propIntParts[1], - .height = propIntParts[2], - .dpiX = propIntParts[3], - .dpiY = propIntParts[3], - .refreshRateHz = 160, - }; + while (!propIntParts.empty()) { + DisplayConfig display_config = { + .width = propIntParts[1], + .height = propIntParts[2], + .dpiX = propIntParts[3], + .dpiY = propIntParts[3], + .refreshRateHz = 160, + }; - configs->push_back(display_config); + configs->push_back(display_config); - propIntParts.erase(propIntParts.begin(), propIntParts.begin() + 5); - } + propIntParts.erase(propIntParts.begin(), propIntParts.begin() + 5); + } - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error GuestFrameComposer::validateDisplay(Display* display, - DisplayChanges* outChanges) { - const auto displayId = display->getId(); - DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); +HWC3::Error GuestFrameComposer::validateDisplay(Display* display, DisplayChanges* outChanges) { + const auto displayId = display->getId(); + DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - const std::vector<Layer*>& layers = display->getOrderedLayers(); + const std::vector<Layer*>& layers = display->getOrderedLayers(); - bool fallbackToClientComposition = false; - for (Layer* layer : layers) { - const auto layerId = layer->getId(); - const auto layerCompositionType = layer->getCompositionType(); - const auto layerCompositionTypeString = toString(layerCompositionType); - - if (layerCompositionType == Composition::INVALID) { - ALOGE("%s display:%" PRIu64 " layer:%" PRIu64 " has Invalid composition", - __FUNCTION__, displayId, layerId); - continue; - } + bool fallbackToClientComposition = false; + for (Layer* layer : layers) { + const auto layerId = layer->getId(); + const auto layerCompositionType = layer->getCompositionType(); + const auto layerCompositionTypeString = toString(layerCompositionType); + + if (layerCompositionType == Composition::INVALID) { + ALOGE("%s display:%" PRIu64 " layer:%" PRIu64 " has Invalid composition", __FUNCTION__, + displayId, layerId); + continue; + } - if (layerCompositionType == Composition::CLIENT || - layerCompositionType == Composition::CURSOR || - layerCompositionType == Composition::SIDEBAND) { - DEBUG_LOG("%s: display:%" PRIu64 " layer:%" PRIu64 - " has composition type %s, falling back to client composition", - __FUNCTION__, displayId, layerId, - layerCompositionTypeString.c_str()); - fallbackToClientComposition = true; - break; - } + if (layerCompositionType == Composition::CLIENT || + layerCompositionType == Composition::CURSOR || + layerCompositionType == Composition::SIDEBAND) { + DEBUG_LOG("%s: display:%" PRIu64 " layer:%" PRIu64 + " has composition type %s, falling back to client composition", + __FUNCTION__, displayId, layerId, layerCompositionTypeString.c_str()); + fallbackToClientComposition = true; + break; + } - if (layerCompositionType == Composition::DISPLAY_DECORATION) { - return HWC3::Error::Unsupported; - } + if (layerCompositionType == Composition::DISPLAY_DECORATION) { + return HWC3::Error::Unsupported; + } - if (!canComposeLayer(layer)) { - DEBUG_LOG( - "%s: display:%" PRIu64 " layer:%" PRIu64 - " composition not supported, falling back to client composition", - __FUNCTION__, displayId, layerId); - fallbackToClientComposition = true; - break; + if (!canComposeLayer(layer)) { + DEBUG_LOG("%s: display:%" PRIu64 " layer:%" PRIu64 + " composition not supported, falling back to client composition", + __FUNCTION__, displayId, layerId); + fallbackToClientComposition = true; + break; + } } - } - if (fallbackToClientComposition) { - for (Layer* layer : layers) { - const auto layerId = layer->getId(); - const auto layerCompositionType = layer->getCompositionType(); + if (fallbackToClientComposition) { + for (Layer* layer : layers) { + const auto layerId = layer->getId(); + const auto layerCompositionType = layer->getCompositionType(); - if (layerCompositionType == Composition::INVALID) { - continue; - } + if (layerCompositionType == Composition::INVALID) { + continue; + } - if (layerCompositionType != Composition::CLIENT) { - DEBUG_LOG("%s display:%" PRIu64 " layer:%" PRIu64 - "composition updated to Client", - __FUNCTION__, displayId, layerId); + if (layerCompositionType != Composition::CLIENT) { + DEBUG_LOG("%s display:%" PRIu64 " layer:%" PRIu64 "composition updated to Client", + __FUNCTION__, displayId, layerId); - outChanges->addLayerCompositionChange(displayId, layerId, - Composition::CLIENT); - } + outChanges->addLayerCompositionChange(displayId, layerId, Composition::CLIENT); + } + } } - } - - // We can not draw below a Client (SurfaceFlinger) composed layer. Change all - // layers below a Client composed layer to also be Client composed. - if (layers.size() > 1) { - for (std::size_t layerIndex = layers.size() - 1; layerIndex > 0; - layerIndex--) { - auto layer = layers[layerIndex]; - auto layerCompositionType = layer->getCompositionType(); - - if (layerCompositionType == Composition::CLIENT) { - for (std::size_t lowerLayerIndex = 0; lowerLayerIndex < layerIndex; - lowerLayerIndex++) { - auto lowerLayer = layers[lowerLayerIndex]; - auto lowerLayerId = lowerLayer->getId(); - auto lowerLayerCompositionType = lowerLayer->getCompositionType(); - - if (lowerLayerCompositionType != Composition::CLIENT) { - DEBUG_LOG("%s: display:%" PRIu64 " changing layer:%" PRIu64 - " to Client because" - "hwcomposer can not draw below the Client composed " - "layer:%" PRIu64, - __FUNCTION__, displayId, lowerLayerId, layer->getId()); - - outChanges->addLayerCompositionChange(displayId, lowerLayerId, - Composition::CLIENT); - } + + // We can not draw below a Client (SurfaceFlinger) composed layer. Change all + // layers below a Client composed layer to also be Client composed. + if (layers.size() > 1) { + for (std::size_t layerIndex = layers.size() - 1; layerIndex > 0; layerIndex--) { + auto layer = layers[layerIndex]; + auto layerCompositionType = layer->getCompositionType(); + + if (layerCompositionType == Composition::CLIENT) { + for (std::size_t lowerLayerIndex = 0; lowerLayerIndex < layerIndex; + lowerLayerIndex++) { + auto lowerLayer = layers[lowerLayerIndex]; + auto lowerLayerId = lowerLayer->getId(); + auto lowerLayerCompositionType = lowerLayer->getCompositionType(); + + if (lowerLayerCompositionType != Composition::CLIENT) { + DEBUG_LOG("%s: display:%" PRIu64 " changing layer:%" PRIu64 + " to Client because" + "hwcomposer can not draw below the Client composed " + "layer:%" PRIu64, + __FUNCTION__, displayId, lowerLayerId, layer->getId()); + + outChanges->addLayerCompositionChange(displayId, lowerLayerId, + Composition::CLIENT); + } + } + } } - } } - } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error GuestFrameComposer::presentDisplay( Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, - ::android::base::unique_fd>* /*outLayerFences*/) { - const uint32_t displayId = static_cast<uint32_t>(display->getId()); - DEBUG_LOG("%s display:%" PRIu32, __FUNCTION__, displayId); + std::unordered_map<int64_t, ::android::base::unique_fd>* /*outLayerFences*/) { + const uint32_t displayId = static_cast<uint32_t>(display->getId()); + DEBUG_LOG("%s display:%" PRIu32, __FUNCTION__, displayId); - if (mPresentDisabled) { - return HWC3::Error::None; - } - - auto it = mDisplayInfos.find(displayId); - if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu32 " not found", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - DisplayInfo& displayInfo = it->second; - - if (displayInfo.compositionResultBuffer == nullptr) { - ALOGE("%s: display:%" PRIu32 " missing composition result buffer", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - if (displayInfo.compositionResultDrmBuffer == nullptr) { - ALOGE("%s: display:%" PRIu32 " missing composition result drm buffer", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - std::optional<GrallocBuffer> compositionResultBufferOpt = - mGralloc.Import(displayInfo.compositionResultBuffer); - if (!compositionResultBufferOpt) { - ALOGE("%s: display:%" PRIu32 " failed to import buffer", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - std::optional<uint32_t> compositionResultBufferWidthOpt = - compositionResultBufferOpt->GetWidth(); - if (!compositionResultBufferWidthOpt) { - ALOGE("%s: display:%" PRIu32 " failed to query buffer width", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - std::optional<uint32_t> compositionResultBufferHeightOpt = - compositionResultBufferOpt->GetHeight(); - if (!compositionResultBufferHeightOpt) { - ALOGE("%s: display:%" PRIu32 " failed to query buffer height", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - std::optional<uint32_t> compositionResultBufferStrideOpt = - compositionResultBufferOpt->GetMonoPlanarStrideBytes(); - if (!compositionResultBufferStrideOpt) { - ALOGE("%s: display:%" PRIu32 " failed to query buffer stride", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - std::optional<GrallocBufferView> compositionResultBufferViewOpt = - compositionResultBufferOpt->Lock(); - if (!compositionResultBufferViewOpt) { - ALOGE("%s: display:%" PRIu32 " failed to get buffer view", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - const std::optional<void*> compositionResultBufferDataOpt = - compositionResultBufferViewOpt->Get(); - if (!compositionResultBufferDataOpt) { - ALOGE("%s: display:%" PRIu32 " failed to get buffer data", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - - uint32_t compositionResultBufferWidth = *compositionResultBufferWidthOpt; - uint32_t compositionResultBufferHeight = *compositionResultBufferHeightOpt; - uint32_t compositionResultBufferStride = *compositionResultBufferStrideOpt; - uint8_t* compositionResultBufferData = - reinterpret_cast<uint8_t*>(*compositionResultBufferDataOpt); - - const std::vector<Layer*>& layers = display->getOrderedLayers(); - - const bool noOpComposition = layers.empty(); - const bool allLayersClientComposed = - std::all_of(layers.begin(), // - layers.end(), // - [](const Layer* layer) { - return layer->getCompositionType() == Composition::CLIENT; - }); - - if (noOpComposition) { - ALOGW("%s: display:%" PRIu32 " empty composition", __FUNCTION__, displayId); - } else if (allLayersClientComposed) { - auto clientTargetBufferOpt = - mGralloc.Import(display->waitAndGetClientTargetBuffer()); - if (!clientTargetBufferOpt) { - ALOGE("%s: failed to import client target buffer.", __FUNCTION__); - return HWC3::Error::NoResources; + if (mPresentDisabled) { + return HWC3::Error::None; } - GrallocBuffer& clientTargetBuffer = *clientTargetBufferOpt; - auto clientTargetBufferViewOpt = clientTargetBuffer.Lock(); - if (!clientTargetBufferViewOpt) { - ALOGE("%s: failed to lock client target buffer.", __FUNCTION__); - return HWC3::Error::NoResources; + auto it = mDisplayInfos.find(displayId); + if (it == mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu32 " not found", __FUNCTION__, displayId); + return HWC3::Error::NoResources; } - GrallocBufferView& clientTargetBufferView = *clientTargetBufferViewOpt; - auto clientTargetPlaneLayoutsOpt = clientTargetBuffer.GetPlaneLayouts(); - if (!clientTargetPlaneLayoutsOpt) { - ALOGE("Failed to get client target buffer plane layouts."); - return HWC3::Error::NoResources; + DisplayInfo& displayInfo = it->second; + + if (displayInfo.compositionResultBuffer == nullptr) { + ALOGE("%s: display:%" PRIu32 " missing composition result buffer", __FUNCTION__, displayId); + return HWC3::Error::NoResources; } - auto& clientTargetPlaneLayouts = *clientTargetPlaneLayoutsOpt; - if (clientTargetPlaneLayouts.size() != 1) { - ALOGE("Unexpected number of plane layouts for client target buffer."); - return HWC3::Error::NoResources; + if (displayInfo.compositionResultDrmBuffer == nullptr) { + ALOGE("%s: display:%" PRIu32 " missing composition result drm buffer", __FUNCTION__, + displayId); + return HWC3::Error::NoResources; } - std::size_t clientTargetPlaneSize = - static_cast<std::size_t>(clientTargetPlaneLayouts[0].totalSizeInBytes); + std::optional<GrallocBuffer> compositionResultBufferOpt = + mGralloc.Import(displayInfo.compositionResultBuffer); + if (!compositionResultBufferOpt) { + ALOGE("%s: display:%" PRIu32 " failed to import buffer", __FUNCTION__, displayId); + return HWC3::Error::NoResources; + } - auto clientTargetDataOpt = clientTargetBufferView.Get(); - if (!clientTargetDataOpt) { - ALOGE("%s failed to lock gralloc buffer.", __FUNCTION__); - return HWC3::Error::NoResources; + std::optional<uint32_t> compositionResultBufferWidthOpt = + compositionResultBufferOpt->GetWidth(); + if (!compositionResultBufferWidthOpt) { + ALOGE("%s: display:%" PRIu32 " failed to query buffer width", __FUNCTION__, displayId); + return HWC3::Error::NoResources; } - auto* clientTargetData = reinterpret_cast<uint8_t*>(*clientTargetDataOpt); - std::memcpy(compositionResultBufferData, clientTargetData, - clientTargetPlaneSize); - } else { - for (Layer* layer : layers) { - const auto layerId = layer->getId(); - const auto layerCompositionType = layer->getCompositionType(); - if (layerCompositionType != Composition::DEVICE && - layerCompositionType != Composition::SOLID_COLOR) { - continue; - } - - HWC3::Error error = composeLayerInto(layer, // - compositionResultBufferData, // - compositionResultBufferWidth, // - compositionResultBufferHeight, // - compositionResultBufferStride, // - 4); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to compose layer:%" PRIu64, __FUNCTION__, displayId, - layerId); - return error; - } + std::optional<uint32_t> compositionResultBufferHeightOpt = + compositionResultBufferOpt->GetHeight(); + if (!compositionResultBufferHeightOpt) { + ALOGE("%s: display:%" PRIu32 " failed to query buffer height", __FUNCTION__, displayId); + return HWC3::Error::NoResources; } - } - - if (display->hasColorTransform()) { - HWC3::Error error = - applyColorTransformToRGBA(display->getColorTransform(), // - compositionResultBufferData, // - compositionResultBufferWidth, // - compositionResultBufferHeight, // - compositionResultBufferStride); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to apply color transform", __FUNCTION__, displayId); - return error; + + std::optional<uint32_t> compositionResultBufferStrideOpt = + compositionResultBufferOpt->GetMonoPlanarStrideBytes(); + if (!compositionResultBufferStrideOpt) { + ALOGE("%s: display:%" PRIu32 " failed to query buffer stride", __FUNCTION__, displayId); + return HWC3::Error::NoResources; + } + + std::optional<GrallocBufferView> compositionResultBufferViewOpt = + compositionResultBufferOpt->Lock(); + if (!compositionResultBufferViewOpt) { + ALOGE("%s: display:%" PRIu32 " failed to get buffer view", __FUNCTION__, displayId); + return HWC3::Error::NoResources; + } + + const std::optional<void*> compositionResultBufferDataOpt = + compositionResultBufferViewOpt->Get(); + if (!compositionResultBufferDataOpt) { + ALOGE("%s: display:%" PRIu32 " failed to get buffer data", __FUNCTION__, displayId); + return HWC3::Error::NoResources; } - } - DEBUG_LOG("%s display:%" PRIu32 " flushing drm buffer", __FUNCTION__, displayId); + uint32_t compositionResultBufferWidth = *compositionResultBufferWidthOpt; + uint32_t compositionResultBufferHeight = *compositionResultBufferHeightOpt; + uint32_t compositionResultBufferStride = *compositionResultBufferStrideOpt; + uint8_t* compositionResultBufferData = + reinterpret_cast<uint8_t*>(*compositionResultBufferDataOpt); + + const std::vector<Layer*>& layers = display->getOrderedLayers(); + + const bool noOpComposition = layers.empty(); + const bool allLayersClientComposed = std::all_of( + layers.begin(), // + layers.end(), // + [](const Layer* layer) { return layer->getCompositionType() == Composition::CLIENT; }); + + if (noOpComposition) { + ALOGW("%s: display:%" PRIu32 " empty composition", __FUNCTION__, displayId); + } else if (allLayersClientComposed) { + auto clientTargetBufferOpt = mGralloc.Import(display->waitAndGetClientTargetBuffer()); + if (!clientTargetBufferOpt) { + ALOGE("%s: failed to import client target buffer.", __FUNCTION__); + return HWC3::Error::NoResources; + } + GrallocBuffer& clientTargetBuffer = *clientTargetBufferOpt; - auto [error, fence] = mDrmClient.flushToDisplay( - displayId, displayInfo.compositionResultDrmBuffer, -1); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to flush drm buffer" PRIu64, __FUNCTION__, displayId); - } + auto clientTargetBufferViewOpt = clientTargetBuffer.Lock(); + if (!clientTargetBufferViewOpt) { + ALOGE("%s: failed to lock client target buffer.", __FUNCTION__); + return HWC3::Error::NoResources; + } + GrallocBufferView& clientTargetBufferView = *clientTargetBufferViewOpt; + + auto clientTargetPlaneLayoutsOpt = clientTargetBuffer.GetPlaneLayouts(); + if (!clientTargetPlaneLayoutsOpt) { + ALOGE("Failed to get client target buffer plane layouts."); + return HWC3::Error::NoResources; + } + auto& clientTargetPlaneLayouts = *clientTargetPlaneLayoutsOpt; - *outDisplayFence = std::move(fence); - return error; + if (clientTargetPlaneLayouts.size() != 1) { + ALOGE("Unexpected number of plane layouts for client target buffer."); + return HWC3::Error::NoResources; + } + + std::size_t clientTargetPlaneSize = + static_cast<std::size_t>(clientTargetPlaneLayouts[0].totalSizeInBytes); + + auto clientTargetDataOpt = clientTargetBufferView.Get(); + if (!clientTargetDataOpt) { + ALOGE("%s failed to lock gralloc buffer.", __FUNCTION__); + return HWC3::Error::NoResources; + } + auto* clientTargetData = reinterpret_cast<uint8_t*>(*clientTargetDataOpt); + + std::memcpy(compositionResultBufferData, clientTargetData, clientTargetPlaneSize); + } else { + for (Layer* layer : layers) { + const auto layerId = layer->getId(); + const auto layerCompositionType = layer->getCompositionType(); + if (layerCompositionType != Composition::DEVICE && + layerCompositionType != Composition::SOLID_COLOR) { + continue; + } + + HWC3::Error error = composeLayerInto(layer, // + compositionResultBufferData, // + compositionResultBufferWidth, // + compositionResultBufferHeight, // + compositionResultBufferStride, // + 4); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to compose layer:%" PRIu64, __FUNCTION__, + displayId, layerId); + return error; + } + } + } + + if (display->hasColorTransform()) { + HWC3::Error error = applyColorTransformToRGBA(display->getColorTransform(), // + compositionResultBufferData, // + compositionResultBufferWidth, // + compositionResultBufferHeight, // + compositionResultBufferStride); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to apply color transform", __FUNCTION__, + displayId); + return error; + } + } + + DEBUG_LOG("%s display:%" PRIu32 " flushing drm buffer", __FUNCTION__, displayId); + + auto [error, fence] = + mDrmClient.flushToDisplay(displayId, displayInfo.compositionResultDrmBuffer, -1); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to flush drm buffer" PRIu64, __FUNCTION__, displayId); + } + + *outDisplayFence = std::move(fence); + return error; } bool GuestFrameComposer::canComposeLayer(Layer* layer) { - const auto layerCompositionType = layer->getCompositionType(); - if (layerCompositionType == Composition::SOLID_COLOR) { + const auto layerCompositionType = layer->getCompositionType(); + if (layerCompositionType == Composition::SOLID_COLOR) { + return true; + } + + if (layerCompositionType != Composition::DEVICE) { + return false; + } + + buffer_handle_t bufferHandle = layer->getBuffer().getBuffer(); + if (bufferHandle == nullptr) { + ALOGW("%s received a layer with a null handle", __FUNCTION__); + return false; + } + + auto bufferOpt = mGralloc.Import(bufferHandle); + if (!bufferOpt) { + ALOGE("Failed to import layer buffer."); + return false; + } + GrallocBuffer& buffer = *bufferOpt; + + auto bufferFormatOpt = buffer.GetDrmFormat(); + if (!bufferFormatOpt) { + ALOGE("Failed to get layer buffer format."); + return false; + } + uint32_t bufferFormat = *bufferFormatOpt; + + if (!IsDrmFormatSupported(bufferFormat)) { + return false; + } + return true; - } - - if (layerCompositionType != Composition::DEVICE) { - return false; - } - - buffer_handle_t bufferHandle = layer->getBuffer().getBuffer(); - if (bufferHandle == nullptr) { - ALOGW("%s received a layer with a null handle", __FUNCTION__); - return false; - } - - auto bufferOpt = mGralloc.Import(bufferHandle); - if (!bufferOpt) { - ALOGE("Failed to import layer buffer."); - return false; - } - GrallocBuffer& buffer = *bufferOpt; - - auto bufferFormatOpt = buffer.GetDrmFormat(); - if (!bufferFormatOpt) { - ALOGE("Failed to get layer buffer format."); - return false; - } - uint32_t bufferFormat = *bufferFormatOpt; - - if (!IsDrmFormatSupported(bufferFormat)) { - return false; - } - - return true; } -HWC3::Error GuestFrameComposer::composeLayerInto( - Layer* srcLayer, // - std::uint8_t* dstBuffer, // - std::uint32_t dstBufferWidth, // - std::uint32_t dstBufferHeight, // - std::uint32_t dstBufferStrideBytes, // - std::uint32_t dstBufferBytesPerPixel) { - ATRACE_CALL(); +HWC3::Error GuestFrameComposer::composeLayerInto(Layer* srcLayer, // + std::uint8_t* dstBuffer, // + std::uint32_t dstBufferWidth, // + std::uint32_t dstBufferHeight, // + std::uint32_t dstBufferStrideBytes, // + std::uint32_t dstBufferBytesPerPixel) { + ATRACE_CALL(); - libyuv::RotationMode rotation = - GetRotationFromTransform(srcLayer->getTransform()); + libyuv::RotationMode rotation = GetRotationFromTransform(srcLayer->getTransform()); - common::Rect srcLayerCrop = srcLayer->getSourceCropInt(); - common::Rect srcLayerDisplayFrame = srcLayer->getDisplayFrame(); + common::Rect srcLayerCrop = srcLayer->getSourceCropInt(); + common::Rect srcLayerDisplayFrame = srcLayer->getDisplayFrame(); - BufferSpec srcLayerSpec; + BufferSpec srcLayerSpec; - std::optional<GrallocBuffer> srcBufferOpt; - std::optional<GrallocBufferView> srcBufferViewOpt; + std::optional<GrallocBuffer> srcBufferOpt; + std::optional<GrallocBufferView> srcBufferViewOpt; - const auto srcLayerCompositionType = srcLayer->getCompositionType(); - if (srcLayerCompositionType == Composition::DEVICE) { - srcBufferOpt = mGralloc.Import(srcLayer->waitAndGetBuffer()); - if (!srcBufferOpt) { - ALOGE("%s: failed to import layer buffer.", __FUNCTION__); - return HWC3::Error::NoResources; - } - GrallocBuffer& srcBuffer = *srcBufferOpt; + const auto srcLayerCompositionType = srcLayer->getCompositionType(); + if (srcLayerCompositionType == Composition::DEVICE) { + srcBufferOpt = mGralloc.Import(srcLayer->waitAndGetBuffer()); + if (!srcBufferOpt) { + ALOGE("%s: failed to import layer buffer.", __FUNCTION__); + return HWC3::Error::NoResources; + } + GrallocBuffer& srcBuffer = *srcBufferOpt; - srcBufferViewOpt = srcBuffer.Lock(); - if (!srcBufferViewOpt) { - ALOGE("%s: failed to lock import layer buffer.", __FUNCTION__); - return HWC3::Error::NoResources; - } - GrallocBufferView& srcBufferView = *srcBufferViewOpt; + srcBufferViewOpt = srcBuffer.Lock(); + if (!srcBufferViewOpt) { + ALOGE("%s: failed to lock import layer buffer.", __FUNCTION__); + return HWC3::Error::NoResources; + } + GrallocBufferView& srcBufferView = *srcBufferViewOpt; - auto srcLayerSpecOpt = GetBufferSpec(srcBuffer, srcBufferView, srcLayerCrop); - if (!srcLayerSpecOpt) { - return HWC3::Error::NoResources; - } + auto srcLayerSpecOpt = GetBufferSpec(srcBuffer, srcBufferView, srcLayerCrop); + if (!srcLayerSpecOpt) { + return HWC3::Error::NoResources; + } - srcLayerSpec = *srcLayerSpecOpt; - } else if (srcLayerCompositionType == Composition::SOLID_COLOR) { - // srcLayerSpec not used by `needsFill` below. - } - - // TODO(jemoreira): Remove the hardcoded fomat. - bool needsFill = srcLayerCompositionType == Composition::SOLID_COLOR; - bool needsConversion = srcLayerCompositionType == Composition::DEVICE && - srcLayerSpec.drmFormat != DRM_FORMAT_XBGR8888 && - srcLayerSpec.drmFormat != DRM_FORMAT_ABGR8888; - bool needsScaling = LayerNeedsScaling(*srcLayer); - bool needsRotation = rotation != libyuv::kRotate0; - bool needsTranspose = needsRotation && rotation != libyuv::kRotate180; - bool needsVFlip = GetVFlipFromTransform(srcLayer->getTransform()); - bool needsAttenuation = LayerNeedsAttenuation(*srcLayer); - bool needsBlending = LayerNeedsBlending(*srcLayer); - bool needsCopy = !(needsConversion || needsScaling || needsRotation || - needsVFlip || needsAttenuation || needsBlending); - - BufferSpec dstLayerSpec( - dstBuffer, - /*buffer_ycbcr=*/std::nullopt, dstBufferWidth, dstBufferHeight, - static_cast<uint32_t>(srcLayerDisplayFrame.left), - static_cast<uint32_t>(srcLayerDisplayFrame.top), - static_cast<uint32_t>(srcLayerDisplayFrame.right - srcLayerDisplayFrame.left), - static_cast<uint32_t>(srcLayerDisplayFrame.bottom - srcLayerDisplayFrame.top), - DRM_FORMAT_XBGR8888, dstBufferStrideBytes, dstBufferBytesPerPixel); - - // Add the destination layer to the bottom of the buffer stack - std::vector<BufferSpec> dstBufferStack(1, dstLayerSpec); - - // If more than operation is to be performed, a temporary buffer is needed for - // each additional operation - - // N operations need N destination buffers, the destination layer (the - // framebuffer) is one of them, so only N-1 temporary buffers are needed. - // Vertical flip is not taken into account because it can be done together - // with any other operation. - int neededScratchBuffers = (needsFill ? 1 : 0) + - (needsConversion ? 1 : 0) + - (needsScaling ? 1 : 0) + (needsRotation ? 1 : 0) + - (needsAttenuation ? 1 : 0) + - (needsBlending ? 1 : 0) + (needsCopy ? 1 : 0) - 1; - - uint32_t mScratchBufferWidth = - static_cast<uint32_t>(srcLayerDisplayFrame.right - srcLayerDisplayFrame.left); - uint32_t mScratchBufferHeight = - static_cast<uint32_t>(srcLayerDisplayFrame.bottom - srcLayerDisplayFrame.top); - uint32_t mScratchBufferStrideBytes = - AlignToPower2(mScratchBufferWidth * dstBufferBytesPerPixel, 4); - uint32_t mScratchBufferSizeBytes = mScratchBufferHeight * mScratchBufferStrideBytes; - - for (uint32_t i = 0; i < neededScratchBuffers; i++) { - BufferSpec mScratchBufferspec(getRotatingScratchBuffer(mScratchBufferSizeBytes, i), - mScratchBufferWidth, mScratchBufferHeight, - mScratchBufferStrideBytes); - dstBufferStack.push_back(mScratchBufferspec); - } - - // Filling, conversion, and scaling should always be the first operations, so - // that every other operation works on equally sized frames (guaranteed to fit - // in the scratch buffers) in a common format. - - if (needsFill) { - BufferSpec& dstBufferSpec = dstBufferStack.back(); - - int retval = DoFill(dstBufferSpec, srcLayer->getColor()); - if (retval) { - ALOGE("Got error code %d from DoFill function", retval); + srcLayerSpec = *srcLayerSpecOpt; + } else if (srcLayerCompositionType == Composition::SOLID_COLOR) { + // srcLayerSpec not used by `needsFill` below. } - srcLayerSpec = dstBufferSpec; - dstBufferStack.pop_back(); - } - - // TODO(jemoreira): We are converting to ARGB as the first step under the - // assumption that scaling ARGB is faster than scaling I420 (the most common). - // This should be confirmed with testing. - if (needsConversion) { - BufferSpec& dstBufferSpec = dstBufferStack.back(); - if (needsScaling || needsTranspose) { - // If a rotation or a scaling operation are needed the dimensions at the - // top of the buffer stack are wrong (wrong sizes for scaling, swapped - // width and height for 90 and 270 rotations). - // Make width and height match the crop sizes on the source - uint32_t srcWidth = srcLayerSpec.cropWidth; - uint32_t srcHeight = srcLayerSpec.cropHeight; - uint32_t dst_stride_bytes = AlignToPower2(srcWidth * dstBufferBytesPerPixel, 4); - uint32_t needed_size = dst_stride_bytes * srcHeight; - dstBufferSpec.width = srcWidth; - dstBufferSpec.height = srcHeight; - // Adjust the stride accordingly - dstBufferSpec.strideBytes = dst_stride_bytes; - // Crop sizes also need to be adjusted - dstBufferSpec.cropWidth = srcWidth; - dstBufferSpec.cropHeight = srcHeight; - // cropX and y are fine at 0, format is already set to match destination - - // In case of a scale, the source frame may be bigger than the default tmp - // buffer size - dstBufferSpec.buffer = getSpecialScratchBuffer(needed_size); + // TODO(jemoreira): Remove the hardcoded fomat. + bool needsFill = srcLayerCompositionType == Composition::SOLID_COLOR; + bool needsConversion = srcLayerCompositionType == Composition::DEVICE && + srcLayerSpec.drmFormat != DRM_FORMAT_XBGR8888 && + srcLayerSpec.drmFormat != DRM_FORMAT_ABGR8888; + bool needsScaling = LayerNeedsScaling(*srcLayer); + bool needsRotation = rotation != libyuv::kRotate0; + bool needsTranspose = needsRotation && rotation != libyuv::kRotate180; + bool needsVFlip = GetVFlipFromTransform(srcLayer->getTransform()); + bool needsAttenuation = LayerNeedsAttenuation(*srcLayer); + bool needsBlending = LayerNeedsBlending(*srcLayer); + bool needsCopy = !(needsConversion || needsScaling || needsRotation || needsVFlip || + needsAttenuation || needsBlending); + + BufferSpec dstLayerSpec( + dstBuffer, + /*buffer_ycbcr=*/std::nullopt, dstBufferWidth, dstBufferHeight, + static_cast<uint32_t>(srcLayerDisplayFrame.left), + static_cast<uint32_t>(srcLayerDisplayFrame.top), + static_cast<uint32_t>(srcLayerDisplayFrame.right - srcLayerDisplayFrame.left), + static_cast<uint32_t>(srcLayerDisplayFrame.bottom - srcLayerDisplayFrame.top), + DRM_FORMAT_XBGR8888, dstBufferStrideBytes, dstBufferBytesPerPixel); + + // Add the destination layer to the bottom of the buffer stack + std::vector<BufferSpec> dstBufferStack(1, dstLayerSpec); + + // If more than operation is to be performed, a temporary buffer is needed for + // each additional operation + + // N operations need N destination buffers, the destination layer (the + // framebuffer) is one of them, so only N-1 temporary buffers are needed. + // Vertical flip is not taken into account because it can be done together + // with any other operation. + int neededScratchBuffers = (needsFill ? 1 : 0) + (needsConversion ? 1 : 0) + + (needsScaling ? 1 : 0) + (needsRotation ? 1 : 0) + + (needsAttenuation ? 1 : 0) + (needsBlending ? 1 : 0) + + (needsCopy ? 1 : 0) - 1; + + uint32_t mScratchBufferWidth = + static_cast<uint32_t>(srcLayerDisplayFrame.right - srcLayerDisplayFrame.left); + uint32_t mScratchBufferHeight = + static_cast<uint32_t>(srcLayerDisplayFrame.bottom - srcLayerDisplayFrame.top); + uint32_t mScratchBufferStrideBytes = + AlignToPower2(mScratchBufferWidth * dstBufferBytesPerPixel, 4); + uint32_t mScratchBufferSizeBytes = mScratchBufferHeight * mScratchBufferStrideBytes; + + for (uint32_t i = 0; i < neededScratchBuffers; i++) { + BufferSpec mScratchBufferspec(getRotatingScratchBuffer(mScratchBufferSizeBytes, i), + mScratchBufferWidth, mScratchBufferHeight, + mScratchBufferStrideBytes); + dstBufferStack.push_back(mScratchBufferspec); } - int retval = DoConversion(srcLayerSpec, dstBufferSpec, needsVFlip); - if (retval) { - ALOGE("Got error code %d from DoConversion function", retval); + // Filling, conversion, and scaling should always be the first operations, so + // that every other operation works on equally sized frames (guaranteed to fit + // in the scratch buffers) in a common format. + + if (needsFill) { + BufferSpec& dstBufferSpec = dstBufferStack.back(); + + int retval = DoFill(dstBufferSpec, srcLayer->getColor()); + if (retval) { + ALOGE("Got error code %d from DoFill function", retval); + } + + srcLayerSpec = dstBufferSpec; + dstBufferStack.pop_back(); } - needsVFlip = false; - srcLayerSpec = dstBufferSpec; - dstBufferStack.pop_back(); - } - - if (needsScaling) { - BufferSpec& dstBufferSpec = dstBufferStack.back(); - if (needsTranspose) { - // If a rotation is needed, the temporary buffer has the correct size but - // needs to be transposed and have its stride updated accordingly. The - // crop sizes also needs to be transposed, but not the x and y since they - // are both zero in a temporary buffer (and it is a temporary buffer - // because a rotation will be performed next). - std::swap(dstBufferSpec.width, dstBufferSpec.height); - std::swap(dstBufferSpec.cropWidth, dstBufferSpec.cropHeight); - // TODO (jemoreira): Aligment (To align here may cause the needed size to - // be bigger than the buffer, so care should be taken) - dstBufferSpec.strideBytes = dstBufferSpec.width * dstBufferBytesPerPixel; + + // TODO(jemoreira): We are converting to ARGB as the first step under the + // assumption that scaling ARGB is faster than scaling I420 (the most common). + // This should be confirmed with testing. + if (needsConversion) { + BufferSpec& dstBufferSpec = dstBufferStack.back(); + if (needsScaling || needsTranspose) { + // If a rotation or a scaling operation are needed the dimensions at the + // top of the buffer stack are wrong (wrong sizes for scaling, swapped + // width and height for 90 and 270 rotations). + // Make width and height match the crop sizes on the source + uint32_t srcWidth = srcLayerSpec.cropWidth; + uint32_t srcHeight = srcLayerSpec.cropHeight; + uint32_t dst_stride_bytes = AlignToPower2(srcWidth * dstBufferBytesPerPixel, 4); + uint32_t needed_size = dst_stride_bytes * srcHeight; + dstBufferSpec.width = srcWidth; + dstBufferSpec.height = srcHeight; + // Adjust the stride accordingly + dstBufferSpec.strideBytes = dst_stride_bytes; + // Crop sizes also need to be adjusted + dstBufferSpec.cropWidth = srcWidth; + dstBufferSpec.cropHeight = srcHeight; + // cropX and y are fine at 0, format is already set to match destination + + // In case of a scale, the source frame may be bigger than the default tmp + // buffer size + dstBufferSpec.buffer = getSpecialScratchBuffer(needed_size); + } + + int retval = DoConversion(srcLayerSpec, dstBufferSpec, needsVFlip); + if (retval) { + ALOGE("Got error code %d from DoConversion function", retval); + } + needsVFlip = false; + srcLayerSpec = dstBufferSpec; + dstBufferStack.pop_back(); } - int retval = DoScaling(srcLayerSpec, dstBufferSpec, needsVFlip); - needsVFlip = false; - if (retval) { - ALOGE("Got error code %d from DoScaling function", retval); + + if (needsScaling) { + BufferSpec& dstBufferSpec = dstBufferStack.back(); + if (needsTranspose) { + // If a rotation is needed, the temporary buffer has the correct size but + // needs to be transposed and have its stride updated accordingly. The + // crop sizes also needs to be transposed, but not the x and y since they + // are both zero in a temporary buffer (and it is a temporary buffer + // because a rotation will be performed next). + std::swap(dstBufferSpec.width, dstBufferSpec.height); + std::swap(dstBufferSpec.cropWidth, dstBufferSpec.cropHeight); + // TODO (jemoreira): Aligment (To align here may cause the needed size to + // be bigger than the buffer, so care should be taken) + dstBufferSpec.strideBytes = dstBufferSpec.width * dstBufferBytesPerPixel; + } + int retval = DoScaling(srcLayerSpec, dstBufferSpec, needsVFlip); + needsVFlip = false; + if (retval) { + ALOGE("Got error code %d from DoScaling function", retval); + } + srcLayerSpec = dstBufferSpec; + dstBufferStack.pop_back(); } - srcLayerSpec = dstBufferSpec; - dstBufferStack.pop_back(); - } - - if (needsRotation) { - int retval = - DoRotation(srcLayerSpec, dstBufferStack.back(), rotation, needsVFlip); - needsVFlip = false; - if (retval) { - ALOGE("Got error code %d from DoTransform function", retval); + + if (needsRotation) { + int retval = DoRotation(srcLayerSpec, dstBufferStack.back(), rotation, needsVFlip); + needsVFlip = false; + if (retval) { + ALOGE("Got error code %d from DoTransform function", retval); + } + srcLayerSpec = dstBufferStack.back(); + dstBufferStack.pop_back(); } - srcLayerSpec = dstBufferStack.back(); - dstBufferStack.pop_back(); - } - - if (needsAttenuation) { - int retval = DoAttenuation(srcLayerSpec, dstBufferStack.back(), needsVFlip); - needsVFlip = false; - if (retval) { - ALOGE("Got error code %d from DoBlending function", retval); + + if (needsAttenuation) { + int retval = DoAttenuation(srcLayerSpec, dstBufferStack.back(), needsVFlip); + needsVFlip = false; + if (retval) { + ALOGE("Got error code %d from DoBlending function", retval); + } + srcLayerSpec = dstBufferStack.back(); + dstBufferStack.pop_back(); } - srcLayerSpec = dstBufferStack.back(); - dstBufferStack.pop_back(); - } - - if (needsCopy) { - int retval = DoCopy(srcLayerSpec, dstBufferStack.back(), needsVFlip); - needsVFlip = false; - if (retval) { - ALOGE("Got error code %d from DoBlending function", retval); + + if (needsCopy) { + int retval = DoCopy(srcLayerSpec, dstBufferStack.back(), needsVFlip); + needsVFlip = false; + if (retval) { + ALOGE("Got error code %d from DoBlending function", retval); + } + srcLayerSpec = dstBufferStack.back(); + dstBufferStack.pop_back(); } - srcLayerSpec = dstBufferStack.back(); - dstBufferStack.pop_back(); - } - - // Blending (if needed) should always be the last operation, so that it reads - // and writes in the destination layer and not some temporary buffer. - if (needsBlending) { - int retval = DoBlending(srcLayerSpec, dstBufferStack.back(), needsVFlip); - needsVFlip = false; - if (retval) { - ALOGE("Got error code %d from DoBlending function", retval); + + // Blending (if needed) should always be the last operation, so that it reads + // and writes in the destination layer and not some temporary buffer. + if (needsBlending) { + int retval = DoBlending(srcLayerSpec, dstBufferStack.back(), needsVFlip); + needsVFlip = false; + if (retval) { + ALOGE("Got error code %d from DoBlending function", retval); + } + // Don't need to assign destination to source in the last one + dstBufferStack.pop_back(); } - // Don't need to assign destination to source in the last one - dstBufferStack.pop_back(); - } - return HWC3::Error::None; + return HWC3::Error::None; } namespace { // Returns a color matrix that can be used with libyuv by converting values // in -1 to 1 into -64 to 64 and transposing. -std::array<std::int8_t, 16> ToLibyuvColorMatrix( - const std::array<float, 16>& in) { - std::array<std::int8_t, 16> out; +std::array<std::int8_t, 16> ToLibyuvColorMatrix(const std::array<float, 16>& in) { + std::array<std::int8_t, 16> out; - for (size_t r = 0; r < 4; r++) { - for (size_t c = 0; c < 4; c++) { - size_t indexIn = (4 * r) + c; - size_t indexOut = (4 * c) + r; + for (size_t r = 0; r < 4; r++) { + for (size_t c = 0; c < 4; c++) { + size_t indexIn = (4 * r) + c; + size_t indexOut = (4 * c) + r; - out[indexOut] = static_cast<std::int8_t>( - std::max(-128, std::min(127, static_cast<int>(in[indexIn] * 64.0f + 0.5f)))); + out[indexOut] = static_cast<std::int8_t>( + std::max(-128, std::min(127, static_cast<int>(in[indexIn] * 64.0f + 0.5f)))); + } } - } - return out; + return out; } } // namespace @@ -1164,38 +1124,37 @@ HWC3::Error GuestFrameComposer::applyColorTransformToRGBA( std::uint32_t bufferWidth, // std::uint32_t bufferHeight, // std::uint32_t bufferStrideBytes) { - ATRACE_CALL(); + ATRACE_CALL(); - const auto transformMatrixLibyuv = ToLibyuvColorMatrix(transfromMatrix); - libyuv::ARGBColorMatrix(buffer, static_cast<int>(bufferStrideBytes), // - buffer, static_cast<int>(bufferStrideBytes), // - transformMatrixLibyuv.data(), // - static_cast<int>(bufferWidth), // - static_cast<int>(bufferHeight)); + const auto transformMatrixLibyuv = ToLibyuvColorMatrix(transfromMatrix); + libyuv::ARGBColorMatrix(buffer, static_cast<int>(bufferStrideBytes), // + buffer, static_cast<int>(bufferStrideBytes), // + transformMatrixLibyuv.data(), // + static_cast<int>(bufferWidth), // + static_cast<int>(bufferHeight)); - return HWC3::Error::None; + return HWC3::Error::None; } -uint8_t* GuestFrameComposer::getRotatingScratchBuffer(std::size_t neededSize, - std::uint32_t order) { - static constexpr const int kNumScratchBufferPieces = 2; +uint8_t* GuestFrameComposer::getRotatingScratchBuffer(std::size_t neededSize, std::uint32_t order) { + static constexpr const int kNumScratchBufferPieces = 2; - std::size_t totalNeededSize = neededSize * kNumScratchBufferPieces; - if (mScratchBuffer.size() < totalNeededSize) { - mScratchBuffer.resize(totalNeededSize); - } + std::size_t totalNeededSize = neededSize * kNumScratchBufferPieces; + if (mScratchBuffer.size() < totalNeededSize) { + mScratchBuffer.resize(totalNeededSize); + } - std::size_t bufferIndex = order % kNumScratchBufferPieces; - std::size_t bufferOffset = bufferIndex * neededSize; - return &mScratchBuffer[bufferOffset]; + std::size_t bufferIndex = order % kNumScratchBufferPieces; + std::size_t bufferOffset = bufferIndex * neededSize; + return &mScratchBuffer[bufferOffset]; } uint8_t* GuestFrameComposer::getSpecialScratchBuffer(size_t neededSize) { - if (mSpecialScratchBuffer.size() < neededSize) { - mSpecialScratchBuffer.resize(neededSize); - } + if (mSpecialScratchBuffer.size() < neededSize) { + mSpecialScratchBuffer.resize(neededSize); + } - return &mSpecialScratchBuffer[0]; + return &mSpecialScratchBuffer[0]; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/GuestFrameComposer.h b/system/hwc3/GuestFrameComposer.h index 4aea37a8..196df3e2 100644 --- a/system/hwc3/GuestFrameComposer.h +++ b/system/hwc3/GuestFrameComposer.h @@ -27,97 +27,89 @@ namespace aidl::android::hardware::graphics::composer3::impl { class GuestFrameComposer : public FrameComposer { - public: - GuestFrameComposer() = default; + public: + GuestFrameComposer() = default; - GuestFrameComposer(const GuestFrameComposer&) = delete; - GuestFrameComposer& operator=(const GuestFrameComposer&) = delete; + GuestFrameComposer(const GuestFrameComposer&) = delete; + GuestFrameComposer& operator=(const GuestFrameComposer&) = delete; - GuestFrameComposer(GuestFrameComposer&&) = delete; - GuestFrameComposer& operator=(GuestFrameComposer&&) = delete; + GuestFrameComposer(GuestFrameComposer&&) = delete; + GuestFrameComposer& operator=(GuestFrameComposer&&) = delete; - HWC3::Error init() override; + HWC3::Error init() override; - HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; + HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; - HWC3::Error unregisterOnHotplugCallback() override; + HWC3::Error unregisterOnHotplugCallback() override; - HWC3::Error onDisplayCreate(Display*) override; + HWC3::Error onDisplayCreate(Display*) override; - HWC3::Error onDisplayDestroy(Display*) override; + HWC3::Error onDisplayDestroy(Display*) override; - HWC3::Error onDisplayClientTargetSet(Display*) override; + HWC3::Error onDisplayClientTargetSet(Display*) override; - // Determines if this composer can compose the given layers on the given - // display and requests changes for layers that can't not be composed. - HWC3::Error validateDisplay(Display* display, - DisplayChanges* outChanges) override; + // Determines if this composer can compose the given layers on the given + // display and requests changes for layers that can't not be composed. + HWC3::Error validateDisplay(Display* display, DisplayChanges* outChanges) override; - // Performs the actual composition of layers and presents the composed result - // to the display. - HWC3::Error presentDisplay( - Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) - override; + // Performs the actual composition of layers and presents the composed result + // to the display. + HWC3::Error presentDisplay( + Display* display, ::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) override; - HWC3::Error onActiveConfigChange(Display* /*display*/) override; + HWC3::Error onActiveConfigChange(Display* /*display*/) override; - const DrmClient* getDrmPresenter() const override { - return &mDrmClient; - } + const DrmClient* getDrmPresenter() const override { return &mDrmClient; } - private: - struct DisplayConfig { - int width; - int height; - int dpiX; - int dpiY; - int refreshRateHz; - }; + private: + struct DisplayConfig { + int width; + int height; + int dpiX; + int dpiY; + int refreshRateHz; + }; - HWC3::Error getDisplayConfigsFromSystemProp( - std::vector<DisplayConfig>* configs); + HWC3::Error getDisplayConfigsFromSystemProp(std::vector<DisplayConfig>* configs); - // Returns true if the given layer's buffer has supported format. - bool canComposeLayer(Layer* layer); + // Returns true if the given layer's buffer has supported format. + bool canComposeLayer(Layer* layer); - // Composes the given layer into the given destination buffer. - HWC3::Error composeLayerInto(Layer* layer, std::uint8_t* dstBuffer, - std::uint32_t dstBufferWidth, - std::uint32_t dstBufferHeight, - std::uint32_t dstBufferStrideBytes, - std::uint32_t dstBufferBytesPerPixel); + // Composes the given layer into the given destination buffer. + HWC3::Error composeLayerInto(Layer* layer, std::uint8_t* dstBuffer, + std::uint32_t dstBufferWidth, std::uint32_t dstBufferHeight, + std::uint32_t dstBufferStrideBytes, + std::uint32_t dstBufferBytesPerPixel); - struct DisplayInfo { - // Additional per display buffer for the composition result. - buffer_handle_t compositionResultBuffer = nullptr; + struct DisplayInfo { + // Additional per display buffer for the composition result. + buffer_handle_t compositionResultBuffer = nullptr; - std::shared_ptr<DrmBuffer> compositionResultDrmBuffer; - }; + std::shared_ptr<DrmBuffer> compositionResultDrmBuffer; + }; - std::unordered_map<int64_t, DisplayInfo> mDisplayInfos; + std::unordered_map<int64_t, DisplayInfo> mDisplayInfos; - Gralloc mGralloc; + Gralloc mGralloc; - DrmClient mDrmClient; + DrmClient mDrmClient; - // Cuttlefish on QEMU does not have a display. Disable presenting to avoid - // spamming logcat with DRM commit failures. - bool mPresentDisabled = false; + // Cuttlefish on QEMU does not have a display. Disable presenting to avoid + // spamming logcat with DRM commit failures. + bool mPresentDisabled = false; - uint8_t* getRotatingScratchBuffer(std::size_t neededSize, - std::uint32_t order); - uint8_t* getSpecialScratchBuffer(std::size_t neededSize); + uint8_t* getRotatingScratchBuffer(std::size_t neededSize, std::uint32_t order); + uint8_t* getSpecialScratchBuffer(std::size_t neededSize); - HWC3::Error applyColorTransformToRGBA( - const std::array<float, 16>& colorTransform, // - std::uint8_t* buffer, // - std::uint32_t bufferWidth, // - std::uint32_t bufferHeight, // - std::uint32_t bufferStrideBytes); + HWC3::Error applyColorTransformToRGBA(const std::array<float, 16>& colorTransform, // + std::uint8_t* buffer, // + std::uint32_t bufferWidth, // + std::uint32_t bufferHeight, // + std::uint32_t bufferStrideBytes); - std::vector<uint8_t> mScratchBuffer; - std::vector<uint8_t> mSpecialScratchBuffer; + std::vector<uint8_t> mScratchBuffer; + std::vector<uint8_t> mSpecialScratchBuffer; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/HostFrameComposer.cpp b/system/hwc3/HostFrameComposer.cpp index 6f146487..d440b880 100644 --- a/system/hwc3/HostFrameComposer.cpp +++ b/system/hwc3/HostFrameComposer.cpp @@ -39,713 +39,697 @@ namespace aidl::android::hardware::graphics::composer3::impl { namespace { hwc_rect AsHwcRect(const common::Rect& rect) { - hwc_rect out; - out.left = rect.left; - out.top = rect.top; - out.right = rect.right; - out.bottom = rect.bottom; - return out; + hwc_rect out; + out.left = rect.left; + out.top = rect.top; + out.right = rect.right; + out.bottom = rect.bottom; + return out; } hwc_frect AsHwcFrect(const common::FRect& rect) { - hwc_frect out; - out.left = rect.left; - out.top = rect.top; - out.right = rect.right; - out.bottom = rect.bottom; - return out; + hwc_frect out; + out.left = rect.left; + out.top = rect.top; + out.right = rect.right; + out.bottom = rect.bottom; + return out; } hwc_color AsHwcColor(const Color& color) { - hwc_color out; - out.r = static_cast<uint8_t>(color.r * 255.0f); - out.g = static_cast<uint8_t>(color.g * 255.0f); - out.b = static_cast<uint8_t>(color.b * 255.0f); - out.a = static_cast<uint8_t>(color.a * 255.0f); - return out; + hwc_color out; + out.r = static_cast<uint8_t>(color.r * 255.0f); + out.g = static_cast<uint8_t>(color.g * 255.0f); + out.b = static_cast<uint8_t>(color.b * 255.0f); + out.a = static_cast<uint8_t>(color.a * 255.0f); + return out; } hwc_transform_t AsHwcTransform(const common::Transform& transform) { - switch (transform) { - case common::Transform::NONE: - return static_cast<hwc_transform_t>(0); - case common::Transform::FLIP_H: - return HWC_TRANSFORM_FLIP_H; - case common::Transform::FLIP_V: - return HWC_TRANSFORM_FLIP_V; - case common::Transform::ROT_90: - return HWC_TRANSFORM_ROT_90; - case common::Transform::ROT_180: - return HWC_TRANSFORM_ROT_180; - case common::Transform::ROT_270: - return HWC_TRANSFORM_ROT_270; - } + switch (transform) { + case common::Transform::NONE: + return static_cast<hwc_transform_t>(0); + case common::Transform::FLIP_H: + return HWC_TRANSFORM_FLIP_H; + case common::Transform::FLIP_V: + return HWC_TRANSFORM_FLIP_V; + case common::Transform::ROT_90: + return HWC_TRANSFORM_ROT_90; + case common::Transform::ROT_180: + return HWC_TRANSFORM_ROT_180; + case common::Transform::ROT_270: + return HWC_TRANSFORM_ROT_270; + } } static bool isMinigbmFromProperty() { - static constexpr const auto kGrallocProp = "ro.hardware.gralloc"; - - const auto grallocProp = ::android::base::GetProperty(kGrallocProp, ""); - DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, grallocProp.c_str()); - - if (grallocProp == "minigbm") { - DEBUG_LOG("%s: Using minigbm, in minigbm mode.\n", __FUNCTION__); - return true; - } else { - DEBUG_LOG("%s: Is not using minigbm, in goldfish mode.\n", __FUNCTION__); - return false; - } + static constexpr const auto kGrallocProp = "ro.hardware.gralloc"; + + const auto grallocProp = ::android::base::GetProperty(kGrallocProp, ""); + DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, grallocProp.c_str()); + + if (grallocProp == "minigbm") { + DEBUG_LOG("%s: Using minigbm, in minigbm mode.\n", __FUNCTION__); + return true; + } else { + DEBUG_LOG("%s: Is not using minigbm, in goldfish mode.\n", __FUNCTION__); + return false; + } } typedef struct compose_layer { - uint32_t cbHandle; - hwc2_composition_t composeMode; - hwc_rect_t displayFrame; - hwc_frect_t crop; - int32_t blendMode; - float alpha; - hwc_color_t color; - hwc_transform_t transform; + uint32_t cbHandle; + hwc2_composition_t composeMode; + hwc_rect_t displayFrame; + hwc_frect_t crop; + int32_t blendMode; + float alpha; + hwc_color_t color; + hwc_transform_t transform; } ComposeLayer; typedef struct compose_device { - uint32_t version; - uint32_t targetHandle; - uint32_t numLayers; - struct compose_layer layer[0]; + uint32_t version; + uint32_t targetHandle; + uint32_t numLayers; + struct compose_layer layer[0]; } ComposeDevice; typedef struct compose_device_v2 { - uint32_t version; - uint32_t displayId; - uint32_t targetHandle; - uint32_t numLayers; - struct compose_layer layer[0]; + uint32_t version; + uint32_t displayId; + uint32_t targetHandle; + uint32_t numLayers; + struct compose_layer layer[0]; } ComposeDevice_v2; class ComposeMsg { - public: - ComposeMsg(uint32_t layerCnt = 0) - : mData(sizeof(ComposeDevice) + layerCnt * sizeof(ComposeLayer)) { - mComposeDevice = reinterpret_cast<ComposeDevice*>(mData.data()); - mLayerCnt = layerCnt; - } + public: + ComposeMsg(uint32_t layerCnt = 0) + : mData(sizeof(ComposeDevice) + layerCnt * sizeof(ComposeLayer)) { + mComposeDevice = reinterpret_cast<ComposeDevice*>(mData.data()); + mLayerCnt = layerCnt; + } - ComposeDevice* get() { return mComposeDevice; } + ComposeDevice* get() { return mComposeDevice; } - uint32_t getLayerCnt() { return mLayerCnt; } + uint32_t getLayerCnt() { return mLayerCnt; } - private: - std::vector<uint8_t> mData; - uint32_t mLayerCnt; - ComposeDevice* mComposeDevice; + private: + std::vector<uint8_t> mData; + uint32_t mLayerCnt; + ComposeDevice* mComposeDevice; }; class ComposeMsg_v2 { - public: - ComposeMsg_v2(uint32_t layerCnt = 0) - : mData(sizeof(ComposeDevice_v2) + layerCnt * sizeof(ComposeLayer)) { - mComposeDevice = reinterpret_cast<ComposeDevice_v2*>(mData.data()); - mLayerCnt = layerCnt; - } + public: + ComposeMsg_v2(uint32_t layerCnt = 0) + : mData(sizeof(ComposeDevice_v2) + layerCnt * sizeof(ComposeLayer)) { + mComposeDevice = reinterpret_cast<ComposeDevice_v2*>(mData.data()); + mLayerCnt = layerCnt; + } - ComposeDevice_v2* get() { return mComposeDevice; } + ComposeDevice_v2* get() { return mComposeDevice; } - uint32_t getLayerCnt() { return mLayerCnt; } + uint32_t getLayerCnt() { return mLayerCnt; } - private: - std::vector<uint8_t> mData; - uint32_t mLayerCnt; - ComposeDevice_v2* mComposeDevice; + private: + std::vector<uint8_t> mData; + uint32_t mLayerCnt; + ComposeDevice_v2* mComposeDevice; }; } // namespace HWC3::Error HostFrameComposer::init() { - mIsMinigbm = isMinigbmFromProperty(); + mIsMinigbm = isMinigbmFromProperty(); - if (mIsMinigbm) { - mDrmClient.emplace(); + if (mIsMinigbm) { + mDrmClient.emplace(); - HWC3::Error error = mDrmClient->init(); - if (error != HWC3::Error::None) { - ALOGE("%s: failed to initialize DrmClient", __FUNCTION__); - return error; + HWC3::Error error = mDrmClient->init(); + if (error != HWC3::Error::None) { + ALOGE("%s: failed to initialize DrmClient", __FUNCTION__); + return error; + } + } else { + mSyncDeviceFd = goldfish_sync_open(); } - } else { - mSyncDeviceFd = goldfish_sync_open(); - } - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error HostFrameComposer::registerOnHotplugCallback( - const HotplugCallback& cb) { - if (mDrmClient) { - mDrmClient->registerOnHotplugCallback(cb); - } - return HWC3::Error::None; +HWC3::Error HostFrameComposer::registerOnHotplugCallback(const HotplugCallback& cb) { + if (mDrmClient) { + mDrmClient->registerOnHotplugCallback(cb); + } + return HWC3::Error::None; } HWC3::Error HostFrameComposer::unregisterOnHotplugCallback() { - if (mDrmClient) { - mDrmClient->unregisterOnHotplugCallback(); - } - return HWC3::Error::None; + if (mDrmClient) { + mDrmClient->unregisterOnHotplugCallback(); + } + return HWC3::Error::None; } -HWC3::Error HostFrameComposer::createHostComposerDisplayInfo( - Display* display, uint32_t hostDisplayId) { - HWC3::Error error = HWC3::Error::None; - - int64_t displayId = display->getId(); - int32_t displayConfigId; - int32_t displayWidth; - int32_t displayHeight; - - error = display->getActiveConfig(&displayConfigId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " has no active config", __FUNCTION__, - displayId); - return error; - } - - error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, - &displayWidth); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to get width", __FUNCTION__, - displayId); - return error; - } - - error = display->getDisplayAttribute( - displayConfigId, DisplayAttribute::HEIGHT, &displayHeight); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to get height", __FUNCTION__, - displayId); - return error; - } - - HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId]; - - displayInfo.hostDisplayId = hostDisplayId; - displayInfo.swapchain = DrmSwapchain::create( - static_cast<uint32_t>(displayWidth), static_cast<uint32_t>(displayHeight), - ::android::GraphicBuffer::USAGE_HW_COMPOSER | ::android::GraphicBuffer::USAGE_HW_RENDER, - mDrmClient ? &mDrmClient.value() : nullptr); - if (!displayInfo.swapchain) { - ALOGE("%s: display:%" PRIu64 " failed to allocate swapchain", __FUNCTION__, displayId); - return HWC3::Error::NoResources; - } - return HWC3::Error::None; +HWC3::Error HostFrameComposer::createHostComposerDisplayInfo(Display* display, + uint32_t hostDisplayId) { + HWC3::Error error = HWC3::Error::None; + + int64_t displayId = display->getId(); + int32_t displayConfigId; + int32_t displayWidth; + int32_t displayHeight; + + error = display->getActiveConfig(&displayConfigId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " has no active config", __FUNCTION__, displayId); + return error; + } + + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, &displayWidth); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to get width", __FUNCTION__, displayId); + return error; + } + + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::HEIGHT, &displayHeight); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to get height", __FUNCTION__, displayId); + return error; + } + + HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId]; + + displayInfo.hostDisplayId = hostDisplayId; + displayInfo.swapchain = DrmSwapchain::create( + static_cast<uint32_t>(displayWidth), static_cast<uint32_t>(displayHeight), + ::android::GraphicBuffer::USAGE_HW_COMPOSER | ::android::GraphicBuffer::USAGE_HW_RENDER, + mDrmClient ? &mDrmClient.value() : nullptr); + if (!displayInfo.swapchain) { + ALOGE("%s: display:%" PRIu64 " failed to allocate swapchain", __FUNCTION__, displayId); + return HWC3::Error::NoResources; + } + return HWC3::Error::None; } HWC3::Error HostFrameComposer::onDisplayCreate(Display* display) { - HWC3::Error error = HWC3::Error::None; - - const uint32_t displayId = static_cast<uint32_t>(display->getId()); - int32_t displayConfigId; - int32_t displayWidth; - int32_t displayHeight; - int32_t displayDpiX; - - error = display->getActiveConfig(&displayConfigId); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " has no active config", __FUNCTION__, displayId); - return error; - } - - error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, - &displayWidth); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to get width", __FUNCTION__, displayId); - return error; - } - - error = display->getDisplayAttribute( - displayConfigId, DisplayAttribute::HEIGHT, &displayHeight); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId); - return error; - } - - error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::DPI_X, - &displayDpiX); - if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId); - return error; - } - - uint32_t hostDisplayId = 0; - - DEFINE_AND_VALIDATE_HOST_CONNECTION - if (displayId == 0) { - // Primary display: - hostCon->lock(); - if (rcEnc->rcCreateDisplayById(rcEnc, displayId)) { - ALOGE("%s host failed to create display %" PRIu32, __func__, displayId); - hostCon->unlock(); - return HWC3::Error::NoResources; - } - if (rcEnc->rcSetDisplayPoseDpi(rcEnc, displayId, -1, -1, static_cast<uint32_t>(displayWidth), - static_cast<uint32_t>(displayHeight), - static_cast<uint32_t>(displayDpiX / 1000))) { - ALOGE("%s host failed to set display %" PRIu32, __func__, displayId); - hostCon->unlock(); - return HWC3::Error::NoResources; + HWC3::Error error = HWC3::Error::None; + + const uint32_t displayId = static_cast<uint32_t>(display->getId()); + int32_t displayConfigId; + int32_t displayWidth; + int32_t displayHeight; + int32_t displayDpiX; + + error = display->getActiveConfig(&displayConfigId); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " has no active config", __FUNCTION__, displayId); + return error; } - hostCon->unlock(); - } else { - // Secondary display: - static constexpr const uint32_t kHostDisplayIdStart = 6; - uint32_t expectedHostDisplayId = kHostDisplayIdStart + displayId - 1; - uint32_t actualHostDisplayId = 0; + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, &displayWidth); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to get width", __FUNCTION__, displayId); + return error; + } - hostCon->lock(); - rcEnc->rcDestroyDisplay(rcEnc, expectedHostDisplayId); - rcEnc->rcCreateDisplay(rcEnc, &actualHostDisplayId); - rcEnc->rcSetDisplayPose(rcEnc, actualHostDisplayId, -1, -1, static_cast<uint32_t>(displayWidth), - static_cast<uint32_t>(displayHeight)); - hostCon->unlock(); + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::HEIGHT, &displayHeight); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId); + return error; + } - if (actualHostDisplayId != expectedHostDisplayId) { - ALOGE( - "Something wrong with host displayId allocation, expected %d " - "but received %d", - expectedHostDisplayId, actualHostDisplayId); + error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::DPI_X, &displayDpiX); + if (error != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId); + return error; } - hostDisplayId = actualHostDisplayId; - } + uint32_t hostDisplayId = 0; - error = createHostComposerDisplayInfo(display, hostDisplayId); - if (error != HWC3::Error::None) { - ALOGE("%s failed to initialize host info for display:%" PRIu32, __FUNCTION__, displayId); - return error; - } + DEFINE_AND_VALIDATE_HOST_CONNECTION + if (displayId == 0) { + // Primary display: + hostCon->lock(); + if (rcEnc->rcCreateDisplayById(rcEnc, displayId)) { + ALOGE("%s host failed to create display %" PRIu32, __func__, displayId); + hostCon->unlock(); + return HWC3::Error::NoResources; + } + if (rcEnc->rcSetDisplayPoseDpi( + rcEnc, displayId, -1, -1, static_cast<uint32_t>(displayWidth), + static_cast<uint32_t>(displayHeight), static_cast<uint32_t>(displayDpiX / 1000))) { + ALOGE("%s host failed to set display %" PRIu32, __func__, displayId); + hostCon->unlock(); + return HWC3::Error::NoResources; + } + hostCon->unlock(); + } else { + // Secondary display: + static constexpr const uint32_t kHostDisplayIdStart = 6; + + uint32_t expectedHostDisplayId = kHostDisplayIdStart + displayId - 1; + uint32_t actualHostDisplayId = 0; + + hostCon->lock(); + rcEnc->rcDestroyDisplay(rcEnc, expectedHostDisplayId); + rcEnc->rcCreateDisplay(rcEnc, &actualHostDisplayId); + rcEnc->rcSetDisplayPose(rcEnc, actualHostDisplayId, -1, -1, + static_cast<uint32_t>(displayWidth), + static_cast<uint32_t>(displayHeight)); + hostCon->unlock(); + + if (actualHostDisplayId != expectedHostDisplayId) { + ALOGE( + "Something wrong with host displayId allocation, expected %d " + "but received %d", + expectedHostDisplayId, actualHostDisplayId); + } + + hostDisplayId = actualHostDisplayId; + } - std::optional<std::vector<uint8_t>> edid; - if (mDrmClient) { - edid = mDrmClient->getEdid(displayId); - if (edid) { - display->setEdid(*edid); + error = createHostComposerDisplayInfo(display, hostDisplayId); + if (error != HWC3::Error::None) { + ALOGE("%s failed to initialize host info for display:%" PRIu32, __FUNCTION__, displayId); + return error; } - } - return HWC3::Error::None; + std::optional<std::vector<uint8_t>> edid; + if (mDrmClient) { + edid = mDrmClient->getEdid(displayId); + if (edid) { + display->setEdid(*edid); + } + } + + return HWC3::Error::None; } HWC3::Error HostFrameComposer::onDisplayDestroy(Display* display) { - int64_t displayId = display->getId(); + int64_t displayId = display->getId(); - auto it = mDisplayInfos.find(displayId); - if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, - displayId); - return HWC3::Error::BadDisplay; - } + auto it = mDisplayInfos.find(displayId); + if (it == mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; + } - HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId]; + HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId]; - if (displayId != 0) { - DEFINE_AND_VALIDATE_HOST_CONNECTION - hostCon->lock(); - rcEnc->rcDestroyDisplay(rcEnc, displayInfo.hostDisplayId); - hostCon->unlock(); - } + if (displayId != 0) { + DEFINE_AND_VALIDATE_HOST_CONNECTION + hostCon->lock(); + rcEnc->rcDestroyDisplay(rcEnc, displayInfo.hostDisplayId); + hostCon->unlock(); + } - mDisplayInfos.erase(it); + mDisplayInfos.erase(it); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error HostFrameComposer::onDisplayClientTargetSet(Display* display) { - int64_t displayId = display->getId(); - - auto it = mDisplayInfos.find(displayId); - if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, - displayId); - return HWC3::Error::BadDisplay; - } - - HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId]; - - if (mIsMinigbm) { - FencedBuffer& clientTargetFencedBuffer = display->getClientTarget(); - - auto [drmBufferCreateError, drmBuffer] = - mDrmClient->create(clientTargetFencedBuffer.getBuffer()); - if (drmBufferCreateError != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer", - __FUNCTION__, displayId); - return HWC3::Error::NoResources; + int64_t displayId = display->getId(); + + auto it = mDisplayInfos.find(displayId); + if (it == mDisplayInfos.end()) { + ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; } - displayInfo.clientTargetDrmBuffer = std::move(drmBuffer); - } - return HWC3::Error::None; -} + HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId]; -HWC3::Error HostFrameComposer::validateDisplay(Display* display, - DisplayChanges* outChanges) { - const auto& displayId = display->getId(); - - DEFINE_AND_VALIDATE_HOST_CONNECTION - hostCon->lock(); - bool hostCompositionV1 = rcEnc->hasHostCompositionV1(); - bool hostCompositionV2 = rcEnc->hasHostCompositionV2(); - hostCon->unlock(); - - const std::vector<Layer*> layers = display->getOrderedLayers(); - for (const auto& layer : layers) { - switch (layer->getCompositionType()) { - case Composition::INVALID: - // Log error for unused layers, layer leak? - ALOGE("%s layer:%" PRIu64 " CompositionType not set", __FUNCTION__, - layer->getId()); - break; - case Composition::DISPLAY_DECORATION: - return HWC3::Error::Unsupported; - default: - break; + if (mIsMinigbm) { + FencedBuffer& clientTargetFencedBuffer = display->getClientTarget(); + + auto [drmBufferCreateError, drmBuffer] = + mDrmClient->create(clientTargetFencedBuffer.getBuffer()); + if (drmBufferCreateError != HWC3::Error::None) { + ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer", __FUNCTION__, + displayId); + return HWC3::Error::NoResources; + } + displayInfo.clientTargetDrmBuffer = std::move(drmBuffer); } - } - // If one layer requires a fall back to the client composition type, all - // layers will fall back to the client composition type. - bool fallBackToClient = (!hostCompositionV1 && !hostCompositionV2) || - display->hasColorTransform(); - std::unordered_map<Layer*, Composition> changes; + return HWC3::Error::None; +} + +HWC3::Error HostFrameComposer::validateDisplay(Display* display, DisplayChanges* outChanges) { + const auto& displayId = display->getId(); + + DEFINE_AND_VALIDATE_HOST_CONNECTION + hostCon->lock(); + bool hostCompositionV1 = rcEnc->hasHostCompositionV1(); + bool hostCompositionV2 = rcEnc->hasHostCompositionV2(); + hostCon->unlock(); - if (!fallBackToClient) { + const std::vector<Layer*> layers = display->getOrderedLayers(); for (const auto& layer : layers) { - const auto& layerCompositionType = layer->getCompositionType(); - - std::optional<Composition> layerFallBackTo = std::nullopt; - switch (layerCompositionType) { - case Composition::CLIENT: - case Composition::SIDEBAND: - ALOGV("%s: layer %" PRIu32 " CompositionType %d, fallback to client", - __FUNCTION__, static_cast<uint32_t>(layer->getId()), - layerCompositionType); - layerFallBackTo = Composition::CLIENT; - break; - case Composition::CURSOR: - ALOGV("%s: layer %" PRIu32 " CompositionType %d, fallback to device", - __FUNCTION__, static_cast<uint32_t>(layer->getId()), - layerCompositionType); - layerFallBackTo = Composition::DEVICE; - break; - case Composition::INVALID: - case Composition::DEVICE: - case Composition::SOLID_COLOR: - layerFallBackTo = std::nullopt; - break; - default: - ALOGE("%s: layer %" PRIu32 " has an unknown composition type: %d", - __FUNCTION__, static_cast<uint32_t>(layer->getId()), - layerCompositionType); - } - if (layerFallBackTo == Composition::CLIENT) { - fallBackToClient = true; - } - if (layerFallBackTo.has_value()) { - changes.emplace(layer, layerFallBackTo.value()); - } + switch (layer->getCompositionType()) { + case Composition::INVALID: + // Log error for unused layers, layer leak? + ALOGE("%s layer:%" PRIu64 " CompositionType not set", __FUNCTION__, layer->getId()); + break; + case Composition::DISPLAY_DECORATION: + return HWC3::Error::Unsupported; + default: + break; + } } - } - - if (fallBackToClient) { - changes.clear(); - for (auto& layer : layers) { - const auto& layerId = layer->getId(); - if (layer->getCompositionType() == Composition::INVALID) { - continue; - } - if (layer->getCompositionType() != Composition::CLIENT) { - changes.emplace(layer, Composition::CLIENT); - } + + // If one layer requires a fall back to the client composition type, all + // layers will fall back to the client composition type. + bool fallBackToClient = + (!hostCompositionV1 && !hostCompositionV2) || display->hasColorTransform(); + std::unordered_map<Layer*, Composition> changes; + + if (!fallBackToClient) { + for (const auto& layer : layers) { + const auto& layerCompositionType = layer->getCompositionType(); + + std::optional<Composition> layerFallBackTo = std::nullopt; + switch (layerCompositionType) { + case Composition::CLIENT: + case Composition::SIDEBAND: + ALOGV("%s: layer %" PRIu32 " CompositionType %d, fallback to client", + __FUNCTION__, static_cast<uint32_t>(layer->getId()), + layerCompositionType); + layerFallBackTo = Composition::CLIENT; + break; + case Composition::CURSOR: + ALOGV("%s: layer %" PRIu32 " CompositionType %d, fallback to device", + __FUNCTION__, static_cast<uint32_t>(layer->getId()), + layerCompositionType); + layerFallBackTo = Composition::DEVICE; + break; + case Composition::INVALID: + case Composition::DEVICE: + case Composition::SOLID_COLOR: + layerFallBackTo = std::nullopt; + break; + default: + ALOGE("%s: layer %" PRIu32 " has an unknown composition type: %d", __FUNCTION__, + static_cast<uint32_t>(layer->getId()), layerCompositionType); + } + if (layerFallBackTo == Composition::CLIENT) { + fallBackToClient = true; + } + if (layerFallBackTo.has_value()) { + changes.emplace(layer, layerFallBackTo.value()); + } + } + } + + if (fallBackToClient) { + changes.clear(); + for (auto& layer : layers) { + const auto& layerId = layer->getId(); + if (layer->getCompositionType() == Composition::INVALID) { + continue; + } + if (layer->getCompositionType() != Composition::CLIENT) { + changes.emplace(layer, Composition::CLIENT); + } + } } - } - outChanges->clearLayerCompositionChanges(); - for (auto& [layer, newCompositionType] : changes) { - layer->logCompositionFallbackIfChanged(newCompositionType); - outChanges->addLayerCompositionChange(displayId, layer->getId(), newCompositionType); - } + outChanges->clearLayerCompositionChanges(); + for (auto& [layer, newCompositionType] : changes) { + layer->logCompositionFallbackIfChanged(newCompositionType); + outChanges->addLayerCompositionChange(displayId, layer->getId(), newCompositionType); + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error HostFrameComposer::presentDisplay( Display* display, ::android::base::unique_fd* outDisplayFence, std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) { - const uint32_t displayId = static_cast<uint32_t>(display->getId()); - auto displayInfoIt = mDisplayInfos.find(displayId); - if (displayInfoIt == mDisplayInfos.end()) { - ALOGE("%s: failed to find display buffers for display:%" PRIu32, __FUNCTION__, displayId); - return HWC3::Error::BadDisplay; - } - - HostComposerDisplayInfo& displayInfo = displayInfoIt->second; - - HostConnection* hostCon; - ExtendedRCEncoderContext* rcEnc; - HWC3::Error error = getAndValidateHostConnection(&hostCon, &rcEnc); - if (error != HWC3::Error::None) { - return error; - } - *outDisplayFence = ::android::base::unique_fd(); - hostCon->lock(); - bool hostCompositionV1 = rcEnc->hasHostCompositionV1(); - bool hostCompositionV2 = rcEnc->hasHostCompositionV2(); - hostCon->unlock(); - - // Ff we supports v2, then discard v1 - if (hostCompositionV2) { - hostCompositionV1 = false; - } - - auto compositionResult = displayInfo.swapchain->getNextImage(); - compositionResult->wait(); - - const std::vector<Layer*> layers = display->getOrderedLayers(); - if (hostCompositionV2 || hostCompositionV1) { - uint32_t numLayer = 0; - for (auto layer : layers) { - if (layer->getCompositionType() == Composition::DEVICE || - layer->getCompositionType() == Composition::SOLID_COLOR) { - numLayer++; - } + const uint32_t displayId = static_cast<uint32_t>(display->getId()); + auto displayInfoIt = mDisplayInfos.find(displayId); + if (displayInfoIt == mDisplayInfos.end()) { + ALOGE("%s: failed to find display buffers for display:%" PRIu32, __FUNCTION__, displayId); + return HWC3::Error::BadDisplay; } - DEBUG_LOG("%s: presenting display:%" PRIu32 " with %d layers", __FUNCTION__, displayId, - static_cast<int>(layers.size())); + HostComposerDisplayInfo& displayInfo = displayInfoIt->second; - if (numLayer == 0) { - ALOGV( - "%s display has no layers to compose, flushing client target buffer.", - __FUNCTION__); + HostConnection* hostCon; + ExtendedRCEncoderContext* rcEnc; + HWC3::Error error = getAndValidateHostConnection(&hostCon, &rcEnc); + if (error != HWC3::Error::None) { + return error; + } + *outDisplayFence = ::android::base::unique_fd(); + hostCon->lock(); + bool hostCompositionV1 = rcEnc->hasHostCompositionV1(); + bool hostCompositionV2 = rcEnc->hasHostCompositionV2(); + hostCon->unlock(); - FencedBuffer& displayClientTarget = display->getClientTarget(); - if (displayClientTarget.getBuffer() != nullptr) { - ::android::base::unique_fd fence = displayClientTarget.getFence(); - if (mIsMinigbm) { - auto [_, flushCompleteFence] = mDrmClient->flushToDisplay( - displayId, displayInfo.clientTargetDrmBuffer, fence); + // Ff we supports v2, then discard v1 + if (hostCompositionV2) { + hostCompositionV1 = false; + } - *outDisplayFence = std::move(flushCompleteFence); - } else { - rcEnc->rcSetDisplayColorBuffer(rcEnc, displayInfo.hostDisplayId, - hostCon->grallocHelper()->getHostHandle(displayClientTarget.getBuffer())); - post(hostCon, rcEnc, displayClientTarget.getBuffer()); - *outDisplayFence = std::move(fence); + auto compositionResult = displayInfo.swapchain->getNextImage(); + compositionResult->wait(); + + const std::vector<Layer*> layers = display->getOrderedLayers(); + if (hostCompositionV2 || hostCompositionV1) { + uint32_t numLayer = 0; + for (auto layer : layers) { + if (layer->getCompositionType() == Composition::DEVICE || + layer->getCompositionType() == Composition::SOLID_COLOR) { + numLayer++; + } } - } - return HWC3::Error::None; - } - std::unique_ptr<ComposeMsg> composeMsg; - std::unique_ptr<ComposeMsg_v2> composeMsgV2; + DEBUG_LOG("%s: presenting display:%" PRIu32 " with %d layers", __FUNCTION__, displayId, + static_cast<int>(layers.size())); + + if (numLayer == 0) { + ALOGV("%s display has no layers to compose, flushing client target buffer.", + __FUNCTION__); + + FencedBuffer& displayClientTarget = display->getClientTarget(); + if (displayClientTarget.getBuffer() != nullptr) { + ::android::base::unique_fd fence = displayClientTarget.getFence(); + if (mIsMinigbm) { + auto [_, flushCompleteFence] = mDrmClient->flushToDisplay( + displayId, displayInfo.clientTargetDrmBuffer, fence); + + *outDisplayFence = std::move(flushCompleteFence); + } else { + rcEnc->rcSetDisplayColorBuffer( + rcEnc, displayInfo.hostDisplayId, + hostCon->grallocHelper()->getHostHandle(displayClientTarget.getBuffer())); + post(hostCon, rcEnc, displayClientTarget.getBuffer()); + *outDisplayFence = std::move(fence); + } + } + return HWC3::Error::None; + } - if (hostCompositionV1) { - composeMsg.reset(new ComposeMsg(numLayer)); - } else { - composeMsgV2.reset(new ComposeMsg_v2(numLayer)); - } + std::unique_ptr<ComposeMsg> composeMsg; + std::unique_ptr<ComposeMsg_v2> composeMsgV2; - // Handle the composition - ComposeDevice* p; - ComposeDevice_v2* p2; - ComposeLayer* l; + if (hostCompositionV1) { + composeMsg.reset(new ComposeMsg(numLayer)); + } else { + composeMsgV2.reset(new ComposeMsg_v2(numLayer)); + } - if (hostCompositionV1) { - p = composeMsg->get(); - l = p->layer; - } else { - p2 = composeMsgV2->get(); - l = p2->layer; - } + // Handle the composition + ComposeDevice* p; + ComposeDevice_v2* p2; + ComposeLayer* l; - std::vector<int64_t> releaseLayerIds; - for (auto layer : layers) { - // TODO: use local var composisitonType to store getCompositionType() - if (layer->getCompositionType() != Composition::DEVICE && - layer->getCompositionType() != Composition::SOLID_COLOR) { - ALOGE("%s: Unsupported composition types %d layer %u", __FUNCTION__, - layer->getCompositionType(), (uint32_t)layer->getId()); - continue; - } - // send layer composition command to host - if (layer->getCompositionType() == Composition::DEVICE) { - releaseLayerIds.emplace_back(layer->getId()); - - ::android::base::unique_fd fence = layer->getBuffer().getFence(); - if (fence.ok()) { - int err = sync_wait(fence.get(), 3000); - if (err < 0 && errno == ETIME) { - ALOGE("%s waited on fence %d for 3000 ms", __FUNCTION__, - fence.get()); - } + if (hostCompositionV1) { + p = composeMsg->get(); + l = p->layer; } else { - ALOGV("%s: acquire fence not set for layer %u", __FUNCTION__, - (uint32_t)layer->getId()); + p2 = composeMsgV2->get(); + l = p2->layer; } - const native_handle_t* cb = layer->getBuffer().getBuffer(); - if (cb != nullptr) { - l->cbHandle = hostCon->grallocHelper()->getHostHandle(cb); - } else { - ALOGE("%s null buffer for layer %d", __FUNCTION__, - (uint32_t)layer->getId()); + + std::vector<int64_t> releaseLayerIds; + for (auto layer : layers) { + // TODO: use local var composisitonType to store getCompositionType() + if (layer->getCompositionType() != Composition::DEVICE && + layer->getCompositionType() != Composition::SOLID_COLOR) { + ALOGE("%s: Unsupported composition types %d layer %u", __FUNCTION__, + layer->getCompositionType(), (uint32_t)layer->getId()); + continue; + } + // send layer composition command to host + if (layer->getCompositionType() == Composition::DEVICE) { + releaseLayerIds.emplace_back(layer->getId()); + + ::android::base::unique_fd fence = layer->getBuffer().getFence(); + if (fence.ok()) { + int err = sync_wait(fence.get(), 3000); + if (err < 0 && errno == ETIME) { + ALOGE("%s waited on fence %d for 3000 ms", __FUNCTION__, fence.get()); + } + } else { + ALOGV("%s: acquire fence not set for layer %u", __FUNCTION__, + (uint32_t)layer->getId()); + } + const native_handle_t* cb = layer->getBuffer().getBuffer(); + if (cb != nullptr) { + l->cbHandle = hostCon->grallocHelper()->getHostHandle(cb); + } else { + ALOGE("%s null buffer for layer %d", __FUNCTION__, (uint32_t)layer->getId()); + } + } else { + // solidcolor has no buffer + l->cbHandle = 0; + } + l->composeMode = (hwc2_composition_t)layer->getCompositionType(); + l->displayFrame = AsHwcRect(layer->getDisplayFrame()); + l->crop = AsHwcFrect(layer->getSourceCrop()); + l->blendMode = static_cast<int32_t>(layer->getBlendMode()); + l->alpha = layer->getPlaneAlpha(); + l->color = AsHwcColor(layer->getColor()); + l->transform = AsHwcTransform(layer->getTransform()); + ALOGV( + " cb %d blendmode %d alpha %f %d %d %d %d z %d" + " composeMode %d, transform %d", + l->cbHandle, l->blendMode, l->alpha, l->displayFrame.left, l->displayFrame.top, + l->displayFrame.right, l->displayFrame.bottom, layer->getZOrder(), l->composeMode, + l->transform); + l++; } - } else { - // solidcolor has no buffer - l->cbHandle = 0; - } - l->composeMode = (hwc2_composition_t)layer->getCompositionType(); - l->displayFrame = AsHwcRect(layer->getDisplayFrame()); - l->crop = AsHwcFrect(layer->getSourceCrop()); - l->blendMode = static_cast<int32_t>(layer->getBlendMode()); - l->alpha = layer->getPlaneAlpha(); - l->color = AsHwcColor(layer->getColor()); - l->transform = AsHwcTransform(layer->getTransform()); - ALOGV( - " cb %d blendmode %d alpha %f %d %d %d %d z %d" - " composeMode %d, transform %d", - l->cbHandle, l->blendMode, l->alpha, l->displayFrame.left, - l->displayFrame.top, l->displayFrame.right, l->displayFrame.bottom, - layer->getZOrder(), l->composeMode, l->transform); - l++; - } - if (hostCompositionV1) { - p->version = 1; - p->targetHandle = hostCon->grallocHelper()->getHostHandle(compositionResult->getBuffer()); - p->numLayers = numLayer; - } else { - p2->version = 2; - p2->displayId = displayInfo.hostDisplayId; - p2->targetHandle = hostCon->grallocHelper()->getHostHandle(compositionResult->getBuffer()); - p2->numLayers = numLayer; - } + if (hostCompositionV1) { + p->version = 1; + p->targetHandle = + hostCon->grallocHelper()->getHostHandle(compositionResult->getBuffer()); + p->numLayers = numLayer; + } else { + p2->version = 2; + p2->displayId = displayInfo.hostDisplayId; + p2->targetHandle = + hostCon->grallocHelper()->getHostHandle(compositionResult->getBuffer()); + p2->numLayers = numLayer; + } - void* buffer; - uint32_t bufferSize; - if (hostCompositionV1) { - buffer = (void*)p; - bufferSize = sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer); - } else { - bufferSize = sizeof(ComposeDevice_v2) + numLayer * sizeof(ComposeLayer); - buffer = (void*)p2; - } + void* buffer; + uint32_t bufferSize; + if (hostCompositionV1) { + buffer = (void*)p; + bufferSize = sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer); + } else { + bufferSize = sizeof(ComposeDevice_v2) + numLayer * sizeof(ComposeLayer); + buffer = (void*)p2; + } - ::android::base::unique_fd retire_fd; - hostCon->lock(); - if (rcEnc->hasAsyncFrameCommands()) { - if (mIsMinigbm) { - rcEnc->rcComposeAsyncWithoutPost(rcEnc, bufferSize, buffer); - } else { - rcEnc->rcComposeAsync(rcEnc, bufferSize, buffer); - } - } else { - if (mIsMinigbm) { - rcEnc->rcComposeWithoutPost(rcEnc, bufferSize, buffer); - } else { - rcEnc->rcCompose(rcEnc, bufferSize, buffer); - } - } - hostCon->unlock(); + ::android::base::unique_fd retire_fd; + hostCon->lock(); + if (rcEnc->hasAsyncFrameCommands()) { + if (mIsMinigbm) { + rcEnc->rcComposeAsyncWithoutPost(rcEnc, bufferSize, buffer); + } else { + rcEnc->rcComposeAsync(rcEnc, bufferSize, buffer); + } + } else { + if (mIsMinigbm) { + rcEnc->rcComposeWithoutPost(rcEnc, bufferSize, buffer); + } else { + rcEnc->rcCompose(rcEnc, bufferSize, buffer); + } + } + hostCon->unlock(); - // Send a retire fence and use it as the release fence for all layers, - // since media expects it - EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_ANDROID, - EGL_NO_NATIVE_FENCE_FD_ANDROID}; + // Send a retire fence and use it as the release fence for all layers, + // since media expects it + EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID}; - uint64_t sync_handle, thread_handle; + uint64_t sync_handle, thread_handle; - // We don't use rc command to sync if we are using virtio-gpu, which is - // proxied by minigbm. - bool useRcCommandToSync = !mIsMinigbm; + // We don't use rc command to sync if we are using virtio-gpu, which is + // proxied by minigbm. + bool useRcCommandToSync = !mIsMinigbm; - if (useRcCommandToSync) { - hostCon->lock(); - rcEnc->rcCreateSyncKHR( - rcEnc, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs, 2 * sizeof(EGLint), - true /* destroy when signaled */, &sync_handle, &thread_handle); - hostCon->unlock(); - } + if (useRcCommandToSync) { + hostCon->lock(); + rcEnc->rcCreateSyncKHR(rcEnc, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs, + 2 * sizeof(EGLint), true /* destroy when signaled */, + &sync_handle, &thread_handle); + hostCon->unlock(); + } - if (mIsMinigbm) { - auto [_, fence] = - mDrmClient->flushToDisplay(displayId, compositionResult->getDrmBuffer(), -1); - retire_fd = std::move(fence); - } else { - int fd; - goldfish_sync_queue_work(mSyncDeviceFd, sync_handle, thread_handle, &fd); - retire_fd = ::android::base::unique_fd(fd); - } + if (mIsMinigbm) { + auto [_, fence] = + mDrmClient->flushToDisplay(displayId, compositionResult->getDrmBuffer(), -1); + retire_fd = std::move(fence); + } else { + int fd; + goldfish_sync_queue_work(mSyncDeviceFd, sync_handle, thread_handle, &fd); + retire_fd = ::android::base::unique_fd(fd); + } - for (int64_t layerId : releaseLayerIds) { - (*outLayerFences)[layerId] = - ::android::base::unique_fd(dup(retire_fd.get())); - } - *outDisplayFence = ::android::base::unique_fd(dup(retire_fd.get())); - - if (useRcCommandToSync) { - hostCon->lock(); - if (rcEnc->hasAsyncFrameCommands()) { - rcEnc->rcDestroySyncKHRAsync(rcEnc, sync_handle); - } else { - rcEnc->rcDestroySyncKHR(rcEnc, sync_handle); - } - hostCon->unlock(); - } - } else { - // we set all layers Composition::CLIENT, so do nothing. - FencedBuffer& displayClientTarget = display->getClientTarget(); - ::android::base::unique_fd displayClientTargetFence = - displayClientTarget.getFence(); - if (mIsMinigbm) { - auto [_, flushFence] = mDrmClient->flushToDisplay( - displayId, compositionResult->getDrmBuffer(), displayClientTargetFence); - *outDisplayFence = std::move(flushFence); + for (int64_t layerId : releaseLayerIds) { + (*outLayerFences)[layerId] = ::android::base::unique_fd(dup(retire_fd.get())); + } + *outDisplayFence = ::android::base::unique_fd(dup(retire_fd.get())); + + if (useRcCommandToSync) { + hostCon->lock(); + if (rcEnc->hasAsyncFrameCommands()) { + rcEnc->rcDestroySyncKHRAsync(rcEnc, sync_handle); + } else { + rcEnc->rcDestroySyncKHR(rcEnc, sync_handle); + } + hostCon->unlock(); + } } else { - rcEnc->rcSetDisplayColorBuffer(rcEnc, displayInfo.hostDisplayId, - hostCon->grallocHelper()->getHostHandle(displayClientTarget.getBuffer())); - post(hostCon, rcEnc, displayClientTarget.getBuffer()); - *outDisplayFence = std::move(displayClientTargetFence); + // we set all layers Composition::CLIENT, so do nothing. + FencedBuffer& displayClientTarget = display->getClientTarget(); + ::android::base::unique_fd displayClientTargetFence = displayClientTarget.getFence(); + if (mIsMinigbm) { + auto [_, flushFence] = mDrmClient->flushToDisplay( + displayId, compositionResult->getDrmBuffer(), displayClientTargetFence); + *outDisplayFence = std::move(flushFence); + } else { + rcEnc->rcSetDisplayColorBuffer( + rcEnc, displayInfo.hostDisplayId, + hostCon->grallocHelper()->getHostHandle(displayClientTarget.getBuffer())); + post(hostCon, rcEnc, displayClientTarget.getBuffer()); + *outDisplayFence = std::move(displayClientTargetFence); + } + ALOGV("%s fallback to post, returns outRetireFence %d", __FUNCTION__, + outDisplayFence->get()); } - ALOGV("%s fallback to post, returns outRetireFence %d", __FUNCTION__, - outDisplayFence->get()); - } - compositionResult->markAsInUse(outDisplayFence->ok() - ? ::android::base::unique_fd(dup(*outDisplayFence)) - : ::android::base::unique_fd()); - return HWC3::Error::None; + compositionResult->markAsInUse(outDisplayFence->ok() + ? ::android::base::unique_fd(dup(*outDisplayFence)) + : ::android::base::unique_fd()); + return HWC3::Error::None; } -void HostFrameComposer::post(HostConnection* hostCon, - ExtendedRCEncoderContext* rcEnc, +void HostFrameComposer::post(HostConnection* hostCon, ExtendedRCEncoderContext* rcEnc, buffer_handle_t h) { - assert(cb && "native_handle_t::from(h) failed"); + assert(cb && "native_handle_t::from(h) failed"); - hostCon->lock(); - rcEnc->rcFBPost(rcEnc, hostCon->grallocHelper()->getHostHandle(h)); - hostCon->flush(); - hostCon->unlock(); + hostCon->lock(); + rcEnc->rcFBPost(rcEnc, hostCon->grallocHelper()->getHostHandle(h)); + hostCon->flush(); + hostCon->unlock(); } HWC3::Error HostFrameComposer::onActiveConfigChange(Display* display) { - const uint32_t displayId = static_cast<uint32_t>(display->getId()); - DEBUG_LOG("%s: display:%" PRIu32, __FUNCTION__, displayId); - HWC3::Error error = createHostComposerDisplayInfo(display, displayId); - if (error != HWC3::Error::None) { - ALOGE("%s failed to update host info for display:%" PRIu32, __FUNCTION__, displayId); - return error; - } - return HWC3::Error::None; + const uint32_t displayId = static_cast<uint32_t>(display->getId()); + DEBUG_LOG("%s: display:%" PRIu32, __FUNCTION__, displayId); + HWC3::Error error = createHostComposerDisplayInfo(display, displayId); + if (error != HWC3::Error::None) { + ALOGE("%s failed to update host info for display:%" PRIu32, __FUNCTION__, displayId); + return error; + } + return HWC3::Error::None; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/HostFrameComposer.h b/system/hwc3/HostFrameComposer.h index 9b5e5c34..e90f7cfd 100644 --- a/system/hwc3/HostFrameComposer.h +++ b/system/hwc3/HostFrameComposer.h @@ -31,69 +31,65 @@ namespace aidl::android::hardware::graphics::composer3::impl { class HostFrameComposer : public FrameComposer { - public: - HostFrameComposer() = default; + public: + HostFrameComposer() = default; - HostFrameComposer(const HostFrameComposer&) = delete; - HostFrameComposer& operator=(const HostFrameComposer&) = delete; + HostFrameComposer(const HostFrameComposer&) = delete; + HostFrameComposer& operator=(const HostFrameComposer&) = delete; - HostFrameComposer(HostFrameComposer&&) = delete; - HostFrameComposer& operator=(HostFrameComposer&&) = delete; + HostFrameComposer(HostFrameComposer&&) = delete; + HostFrameComposer& operator=(HostFrameComposer&&) = delete; - HWC3::Error init() override; + HWC3::Error init() override; - HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; + HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; - HWC3::Error unregisterOnHotplugCallback() override; + HWC3::Error unregisterOnHotplugCallback() override; - HWC3::Error onDisplayCreate(Display* display) override; + HWC3::Error onDisplayCreate(Display* display) override; - HWC3::Error onDisplayDestroy(Display* display) override; + HWC3::Error onDisplayDestroy(Display* display) override; - HWC3::Error onDisplayClientTargetSet(Display* display) override; + HWC3::Error onDisplayClientTargetSet(Display* display) override; - // Determines if this composer can compose the given layers on the given - // display and requests changes for layers that can't not be composed. - HWC3::Error validateDisplay(Display* display, - DisplayChanges* outChanges) override; + // Determines if this composer can compose the given layers on the given + // display and requests changes for layers that can't not be composed. + HWC3::Error validateDisplay(Display* display, DisplayChanges* outChanges) override; - // Performs the actual composition of layers and presents the composed result - // to the display. - HWC3::Error presentDisplay( - Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) - override; + // Performs the actual composition of layers and presents the composed result + // to the display. + HWC3::Error presentDisplay( + Display* display, ::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) override; - HWC3::Error onActiveConfigChange(Display* display) override; + HWC3::Error onActiveConfigChange(Display* display) override; - const DrmClient* getDrmPresenter() const override { - if (mDrmClient) { - return &*mDrmClient; + const DrmClient* getDrmPresenter() const override { + if (mDrmClient) { + return &*mDrmClient; + } + return nullptr; } - return nullptr; - } - private: - HWC3::Error createHostComposerDisplayInfo(Display* display, - uint32_t hostDisplayId); + private: + HWC3::Error createHostComposerDisplayInfo(Display* display, uint32_t hostDisplayId); - void post(HostConnection* hostCon, ExtendedRCEncoderContext* rcEnc, - buffer_handle_t h); + void post(HostConnection* hostCon, ExtendedRCEncoderContext* rcEnc, buffer_handle_t h); - bool mIsMinigbm = false; + bool mIsMinigbm = false; - int mSyncDeviceFd = -1; + int mSyncDeviceFd = -1; - struct HostComposerDisplayInfo { - uint32_t hostDisplayId = 0; - std::unique_ptr<DrmSwapchain> swapchain = {}; - // Drm info for the displays client target buffer. - std::shared_ptr<DrmBuffer> clientTargetDrmBuffer; - }; + struct HostComposerDisplayInfo { + uint32_t hostDisplayId = 0; + std::unique_ptr<DrmSwapchain> swapchain = {}; + // Drm info for the displays client target buffer. + std::shared_ptr<DrmBuffer> clientTargetDrmBuffer; + }; - std::unordered_map<int64_t, HostComposerDisplayInfo> mDisplayInfos; + std::unordered_map<int64_t, HostComposerDisplayInfo> mDisplayInfos; - std::optional<DrmClient> mDrmClient; + std::optional<DrmClient> mDrmClient; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/HostUtils.cpp b/system/hwc3/HostUtils.cpp index ea0e8074..21ec83ce 100644 --- a/system/hwc3/HostUtils.cpp +++ b/system/hwc3/HostUtils.cpp @@ -21,12 +21,12 @@ namespace aidl::android::hardware::graphics::composer3::impl { HostConnection* createOrGetHostConnection() { - static std::unique_ptr<HostConnection> sHostCon; + static std::unique_ptr<HostConnection> sHostCon; - if (!sHostCon) { - sHostCon = HostConnection::createUnique(); - } - return sHostCon.get(); + if (!sHostCon) { + sHostCon = HostConnection::createUnique(); + } + return sHostCon.get(); } } // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file diff --git a/system/hwc3/HostUtils.h b/system/hwc3/HostUtils.h index ef023891..95d8b1d4 100644 --- a/system/hwc3/HostUtils.h +++ b/system/hwc3/HostUtils.h @@ -24,36 +24,36 @@ namespace aidl::android::hardware::graphics::composer3::impl { HostConnection* createOrGetHostConnection(); -inline HWC3::Error getAndValidateHostConnection( - HostConnection** ppHostCon, ExtendedRCEncoderContext** ppRcEnc) { - *ppHostCon = nullptr; - *ppRcEnc = nullptr; - - HostConnection* hostCon = createOrGetHostConnection(); - if (!hostCon) { - ALOGE("%s: Failed to get host connection\n", __FUNCTION__); - return HWC3::Error::NoResources; - } - ExtendedRCEncoderContext* rcEnc = hostCon->rcEncoder(); - if (!rcEnc) { - ALOGE("%s: Failed to get renderControl encoder context\n", __FUNCTION__); - return HWC3::Error::NoResources; - } - - *ppHostCon = hostCon; - *ppRcEnc = rcEnc; - return HWC3::Error::None; +inline HWC3::Error getAndValidateHostConnection(HostConnection** ppHostCon, + ExtendedRCEncoderContext** ppRcEnc) { + *ppHostCon = nullptr; + *ppRcEnc = nullptr; + + HostConnection* hostCon = createOrGetHostConnection(); + if (!hostCon) { + ALOGE("%s: Failed to get host connection\n", __FUNCTION__); + return HWC3::Error::NoResources; + } + ExtendedRCEncoderContext* rcEnc = hostCon->rcEncoder(); + if (!rcEnc) { + ALOGE("%s: Failed to get renderControl encoder context\n", __FUNCTION__); + return HWC3::Error::NoResources; + } + + *ppHostCon = hostCon; + *ppRcEnc = rcEnc; + return HWC3::Error::None; } -#define DEFINE_AND_VALIDATE_HOST_CONNECTION \ - HostConnection* hostCon; \ - ExtendedRCEncoderContext* rcEnc; \ - { \ - HWC3::Error res = getAndValidateHostConnection(&hostCon, &rcEnc); \ - if (res != HWC3::Error::None) { \ - return res; \ - } \ - } +#define DEFINE_AND_VALIDATE_HOST_CONNECTION \ + HostConnection* hostCon; \ + ExtendedRCEncoderContext* rcEnc; \ + { \ + HWC3::Error res = getAndValidateHostConnection(&hostCon, &rcEnc); \ + if (res != HWC3::Error::None) { \ + return res; \ + } \ + } } // namespace aidl::android::hardware::graphics::composer3::impl #endif diff --git a/system/hwc3/Layer.cpp b/system/hwc3/Layer.cpp index 6192b42a..7cc1abab 100644 --- a/system/hwc3/Layer.cpp +++ b/system/hwc3/Layer.cpp @@ -32,322 +32,302 @@ std::atomic<int64_t> sNextId{1}; Layer::Layer() : mId(sNextId++) {} HWC3::Error Layer::setCursorPosition(const common::Point& position) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - if (mCompositionType != Composition::CURSOR) { - ALOGE("%s: CompositionType not Cursor type", __FUNCTION__); - return HWC3::Error::BadLayer; - } + if (mCompositionType != Composition::CURSOR) { + ALOGE("%s: CompositionType not Cursor type", __FUNCTION__); + return HWC3::Error::BadLayer; + } - mCursorPosition = position; - return HWC3::Error::None; + mCursorPosition = position; + return HWC3::Error::None; } common::Point Layer::getCursorPosition() const { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return mCursorPosition; + return mCursorPosition; } -HWC3::Error Layer::setBuffer(buffer_handle_t buffer, - const ndk::ScopedFileDescriptor& fence) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); +HWC3::Error Layer::setBuffer(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence) { + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - if (buffer == nullptr) { - ALOGE("%s: missing handle", __FUNCTION__); - return HWC3::Error::BadParameter; - } + if (buffer == nullptr) { + ALOGE("%s: missing handle", __FUNCTION__); + return HWC3::Error::BadParameter; + } - mBuffer.set(buffer, fence); - return HWC3::Error::None; + mBuffer.set(buffer, fence); + return HWC3::Error::None; } FencedBuffer& Layer::getBuffer() { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return mBuffer; + return mBuffer; } buffer_handle_t Layer::waitAndGetBuffer() { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - - ::android::base::unique_fd fence = mBuffer.getFence(); - if (fence.ok()) { - int err = sync_wait(fence.get(), 3000); - if (err < 0 && errno == ETIME) { - ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__, - fence.get()); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + + ::android::base::unique_fd fence = mBuffer.getFence(); + if (fence.ok()) { + int err = sync_wait(fence.get(), 3000); + if (err < 0 && errno == ETIME) { + ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__, fence.get()); + } } - } - return mBuffer.getBuffer(); + return mBuffer.getBuffer(); } -HWC3::Error Layer::setSurfaceDamage( - const std::vector<std::optional<common::Rect>>& /*damage*/) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); +HWC3::Error Layer::setSurfaceDamage(const std::vector<std::optional<common::Rect>>& /*damage*/) { + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Layer::setBlendMode(common::BlendMode blendMode) { - const auto blendModeString = toString(blendMode); - DEBUG_LOG("%s: layer:%" PRId64 " blend mode:%s", __FUNCTION__, mId, - blendModeString.c_str()); + const auto blendModeString = toString(blendMode); + DEBUG_LOG("%s: layer:%" PRId64 " blend mode:%s", __FUNCTION__, mId, blendModeString.c_str()); - mBlendMode = blendMode; - return HWC3::Error::None; + mBlendMode = blendMode; + return HWC3::Error::None; } common::BlendMode Layer::getBlendMode() const { - const auto blendMode = mBlendMode; - const auto blendModeString = toString(blendMode); - DEBUG_LOG("%s: layer:%" PRId64 " blend mode:%s", __FUNCTION__, mId, - blendModeString.c_str()); + const auto blendMode = mBlendMode; + const auto blendModeString = toString(blendMode); + DEBUG_LOG("%s: layer:%" PRId64 " blend mode:%s", __FUNCTION__, mId, blendModeString.c_str()); - return blendMode; + return blendMode; } HWC3::Error Layer::setColor(Color color) { - DEBUG_LOG("%s: layer:%" PRId64 - " color-r:%f color-g:%f color-b:%f color-a:%f)", - __FUNCTION__, mId, color.r, color.g, color.b, color.a); + DEBUG_LOG("%s: layer:%" PRId64 " color-r:%f color-g:%f color-b:%f color-a:%f)", __FUNCTION__, + mId, color.r, color.g, color.b, color.a); - mColor = color; - return HWC3::Error::None; + mColor = color; + return HWC3::Error::None; } Color Layer::getColor() const { - auto color = mColor; - DEBUG_LOG("%s: layer:%" PRId64 - " color-r:%f color-g:%f color-b:%f color-a:%f)", - __FUNCTION__, mId, color.r, color.g, color.b, color.a); + auto color = mColor; + DEBUG_LOG("%s: layer:%" PRId64 " color-r:%f color-g:%f color-b:%f color-a:%f)", __FUNCTION__, + mId, color.r, color.g, color.b, color.a); - return color; + return color; } HWC3::Error Layer::setCompositionType(Composition compositionType) { - const auto compositionTypeString = toString(compositionType); - DEBUG_LOG("%s: layer:%" PRId64 " composition type:%s", __FUNCTION__, mId, - compositionTypeString.c_str()); + const auto compositionTypeString = toString(compositionType); + DEBUG_LOG("%s: layer:%" PRId64 " composition type:%s", __FUNCTION__, mId, + compositionTypeString.c_str()); - mCompositionType = compositionType; - return HWC3::Error::None; + mCompositionType = compositionType; + return HWC3::Error::None; } Composition Layer::getCompositionType() const { - const auto compositionTypeString = toString(mCompositionType); - DEBUG_LOG("%s: layer:%" PRId64 " composition type:%s", __FUNCTION__, mId, - compositionTypeString.c_str()); + const auto compositionTypeString = toString(mCompositionType); + DEBUG_LOG("%s: layer:%" PRId64 " composition type:%s", __FUNCTION__, mId, + compositionTypeString.c_str()); - return mCompositionType; + return mCompositionType; } HWC3::Error Layer::setDataspace(common::Dataspace dataspace) { - const auto dataspaceString = toString(dataspace); - DEBUG_LOG("%s: layer:%" PRId64 " dataspace:%s", __FUNCTION__, mId, - dataspaceString.c_str()); + const auto dataspaceString = toString(dataspace); + DEBUG_LOG("%s: layer:%" PRId64 " dataspace:%s", __FUNCTION__, mId, dataspaceString.c_str()); - mDataspace = dataspace; - return HWC3::Error::None; + mDataspace = dataspace; + return HWC3::Error::None; } common::Dataspace Layer::getDataspace() const { - const auto dataspaceString = toString(mDataspace); - DEBUG_LOG("%s: layer:%" PRId64 " dataspace:%s", __FUNCTION__, mId, - dataspaceString.c_str()); + const auto dataspaceString = toString(mDataspace); + DEBUG_LOG("%s: layer:%" PRId64 " dataspace:%s", __FUNCTION__, mId, dataspaceString.c_str()); - return mDataspace; + return mDataspace; } HWC3::Error Layer::setDisplayFrame(common::Rect frame) { - DEBUG_LOG("%s: layer:%" PRId64 - " display frame rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", - __FUNCTION__, mId, frame.left, frame.top, frame.right, - frame.bottom); + DEBUG_LOG("%s: layer:%" PRId64 + " display frame rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", + __FUNCTION__, mId, frame.left, frame.top, frame.right, frame.bottom); - mDisplayFrame = frame; - return HWC3::Error::None; + mDisplayFrame = frame; + return HWC3::Error::None; } common::Rect Layer::getDisplayFrame() const { - auto frame = mDisplayFrame; - DEBUG_LOG("%s: layer:%" PRId64 - " display frame rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", - __FUNCTION__, mId, frame.left, frame.top, frame.right, - frame.bottom); + auto frame = mDisplayFrame; + DEBUG_LOG("%s: layer:%" PRId64 + " display frame rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", + __FUNCTION__, mId, frame.left, frame.top, frame.right, frame.bottom); - return frame; + return frame; } HWC3::Error Layer::setPlaneAlpha(float alpha) { - DEBUG_LOG("%s: layer:%" PRId64 "alpha:%f", __FUNCTION__, mId, alpha); + DEBUG_LOG("%s: layer:%" PRId64 "alpha:%f", __FUNCTION__, mId, alpha); - mPlaneAlpha = alpha; - return HWC3::Error::None; + mPlaneAlpha = alpha; + return HWC3::Error::None; } float Layer::getPlaneAlpha() const { - auto alpha = mPlaneAlpha; - DEBUG_LOG("%s: layer:%" PRId64 "alpha:%f", __FUNCTION__, mId, alpha); + auto alpha = mPlaneAlpha; + DEBUG_LOG("%s: layer:%" PRId64 "alpha:%f", __FUNCTION__, mId, alpha); - return alpha; + return alpha; } HWC3::Error Layer::setSidebandStream(buffer_handle_t /*stream*/) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Layer::setSourceCrop(common::FRect crop) { - DEBUG_LOG("%s: layer:%" PRId64 - "crop rect-left:%f rect-top:%f rect-right:%f rect-bot:%f", - __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); + DEBUG_LOG("%s: layer:%" PRId64 "crop rect-left:%f rect-top:%f rect-right:%f rect-bot:%f", + __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); - mSourceCrop = crop; - return HWC3::Error::None; + mSourceCrop = crop; + return HWC3::Error::None; } common::FRect Layer::getSourceCrop() const { - common::FRect crop = mSourceCrop; - DEBUG_LOG("%s: layer:%" PRId64 - "crop rect-left:%f rect-top:%f rect-right:%f rect-bot:%f", - __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); + common::FRect crop = mSourceCrop; + DEBUG_LOG("%s: layer:%" PRId64 "crop rect-left:%f rect-top:%f rect-right:%f rect-bot:%f", + __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); - return crop; + return crop; } common::Rect Layer::getSourceCropInt() const { - common::Rect crop = {}; - crop.left = static_cast<int>(mSourceCrop.left); - crop.top = static_cast<int>(mSourceCrop.top); - crop.right = static_cast<int>(mSourceCrop.right); - crop.bottom = static_cast<int>(mSourceCrop.bottom); - DEBUG_LOG("%s: layer:%" PRId64 - "crop rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", - __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); + common::Rect crop = {}; + crop.left = static_cast<int>(mSourceCrop.left); + crop.top = static_cast<int>(mSourceCrop.top); + crop.right = static_cast<int>(mSourceCrop.right); + crop.bottom = static_cast<int>(mSourceCrop.bottom); + DEBUG_LOG("%s: layer:%" PRId64 "crop rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", + __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); - return crop; + return crop; } HWC3::Error Layer::setTransform(common::Transform transform) { - const auto transformString = toString(transform); - DEBUG_LOG("%s: layer:%" PRId64 " transform:%s", __FUNCTION__, mId, - transformString.c_str()); + const auto transformString = toString(transform); + DEBUG_LOG("%s: layer:%" PRId64 " transform:%s", __FUNCTION__, mId, transformString.c_str()); - mTransform = transform; - return HWC3::Error::None; + mTransform = transform; + return HWC3::Error::None; } common::Transform Layer::getTransform() const { - const auto transformString = toString(mTransform); - DEBUG_LOG("%s: layer:%" PRId64 " transform:%s", __FUNCTION__, mId, - transformString.c_str()); + const auto transformString = toString(mTransform); + DEBUG_LOG("%s: layer:%" PRId64 " transform:%s", __FUNCTION__, mId, transformString.c_str()); - return mTransform; + return mTransform; } -HWC3::Error Layer::setVisibleRegion( - const std::vector<std::optional<common::Rect>>& visible) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); +HWC3::Error Layer::setVisibleRegion(const std::vector<std::optional<common::Rect>>& visible) { + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - mVisibleRegion.clear(); - mVisibleRegion.reserve(visible.size()); - for (const auto& rectOption : visible) { - if (rectOption) { - mVisibleRegion.push_back(*rectOption); + mVisibleRegion.clear(); + mVisibleRegion.reserve(visible.size()); + for (const auto& rectOption : visible) { + if (rectOption) { + mVisibleRegion.push_back(*rectOption); + } } - } - return HWC3::Error::None; + return HWC3::Error::None; } std::size_t Layer::getNumVisibleRegions() const { - const std::size_t num = mVisibleRegion.size(); - DEBUG_LOG("%s: layer:%" PRId64 " number of visible regions: %zu", - __FUNCTION__, mId, num); + const std::size_t num = mVisibleRegion.size(); + DEBUG_LOG("%s: layer:%" PRId64 " number of visible regions: %zu", __FUNCTION__, mId, num); - return num; + return num; } HWC3::Error Layer::setZOrder(int32_t z) { - DEBUG_LOG("%s: layer:%" PRId64 " z:%d", __FUNCTION__, mId, z); + DEBUG_LOG("%s: layer:%" PRId64 " z:%d", __FUNCTION__, mId, z); - mZOrder = z; - return HWC3::Error::None; + mZOrder = z; + return HWC3::Error::None; } int32_t Layer::getZOrder() const { - DEBUG_LOG("%s: layer:%" PRId64 " z:%d", __FUNCTION__, mId, mZOrder); + DEBUG_LOG("%s: layer:%" PRId64 " z:%d", __FUNCTION__, mId, mZOrder); - return mZOrder; + return mZOrder; } HWC3::Error Layer::setPerFrameMetadata( const std::vector<std::optional<PerFrameMetadata>>& /*perFrameMetadata*/) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error Layer::setColorTransform(const std::vector<float>& colorTransform) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - if (colorTransform.size() < 16) { - return HWC3::Error::BadParameter; - } + if (colorTransform.size() < 16) { + return HWC3::Error::BadParameter; + } - mColorTransform.emplace(); - std::copy_n(colorTransform.data(), 16, mColorTransform->data()); - return HWC3::Error::None; + mColorTransform.emplace(); + std::copy_n(colorTransform.data(), 16, mColorTransform->data()); + return HWC3::Error::None; } const std::optional<std::array<float, 16>>& Layer::getColorTransform() const { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return mColorTransform; + return mColorTransform; } HWC3::Error Layer::setBrightness(float brightness) { - DEBUG_LOG("%s: layer:%" PRId64 " brightness:%f", __FUNCTION__, mId, - brightness); + DEBUG_LOG("%s: layer:%" PRId64 " brightness:%f", __FUNCTION__, mId, brightness); - if (std::isnan(brightness) || brightness < 0.0f || brightness > 1.0f) { - ALOGE("%s: layer:%" PRId64 " brightness:%f", __FUNCTION__, mId, brightness); - return HWC3::Error::BadParameter; - } + if (std::isnan(brightness) || brightness < 0.0f || brightness > 1.0f) { + ALOGE("%s: layer:%" PRId64 " brightness:%f", __FUNCTION__, mId, brightness); + return HWC3::Error::BadParameter; + } - mBrightness = brightness; - return HWC3::Error::None; + mBrightness = brightness; + return HWC3::Error::None; } float Layer::getBrightness() const { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return mBrightness; + return mBrightness; } HWC3::Error Layer::setPerFrameMetadataBlobs( - const std::vector< - std::optional<PerFrameMetadataBlob>>& /*perFrameMetadata*/) { - DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); + const std::vector<std::optional<PerFrameMetadataBlob>>& /*perFrameMetadata*/) { + DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); - return HWC3::Error::None; + return HWC3::Error::None; } void Layer::logCompositionFallbackIfChanged(Composition to) { - Composition from = getCompositionType(); - if (mLastCompositionFallback && mLastCompositionFallback->from == from && - mLastCompositionFallback->to == to) { - return; - } - ALOGI("%s: layer %" PRIu32 " CompositionType fallback from %d to %d", __FUNCTION__, - static_cast<uint32_t>(getId()), static_cast<int>(from), static_cast<int>(to)); - mLastCompositionFallback = { - .from = from, - .to = to, - }; + Composition from = getCompositionType(); + if (mLastCompositionFallback && mLastCompositionFallback->from == from && + mLastCompositionFallback->to == to) { + return; + } + ALOGI("%s: layer %" PRIu32 " CompositionType fallback from %d to %d", __FUNCTION__, + static_cast<uint32_t>(getId()), static_cast<int>(from), static_cast<int>(to)); + mLastCompositionFallback = { + .from = from, + .to = to, + }; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Layer.h b/system/hwc3/Layer.h index 5bb7f235..05dc5ee2 100644 --- a/system/hwc3/Layer.h +++ b/system/hwc3/Layer.h @@ -26,99 +26,96 @@ namespace aidl::android::hardware::graphics::composer3::impl { class Layer { - public: - explicit Layer(); + public: + explicit Layer(); - Layer(const Layer&) = delete; - Layer& operator=(const Layer&) = delete; + Layer(const Layer&) = delete; + Layer& operator=(const Layer&) = delete; - Layer(Layer&&) = delete; - Layer& operator=(Layer&&) = delete; + Layer(Layer&&) = delete; + Layer& operator=(Layer&&) = delete; - int64_t getId() const { return mId; } + int64_t getId() const { return mId; } - HWC3::Error setCursorPosition(const common::Point& cursorPosition); - common::Point getCursorPosition() const; + HWC3::Error setCursorPosition(const common::Point& cursorPosition); + common::Point getCursorPosition() const; - HWC3::Error setBuffer(buffer_handle_t buffer, - const ndk::ScopedFileDescriptor& fence); - FencedBuffer& getBuffer(); - buffer_handle_t waitAndGetBuffer(); + HWC3::Error setBuffer(buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence); + FencedBuffer& getBuffer(); + buffer_handle_t waitAndGetBuffer(); - HWC3::Error setSurfaceDamage( - const std::vector<std::optional<common::Rect>>& damage); + HWC3::Error setSurfaceDamage(const std::vector<std::optional<common::Rect>>& damage); - HWC3::Error setBlendMode(common::BlendMode mode); - common::BlendMode getBlendMode() const; + HWC3::Error setBlendMode(common::BlendMode mode); + common::BlendMode getBlendMode() const; - HWC3::Error setColor(Color color); - Color getColor() const; + HWC3::Error setColor(Color color); + Color getColor() const; - HWC3::Error setCompositionType(Composition composition); - Composition getCompositionType() const; + HWC3::Error setCompositionType(Composition composition); + Composition getCompositionType() const; - HWC3::Error setDataspace(common::Dataspace dataspace); - common::Dataspace getDataspace() const; + HWC3::Error setDataspace(common::Dataspace dataspace); + common::Dataspace getDataspace() const; - HWC3::Error setDisplayFrame(common::Rect frame); - common::Rect getDisplayFrame() const; + HWC3::Error setDisplayFrame(common::Rect frame); + common::Rect getDisplayFrame() const; - HWC3::Error setPlaneAlpha(float alpha); - float getPlaneAlpha() const; + HWC3::Error setPlaneAlpha(float alpha); + float getPlaneAlpha() const; - HWC3::Error setSidebandStream(buffer_handle_t stream); + HWC3::Error setSidebandStream(buffer_handle_t stream); - HWC3::Error setSourceCrop(common::FRect crop); - common::FRect getSourceCrop() const; - common::Rect getSourceCropInt() const; + HWC3::Error setSourceCrop(common::FRect crop); + common::FRect getSourceCrop() const; + common::Rect getSourceCropInt() const; - HWC3::Error setTransform(common::Transform transform); - common::Transform getTransform() const; + HWC3::Error setTransform(common::Transform transform); + common::Transform getTransform() const; - HWC3::Error setVisibleRegion( - const std::vector<std::optional<common::Rect>>& visible); - std::size_t getNumVisibleRegions() const; + HWC3::Error setVisibleRegion(const std::vector<std::optional<common::Rect>>& visible); + std::size_t getNumVisibleRegions() const; - HWC3::Error setZOrder(int32_t z); - int32_t getZOrder() const; + HWC3::Error setZOrder(int32_t z); + int32_t getZOrder() const; - HWC3::Error setPerFrameMetadata( - const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata); + HWC3::Error setPerFrameMetadata( + const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata); - HWC3::Error setColorTransform(const std::vector<float>& colorTransform); - const std::optional<std::array<float, 16>>& getColorTransform() const; + HWC3::Error setColorTransform(const std::vector<float>& colorTransform); + const std::optional<std::array<float, 16>>& getColorTransform() const; - HWC3::Error setBrightness(float brightness); - float getBrightness() const; + HWC3::Error setBrightness(float brightness); + float getBrightness() const; - HWC3::Error setPerFrameMetadataBlobs( - const std::vector<std::optional<PerFrameMetadataBlob>>& perFrameMetadata); + HWC3::Error setPerFrameMetadataBlobs( + const std::vector<std::optional<PerFrameMetadataBlob>>& perFrameMetadata); - // For log use only. - void logCompositionFallbackIfChanged(Composition to); + // For log use only. + void logCompositionFallbackIfChanged(Composition to); - private: - const int64_t mId; - common::Point mCursorPosition; - FencedBuffer mBuffer; - common::BlendMode mBlendMode = common::BlendMode::NONE; - Color mColor = {0, 0, 0, 0}; - Composition mCompositionType = Composition::INVALID; - common::Dataspace mDataspace = common::Dataspace::UNKNOWN; - struct CompositionTypeFallback { - Composition from; - Composition to; - }; - // For log use only. - std::optional<CompositionTypeFallback> mLastCompositionFallback = std::nullopt; - common::Rect mDisplayFrame = {0, 0, -1, -1}; - float mPlaneAlpha = 0.0f; - common::FRect mSourceCrop = {0.0f, 0.0f, -1.0f, -1.0f}; - common::Transform mTransform = common::Transform{0}; - std::vector<common::Rect> mVisibleRegion; - int32_t mZOrder = 0; - std::optional<std::array<float, 16>> mColorTransform; - float mBrightness = 1.0f; + private: + const int64_t mId; + common::Point mCursorPosition; + FencedBuffer mBuffer; + common::BlendMode mBlendMode = common::BlendMode::NONE; + Color mColor = {0, 0, 0, 0}; + Composition mCompositionType = Composition::INVALID; + common::Dataspace mDataspace = common::Dataspace::UNKNOWN; + struct CompositionTypeFallback { + Composition from; + Composition to; + }; + // For log use only. + std::optional<CompositionTypeFallback> mLastCompositionFallback = std::nullopt; + common::Rect mDisplayFrame = {0, 0, -1, -1}; + float mPlaneAlpha = 0.0f; + common::FRect mSourceCrop = {0.0f, 0.0f, -1.0f, -1.0f}; + common::Transform mTransform = common::Transform{0}; + std::vector<common::Rect> mVisibleRegion; + int32_t mZOrder = 0; + std::optional<std::array<float, 16>> mColorTransform; + float mBrightness = 1.0f; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/LruCache.h b/system/hwc3/LruCache.h index 9ffca46a..f5b8f986 100644 --- a/system/hwc3/LruCache.h +++ b/system/hwc3/LruCache.h @@ -19,10 +19,8 @@ template <typename Key, typename Value> class LruCache { - public: - LruCache(std::size_t maxSize) : m_maxSize(maxSize) { - m_table.reserve(maxSize); - } + public: + LruCache(std::size_t maxSize) : m_maxSize(maxSize) { m_table.reserve(maxSize); } Value* get(const Key& key) { auto tableIt = m_table.find(key); @@ -70,7 +68,7 @@ class LruCache { m_table.clear(); } - private: + private: struct KeyValue { Key key; Value value; diff --git a/system/hwc3/Main.cpp b/system/hwc3/Main.cpp index fbb1206b..811d5f8a 100644 --- a/system/hwc3/Main.cpp +++ b/system/hwc3/Main.cpp @@ -24,29 +24,28 @@ using aidl::android::hardware::graphics::composer3::impl::Composer; int main(int /*argc*/, char** /*argv*/) { - ALOGI("RanchuHWC (HWComposer3/HWC3) starting up..."); - - // same as SF main thread - struct sched_param param = {0}; - param.sched_priority = 2; - if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) { - ALOGE("%s: failed to set priority: %s", __FUNCTION__, strerror(errno)); - } - - auto composer = ndk::SharedRefBase::make<Composer>(); - CHECK(composer != nullptr); - - const std::string instance = - std::string() + Composer::descriptor + "/default"; - binder_status_t status = - AServiceManager_addService(composer->asBinder().get(), instance.c_str()); - CHECK(status == STATUS_OK); - - // Thread pool for system libbinder (via libbinder_ndk) for aidl services - // IComposer and IDisplay - ABinderProcess_setThreadPoolMaxThreadCount(5); - ABinderProcess_startThreadPool(); - ABinderProcess_joinThreadPool(); - - return EXIT_FAILURE; + ALOGI("RanchuHWC (HWComposer3/HWC3) starting up..."); + + // same as SF main thread + struct sched_param param = {0}; + param.sched_priority = 2; + if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) { + ALOGE("%s: failed to set priority: %s", __FUNCTION__, strerror(errno)); + } + + auto composer = ndk::SharedRefBase::make<Composer>(); + CHECK(composer != nullptr); + + const std::string instance = std::string() + Composer::descriptor + "/default"; + binder_status_t status = + AServiceManager_addService(composer->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + // Thread pool for system libbinder (via libbinder_ndk) for aidl services + // IComposer and IDisplay + ABinderProcess_setThreadPoolMaxThreadCount(5); + ABinderProcess_startThreadPool(); + ABinderProcess_joinThreadPool(); + + return EXIT_FAILURE; } diff --git a/system/hwc3/NoOpFrameComposer.cpp b/system/hwc3/NoOpFrameComposer.cpp index e988d465..b665d99b 100644 --- a/system/hwc3/NoOpFrameComposer.cpp +++ b/system/hwc3/NoOpFrameComposer.cpp @@ -23,61 +23,59 @@ namespace aidl::android::hardware::graphics::composer3::impl { HWC3::Error NoOpFrameComposer::init() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error NoOpFrameComposer::registerOnHotplugCallback( - const HotplugCallback&) { - DEBUG_LOG("%s", __FUNCTION__); +HWC3::Error NoOpFrameComposer::registerOnHotplugCallback(const HotplugCallback&) { + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error NoOpFrameComposer::unregisterOnHotplugCallback() { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error NoOpFrameComposer::onDisplayCreate(Display*) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error NoOpFrameComposer::onDisplayDestroy(Display*) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error NoOpFrameComposer::onDisplayClientTargetSet(Display*) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error NoOpFrameComposer::onActiveConfigChange(Display*) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; }; HWC3::Error NoOpFrameComposer::validateDisplay(Display*, DisplayChanges*) { - DEBUG_LOG("%s", __FUNCTION__); + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error NoOpFrameComposer::presentDisplay( Display*, ::android::base::unique_fd*, - std::unordered_map<int64_t, - ::android::base::unique_fd>* /*outLayerFences*/) { - DEBUG_LOG("%s", __FUNCTION__); + std::unordered_map<int64_t, ::android::base::unique_fd>* /*outLayerFences*/) { + DEBUG_LOG("%s", __FUNCTION__); - return HWC3::Error::None; + return HWC3::Error::None; } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/NoOpFrameComposer.h b/system/hwc3/NoOpFrameComposer.h index b773a3e5..a8b2acb5 100644 --- a/system/hwc3/NoOpFrameComposer.h +++ b/system/hwc3/NoOpFrameComposer.h @@ -27,40 +27,38 @@ namespace aidl::android::hardware::graphics::composer3::impl { class NoOpFrameComposer : public FrameComposer { - public: - NoOpFrameComposer() = default; + public: + NoOpFrameComposer() = default; - NoOpFrameComposer(const NoOpFrameComposer&) = delete; - NoOpFrameComposer& operator=(const NoOpFrameComposer&) = delete; + NoOpFrameComposer(const NoOpFrameComposer&) = delete; + NoOpFrameComposer& operator=(const NoOpFrameComposer&) = delete; - NoOpFrameComposer(NoOpFrameComposer&&) = delete; - NoOpFrameComposer& operator=(NoOpFrameComposer&&) = delete; + NoOpFrameComposer(NoOpFrameComposer&&) = delete; + NoOpFrameComposer& operator=(NoOpFrameComposer&&) = delete; - HWC3::Error init() override; + HWC3::Error init() override; - HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; + HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb) override; - HWC3::Error unregisterOnHotplugCallback() override; + HWC3::Error unregisterOnHotplugCallback() override; - HWC3::Error onDisplayCreate(Display*) override; + HWC3::Error onDisplayCreate(Display*) override; - HWC3::Error onDisplayDestroy(Display*) override; + HWC3::Error onDisplayDestroy(Display*) override; - HWC3::Error onDisplayClientTargetSet(Display*) override; + HWC3::Error onDisplayClientTargetSet(Display*) override; - // Determines if this composer can compose the given layers on the given - // display and requests changes for layers that can't not be composed. - HWC3::Error validateDisplay(Display* display, - DisplayChanges* outChanges) override; + // Determines if this composer can compose the given layers on the given + // display and requests changes for layers that can't not be composed. + HWC3::Error validateDisplay(Display* display, DisplayChanges* outChanges) override; - // Performs the actual composition of layers and presents the composed result - // to the display. - HWC3::Error presentDisplay( - Display* display, ::android::base::unique_fd* outDisplayFence, - std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) - override; + // Performs the actual composition of layers and presents the composed result + // to the display. + HWC3::Error presentDisplay( + Display* display, ::android::base::unique_fd* outDisplayFence, + std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) override; - HWC3::Error onActiveConfigChange(Display* /*display*/) override; + HWC3::Error onActiveConfigChange(Display* /*display*/) override; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/Time.h b/system/hwc3/Time.h index f83e400a..f05e965a 100644 --- a/system/hwc3/Time.h +++ b/system/hwc3/Time.h @@ -29,19 +29,15 @@ using Nanoseconds = std::chrono::nanoseconds; using TimePoint = std::chrono::time_point<std::chrono::steady_clock>; -inline TimePoint asTimePoint(int64_t nanos) { - return TimePoint(Nanoseconds(nanos)); -} +inline TimePoint asTimePoint(int64_t nanos) { return TimePoint(Nanoseconds(nanos)); } -inline TimePoint now() { - return asTimePoint(systemTime(SYSTEM_TIME_MONOTONIC)); -} +inline TimePoint now() { return asTimePoint(systemTime(SYSTEM_TIME_MONOTONIC)); } inline int64_t asNanosDuration(Nanoseconds duration) { return duration.count(); } inline int64_t asNanosTimePoint(TimePoint time) { - TimePoint zero(Nanoseconds(0)); - return static_cast<int64_t>(std::chrono::duration_cast<Nanoseconds>(time - zero).count()); + TimePoint zero(Nanoseconds(0)); + return static_cast<int64_t>(std::chrono::duration_cast<Nanoseconds>(time - zero).count()); } constexpr int32_t HertzToPeriodNanos(uint32_t hertz) { return 1000 * 1000 * 1000 / hertz; } diff --git a/system/hwc3/VsyncThread.cpp b/system/hwc3/VsyncThread.cpp index ce695639..3976130b 100644 --- a/system/hwc3/VsyncThread.cpp +++ b/system/hwc3/VsyncThread.cpp @@ -32,154 +32,145 @@ namespace { // * vsyncPeriod=50ns previousVsync=500ns now=510ns => 550ns // * vsyncPeriod=50ns previousVsync=300ns now=510ns => 550ns // * vsyncPeriod=50ns previousVsync=500ns now=550ns => 550ns -TimePoint GetNextVsyncInPhase(Nanoseconds vsyncPeriod, TimePoint previousVsync, - TimePoint now) { - const auto elapsed = Nanoseconds(now - previousVsync); - const auto nextMultiple = (elapsed / vsyncPeriod) + 1; - return previousVsync + (nextMultiple * vsyncPeriod); +TimePoint GetNextVsyncInPhase(Nanoseconds vsyncPeriod, TimePoint previousVsync, TimePoint now) { + const auto elapsed = Nanoseconds(now - previousVsync); + const auto nextMultiple = (elapsed / vsyncPeriod) + 1; + return previousVsync + (nextMultiple * vsyncPeriod); } } // namespace VsyncThread::VsyncThread(int64_t displayId) : mDisplayId(displayId) { - mPreviousVsync = std::chrono::steady_clock::now() - mVsyncPeriod; + mPreviousVsync = std::chrono::steady_clock::now() - mVsyncPeriod; } VsyncThread::~VsyncThread() { stop(); } HWC3::Error VsyncThread::start(int32_t vsyncPeriodNanos) { - DEBUG_LOG("%s for display:%" PRIu64, __FUNCTION__, mDisplayId); + DEBUG_LOG("%s for display:%" PRIu64, __FUNCTION__, mDisplayId); - mVsyncPeriod = Nanoseconds(vsyncPeriodNanos); + mVsyncPeriod = Nanoseconds(vsyncPeriodNanos); - mThread = std::thread([this]() { threadLoop(); }); + mThread = std::thread([this]() { threadLoop(); }); - const std::string name = - "display_" + std::to_string(mDisplayId) + "_vsync_thread"; + const std::string name = "display_" + std::to_string(mDisplayId) + "_vsync_thread"; - int ret = pthread_setname_np(mThread.native_handle(), name.c_str()); - if (ret != 0) { - ALOGE("%s: failed to set Vsync thread name: %s", __FUNCTION__, - strerror(ret)); - } + int ret = pthread_setname_np(mThread.native_handle(), name.c_str()); + if (ret != 0) { + ALOGE("%s: failed to set Vsync thread name: %s", __FUNCTION__, strerror(ret)); + } - struct sched_param param = { - .sched_priority = ANDROID_PRIORITY_DISPLAY, - }; - ret = pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, ¶m); - if (ret != 0) { - ALOGE("%s: failed to set Vsync thread priority: %s", __FUNCTION__, - strerror(ret)); - } + struct sched_param param = { + .sched_priority = ANDROID_PRIORITY_DISPLAY, + }; + ret = pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, ¶m); + if (ret != 0) { + ALOGE("%s: failed to set Vsync thread priority: %s", __FUNCTION__, strerror(ret)); + } - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error VsyncThread::stop() { - mShuttingDown.store(true); - mThread.join(); + mShuttingDown.store(true); + mThread.join(); - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error VsyncThread::setCallbacks( - const std::shared_ptr<IComposerCallback>& callback) { - DEBUG_LOG("%s for display:%" PRIu64, __FUNCTION__, mDisplayId); +HWC3::Error VsyncThread::setCallbacks(const std::shared_ptr<IComposerCallback>& callback) { + DEBUG_LOG("%s for display:%" PRIu64, __FUNCTION__, mDisplayId); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - mCallbacks = callback; + mCallbacks = callback; - return HWC3::Error::None; + return HWC3::Error::None; } HWC3::Error VsyncThread::setVsyncEnabled(bool enabled) { - DEBUG_LOG("%s for display:%" PRIu64 " enabled:%d", __FUNCTION__, mDisplayId, - enabled); + DEBUG_LOG("%s for display:%" PRIu64 " enabled:%d", __FUNCTION__, mDisplayId, enabled); - std::unique_lock<std::mutex> lock(mStateMutex); + std::unique_lock<std::mutex> lock(mStateMutex); - mVsyncEnabled = enabled; + mVsyncEnabled = enabled; - return HWC3::Error::None; + return HWC3::Error::None; } -HWC3::Error VsyncThread::scheduleVsyncUpdate( - int32_t newVsyncPeriod, const VsyncPeriodChangeConstraints& constraints, - VsyncPeriodChangeTimeline* outTimeline) { - DEBUG_LOG("%s for display:%" PRIu64, __FUNCTION__, mDisplayId); +HWC3::Error VsyncThread::scheduleVsyncUpdate(int32_t newVsyncPeriod, + const VsyncPeriodChangeConstraints& constraints, + VsyncPeriodChangeTimeline* outTimeline) { + DEBUG_LOG("%s for display:%" PRIu64, __FUNCTION__, mDisplayId); - PendingUpdate update; - update.period = Nanoseconds(newVsyncPeriod); - update.updateAfter = asTimePoint(constraints.desiredTimeNanos); + PendingUpdate update; + update.period = Nanoseconds(newVsyncPeriod); + update.updateAfter = asTimePoint(constraints.desiredTimeNanos); - std::unique_lock<std::mutex> lock(mStateMutex); - mPendingUpdate.emplace(std::move(update)); + std::unique_lock<std::mutex> lock(mStateMutex); + mPendingUpdate.emplace(std::move(update)); - TimePoint nextVsync = - GetNextVsyncInPhase(mVsyncPeriod, mPreviousVsync, update.updateAfter); + TimePoint nextVsync = GetNextVsyncInPhase(mVsyncPeriod, mPreviousVsync, update.updateAfter); - outTimeline->newVsyncAppliedTimeNanos = asNanosTimePoint(nextVsync); - outTimeline->refreshRequired = false; - outTimeline->refreshTimeNanos = 0; + outTimeline->newVsyncAppliedTimeNanos = asNanosTimePoint(nextVsync); + outTimeline->refreshRequired = false; + outTimeline->refreshTimeNanos = 0; - return HWC3::Error::None; + return HWC3::Error::None; } Nanoseconds VsyncThread::updateVsyncPeriodLocked(TimePoint now) { - if (mPendingUpdate && now > mPendingUpdate->updateAfter) { - mVsyncPeriod = mPendingUpdate->period; - mPendingUpdate.reset(); - } + if (mPendingUpdate && now > mPendingUpdate->updateAfter) { + mVsyncPeriod = mPendingUpdate->period; + mPendingUpdate.reset(); + } - return mVsyncPeriod; + return mVsyncPeriod; } void VsyncThread::threadLoop() { - ALOGI("Vsync thread for display:%" PRId64 " starting", mDisplayId); - - Nanoseconds vsyncPeriod = mVsyncPeriod; - - int vsyncs = 0; - TimePoint previousLog = std::chrono::steady_clock::now(); - - while (!mShuttingDown.load()) { - TimePoint now = std::chrono::steady_clock::now(); - TimePoint nextVsync = GetNextVsyncInPhase(vsyncPeriod, mPreviousVsync, now); - - std::this_thread::sleep_until(nextVsync); - { - std::unique_lock<std::mutex> lock(mStateMutex); - - mPreviousVsync = nextVsync; - - // Display has finished refreshing at previous vsync period. Update the - // vsync period if there was a pending update. - vsyncPeriod = updateVsyncPeriodLocked(mPreviousVsync); - } - - if (mVsyncEnabled) { - if (mCallbacks) { - DEBUG_LOG("%s: for display:%" PRIu64 " calling vsync", __FUNCTION__, - mDisplayId); - mCallbacks->onVsync(mDisplayId, asNanosTimePoint(nextVsync), - static_cast<int32_t>(asNanosDuration(vsyncPeriod))); - } - } - - static constexpr const int kLogIntervalSeconds = 60; - if (now > (previousLog + std::chrono::seconds(kLogIntervalSeconds))) { - DEBUG_LOG("%s: for display:%" PRIu64 " send %" PRIu32 - " in last %d seconds", - __FUNCTION__, mDisplayId, vsyncs, kLogIntervalSeconds); - (void)vsyncs; - previousLog = now; - vsyncs = 0; + ALOGI("Vsync thread for display:%" PRId64 " starting", mDisplayId); + + Nanoseconds vsyncPeriod = mVsyncPeriod; + + int vsyncs = 0; + TimePoint previousLog = std::chrono::steady_clock::now(); + + while (!mShuttingDown.load()) { + TimePoint now = std::chrono::steady_clock::now(); + TimePoint nextVsync = GetNextVsyncInPhase(vsyncPeriod, mPreviousVsync, now); + + std::this_thread::sleep_until(nextVsync); + { + std::unique_lock<std::mutex> lock(mStateMutex); + + mPreviousVsync = nextVsync; + + // Display has finished refreshing at previous vsync period. Update the + // vsync period if there was a pending update. + vsyncPeriod = updateVsyncPeriodLocked(mPreviousVsync); + } + + if (mVsyncEnabled) { + if (mCallbacks) { + DEBUG_LOG("%s: for display:%" PRIu64 " calling vsync", __FUNCTION__, mDisplayId); + mCallbacks->onVsync(mDisplayId, asNanosTimePoint(nextVsync), + static_cast<int32_t>(asNanosDuration(vsyncPeriod))); + } + } + + static constexpr const int kLogIntervalSeconds = 60; + if (now > (previousLog + std::chrono::seconds(kLogIntervalSeconds))) { + DEBUG_LOG("%s: for display:%" PRIu64 " send %" PRIu32 " in last %d seconds", + __FUNCTION__, mDisplayId, vsyncs, kLogIntervalSeconds); + (void)vsyncs; + previousLog = now; + vsyncs = 0; + } + ++vsyncs; } - ++vsyncs; - } - ALOGI("Vsync thread for display:%" PRId64 " finished", mDisplayId); + ALOGI("Vsync thread for display:%" PRId64 " finished", mDisplayId); } } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/VsyncThread.h b/system/hwc3/VsyncThread.h index ffa859fb..0c477632 100644 --- a/system/hwc3/VsyncThread.h +++ b/system/hwc3/VsyncThread.h @@ -32,54 +32,53 @@ namespace aidl::android::hardware::graphics::composer3::impl { // Generates Vsync signals in software. class VsyncThread { - public: - VsyncThread(int64_t id); - virtual ~VsyncThread(); + public: + VsyncThread(int64_t id); + virtual ~VsyncThread(); - VsyncThread(const VsyncThread&) = delete; - VsyncThread& operator=(const VsyncThread&) = delete; + VsyncThread(const VsyncThread&) = delete; + VsyncThread& operator=(const VsyncThread&) = delete; - VsyncThread(VsyncThread&&) = delete; - VsyncThread& operator=(VsyncThread&&) = delete; + VsyncThread(VsyncThread&&) = delete; + VsyncThread& operator=(VsyncThread&&) = delete; - HWC3::Error start(int32_t periodNanos); + HWC3::Error start(int32_t periodNanos); - HWC3::Error setCallbacks(const std::shared_ptr<IComposerCallback>& callback); + HWC3::Error setCallbacks(const std::shared_ptr<IComposerCallback>& callback); - HWC3::Error setVsyncEnabled(bool enabled); + HWC3::Error setVsyncEnabled(bool enabled); - HWC3::Error scheduleVsyncUpdate( - int32_t newVsyncPeriod, - const VsyncPeriodChangeConstraints& newVsyncPeriodChangeConstraints, - VsyncPeriodChangeTimeline* timeline); + HWC3::Error scheduleVsyncUpdate( + int32_t newVsyncPeriod, const VsyncPeriodChangeConstraints& newVsyncPeriodChangeConstraints, + VsyncPeriodChangeTimeline* timeline); - private: - HWC3::Error stop(); + private: + HWC3::Error stop(); - void threadLoop(); + void threadLoop(); - std::chrono::nanoseconds updateVsyncPeriodLocked( - std::chrono::time_point<std::chrono::steady_clock> now); + std::chrono::nanoseconds updateVsyncPeriodLocked( + std::chrono::time_point<std::chrono::steady_clock> now); - const int64_t mDisplayId; + const int64_t mDisplayId; - std::thread mThread; + std::thread mThread; - std::mutex mStateMutex; + std::mutex mStateMutex; - std::atomic<bool> mShuttingDown{false}; + std::atomic<bool> mShuttingDown{false}; - std::shared_ptr<IComposerCallback> mCallbacks; + std::shared_ptr<IComposerCallback> mCallbacks; - bool mVsyncEnabled = false; - std::chrono::nanoseconds mVsyncPeriod; - std::chrono::time_point<std::chrono::steady_clock> mPreviousVsync; + bool mVsyncEnabled = false; + std::chrono::nanoseconds mVsyncPeriod; + std::chrono::time_point<std::chrono::steady_clock> mPreviousVsync; - struct PendingUpdate { - std::chrono::nanoseconds period; - std::chrono::time_point<std::chrono::steady_clock> updateAfter; - }; - std::optional<PendingUpdate> mPendingUpdate; + struct PendingUpdate { + std::chrono::nanoseconds period; + std::chrono::time_point<std::chrono::steady_clock> updateAfter; + }; + std::optional<PendingUpdate> mPendingUpdate; }; } // namespace aidl::android::hardware::graphics::composer3::impl |