QCamera2: HAL3: Support concurrent camera with Easel
We shouldn't call multiple suspend()/resume() when running cameras
concurrently. Instead, we should call suspend() after last camera
is closed, and call resume() before first camera is opened.
Test: testDualCameraPreview CTS
Bug: 35960155
Merged-In: Ibdbea409c9f499f747d5a5aeb3d9c7f4b4fdb159
Change-Id: Ibdbea409c9f499f747d5a5aeb3d9c7f4b4fdb159
(cherry picked from commit 121f8315e21a00e964248a58c8f4b861613b7c22)
diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
index 85d14b7..1a84f62 100644
--- a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
@@ -147,6 +147,7 @@
// The following Easel related variables must be protected by gHdrPlusClientLock.
std::unique_ptr<EaselManagerClient> gEaselManagerClient;
bool EaselManagerClientOpened = false; // If gEaselManagerClient is opened.
+int32_t gActiveEaselClient = 0; // The number of active cameras on Easel.
std::unique_ptr<HdrPlusClient> gHdrPlusClient = nullptr;
bool gHdrPlusClientOpening = false; // If HDR+ client is being opened.
std::condition_variable gHdrPlusClientOpenCond; // Used to synchronize HDR+ client opening.
@@ -909,12 +910,16 @@
std::unique_lock<std::mutex> l(gHdrPlusClientLock);
if (gEaselManagerClient != nullptr && gEaselManagerClient->isEaselPresentOnDevice()) {
logEaselEvent("EASEL_STARTUP_LATENCY", "Resume");
- rc = gEaselManagerClient->resume(this);
- if (rc != 0) {
- ALOGE("%s: Resuming Easel failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
- return rc;
+ if (gActiveEaselClient == 0) {
+ rc = gEaselManagerClient->resume(this);
+ if (rc != 0) {
+ ALOGE("%s: Resuming Easel failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
+ return rc;
+ }
+ mEaselFwUpdated = false;
}
- mEaselFwUpdated = false;
+
+ gActiveEaselClient++;
mQCamera3HdrPlusListenerThread = new QCamera3HdrPlusListenerThread(this);
rc = mQCamera3HdrPlusListenerThread->run("QCamera3HdrPlusListenerThread");
@@ -936,11 +941,14 @@
{
std::unique_lock<std::mutex> l(gHdrPlusClientLock);
if (gEaselManagerClient != nullptr && gEaselManagerClient->isEaselPresentOnDevice()) {
- status_t suspendErr = gEaselManagerClient->suspend();
- if (suspendErr != 0) {
- ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__,
- strerror(-suspendErr), suspendErr);
+ if (gActiveEaselClient == 1) {
+ status_t suspendErr = gEaselManagerClient->suspend();
+ if (suspendErr != 0) {
+ ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__,
+ strerror(-suspendErr), suspendErr);
+ }
}
+ gActiveEaselClient--;
}
mQCamera3HdrPlusListenerThread->requestExit();
@@ -1136,10 +1144,13 @@
{
std::unique_lock<std::mutex> l(gHdrPlusClientLock);
if (EaselManagerClientOpened) {
- rc = gEaselManagerClient->suspend();
- if (rc != 0) {
- ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
+ if (gActiveEaselClient == 1) {
+ rc = gEaselManagerClient->suspend();
+ if (rc != 0) {
+ ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
+ }
}
+ gActiveEaselClient--;
}
mQCamera3HdrPlusListenerThread->requestExit();