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

Commit ea8fec6c authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "C2AllocatorBlob: allow multiple maps"

parents d19faf82 d04f34cd
Loading
Loading
Loading
Loading
+66 −6
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
// #define LOG_NDEBUG 0
#define LOG_TAG "C2AllocatorBlob"

#include <set>

#include <C2AllocatorBlob.h>
#include <C2PlatformSupport.h>

@@ -67,6 +69,10 @@ public:
private:
    const std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
    const C2Allocator::id_t mAllocatorId;

    std::mutex mMapLock;
    std::multiset<std::pair<size_t, size_t>> mMappedOffsetSize;
    uint8_t *mMappedAddr;
};

C2AllocationBlob::C2AllocationBlob(
@@ -74,20 +80,74 @@ C2AllocationBlob::C2AllocationBlob(
        C2Allocator::id_t allocatorId)
      : C2LinearAllocation(capacity),
        mGraphicAllocation(std::move(graphicAllocation)),
        mAllocatorId(allocatorId) {}
        mAllocatorId(allocatorId),
        mMappedAddr(nullptr) {}

C2AllocationBlob::~C2AllocationBlob() {}
C2AllocationBlob::~C2AllocationBlob() {
    if (mMappedAddr) {
        C2Rect rect(capacity(), kLinearBufferHeight);
        mGraphicAllocation->unmap(&mMappedAddr, rect, nullptr);
    }
}

c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage,
                                  C2Fence* fence, void** addr /* nonnull */) {
    *addr = nullptr;
    if (size > capacity() || offset > capacity() || offset > capacity() - size) {
        ALOGV("C2AllocationBlob: map: bad offset / size: offset=%zu size=%zu capacity=%u",
                offset, size, capacity());
        return C2_BAD_VALUE;
    }
    std::unique_lock<std::mutex> lock(mMapLock);
    if (mMappedAddr) {
        *addr = mMappedAddr + offset;
        mMappedOffsetSize.insert({offset, size});
        ALOGV("C2AllocationBlob: mapped from existing mapping: offset=%zu size=%zu capacity=%u",
                offset, size, capacity());
        return C2_OK;
    }
    C2PlanarLayout layout;
    C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u);
    return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast<uint8_t**>(addr));
    C2Rect rect = C2Rect(capacity(), kLinearBufferHeight);
    c2_status_t err = mGraphicAllocation->map(rect, usage, fence, &layout, &mMappedAddr);
    if (err != C2_OK) {
        ALOGV("C2AllocationBlob: map failed: offset=%zu size=%zu capacity=%u err=%d",
                offset, size, capacity(), err);
        mMappedAddr = nullptr;
        return err;
    }
    *addr = mMappedAddr + offset;
    mMappedOffsetSize.insert({offset, size});
    ALOGV("C2AllocationBlob: new map succeeded: offset=%zu size=%zu capacity=%u",
            offset, size, capacity());
    return C2_OK;
}

c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) {
    C2Rect rect(size, kLinearBufferHeight);
    return mGraphicAllocation->unmap(reinterpret_cast<uint8_t**>(&addr), rect, fenceFd);
    std::unique_lock<std::mutex> lock(mMapLock);
    uint8_t *u8Addr = static_cast<uint8_t *>(addr);
    if (u8Addr < mMappedAddr || mMappedAddr + capacity() < u8Addr + size) {
        ALOGV("C2AllocationBlob: unmap: Bad addr / size: addr=%p size=%zu capacity=%u",
                addr, size, capacity());
        return C2_BAD_VALUE;
    }
    auto it = mMappedOffsetSize.find(std::make_pair(u8Addr - mMappedAddr, size));
    if (it == mMappedOffsetSize.end()) {
        ALOGV("C2AllocationBlob: unrecognized map: addr=%p size=%zu capacity=%u",
                addr, size, capacity());
        return C2_BAD_VALUE;
    }
    mMappedOffsetSize.erase(it);
    if (!mMappedOffsetSize.empty()) {
        ALOGV("C2AllocationBlob: still maintain mapping: addr=%p size=%zu capacity=%u",
                addr, size, capacity());
        return C2_OK;
    }
    C2Rect rect(capacity(), kLinearBufferHeight);
    c2_status_t err = mGraphicAllocation->unmap(&mMappedAddr, rect, fenceFd);
    ALOGV("C2AllocationBlob: last unmap: addr=%p size=%zu capacity=%u err=%d",
            addr, size, capacity(), err);
    mMappedAddr = nullptr;
    return err;
}

/* ====================================== BLOB ALLOCATOR ====================================== */