diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp index 8ca0eb3351..862dff138e 100644 --- a/graphics/composer/2.1/default/Hwc.cpp +++ b/graphics/composer/2.1/default/Hwc.cpp @@ -18,6 +18,7 @@ #include "Hwc.h" +#include #include #include @@ -25,6 +26,8 @@ #include "hardware/hwcomposer.h" #include "hwc2on1adapter/HWC2On1Adapter.h" +using namespace std::chrono_literals; + namespace android { namespace hardware { namespace graphics { @@ -218,7 +221,24 @@ Return HwcHal::createClient(createClient_cb hidl_cb) sp client; { - std::lock_guard lock(mClientMutex); + std::unique_lock lock(mClientMutex); + + if (mClient != nullptr) { + // 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. + ALOGI("HwcHal::createClient: Client already exists. Waiting for" + " it to be destroyed."); + mClientDestroyedWait.wait_for(lock, 1s, + [this] { return mClient == nullptr; }); + std::string doneMsg = mClient == nullptr ? + "Existing client was destroyed." : + "Existing client was never destroyed!"; + ALOGI("HwcHal::createClient: Done waiting. %s", doneMsg.c_str()); + } // only one client is allowed if (mClient == nullptr) { @@ -245,6 +265,7 @@ void HwcHal::removeClient() { std::lock_guard lock(mClientMutex); mClient = nullptr; + mClientDestroyedWait.notify_all(); } void HwcHal::hotplugHook(hwc2_callback_data_t callbackData, diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h index b45389ad82..756132759c 100644 --- a/graphics/composer/2.1/default/Hwc.h +++ b/graphics/composer/2.1/default/Hwc.h @@ -17,8 +17,9 @@ #ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H #define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H -#include +#include #include +#include #include #include @@ -211,6 +212,7 @@ private: } mDispatch; std::mutex mClientMutex; + std::condition_variable mClientDestroyedWait; wp mClient; // If the HWC implementation version is < 2.0, use an adapter to interface