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

Commit f6eddb6b authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Enable backpressure for BufferStateLayer

The default behaviour of buffer state layer is to drop older
buffers if there are newer buffers that are ready to be presented.

When emulating BufferQueue behavior via the adapter, we want
to queue up buffers without any present timestamps. To solve this,
we introduce a layer state flag to keep the buffer in the transaction
queue if there is already a buffer that is ready to be applied.

Test: atest SurfaceViewBufferTests:BufferPresentationTests
Bug: 176967609
Change-Id: I33f6347bd1c7a2d80dc4214e596bb864abe8c6bf
parent dd5bfa93
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -146,6 +146,10 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont

    mTransformHint = mSurfaceControl->getTransformHint();
    mBufferItemConsumer->setTransformHint(mTransformHint);
    SurfaceComposerClient::Transaction()
            .setFlags(surface, layer_state_t::eEnableBackpressure,
                      layer_state_t::eEnableBackpressure)
            .apply();

    mNumAcquired = 0;
    mNumFrameAvailable = 0;
@@ -169,13 +173,20 @@ BLASTBufferQueue::~BLASTBufferQueue() {
void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
                              int32_t format) {
    std::unique_lock _lock{mMutex};
    mSurfaceControl = surface;

    if (mFormat != format) {
        mFormat = format;
        mBufferItemConsumer->setDefaultBufferFormat(format);
    }

    SurfaceComposerClient::Transaction t;
    bool applyTransaction = false;
    if (!SurfaceControl::isSameSurface(mSurfaceControl, surface)) {
        mSurfaceControl = surface;
        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
                   layer_state_t::eEnableBackpressure);
        applyTransaction = true;
    }

    ui::Size newSize(width, height);
    if (mRequestedSize != newSize) {
        mRequestedSize.set(newSize);
@@ -184,12 +195,14 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
            // If the buffer supports scaling, update the frame immediately since the client may
            // want to scale the existing buffer to the new size.
            mSize = mRequestedSize;
            SurfaceComposerClient::Transaction t;
            t.setFrame(mSurfaceControl,
                       {0, 0, static_cast<int32_t>(mSize.width),
                        static_cast<int32_t>(mSize.height)});
            t.apply();
            applyTransaction = true;
        }
    }
    if (applyTransaction) {
        t.apply();
    }
}

+3 −5
Original line number Diff line number Diff line
@@ -183,12 +183,9 @@ status_t layer_state_t::read(const Parcel& input)
    SAFE_PARCEL(input.readUint32, &layerStack);
    SAFE_PARCEL(input.readFloat, &alpha);

    uint32_t tmpUint32 = 0;
    SAFE_PARCEL(input.readUint32, &tmpUint32);
    flags = static_cast<uint8_t>(tmpUint32);
    SAFE_PARCEL(input.readUint32, &flags);

    SAFE_PARCEL(input.readUint32, &tmpUint32);
    mask = static_cast<uint8_t>(tmpUint32);
    SAFE_PARCEL(input.readUint32, &mask);

    SAFE_PARCEL(matrix.read, input);
    SAFE_PARCEL(input.read, crop_legacy);
@@ -229,6 +226,7 @@ status_t layer_state_t::read(const Parcel& input)
        SAFE_PARCEL(input.read, *acquireFence);
    }

    uint32_t tmpUint32 = 0;
    SAFE_PARCEL(input.readUint32, &tmpUint32);
    dataspace = static_cast<ui::Dataspace>(tmpUint32);

+2 −1
Original line number Diff line number Diff line
@@ -934,7 +934,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags
        return *this;
    }
    if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot)) {
        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
        (mask & layer_state_t::eEnableBackpressure)) {
        s->what |= layer_state_t::eFlagsChanged;
    }
    s->flags &= ~mask;
+6 −2
Original line number Diff line number Diff line
@@ -82,6 +82,10 @@ struct layer_state_t {
        eLayerOpaque = 0x02,         // SURFACE_OPAQUE
        eLayerSkipScreenshot = 0x40, // SKIP_SCREENSHOT
        eLayerSecure = 0x80,         // SECURE
        // Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is
        // set. This blocks the client until all the buffers have been presented. If the buffers
        // have presentation timestamps, then we may drop buffers.
        eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE
    };

    enum {
@@ -157,8 +161,8 @@ struct layer_state_t {
    uint32_t h;
    uint32_t layerStack;
    float alpha;
    uint8_t flags;
    uint8_t mask;
    uint32_t flags;
    uint32_t mask;
    uint8_t reserved;
    matrix22_t matrix;
    Rect crop_legacy;
+1 −1
Original line number Diff line number Diff line
@@ -1312,7 +1312,7 @@ bool Layer::setBlurRegions(const std::vector<BlurRegion>& blurRegions) {
    return true;
}

bool Layer::setFlags(uint8_t flags, uint8_t mask) {
bool Layer::setFlags(uint32_t flags, uint32_t mask) {
    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
    if (mCurrentState.flags == newFlags) return false;
    mCurrentState.sequence++;
Loading