SF: Store and manage snapshots for virtual displays
Create/destroy VirtualDisplaySnapshot that tracks the virtual display's
lifetime.
For now, VirtualDisplaySnapshots will track a virtual display's
DisplayId and whether or not it's backed by Hal/Gpu. This will be
helpful when moving the cast system of DisplayIds from within
DisplayId.h to SurfaceFlinger.
Bug: 374163881
Flag: EXEMPT refactor
Test: libsurfaceflinger_unittest
Change-Id: Id730e65b24ecd10925282bd72585ac7c5635a4fe
diff --git a/services/surfaceflinger/Display/VirtualDisplaySnapshot.h b/services/surfaceflinger/Display/VirtualDisplaySnapshot.h
new file mode 100644
index 0000000..c68020c
--- /dev/null
+++ b/services/surfaceflinger/Display/VirtualDisplaySnapshot.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <optional>
+#include <string>
+
+#include <ui/DisplayId.h>
+
+#include "Utils/Dumper.h"
+
+namespace android::display {
+
+// Immutable state of a virtual display, captured on creation.
+class VirtualDisplaySnapshot {
+public:
+ VirtualDisplaySnapshot(GpuVirtualDisplayId gpuId, std::string uniqueId)
+ : mIsGpu(true), mUniqueId(std::move(uniqueId)), mVirtualId(gpuId) {}
+ VirtualDisplaySnapshot(HalVirtualDisplayId halId, std::string uniqueId)
+ : mIsGpu(false), mUniqueId(std::move(uniqueId)), mVirtualId(halId) {}
+
+ VirtualDisplayId displayId() const { return mVirtualId; }
+ bool isGpu() const { return mIsGpu; }
+
+ void dump(utils::Dumper& dumper) const {
+ using namespace std::string_view_literals;
+
+ dumper.dump("isGpu"sv, mIsGpu ? "true"sv : "false"sv);
+ dumper.dump("uniqueId"sv, mUniqueId);
+ }
+
+private:
+ const bool mIsGpu;
+ const std::string mUniqueId;
+ const VirtualDisplayId mVirtualId;
+};
+
+} // namespace android::display
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 37b35f2..8247682 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -647,11 +647,12 @@
}
}
-VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution,
- ui::PixelFormat format) {
+VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui::PixelFormat format,
+ const std::string& uniqueId) {
if (auto& generator = mVirtualDisplayIdGenerators.hal) {
if (const auto id = generator->generateId()) {
if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) {
+ acquireVirtualDisplaySnapshot(*id, uniqueId);
return *id;
}
@@ -665,6 +666,7 @@
const auto id = mVirtualDisplayIdGenerators.gpu.generateId();
LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display");
+ acquireVirtualDisplaySnapshot(*id, uniqueId);
return *id;
}
@@ -672,6 +674,7 @@
if (const auto id = HalVirtualDisplayId::tryCast(displayId)) {
if (auto& generator = mVirtualDisplayIdGenerators.hal) {
generator->releaseId(*id);
+ releaseVirtualDisplaySnapshot(*id);
}
return;
}
@@ -679,6 +682,14 @@
const auto id = GpuVirtualDisplayId::tryCast(displayId);
LOG_ALWAYS_FATAL_IF(!id);
mVirtualDisplayIdGenerators.gpu.releaseId(*id);
+ releaseVirtualDisplaySnapshot(*id);
+}
+
+void SurfaceFlinger::releaseVirtualDisplaySnapshot(VirtualDisplayId displayId) {
+ std::lock_guard lock(mVirtualDisplaysMutex);
+ if (!mVirtualDisplays.erase(displayId)) {
+ ALOGW("%s: Virtual display snapshot was not removed", __func__);
+ }
}
std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
@@ -3730,7 +3741,7 @@
if (const auto& physical = state.physical) {
builder.setId(physical->id);
} else {
- builder.setId(acquireVirtualDisplay(resolution, pixelFormat));
+ builder.setId(acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId));
}
builder.setPixels(resolution);
@@ -5717,6 +5728,14 @@
utils::Dumper::Section section(dumper,
ftl::Concat("Virtual Display ", displayId.value).str());
display->dump(dumper);
+
+ if (const auto virtualIdOpt = VirtualDisplayId::tryCast(displayId)) {
+ std::lock_guard lock(mVirtualDisplaysMutex);
+ const auto virtualSnapshotIt = mVirtualDisplays.find(virtualIdOpt.value());
+ if (virtualSnapshotIt != mVirtualDisplays.end()) {
+ virtualSnapshotIt->second.dump(dumper);
+ }
+ }
}
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 7e9d5b8..cbd47bc 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -69,6 +69,7 @@
#include <common/FlagManager.h>
#include "Display/DisplayModeController.h"
#include "Display/PhysicalDisplay.h"
+#include "Display/VirtualDisplaySnapshot.h"
#include "DisplayDevice.h"
#include "DisplayHardware/HWC2.h"
#include "DisplayIdGenerator.h"
@@ -1067,8 +1068,20 @@
void enableHalVirtualDisplays(bool);
// Virtual display lifecycle for ID generation and HAL allocation.
- VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat) REQUIRES(mStateLock);
+ VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, const std::string& uniqueId)
+ REQUIRES(mStateLock);
+ template <typename ID>
+ void acquireVirtualDisplaySnapshot(ID displayId, const std::string& uniqueId) {
+ std::lock_guard lock(mVirtualDisplaysMutex);
+ const bool emplace_success =
+ mVirtualDisplays.try_emplace(displayId, displayId, uniqueId).second;
+ if (!emplace_success) {
+ ALOGW("%s: Virtual display snapshot with the same ID already exists", __func__);
+ }
+ }
+
void releaseVirtualDisplay(VirtualDisplayId);
+ void releaseVirtualDisplaySnapshot(VirtualDisplayId displayId);
// Returns a display other than `mActiveDisplayId` that can be activated, if any.
sp<DisplayDevice> getActivatableDisplay() const REQUIRES(mStateLock, kMainThreadContext);
@@ -1269,6 +1282,10 @@
display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock);
+ mutable std::mutex mVirtualDisplaysMutex;
+ ftl::SmallMap<VirtualDisplayId, const display::VirtualDisplaySnapshot, 2> mVirtualDisplays
+ GUARDED_BY(mVirtualDisplaysMutex);
+
// The inner or outer display for foldables, while unfolded or folded, respectively.
std::atomic<PhysicalDisplayId> mActiveDisplayId;