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

Commit c5222134 authored by KaiChieh Chuang's avatar KaiChieh Chuang Committed by Denis Hsu
Browse files

VirtualDisplaySurface propagate reallocation to VDS producer

When dequeuing from the source through refreshOutputBuffer(),
the dequeue result, BUFFER_NEEDS_REALLOCATION, is not propagated back up.
RenderSurface will not reallocate from VirtualDisplaySurface
 in this situation, causing GLES to render to the wrong buffer.

Wrong buffer example,
beginFrame() -> refreshOutputBuffer() -> dequeueBuffer()
-> dequeueBuffer() needs reallocation.
but the result in refreshOuputBuffer() is overwritten by
mHwc.setOutputBuffer().
(the result is also not received by VDS itself)

We need a flag to indicate producer slot need reallocation,
so that we can sent reallocation to Consumer.

Bug: 157204337
Test: simulate second display with debug.sf.enable_hwc_vds = 1
Change-Id: Ibcbc3bd1ef857382ea9882dd10e0bd55759406f4
parent 59842065
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc,
        mOutputUsage(GRALLOC_USAGE_HW_COMPOSER),
        mProducerSlotSource(0),
        mProducerBuffers(),
        mProducerSlotNeedReallocation(0),
        mQueueBufferOutput(),
        mSinkBufferWidth(0),
        mSinkBufferHeight(0),
@@ -335,10 +336,14 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source,
            dbgSourceStr(source), *sslot, pslot, result);
    uint64_t sourceBit = static_cast<uint64_t>(source) << pslot;

    // reset producer slot reallocation flag
    mProducerSlotNeedReallocation &= ~(1ULL << pslot);

    if ((mProducerSlotSource & (1ULL << pslot)) != sourceBit) {
        // This slot was previously dequeued from the other source; must
        // re-request the buffer.
        result |= BUFFER_NEEDS_REALLOCATION;
        mProducerSlotNeedReallocation |= 1ULL << pslot;

        mProducerSlotSource &= ~(1ULL << pslot);
        mProducerSlotSource |= sourceBit;
    }
@@ -360,6 +365,9 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source,
                dbgSourceStr(source), pslot, mProducerBuffers[pslot].get(),
                mProducerBuffers[pslot]->getPixelFormat(),
                mProducerBuffers[pslot]->getUsage());

        // propagate reallocation to VDS consumer
        mProducerSlotNeedReallocation |= 1ULL << pslot;
    }

    return result;
@@ -434,6 +442,11 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint
    if (outBufferAge) {
        *outBufferAge = 0;
    }

    if ((mProducerSlotNeedReallocation & (1ULL << *pslot)) != 0) {
        result |= BUFFER_NEEDS_REALLOCATION;
    }

    return result;
}

+4 −0
Original line number Diff line number Diff line
@@ -180,6 +180,10 @@ private:
    uint64_t mProducerSlotSource;
    sp<GraphicBuffer> mProducerBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS];

    // Need to propagate reallocation to VDS consumer.
    // Each bit corresponds to a producer slot.
    uint64_t mProducerSlotNeedReallocation;

    // The QueueBufferOutput with the latest info from the sink, and with the
    // transform hint cleared. Since we defer queueBuffer from the GPU driver
    // to the sink, we have to return the previous version.