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

Commit 075d3170 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Generalize display management

This CL enables SF to manage an arbitrary number of physical displays.
Previously, displays were identified by 32-bit IDs, where 0 is the
internal display, 1 is the external display, [2, INT32_MAX] are HWC
virtual displays, and -1 represents an invalid display or a non-HWC
virtual display.

If the HWC provides display identification data, SF now allocates 64-bit
display IDs for physical and HWC virtual displays. The IDs are expressed
using an option type, where the null value represents an invalid display
or non-HWC virtual display. Without HWC support, SF falls back to legacy
behavior with at most two physical displays.

The dynamic display IDs are translated to the legacy constants at the
SF/DMS boundary, as a stopgap until the framework is generalized.

Bug: 74619554
Test: Connect 3 displays and create virtual displays on HWC 2.2 and 2.3
Test: libsurfaceflinger_unittest
Test: SurfaceFlinger_test
Change-Id: I0a4a57b6ab7de2dbcf719a4eb1a19a133694012e
parent b04f98a2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ message VSyncEvent {
message DisplayCreation {
    required int32     id                = 1;
    required string    name              = 2;
    required int32     type              = 3;
    optional uint64    display_id        = 3;
    required bool      is_secure         = 4;
}

+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ def surface_delete(increment):
def display_create(increment):
    increment.display_creation.id = int(input("Enter id: "))
    increment.display_creation.name = str(raw_input("Enter name: "))
    increment.display_creation.type = int(input("Enter type: "))
    increment.display_creation.display_id = int(input("Enter display ID: "))
    increment.display_creation.is_secure = bool(input("Enter if secure: "))

def display_delete(increment):
+12 −14
Original line number Diff line number Diff line
@@ -229,15 +229,14 @@ bool BufferLayer::isHdrY410() const {
            getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
}

void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& display) {
void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
                                  const Rect& viewport, int32_t supportedPerFrameMetadata) {
    // Apply this display's projection's viewport to the visible region
    // before giving it to the HWC HAL.
    const ui::Transform& tr = display->getTransform();
    const auto& viewport = display->getViewport();
    Region visible = tr.transform(visibleRegion.intersect(viewport));
    const auto displayId = display->getId();
    Region visible = transform.transform(visibleRegion.intersect(viewport));

    if (!hasHwcLayer(displayId)) {
        ALOGE("[%s] failed to setPerFrameData: no HWC layer found (%d)",
        ALOGE("[%s] failed to setPerFrameData: no HWC layer found for display %" PRIu64,
              mName.string(), displayId);
        return;
    }
@@ -290,7 +289,7 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& display) {
    }

    const HdrMetadata& metadata = getDrawingHdrMetadata();
    error = hwcLayer->setPerFrameMetadata(display->getSupportedPerFrameMetadata(), metadata);
    error = hwcLayer->setPerFrameMetadata(supportedPerFrameMetadata, metadata);
    if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
        ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
@@ -303,10 +302,10 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& display) {
    }
    getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
    getBE().compositionInfo.hwc.hdrMetadata = getDrawingHdrMetadata();
    getBE().compositionInfo.hwc.supportedPerFrameMetadata = display->getSupportedPerFrameMetadata();
    getBE().compositionInfo.hwc.supportedPerFrameMetadata = supportedPerFrameMetadata;
    getBE().compositionInfo.hwc.colorTransform = getColorTransform();

    setHwcLayerBuffer(display);
    setHwcLayerBuffer(displayId);
}

bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
@@ -318,10 +317,10 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
    return hasReadyFrame();
}

bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId,
                                    const std::shared_ptr<FenceTime>& glDoneFence,
                                    const std::shared_ptr<FenceTime>& presentFence,
                                    const CompositorTiming& compositorTiming) {

    // mFrameLatencyNeeded is true when a new frame was latched for the
    // composition.
    if (!mFrameLatencyNeeded) return false;
@@ -352,11 +351,10 @@ bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFenc
    if (presentFence->isValid()) {
        mTimeStats.setPresentFence(layerID, mCurrentFrameNumber, presentFence);
        mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
    } else if (mFlinger->getHwComposer().isConnected(HWC_DISPLAY_PRIMARY)) {
    } else if (displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
        // The HWC doesn't support present fences, so use the refresh
        // timestamp instead.
        const nsecs_t actualPresentTime =
                mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
        const nsecs_t actualPresentTime = mFlinger->getHwComposer().getRefreshTimestamp(*displayId);
        mTimeStats.setPresentTime(layerID, mCurrentFrameNumber, actualPresentTime);
        mFrameTracker.setActualPresentTime(actualPresentTime);
    }
+5 −3
Original line number Diff line number Diff line
@@ -80,10 +80,12 @@ public:

    bool isHdrY410() const override;

    void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
    void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
                         int32_t supportedPerFrameMetadata) override;

    bool onPreComposition(nsecs_t refreshStartTime) override;
    bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
    bool onPostComposition(const std::optional<DisplayId>& displayId,
                           const std::shared_ptr<FenceTime>& glDoneFence,
                           const std::shared_ptr<FenceTime>& presentFence,
                           const CompositorTiming& compositorTiming) override;

@@ -145,7 +147,7 @@ private:
    virtual status_t updateActiveBuffer() = 0;
    virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;

    virtual void setHwcLayerBuffer(const sp<const DisplayDevice>& display) = 0;
    virtual void setHwcLayerBuffer(DisplayId displayId) = 0;

    // -----------------------------------------------------------------------

+1 −2
Original line number Diff line number Diff line
@@ -325,8 +325,7 @@ status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) {
    return NO_ERROR;
}

void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
    const auto displayId = display->getId();
void BufferQueueLayer::setHwcLayerBuffer(DisplayId displayId) {
    auto& hwcInfo = getBE().mHwcLayers[displayId];
    auto& hwcLayer = hwcInfo.layer;

Loading