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

Commit f527548d authored by Lloyd Pique's avatar Lloyd Pique
Browse files

SF: Move/Refactor Layer::setPerFrameData

Moves functionality out of ColorLayer, BufferLayer, BufferStateLayer and
BufferQueueLayer related to setting the per-frame data.

Instead each of the front-end classes now implements a minimal function
to set the per-frame state into the LayerFECompositionState structure.

compositionengine::OutputLayer now takes care of sending the state to
the HWC, and in particular with detecting when client composition needs
to be forced due to lack of HWC support (though the front-end can also
set a flag to force client composition for a few things it knows about).

SurfaceFlinger::calculateWorkingSet is also refactored to work with the
changes made, and prepare it to be moved over to CompositionEngine.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Test: atest CtsColorModeTestCases
Test: atest CtsDisplayTestCases
Test: atest CtsGraphicsTestCases
Test: atest CtsUiRenderingTestCases
Test: atest CtsViewTestCases
Test: atest android.media.cts.EncodeVirtualDisplayWithCompositionTest
Bug: 121291683
Change-Id: I2cb0442f68ec5c5f65f5b4cb418dda4c42e5dc39
parent 216aa49f
Loading
Loading
Loading
Loading
+11 −80
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <compositionengine/Display.h>
#include <compositionengine/Layer.h>
#include <compositionengine/LayerCreationArgs.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/LayerCompositionState.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
@@ -253,90 +254,20 @@ bool BufferLayer::isHdrY410() const {
            mActiveBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
}

void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice,
                                  const ui::Transform& transform, const Rect& viewport,
                                  int32_t supportedPerFrameMetadata,
                                  const ui::Dataspace targetDataspace) {
    RETURN_IF_NO_HWC_LAYER(displayDevice);

    // Apply this display's projection's viewport to the visible region
    // before giving it to the HWC HAL.
    Region visible = transform.transform(visibleRegion.intersect(viewport));

    const auto outputLayer = findOutputLayerForDisplay(displayDevice);
    LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc);

    auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
    auto error = hwcLayer->setVisibleRegion(visible);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
        visible.dump(LOG_TAG);
    }
    outputLayer->editState().visibleRegion = visible;

    auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;

    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
        surfaceDamageRegion.dump(LOG_TAG);
    }
    layerCompositionState.surfaceDamage = surfaceDamageRegion;
void BufferLayer::latchPerFrameState(
        compositionengine::LayerFECompositionState& compositionState) const {
    Layer::latchPerFrameState(compositionState);

    // Sideband layers
    if (layerCompositionState.sidebandStream.get()) {
        setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::SIDEBAND);
        ALOGV("[%s] Requesting Sideband composition", mName.string());
        error = hwcLayer->setSidebandStream(layerCompositionState.sidebandStream->handle());
        if (error != HWC2::Error::None) {
            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
                  layerCompositionState.sidebandStream->handle(), to_string(error).c_str(),
                  static_cast<int32_t>(error));
        }
        layerCompositionState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
        return;
    }

    // Device or Cursor layers
    if (mPotentialCursor) {
        ALOGV("[%s] Requesting Cursor composition", mName.string());
        setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::CURSOR);
    if (compositionState.sidebandStream.get()) {
        compositionState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
    } else {
        ALOGV("[%s] Requesting Device composition", mName.string());
        setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::DEVICE);
        // Normal buffer layers
        compositionState.hdrMetadata = getDrawingHdrMetadata();
        compositionState.compositionType = mPotentialCursor
                ? Hwc2::IComposerClient::Composition::CURSOR
                : Hwc2::IComposerClient::Composition::DEVICE;
    }

    ui::Dataspace dataspace = isColorSpaceAgnostic() && targetDataspace != ui::Dataspace::UNKNOWN
            ? targetDataspace
            : mCurrentDataSpace;
    error = hwcLayer->setDataspace(dataspace);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), dataspace,
              to_string(error).c_str(), static_cast<int32_t>(error));
    }

    const HdrMetadata& metadata = getDrawingHdrMetadata();
    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));
    }

    error = hwcLayer->setColorTransform(getColorTransform());
    if (error == HWC2::Error::Unsupported) {
        // If per layer color transform is not supported, we use GPU composition.
        setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::CLIENT);
    } else if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(),
                to_string(error).c_str(), static_cast<int32_t>(error));
    }
    layerCompositionState.dataspace = mCurrentDataSpace;
    layerCompositionState.colorTransform = getColorTransform();
    layerCompositionState.hdrMetadata = metadata;

    setHwcLayerBuffer(displayDevice);
}

bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
+2 −6
Original line number Diff line number Diff line
@@ -82,10 +82,6 @@ public:

    bool isHdrY410() const override;

    void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
                         const Rect& viewport, int32_t supportedPerFrameMetadata,
                         const ui::Dataspace targetDataspace) override;

    bool onPreComposition(nsecs_t refreshStartTime) override;
    bool onPostComposition(const std::optional<DisplayId>& displayId,
                           const std::shared_ptr<FenceTime>& glDoneFence,
@@ -147,9 +143,9 @@ private:
    virtual status_t updateActiveBuffer() = 0;
    virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;

    virtual void setHwcLayerBuffer(const sp<const DisplayDevice>& displayDevice) = 0;

protected:
    void latchPerFrameState(compositionengine::LayerFECompositionState& outState) const override;

    // Loads the corresponding system property once per process
    static bool latchUnsignaledBuffers();

+9 −25
Original line number Diff line number Diff line
@@ -377,7 +377,6 @@ status_t BufferQueueLayer::updateActiveBuffer() {
    mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot, &mActiveBufferFence);
    auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
    layerCompositionState.buffer = mActiveBuffer;
    layerCompositionState.bufferSlot = mActiveBufferSlot;

    if (mActiveBuffer == nullptr) {
        // this can only happen if the very first buffer was rejected.
@@ -397,32 +396,17 @@ status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) {
    return NO_ERROR;
}

void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
    const auto outputLayer = findOutputLayerForDisplay(display);
    LOG_FATAL_IF(!outputLayer);
    LOG_FATAL_IF(!outputLayer->getState.hwc);
    auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;

    uint32_t hwcSlot = 0;
    sp<GraphicBuffer> hwcBuffer;

    // INVALID_BUFFER_SLOT is used to identify BufferStateLayers.  Default to 0
    // for BufferQueueLayers
    int slot = (mActiveBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) ? 0 : mActiveBufferSlot;
    (*outputLayer->editState().hwc)
            .hwcBufferCache.getHwcBuffer(slot, mActiveBuffer, &hwcSlot, &hwcBuffer);

    auto acquireFence = mConsumer->getCurrentFence();
    auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle,
              to_string(error).c_str(), static_cast<int32_t>(error));
void BufferQueueLayer::latchPerFrameState(
        compositionengine::LayerFECompositionState& compositionState) const {
    BufferLayer::latchPerFrameState(compositionState);
    if (compositionState.compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
        return;
    }

    auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
    layerCompositionState.bufferSlot = mActiveBufferSlot;
    layerCompositionState.buffer = mActiveBuffer;
    layerCompositionState.acquireFence = acquireFence;
    compositionState.buffer = mActiveBuffer;
    compositionState.bufferSlot =
            (mActiveBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) ? 0 : mActiveBufferSlot;
    compositionState.acquireFence = mConsumer->getCurrentFence();
}

// -----------------------------------------------------------------------
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ private:
    status_t updateActiveBuffer() override;
    status_t updateFrameNumber(nsecs_t latchTime) override;

    void setHwcLayerBuffer(const sp<const DisplayDevice>& displayDevice) override;
    void latchPerFrameState(compositionengine::LayerFECompositionState&) const override;

    // -----------------------------------------------------------------------
    // Interface implementation for BufferLayerConsumer::ContentsChangedListener
+9 −16
Original line number Diff line number Diff line
@@ -569,7 +569,6 @@ status_t BufferStateLayer::updateActiveBuffer() {
    mActiveBufferFence = s.acquireFence;
    auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
    layerCompositionState.buffer = mActiveBuffer;
    layerCompositionState.bufferSlot = 0;

    return NO_ERROR;
}
@@ -580,24 +579,18 @@ status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) {
    return NO_ERROR;
}

void BufferStateLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
    const auto outputLayer = findOutputLayerForDisplay(display);
    LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc);
    auto& hwcInfo = *outputLayer->editState().hwc;
    auto& hwcLayer = hwcInfo.hwcLayer;
void BufferStateLayer::latchPerFrameState(
        compositionengine::LayerFECompositionState& compositionState) const {
    BufferLayer::latchPerFrameState(compositionState);
    if (compositionState.compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
        return;
    }

    const State& s(getDrawingState());

    uint32_t hwcSlot;
    sp<GraphicBuffer> buffer;
    hwcInfo.hwcBufferCache.getHwcBuffer(mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId),
                                        s.buffer, &hwcSlot, &buffer);

    auto error = hwcLayer->setBuffer(hwcSlot, buffer, s.acquireFence);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
              s.buffer->handle, to_string(error).c_str(), static_cast<int32_t>(error));
    }
    compositionState.buffer = s.buffer;
    compositionState.bufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
    compositionState.acquireFence = s.acquireFence;

    mFrameNumber++;
}
Loading