Loading services/surfaceflinger/Display/VirtualDisplaySnapshot.h 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * 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 services/surfaceflinger/SurfaceFlinger.cpp +22 −3 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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 { Loading Loading @@ -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); Loading Loading @@ -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); } } } } } Loading services/surfaceflinger/SurfaceFlinger.h +18 −1 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading
services/surfaceflinger/Display/VirtualDisplaySnapshot.h 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * 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
services/surfaceflinger/SurfaceFlinger.cpp +22 −3 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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 { Loading Loading @@ -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); Loading Loading @@ -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); } } } } } Loading
services/surfaceflinger/SurfaceFlinger.h +18 −1 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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); Loading Loading @@ -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; Loading