SF: Remember display type in DisplayData

This obviates querying the HWC to determine if a display is physical or
virtual.

Bug: 74619554
Test: libsurfaceflinger_unittest
Change-Id: I9a18d480358f4195c66c183c70ffbe8480bd25b8
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index ebae006..90a64f1 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -54,6 +54,9 @@
 #include "../Layer.h"           // needed only for debugging
 #include "../SurfaceFlinger.h"
 
+#define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
+    ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
+
 #define LOG_DISPLAY_ERROR(displayId, msg) \
     ALOGE("%s failed for display %d: %s", __FUNCTION__, displayId, msg)
 
@@ -172,32 +175,22 @@
     return displayId;
 }
 
-bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp, int32_t* outDisplay) {
-    auto display = mHwcDevice->getDisplayById(hwcDisplayId);
-    if (!display) {
-        ALOGE("%s: Failed to find display %" PRIu64, __FUNCTION__, hwcDisplayId);
-        return false;
-    }
-    auto displayType = HWC2::DisplayType::Invalid;
-    auto error = display->getType(&displayType);
-    if (error != HWC2::Error::None) {
-        ALOGE("%s: Failed to determine type of display %" PRIu64, __FUNCTION__, display->getId());
+bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp, int32_t* outDisplayId) {
+    const auto it = mHwcDisplaySlots.find(hwcDisplayId);
+    if (it == mHwcDisplaySlots.end()) {
+        LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid display");
         return false;
     }
 
-    if (displayType == HWC2::DisplayType::Virtual) {
-        ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
-                display->getId());
+    const int32_t displayId = it->second;
+    RETURN_IF_INVALID_DISPLAY(displayId, false);
+
+    const auto& displayData = mDisplayData[displayId];
+    if (displayData.isVirtual) {
+        LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
         return false;
     }
 
-    if (mHwcDisplaySlots.count(display->getId()) == 0) {
-        ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
-                display->getId());
-        return false;
-    }
-
-    int32_t disp = mHwcDisplaySlots[display->getId()];
     {
         Mutex::Autolock _l(mLock);
 
@@ -205,22 +198,22 @@
         // with the same timestamp when turning the display off and on. This
         // is a bug in the HWC implementation, but filter the extra events
         // out here so they don't cause havoc downstream.
-        if (timestamp == mLastHwVSync[disp]) {
+        if (timestamp == mLastHwVSync[displayId]) {
             ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
                     timestamp);
             return false;
         }
 
-        mLastHwVSync[disp] = timestamp;
+        mLastHwVSync[displayId] = timestamp;
     }
 
-    if (outDisplay) {
-        *outDisplay = disp;
+    if (outDisplayId) {
+        *outDisplayId = displayId;
     }
 
     char tag[16];
-    snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
-    ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
+    snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", displayId);
+    ATRACE_INT(tag, ++mVSyncCounts[displayId] & 1);
 
     return true;
 }
@@ -262,7 +255,9 @@
         return NO_MEMORY;
     }
 
-    mDisplayData[displaySlot].hwcDisplay = display;
+    auto& displayData = mDisplayData[displaySlot];
+    displayData.hwcDisplay = display;
+    displayData.isVirtual = true;
 
     --mRemainingHwcVirtualDisplays;
     *outId = static_cast<int32_t>(displaySlot);
@@ -385,19 +380,19 @@
 
 
 void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
-    if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
-        ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
+    RETURN_IF_INVALID_DISPLAY(displayId);
+    auto& displayData = mDisplayData[displayId];
+
+    if (displayData.isVirtual) {
+        LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
         return;
     }
 
-    RETURN_IF_INVALID_DISPLAY(displayId);
-
     // NOTE: we use our own internal lock here because we have to call
     // into the HWC with the lock held, and we want to make sure
     // that even if HWC blocks (which it shouldn't), it won't
     // affect other threads.
     Mutex::Autolock _l(mVsyncLock);
-    auto& displayData = mDisplayData[displayId];
     if (enabled != displayData.vsyncEnabled) {
         ATRACE_CALL();
         auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
@@ -621,7 +616,8 @@
     ALOGV("setPowerMode(%d, %d)", displayId, intMode);
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
-    if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
+    const auto& displayData = mDisplayData[displayId];
+    if (displayData.isVirtual) {
         LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
         return INVALID_OPERATION;
     }
@@ -631,7 +627,7 @@
         setVsyncEnabled(displayId, HWC2::Vsync::Disable);
     }
 
-    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
+    auto& hwcDisplay = displayData.hwcDisplay;
     switch (mode) {
         case HWC2::PowerMode::Off:
         case HWC2::PowerMode::On:
@@ -700,17 +696,13 @@
     return NO_ERROR;
 }
 
-void HWComposer::disconnectDisplay(int displayId) {
-    LOG_ALWAYS_FATAL_IF(displayId < 0);
+void HWComposer::disconnectDisplay(int32_t displayId) {
+    RETURN_IF_INVALID_DISPLAY(displayId);
     auto& displayData = mDisplayData[displayId];
 
-    auto displayType = HWC2::DisplayType::Invalid;
-    auto error = displayData.hwcDisplay->getType(&displayType);
-    RETURN_IF_HWC_ERROR_FOR("getType", error, displayId);
-
     // If this was a virtual display, add its slot back for reuse by future
     // virtual displays
-    if (displayType == HWC2::DisplayType::Virtual) {
+    if (displayData.isVirtual) {
         mFreeDisplaySlots.insert(displayId);
         ++mRemainingHwcVirtualDisplays;
     }
@@ -725,18 +717,14 @@
 status_t HWComposer::setOutputBuffer(int32_t displayId,
         const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+    const auto& displayData = mDisplayData[displayId];
 
-    auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
-    auto displayType = HWC2::DisplayType::Invalid;
-    auto error = hwcDisplay->getType(&displayType);
-    RETURN_IF_HWC_ERROR_FOR("getType", error, displayId, NAME_NOT_FOUND);
-
-    if (displayType != HWC2::DisplayType::Virtual) {
+    if (!displayData.isVirtual) {
         LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
         return INVALID_OPERATION;
     }
 
-    error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
+    auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
     return NO_ERROR;
 }