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;
}