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

Commit 54fc1067 authored by Sungtak Lee's avatar Sungtak Lee
Browse files

GraphicsTracker: accept buffers from BASIC_GRAPHIC

GraphicsTracker does not accept blocks created from blockpools which
uses BASIC_GRAPHIC allocator. Accept those blocks.

BYPASS_IGBP_IGBC_API_REASON=GraphicsTracker refactor later

Bug: 441795567
Flag: EXEMPT bugfix
Test: presubmit & pixel
Change-Id: I5299c4c7b315133587de9a52f1830ffe29f1a694
parent 6b3b4ecc
Loading
Loading
Loading
Loading
+135 −15
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <private/android/AHardwareBufferHelpers.h>
#include <vndk/hardware_buffer.h>

#include <C2AllocatorGralloc.h>
#include <C2BlockInternal.h>
#include <codec2/aidl/GraphicsTracker.h>

@@ -58,6 +59,38 @@ c2_status_t retrieveAHardwareBufferId(const C2ConstGraphicBlock &blk, uint64_t *
    }
}

// Create a GraphicBuffer object from a graphic block.
sp<GraphicBuffer> createGraphicBuffer(
        const C2ConstGraphicBlock& block, uint32_t toGeneration, uint64_t toUsage) {
    uint32_t width;
    uint32_t height;
    uint32_t format;
    uint64_t usage;
    uint32_t stride;
    uint32_t generation;
    uint64_t bqId;
    int32_t bqSlot;
    ::android::_UnwrapNativeCodec2GrallocMetadata(
            block.handle(), &width, &height, &format, &usage,
            &stride, &generation, &bqId, reinterpret_cast<uint32_t*>(&bqSlot));

    // android::UnwrapNativCodec2GrallocHandle() returns
    // a new native_handle_t with undup'ed fds.
    native_handle_t *grallocHandle =
            ::android::UnwrapNativeCodec2GrallocHandle(block.handle());
    if (grallocHandle == nullptr) {
        return nullptr;
    }
    sp<GraphicBuffer> graphicBuffer =
            new GraphicBuffer(grallocHandle,
                              GraphicBuffer::CLONE_HANDLE,
                              width, height, format,
                              1, (usage | toUsage), stride);
    graphicBuffer->setGenerationNumber(toGeneration);
    native_handle_delete(grallocHandle);
    return graphicBuffer;
}

} // anonymous namespace

using ::android::BufferQueue;
@@ -1019,6 +1052,75 @@ c2_status_t GraphicsTracker::deallocate(uint64_t bid, const sp<Fence> &fence) {
    return C2_OK;
}

c2_status_t GraphicsTracker::requestAttachForRender(const C2ConstGraphicBlock& blk,
        const sp<Fence> &fence,
        std::shared_ptr<BufferCache> *pCache,
        std::shared_ptr<BufferItem> *pBuffer,
        bool *updateDequeue) {
    if (mStopped.load() == true) {
        ALOGE("cannot requestAttachForRender due to being stopped");
        return C2_BAD_STATE;
    }
    // allocate for attach
    c2_status_t res = C2_OK;
    std::shared_ptr<BufferCache> cache;
    {
        std::unique_lock<std::mutex> l(mLock);
        if (mStopRequested) {
            return C2_BAD_STATE;
        }
        if (!mBufferCache || !(mBufferCache->mIgbp)) {
            return C2_OMITTED;
        }
        res = requestAllocateLocked(&cache);
        if (res != C2_OK) {
            ALOGV("cannot allocate for requestAttachForRender: %d", res);
            return res;
        }
    }
    // attach to the surface
    ::android::sp<IGraphicBufferProducer> igbp = cache->mIgbp;
    uint32_t generation = cache->mGeneration;
    uint64_t usage = 0ULL;
    int slotId = -1;
    (void)igbp->getConsumerUsage(&usage);
    sp<GraphicBuffer> grBuf = createGraphicBuffer(blk, generation, usage);
    std::shared_ptr<BufferItem> buffer;
    if (grBuf) {
        ::android::status_t status = igbp->attachBuffer(&slotId, grBuf);
        if (status != ::android::OK) {
            res = C2_REFUSED;
        } else {
            buffer = std::make_shared<BufferItem>(generation, slotId, grBuf, fence);
            if (buffer->mInit) {
                cache->waitOnSlot(slotId);
                *pCache = cache;
                *pBuffer = buffer;
                res = C2_OK;
            } else {
                (void)igbp->cancelBuffer(slotId, Fence::NO_FENCE);
                buffer.reset();
                res = C2_BAD_VALUE;
            }
        }
    } else {
        res = C2_BAD_VALUE;
    }
    // Do commitAllocate() regardless of the return value, since commitAllocate()
    // also handle rollback from requestAllocateLocked()(removing the pre allocated
    // room).
    commitAllocate(res, cache, false, slotId, fence, &buffer, updateDequeue);
    if (res == C2_OK) {
        // since attach/allocate was successful, prepare for render here.
        {
            std::unique_lock<std::mutex> l(mLock);
            mDeallocating.emplace(buffer->mId);
        }
        cache->blockSlot(buffer->mSlot);
    }
    return res;
}

c2_status_t GraphicsTracker::requestRender(uint64_t bid, std::shared_ptr<BufferCache> *cache,
                                          std::shared_ptr<BufferItem> *pBuffer,
                                          bool *fromCache,
@@ -1095,20 +1197,36 @@ void GraphicsTracker::commitRender(const std::shared_ptr<BufferCache> &cache,
c2_status_t GraphicsTracker::render(const C2ConstGraphicBlock& blk,
                                   const IGraphicBufferProducer::QueueBufferInput &input,
                                   IGraphicBufferProducer::QueueBufferOutput *output) {
    std::shared_ptr<BufferCache> cache;
    std::shared_ptr<BufferItem> buffer;
    uint64_t bid;
    bool updateDequeue = false;
    bool fromCache = false;
    std::shared_ptr<_C2BlockPoolData> poolData = _C2BlockFactory::GetGraphicBlockPoolData(blk);
    if (!poolData) {
        if (!blk.handle()) {
            ALOGE("block does not have native_handle for render");
            return C2_CORRUPTED;
        }
        // This might be a block directly created by gralloc allocator.
        // So we need to attach the block to the surface before render.
        fromCache = true;
        c2_status_t res = requestAttachForRender(
                blk, input.fence, &cache, &buffer, &updateDequeue);
        if (res != C2_OK) {
            if (updateDequeue) {
                updateDequeueConf();
            }
            ALOGE("attaching external buffer for render failed: %d", res);
            return res;
        }
    } else {
        c2_status_t res = retrieveAHardwareBufferId(blk, &bid);
        if (res != C2_OK) {
            ALOGE("retrieving AHB-ID for GraphicBlock failed");
            return C2_CORRUPTED;
        }
    std::shared_ptr<_C2BlockPoolData> poolData =
            _C2BlockFactory::GetGraphicBlockPoolData(blk);
        _C2BlockFactory::DisownIgbaBlock(poolData);
    std::shared_ptr<BufferCache> cache;
    std::shared_ptr<BufferItem> buffer;
    std::shared_ptr<BufferItem> oldBuffer;
    bool updateDequeue = false;
    bool fromCache = false;
        res = requestRender(bid, &cache, &buffer, &fromCache, &updateDequeue);
        if (res != C2_OK) {
            if (updateDequeue) {
@@ -1116,7 +1234,9 @@ c2_status_t GraphicsTracker::render(const C2ConstGraphicBlock& blk,
            }
            return res;
        }
    }
    int cacheSlotId = fromCache ? buffer->mSlot : -1;
    std::shared_ptr<BufferItem> oldBuffer;
    ALOGV("render prepared: igbp(%d) slot(%d)", bool(cache->mIgbp), cacheSlotId);
    if (!fromCache) {
        // The buffer does not come from the current cache.
+5 −0
Original line number Diff line number Diff line
@@ -338,6 +338,11 @@ private:
                              std::shared_ptr<BufferItem> *pBuffer,
                              bool *fromCache,
                              bool *updateDequeue);
    c2_status_t requestAttachForRender(const C2ConstGraphicBlock& blk,
                                const sp<Fence> &fence,
                                std::shared_ptr<BufferCache> *cache,
                                std::shared_ptr<BufferItem> *pBuffer,
                                bool *updateDequeue);

    void commitAllocate(c2_status_t res,
                        const std::shared_ptr<BufferCache> &cache,