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

Commit a42d5399 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Initialize all displays on boot/restart

Generalize SF::initializeDisplays (called on boot and restart) to:
    - Apply the transaction that clears DisplayState to all displays.
    - Power on all displays.

The first change removes a special case for the primary display, setting
the stage for multi-display boot animation. Each display is assigned its
own LayerStack, and set up with a projection to its active resolution.

The second change fixes a bug where DisplayCapability::BRIGHTNESS was
not detected for secondary displays present during boot. SF queries
capabilities when a display is first powered on, but DM asks SF about
brightness when the display is hotplugged, regardless of power mode.
The general fix (covering external displays) is for DM to defer its
query, but this stopgap covers internal displays.

Revert I3a2eae4efc4a5c6113700a9ca9e9b261e364a878, which let the initial
power mode be std::nullopt. This effectively forced DM's first request
to setPowerMode(<rear display>, OFF), which would otherwise be ignored
because OFF had been the default power mode on DisplayDevice creation.
However, that special case confusingly took the same branch as the OFF
to ON transition, and is no longer needed now that all displays are ON
(from SF's perspective, not just HWC's) until the boot animation ends.

Fixes: 267633741
Fixes: 150889228
Bug: 269510347
Test: Boot unfolded and folded.
Test: Induce system_server crash.
Test: InitializeDisplaysTest.initializesDisplays
Change-Id: I5277a629f39b3b285452aa84d49ff84e3dc957ca
parent a9c51987
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -416,26 +416,36 @@ public:
};

struct DisplayState {
    enum {
    enum : uint32_t {
        eSurfaceChanged = 0x01,
        eLayerStackChanged = 0x02,
        eDisplayProjectionChanged = 0x04,
        eDisplaySizeChanged = 0x08,
        eFlagsChanged = 0x10
        eFlagsChanged = 0x10,

        eAllChanged = ~0u
    };

    // Not for direct use. Prefer constructor below for new displays.
    DisplayState();

    DisplayState(sp<IBinder> token, ui::LayerStack layerStack)
          : what(eAllChanged),
            token(std::move(token)),
            layerStack(layerStack),
            layerStackSpaceRect(Rect::INVALID_RECT),
            orientedDisplaySpaceRect(Rect::INVALID_RECT) {}

    void merge(const DisplayState& other);
    void sanitize(int32_t permissions);

    uint32_t what = 0;
    uint32_t flags = 0;
    sp<IBinder> token;
    sp<IGraphicBufferProducer> surface;

    ui::LayerStack layerStack = ui::DEFAULT_LAYER_STACK;

    // These states define how layers are projected onto the physical display.
    // These states define how layers are projected onto the physical or virtual display.
    //
    // Layers are first clipped to `layerStackSpaceRect'.  They are then translated and
    // scaled from `layerStackSpaceRect' to `orientedDisplaySpaceRect'.  Finally, they are rotated
@@ -446,10 +456,17 @@ struct DisplayState {
    // will be scaled by a factor of 2 and translated by (20, 10). When orientation is 1, layers
    // will be additionally rotated by 90 degrees around the origin clockwise and translated by (W,
    // 0).
    //
    // Rect::INVALID_RECT sizes the space to the active resolution of the physical display, or the
    // default dimensions of the virtual display surface.
    //
    ui::Rotation orientation = ui::ROTATION_0;
    Rect layerStackSpaceRect = Rect::EMPTY_RECT;
    Rect orientedDisplaySpaceRect = Rect::EMPTY_RECT;

    // Exclusive to virtual displays: The sink surface into which the virtual display is rendered,
    // and an optional resolution that overrides its default dimensions.
    sp<IGraphicBufferProducer> surface;
    uint32_t width = 0;
    uint32_t height = 0;

+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ public:
    virtual void createClientCompositionCache(uint32_t cacheSize) = 0;

    // Sends the brightness setting to HWC
    virtual void applyDisplayBrightness(const bool applyImmediately) = 0;
    virtual void applyDisplayBrightness(bool applyImmediately) = 0;

protected:
    ~Display() = default;
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ public:
            const compositionengine::DisplayColorProfileCreationArgs&) override;
    void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
    void createClientCompositionCache(uint32_t cacheSize) override;
    void applyDisplayBrightness(const bool applyImmediately) override;
    void applyDisplayBrightness(bool applyImmediately) override;
    void setSecure(bool secure) override;

    // Internal helpers used by chooseCompositionStrategy()
+5 −6
Original line number Diff line number Diff line
@@ -204,13 +204,12 @@ void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs&
    setReleasedLayers(std::move(releasedLayers));
}

void Display::applyDisplayBrightness(const bool applyImmediately) {
void Display::applyDisplayBrightness(bool applyImmediately) {
    if (const auto displayId = ftl::Optional(getDisplayId()).and_then(PhysicalDisplayId::tryCast);
        displayId && getState().displayBrightness) {
        auto& hwc = getCompositionEngine().getHwComposer();
    const auto halDisplayId = HalDisplayId::tryCast(*getDisplayId());
    if (const auto physicalDisplayId = PhysicalDisplayId::tryCast(*halDisplayId);
        physicalDisplayId && getState().displayBrightness) {
        const status_t result =
                hwc.setDisplayBrightness(*physicalDisplayId, *getState().displayBrightness,
                hwc.setDisplayBrightness(*displayId, *getState().displayBrightness,
                                         getState().displayBrightnessNits,
                                         Hwc2::Composer::DisplayBrightnessOptions{
                                                 .applyImmediately = applyImmediately})
+8 −15
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
        mActiveModeFpsTrace(concatId("ActiveModeFps")),
        mRenderRateFpsTrace(concatId("RenderRateFps")),
        mPhysicalOrientation(args.physicalOrientation),
        mPowerMode(ftl::Concat("PowerMode ", getId().value).c_str(), args.initialPowerMode),
        mIsPrimary(args.isPrimary),
        mRequestedRefreshRate(args.requestedRefreshRate),
        mRefreshRateSelector(std::move(args.refreshRateSelector)),
@@ -106,9 +107,7 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)

    mCompositionDisplay->getRenderSurface()->initialize();

    if (const auto powerModeOpt = args.initialPowerMode) {
        setPowerMode(*powerModeOpt);
    }
    setPowerMode(args.initialPowerMode);

    // initialize the display orientation transform.
    setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
@@ -173,6 +172,7 @@ auto DisplayDevice::getFrontEndInfo() const -> frontend::DisplayInfo {
}

void DisplayDevice::setPowerMode(hal::PowerMode mode) {
    // TODO(b/241285876): Skip this for virtual displays.
    if (mode == hal::PowerMode::OFF || mode == hal::PowerMode::ON) {
        if (mStagedBrightness && mBrightness != mStagedBrightness) {
            getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
@@ -182,33 +182,26 @@ void DisplayDevice::setPowerMode(hal::PowerMode mode) {
        getCompositionDisplay()->applyDisplayBrightness(true);
    }

    if (mPowerMode) {
        *mPowerMode = mode;
    } else {
        mPowerMode.emplace("PowerMode -" + to_string(getId()), mode);
    }
    mPowerMode = mode;

    getCompositionDisplay()->setCompositionEnabled(isPoweredOn());
}

void DisplayDevice::tracePowerMode() {
    // assign the same value for tracing
    if (mPowerMode) {
        const hal::PowerMode powerMode = *mPowerMode;
        *mPowerMode = powerMode;
    }
    // Assign the same value for tracing.
    mPowerMode = mPowerMode.get();
}

void DisplayDevice::enableLayerCaching(bool enable) {
    getCompositionDisplay()->setLayerCachingEnabled(enable);
}

std::optional<hal::PowerMode> DisplayDevice::getPowerMode() const {
hal::PowerMode DisplayDevice::getPowerMode() const {
    return mPowerMode;
}

bool DisplayDevice::isPoweredOn() const {
    return mPowerMode && *mPowerMode != hal::PowerMode::OFF;
    return mPowerMode != hal::PowerMode::OFF;
}

void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps vsyncRate, Fps renderFps) {
Loading