Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a3f4096 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Store and manage snapshots for virtual displays" into main

parents c6bc5f54 5d66042a
Loading
Loading
Loading
Loading
+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
+22 −3
Original line number Diff line number Diff line
@@ -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);
                }
            }
        }
    }
}
+18 −1
Original line number Diff line number Diff line
@@ -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;