diff options
author | 2024-12-02 05:46:25 +0000 | |
---|---|---|
committer | 2024-12-02 05:46:25 +0000 | |
commit | 8a3f409623e965f466a7153974766366201c6431 (patch) | |
tree | 421ec13381bf49210058d8fe8ab18c983171722b | |
parent | c6bc5f54f22592c5e9540e7a4ab4161d1e8fb3c3 (diff) | |
parent | 5d66042a2377f5e350fd825063d7d166f6baff4c (diff) |
Merge "SF: Store and manage snapshots for virtual displays" into main
-rw-r--r-- | services/surfaceflinger/Display/VirtualDisplaySnapshot.h | 52 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 25 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 19 |
3 files changed, 92 insertions, 4 deletions
diff --git a/services/surfaceflinger/Display/VirtualDisplaySnapshot.h b/services/surfaceflinger/Display/VirtualDisplaySnapshot.h new file mode 100644 index 0000000000..c68020ce51 --- /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 97c86232f2..4b36edc696 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -649,11 +649,12 @@ void SurfaceFlinger::enableHalVirtualDisplays(bool enable) { } } -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; } @@ -667,6 +668,7 @@ VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, const auto id = mVirtualDisplayIdGenerators.gpu.generateId(); LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display"); + acquireVirtualDisplaySnapshot(*id, uniqueId); return *id; } @@ -674,6 +676,7 @@ void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayId displayId) { if (const auto id = HalVirtualDisplayId::tryCast(displayId)) { if (auto& generator = mVirtualDisplayIdGenerators.hal) { generator->releaseId(*id); + releaseVirtualDisplaySnapshot(*id); } return; } @@ -681,6 +684,14 @@ void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayId displayId) { 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 { @@ -3798,7 +3809,7 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, 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); @@ -5785,6 +5796,14 @@ void SurfaceFlinger::dumpDisplays(std::string& result) const { 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 211f37478a..b20a894dd7 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -73,6 +73,7 @@ #include "BackgroundExecutor.h" #include "Display/DisplayModeController.h" #include "Display/PhysicalDisplay.h" +#include "Display/VirtualDisplaySnapshot.h" #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" #include "DisplayIdGenerator.h" @@ -1075,8 +1076,20 @@ private: 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); @@ -1277,6 +1290,10 @@ private: 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; |