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

Commit b5ec89ec authored by Chih-Yu Huang's avatar Chih-Yu Huang
Browse files

Update usage of GraphicBuffer at buffer migration

When migrating buffers to the new surface, the consumer usage might be
changed. If the usage is mismatched, the attached buffer will be still
dropped when dequeueing from IGBP.

This CL updates the usage of GraphicBuffer with the consumer usage of
the new surface when buffer migration.

Bug: 174188958
Test: android.media.cts.MediaCodecPlayerTest#testPlaybackSwitchViews

Change-Id: Iabae61743891f8ff6a75b56eab7dc2f7b2ece8bd
parent 0549e1a0
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -158,6 +158,11 @@ OutputBufferQueue::~OutputBufferQueue() {
bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp,
                                  uint32_t generation,
                                  uint64_t bqId) {
    uint64_t consumerUsage = 0;
    if (igbp->getConsumerUsage(&consumerUsage) != OK) {
        ALOGW("failed to get consumer usage");
    }

    size_t tryNum = 0;
    size_t success = 0;
    sp<GraphicBuffer> buffers[BufferQueueDefs::NUM_BUFFER_SLOTS];
@@ -183,7 +188,24 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp,
            }
            ++tryNum;
            int bqSlot;

            // Update buffer's generation and usage.
            if ((mBuffers[i]->getUsage() & consumerUsage) != consumerUsage) {
                mBuffers[i] = new GraphicBuffer(
                    mBuffers[i]->handle, GraphicBuffer::CLONE_HANDLE,
                    mBuffers[i]->width, mBuffers[i]->height,
                    mBuffers[i]->format, mBuffers[i]->layerCount,
                    mBuffers[i]->getUsage() | consumerUsage,
                    mBuffers[i]->stride);
                if (mBuffers[i]->initCheck() != OK) {
                    ALOGW("%s() failed to update usage, original usage=%" PRIx64
                          ", consumer usage=%" PRIx64,
                          __func__, mBuffers[i]->getUsage(), consumerUsage);
                    continue;
                }
            }
            mBuffers[i]->setGenerationNumber(generation);

            status_t result = igbp->attachBuffer(&bqSlot, mBuffers[i]);
            if (result != OK) {
                continue;
+2 −2
Original line number Diff line number Diff line
@@ -104,8 +104,8 @@ public:
    virtual type_t getType() const override;

    int migrate(const android::sp<HGraphicBufferProducer>& producer,
                uint32_t toGeneration, uint64_t toBqId,
                android::sp<android::GraphicBuffer> graphicBuffer, uint32_t oldGeneration);
                uint32_t toGeneration, uint64_t toUsage, uint64_t toBqId,
                android::sp<android::GraphicBuffer>& graphicBuffer, uint32_t oldGeneration);

private:
    friend struct _C2BlockFactory;
+22 −7
Original line number Diff line number Diff line
@@ -167,8 +167,8 @@ int64_t getTimestampNow() {
    return stamp;
}

bool getGenerationNumber(const sp<HGraphicBufferProducer> &producer,
                         uint32_t *generation) {
bool getGenerationNumberAndUsage(const sp<HGraphicBufferProducer> &producer,
                                 uint32_t *generation, uint64_t *usage) {
    status_t status{};
    int slot{};
    bool bufferNeedsReallocation{};
@@ -202,7 +202,7 @@ bool getGenerationNumber(const sp<HGraphicBufferProducer> &producer,
    // instead of a new allocation.
    transResult = producer->requestBuffer(
            slot,
            [&status, &slotBuffer, &generation](
            [&status, &slotBuffer, &generation, &usage](
                    HStatus hStatus,
                    HBuffer const& hBuffer,
                    uint32_t generationNumber){
@@ -210,6 +210,7 @@ bool getGenerationNumber(const sp<HGraphicBufferProducer> &producer,
                        h2b(hBuffer, &slotBuffer) &&
                        slotBuffer) {
                    *generation = generationNumber;
                    *usage = slotBuffer->getUsage();
                    slotBuffer->setGenerationNumber(generationNumber);
                } else {
                    status = android::BAD_VALUE;
@@ -460,6 +461,7 @@ public:
    void configureProducer(const sp<HGraphicBufferProducer> &producer) {
        uint64_t producerId = 0;
        uint32_t generation = 0;
        uint64_t usage = 0;
        bool haveGeneration = false;
        if (producer) {
            Return<uint64_t> transResult = producer->getUniqueId();
@@ -469,7 +471,7 @@ public:
            }
            producerId = static_cast<uint64_t>(transResult);
            // TODO: provide gneration number from parameter.
            haveGeneration = getGenerationNumber(producer, &generation);
            haveGeneration = getGenerationNumberAndUsage(producer, &generation, &usage);
            if (!haveGeneration) {
                ALOGW("get generationNumber failed %llu",
                      (unsigned long long)producerId);
@@ -509,7 +511,7 @@ public:
                            mPoolDatas[i].lock();
                    if (data) {
                        int slot = data->migrate(
                                mProducer, generation,
                                mProducer, generation, usage,
                                producerId, mBuffers[i], oldGeneration);
                        if (slot >= 0) {
                            buffers[slot] = mBuffers[i];
@@ -593,8 +595,8 @@ C2BufferQueueBlockPoolData::type_t C2BufferQueueBlockPoolData::getType() const {

int C2BufferQueueBlockPoolData::migrate(
        const sp<HGraphicBufferProducer>& producer,
        uint32_t toGeneration, uint64_t toBqId,
        sp<GraphicBuffer> graphicBuffer, uint32_t oldGeneration) {
        uint32_t toGeneration, uint64_t toUsage, uint64_t toBqId,
        sp<GraphicBuffer>& graphicBuffer, uint32_t oldGeneration) {
    std::scoped_lock<std::mutex> l(mLock);

    mCurrentBqId = toBqId;
@@ -628,6 +630,19 @@ int C2BufferQueueBlockPoolData::migrate(
        ALOGV("buffer is in transfer");
        return -1;
    }

    if (toUsage != graphicBuffer->getUsage()) {
        sp<GraphicBuffer> newBuffer = new GraphicBuffer(
            graphicBuffer->handle, GraphicBuffer::CLONE_HANDLE,
            graphicBuffer->width, graphicBuffer->height, graphicBuffer->format,
            graphicBuffer->layerCount, toUsage, graphicBuffer->stride);
        if (newBuffer->initCheck() == android::NO_ERROR) {
            graphicBuffer = std::move(newBuffer);
        } else {
            ALOGW("%s() failed to update usage, original usage=%" PRIx64 ", toUsage=%" PRIx64,
                  __func__, graphicBuffer->getUsage(), toUsage);
        }
    }
    graphicBuffer->setGenerationNumber(toGeneration);

    HBuffer hBuffer{};