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

Commit 1394860b authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Extract virtual display allocation from CE

Allocate HAL virtual display and generate HAL/GPU virtual display ID in
SF rather than CE. This centralizes the HAL vs. GPU decision as a first
step in isolating display configuration (e.g. hotplug, modeset) to be a
distinct stage from invalidate/refresh.

Rework SF backend hooks for screen capture. Plumb the PhysicalDisplayId
to be mirrored by the virtual display to Composer::createVirtualDisplay.
This enables the ARC backend to know which display to mirror (instead of
making assumptions about the layer stack) or error out if not mirroring
(previously done through maybeAllocateDisplayIdForVirtualDisplay), such
that SF falls back to creating a GPU virtual display.

Bug: 182939859
Bug: 129481165
Test: Enable overlay display and toggle HAL/GPU
Test: libsurfaceflinger_unittest
Test: libcompositionengine_test
Change-Id: I209b245966e544d5ff55d5d118140cfcfa85db15
Merged-In: I209b245966e544d5ff55d5d118140cfcfa85db15
parent b9ac3e11
Loading
Loading
Loading
Loading
+9 −36
Original line number Diff line number Diff line
@@ -21,13 +21,10 @@
#include <string>

#include <ui/DisplayId.h>
#include <ui/PixelFormat.h>
#include <ui/Size.h>
#include <ui/StaticDisplayInfo.h>

#include "DisplayHardware/DisplayIdentification.h"
#include "DisplayHardware/PowerAdvisor.h"
#include "DisplayIdGenerator.h"

namespace android::compositionengine {

@@ -37,24 +34,14 @@ class CompositionEngine;
 * A parameter object for creating Display instances
 */
struct DisplayCreationArgs {
    struct Physical {
    DisplayId id;
        ui::DisplayConnectionType type;
    };

    // Required for physical displays. Gives the HWC display id for the existing
    // display along with the connection type.
    std::optional<Physical> physical;
    // Unset for virtual displays
    std::optional<ui::DisplayConnectionType> connectionType;

    // Size of the display in pixels
    ui::Size pixels = ui::Size::INVALID;

    // Pixel format of the display
    ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);

    // True if virtual displays should be created with the HWC API if possible
    bool useHwcVirtualDisplays = false;

    // True if this display should be considered secure
    bool isSecure = false;

@@ -67,9 +54,6 @@ struct DisplayCreationArgs {

    // Debugging. Human readable name for the display.
    std::string name;

    // Generator for IDs of virtual displays, which are backed by the GPU.
    DisplayIdGenerator<GpuVirtualDisplayId>* gpuVirtualDisplayIdGenerator;
};

/**
@@ -80,29 +64,18 @@ class DisplayCreationArgsBuilder {
public:
    DisplayCreationArgs build() { return std::move(mArgs); }

    DisplayCreationArgsBuilder& setPhysical(DisplayCreationArgs::Physical physical) {
        mArgs.physical = physical;
        return *this;
    }

    DisplayCreationArgsBuilder& setPixels(ui::Size pixels) {
        mArgs.pixels = pixels;
    DisplayCreationArgsBuilder& setId(DisplayId id) {
        mArgs.id = id;
        return *this;
    }

    DisplayCreationArgsBuilder& setPixelFormat(ui::PixelFormat pixelFormat) {
        mArgs.pixelFormat = pixelFormat;
    DisplayCreationArgsBuilder& setConnectionType(ui::DisplayConnectionType connectionType) {
        mArgs.connectionType = connectionType;
        return *this;
    }

    DisplayCreationArgsBuilder& setUseHwcVirtualDisplays(bool useHwcVirtualDisplays) {
        mArgs.useHwcVirtualDisplays = useHwcVirtualDisplays;
        return *this;
    }

    DisplayCreationArgsBuilder& setGpuVirtualDisplayIdGenerator(
            DisplayIdGenerator<GpuVirtualDisplayId>& generator) {
        mArgs.gpuVirtualDisplayIdGenerator = &generator;
    DisplayCreationArgsBuilder& setPixels(ui::Size pixels) {
        mArgs.pixels = pixels;
        return *this;
    }

+0 −6
Original line number Diff line number Diff line
@@ -80,19 +80,13 @@ public:

    // Internal
    virtual void setConfiguration(const compositionengine::DisplayCreationArgs&);
    virtual std::optional<DisplayId> maybeAllocateDisplayIdForVirtualDisplay(ui::Size,
                                                                             ui::PixelFormat) const;
    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;

    // Testing
    void setDisplayIdForTesting(DisplayId displayId);

private:
    bool mIsVirtual = false;
    bool mIsDisconnected = false;
    DisplayId mId;
    Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
    DisplayIdGenerator<GpuVirtualDisplayId>* mGpuVirtualDisplayIdGenerator;
};

// This template factory function standardizes the implementation details of the
+6 −35
Original line number Diff line number Diff line
@@ -50,36 +50,14 @@ std::shared_ptr<Display> createDisplay(
Display::~Display() = default;

void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
    mIsVirtual = !args.physical;
    mId = args.id;
    mIsVirtual = !args.connectionType;
    mPowerAdvisor = args.powerAdvisor;
    editState().isSecure = args.isSecure;
    editState().displaySpace.bounds = Rect(args.pixels);
    setLayerStackFilter(args.layerStackId,
                        args.physical &&
                                args.physical->type == ui::DisplayConnectionType::Internal);
                        args.connectionType == ui::DisplayConnectionType::Internal);
    setName(args.name);
    mGpuVirtualDisplayIdGenerator = args.gpuVirtualDisplayIdGenerator;

    if (args.physical) {
        mId = args.physical->id;
    } else {
        std::optional<DisplayId> id;
        if (args.useHwcVirtualDisplays) {
            id = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
        }
        if (!id) {
            id = mGpuVirtualDisplayIdGenerator->nextId();
        }
        LOG_ALWAYS_FATAL_IF(!id, "Failed to generate display ID");
        mId = *id;
    }
}

std::optional<DisplayId> Display::maybeAllocateDisplayIdForVirtualDisplay(
        ui::Size pixels, ui::PixelFormat pixelFormat) const {
    auto& hwc = getCompositionEngine().getHwComposer();
    return hwc.allocateVirtualDisplay(static_cast<uint32_t>(pixels.width),
                                      static_cast<uint32_t>(pixels.height), &pixelFormat);
}

bool Display::isValid() const {
@@ -102,23 +80,16 @@ std::optional<DisplayId> Display::getDisplayId() const {
    return mId;
}

void Display::setDisplayIdForTesting(DisplayId displayId) {
    mId = displayId;
}

void Display::disconnect() {
    if (mIsDisconnected) {
        return;
    }

    mIsDisconnected = true;
    if (const auto id = GpuVirtualDisplayId::tryCast(mId)) {
        mGpuVirtualDisplayIdGenerator->markUnused(*id);
        return;

    if (const auto id = HalDisplayId::tryCast(mId)) {
        getCompositionEngine().getHwComposer().disconnectDisplay(*id);
    }
    const auto halDisplayId = HalDisplayId::tryCast(mId);
    LOG_FATAL_IF(!halDisplayId);
    getCompositionEngine().getHwComposer().disconnectDisplay(*halDisplayId);
}

void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
+112 −166

File changed.

Preview size limit exceeded, changes collapsed.

+5 −2
Original line number Diff line number Diff line
@@ -45,8 +45,11 @@ public:
    MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability));
    MOCK_CONST_METHOD2(hasDisplayCapability, bool(HalDisplayId, hal::DisplayCapability));

    MOCK_METHOD3(allocateVirtualDisplay,
                 std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
    MOCK_CONST_METHOD0(getMaxVirtualDisplayCount, size_t());
    MOCK_CONST_METHOD0(getMaxVirtualDisplayDimension, size_t());
    MOCK_METHOD4(allocateVirtualDisplay,
                 bool(HalVirtualDisplayId, ui::Size, ui::PixelFormat*,
                      std::optional<PhysicalDisplayId>));
    MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
    MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId));
    MOCK_METHOD4(getDeviceCompositionChanges,
Loading