Loading media/codec2/vndk/C2AllocatorGralloc.cpp +201 −183 Original line number Diff line number Diff line Loading @@ -319,172 +319,21 @@ c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const R return C2_OK; } } // unnamed namespace native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) { return C2HandleGralloc::UnwrapNativeHandle(handle); } C2Handle *WrapNativeCodec2GrallocHandle( const native_handle_t *const handle, uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride, generation, igbp_id, igbp_slot); } bool MigrateNativeCodec2GrallocHandle( native_handle_t *handle, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot); } class C2AllocationGralloc : public C2GraphicAllocation { public: virtual ~C2AllocationGralloc() override; virtual c2_status_t map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override; virtual c2_status_t unmap( uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override; virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; } virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; } virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override; // internal methods // |handle| will be moved. C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId); int dup() const; c2_status_t status() const; private: const uint32_t mWidth; const uint32_t mHeight; const uint32_t mFormat; const uint32_t mLayerCount; const uint64_t mGrallocUsage; const uint32_t mStride; const hidl_handle mHidlHandle; const C2HandleGralloc *mHandle; buffer_handle_t mBuffer; const C2HandleGralloc *mLockedHandle; bool mLocked; C2Allocator::id_t mAllocatorId; std::mutex mMappedLock; }; C2AllocationGralloc::C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId) : C2GraphicAllocation(width, height), mWidth(width), mHeight(height), mFormat(format), mLayerCount(layerCount), mGrallocUsage(grallocUsage), mStride(stride), mHidlHandle(std::move(hidlHandle)), mHandle(handle), mBuffer(nullptr), mLockedHandle(nullptr), mLocked(false), mAllocatorId(allocatorId) { } C2AllocationGralloc::~C2AllocationGralloc() { if (mBuffer && mLocked) { // implementation ignores addresss and rect uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {}; unmap(addr, C2Rect(), nullptr); } if (mBuffer) { status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer); if (err) { ALOGE("failed transaction: freeBuffer"); } } if (mHandle) { native_handle_delete( const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle))); } if (mLockedHandle) { native_handle_delete( const_cast<native_handle_t *>( reinterpret_cast<const native_handle_t *>(mLockedHandle))); } } c2_status_t C2AllocationGralloc::map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, static c2_status_t PopulatePlaneLayout( buffer_handle_t buffer, const Rect &rect, uint32_t format, uint64_t grallocUsage, uint32_t stride, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) { const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top, (int32_t)(c2Rect.left + c2Rect.width) /* right */, (int32_t)(c2Rect.top + c2Rect.height) /* bottom */}; uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage(); ALOGV("mapping buffer with usage %#llx => %#llx", (long long)usage.expected, (long long)grallocUsage); // TODO (void)fence; std::lock_guard<std::mutex> lock(mMappedLock); if (mBuffer && mLocked) { ALOGD("already mapped"); return C2_DUPLICATE; } if (!layout || !addr) { ALOGD("wrong param"); return C2_BAD_VALUE; } if (!mBuffer) { status_t err = GraphicBufferMapper::get().importBuffer( mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount, mFormat, mGrallocUsage, mStride, &mBuffer); if (err) { ALOGE("failed transaction: importBuffer"); return C2_CORRUPTED; } if (mBuffer == nullptr) { ALOGD("importBuffer returned null buffer"); return C2_CORRUPTED; } uint32_t generation = 0; uint64_t igbp_id = 0; uint32_t igbp_slot = 0; if (mHandle) { mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot); } mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle( mBuffer, mWidth, mHeight, mFormat, mGrallocUsage, mStride, generation, igbp_id, igbp_slot); } // 'NATIVE' on Android means LITTLE_ENDIAN constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE; // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if // possible. uint32_t format = mFormat; uint32_t fourCc; if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && !GraphicBufferMapper::get().getPixelFormatFourCC(mBuffer, &fourCc)) { !GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &fourCc)) { switch (fourCc) { case DRM_FORMAT_XBGR8888: format = static_cast<uint32_t>(PixelFormat4::RGBX_8888); Loading @@ -505,7 +354,7 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; // TODO: fence status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(RGBA_1010102)"); return C2_CORRUPTED; Loading @@ -521,7 +370,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_Y] = { C2PlaneInfo::CHANNEL_Y, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -534,7 +383,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_U] = { C2PlaneInfo::CHANNEL_CB, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -547,7 +396,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_V] = { C2PlaneInfo::CHANNEL_CR, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -560,7 +409,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_A] = { C2PlaneInfo::CHANNEL_A, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -580,7 +429,7 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; // TODO: fence status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(RGBA_8888)"); return C2_CORRUPTED; Loading @@ -594,7 +443,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_R] = { C2PlaneInfo::CHANNEL_R, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -607,7 +456,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_G] = { C2PlaneInfo::CHANNEL_G, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -620,7 +469,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_B] = { C2PlaneInfo::CHANNEL_B, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -637,7 +486,7 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; // TODO: fence status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(BLOB)"); return C2_CORRUPTED; Loading @@ -658,7 +507,7 @@ c2_status_t C2AllocationGralloc::map( android_ycbcr ycbcrLayout; status_t err = GraphicBufferMapper::get().lockYCbCr( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout); if (err) { ALOGE("failed transaction: lockYCbCr (err=%d)", err); return C2_CORRUPTED; Loading Loading @@ -728,20 +577,20 @@ c2_status_t C2AllocationGralloc::map( // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes, // try locking with the gralloc4 mapper first. c2_status_t status = Gralloc4Mapper_lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr); const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr); if (status == C2_OK) { break; } void *pointer = nullptr; status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(YCBCR_P010)"); return C2_CORRUPTED; } addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer; addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height(); addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + stride * 2 * rect.height(); addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2; layout->type = C2PlanarLayout::TYPE_YUV; layout->numPlanes = 3; Loading @@ -749,7 +598,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_Y] = { C2PlaneInfo::CHANNEL_Y, // channel 2, // colInc static_cast<int32_t>(2 * mStride), // rowInc static_cast<int32_t>(2 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 16, // allocatedDepth Loading @@ -762,7 +611,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_U] = { C2PlaneInfo::CHANNEL_CB, // channel 4, // colInc static_cast<int32_t>(2 * mStride), // rowInc static_cast<int32_t>(2 * stride), // rowInc 2, // mColSampling 2, // mRowSampling 16, // allocatedDepth Loading @@ -775,7 +624,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_V] = { C2PlaneInfo::CHANNEL_CR, // channel 4, // colInc static_cast<int32_t>(2 * mStride), // rowInc static_cast<int32_t>(2 * stride), // rowInc 2, // mColSampling 2, // mRowSampling 16, // allocatedDepth Loading @@ -793,7 +642,7 @@ c2_status_t C2AllocationGralloc::map( android_ycbcr ycbcrLayout; if (isAtLeastT()) { c2_status_t status = Gralloc4Mapper_lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr); const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr); if (status == C2_OK) { break; } Loading @@ -801,7 +650,7 @@ c2_status_t C2AllocationGralloc::map( // fallback to lockYCbCr status_t err = GraphicBufferMapper::get().lockYCbCr( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout); if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr && ycbcrLayout.ystride > 0 && ycbcrLayout.cstride > 0 Loading Loading @@ -859,7 +708,7 @@ c2_status_t C2AllocationGralloc::map( // unlock previous allocation if it was successful if (err == OK) { err = GraphicBufferMapper::get().unlock(mBuffer); err = GraphicBufferMapper::get().unlock(buffer); if (err) { ALOGE("failed transaction: unlock"); return C2_CORRUPTED; Loading @@ -868,9 +717,9 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; err = GraphicBufferMapper::get().lock( const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(??? %x)", mFormat); ALOGE("failed transaction: lock(??? %x)", format); return C2_CORRUPTED; } addr[0] = (uint8_t *)pointer; Loading @@ -881,7 +730,7 @@ c2_status_t C2AllocationGralloc::map( // TODO: CHANNEL_UNKNOWN? C2PlaneInfo::channel_t(0xFF), // channel 1, // colInc int32_t(mStride), // rowInc int32_t(stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -894,9 +743,11 @@ c2_status_t C2AllocationGralloc::map( break; } } mLocked = true; return C2_OK; } // handle interleaved formats static void HandleInterleavedPlanes( C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) { if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) { intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U]; intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc; Loading @@ -910,6 +761,173 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset; } } } } // unnamed namespace native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) { return C2HandleGralloc::UnwrapNativeHandle(handle); } C2Handle *WrapNativeCodec2GrallocHandle( const native_handle_t *const handle, uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride, generation, igbp_id, igbp_slot); } bool MigrateNativeCodec2GrallocHandle( native_handle_t *handle, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot); } class C2AllocationGralloc : public C2GraphicAllocation { public: virtual ~C2AllocationGralloc() override; virtual c2_status_t map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override; virtual c2_status_t unmap( uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override; virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; } virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; } virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override; // internal methods // |handle| will be moved. C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId); int dup() const; c2_status_t status() const; private: const uint32_t mWidth; const uint32_t mHeight; const uint32_t mFormat; const uint32_t mLayerCount; const uint64_t mGrallocUsage; const uint32_t mStride; const hidl_handle mHidlHandle; const C2HandleGralloc *mHandle; buffer_handle_t mBuffer; const C2HandleGralloc *mLockedHandle; bool mLocked; C2Allocator::id_t mAllocatorId; std::mutex mMappedLock; }; C2AllocationGralloc::C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId) : C2GraphicAllocation(width, height), mWidth(width), mHeight(height), mFormat(format), mLayerCount(layerCount), mGrallocUsage(grallocUsage), mStride(stride), mHidlHandle(std::move(hidlHandle)), mHandle(handle), mBuffer(nullptr), mLockedHandle(nullptr), mLocked(false), mAllocatorId(allocatorId) { } C2AllocationGralloc::~C2AllocationGralloc() { if (mBuffer && mLocked) { // implementation ignores addresss and rect uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {}; unmap(addr, C2Rect(), nullptr); } if (mBuffer) { status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer); if (err) { ALOGE("failed transaction: freeBuffer"); } } if (mHandle) { native_handle_delete( const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle))); } if (mLockedHandle) { native_handle_delete( const_cast<native_handle_t *>( reinterpret_cast<const native_handle_t *>(mLockedHandle))); } } c2_status_t C2AllocationGralloc::map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) { const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top, (int32_t)(c2Rect.left + c2Rect.width) /* right */, (int32_t)(c2Rect.top + c2Rect.height) /* bottom */}; uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage(); ALOGV("mapping buffer with usage %#llx => %#llx", (long long)usage.expected, (long long)grallocUsage); // TODO (void)fence; std::lock_guard<std::mutex> lock(mMappedLock); if (mBuffer && mLocked) { ALOGD("already mapped"); return C2_DUPLICATE; } if (!layout || !addr) { ALOGD("wrong param"); return C2_BAD_VALUE; } if (!mBuffer) { status_t err = GraphicBufferMapper::get().importBuffer( mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount, mFormat, mGrallocUsage, mStride, &mBuffer); if (err) { ALOGE("failed transaction: importBuffer"); return C2_CORRUPTED; } if (mBuffer == nullptr) { ALOGD("importBuffer returned null buffer"); return C2_CORRUPTED; } uint32_t generation = 0; uint64_t igbp_id = 0; uint32_t igbp_slot = 0; if (mHandle) { mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot); } mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle( mBuffer, mWidth, mHeight, mFormat, mGrallocUsage, mStride, generation, igbp_id, igbp_slot); } c2_status_t ret = PopulatePlaneLayout( mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr); if (ret != C2_OK) { return ret; } mLocked = true; HandleInterleavedPlanes(layout, addr); ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d", layout->type, layout->numPlanes, layout->rootPlanes); Loading Loading
media/codec2/vndk/C2AllocatorGralloc.cpp +201 −183 Original line number Diff line number Diff line Loading @@ -319,172 +319,21 @@ c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const R return C2_OK; } } // unnamed namespace native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) { return C2HandleGralloc::UnwrapNativeHandle(handle); } C2Handle *WrapNativeCodec2GrallocHandle( const native_handle_t *const handle, uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride, generation, igbp_id, igbp_slot); } bool MigrateNativeCodec2GrallocHandle( native_handle_t *handle, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot); } class C2AllocationGralloc : public C2GraphicAllocation { public: virtual ~C2AllocationGralloc() override; virtual c2_status_t map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override; virtual c2_status_t unmap( uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override; virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; } virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; } virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override; // internal methods // |handle| will be moved. C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId); int dup() const; c2_status_t status() const; private: const uint32_t mWidth; const uint32_t mHeight; const uint32_t mFormat; const uint32_t mLayerCount; const uint64_t mGrallocUsage; const uint32_t mStride; const hidl_handle mHidlHandle; const C2HandleGralloc *mHandle; buffer_handle_t mBuffer; const C2HandleGralloc *mLockedHandle; bool mLocked; C2Allocator::id_t mAllocatorId; std::mutex mMappedLock; }; C2AllocationGralloc::C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId) : C2GraphicAllocation(width, height), mWidth(width), mHeight(height), mFormat(format), mLayerCount(layerCount), mGrallocUsage(grallocUsage), mStride(stride), mHidlHandle(std::move(hidlHandle)), mHandle(handle), mBuffer(nullptr), mLockedHandle(nullptr), mLocked(false), mAllocatorId(allocatorId) { } C2AllocationGralloc::~C2AllocationGralloc() { if (mBuffer && mLocked) { // implementation ignores addresss and rect uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {}; unmap(addr, C2Rect(), nullptr); } if (mBuffer) { status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer); if (err) { ALOGE("failed transaction: freeBuffer"); } } if (mHandle) { native_handle_delete( const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle))); } if (mLockedHandle) { native_handle_delete( const_cast<native_handle_t *>( reinterpret_cast<const native_handle_t *>(mLockedHandle))); } } c2_status_t C2AllocationGralloc::map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, static c2_status_t PopulatePlaneLayout( buffer_handle_t buffer, const Rect &rect, uint32_t format, uint64_t grallocUsage, uint32_t stride, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) { const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top, (int32_t)(c2Rect.left + c2Rect.width) /* right */, (int32_t)(c2Rect.top + c2Rect.height) /* bottom */}; uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage(); ALOGV("mapping buffer with usage %#llx => %#llx", (long long)usage.expected, (long long)grallocUsage); // TODO (void)fence; std::lock_guard<std::mutex> lock(mMappedLock); if (mBuffer && mLocked) { ALOGD("already mapped"); return C2_DUPLICATE; } if (!layout || !addr) { ALOGD("wrong param"); return C2_BAD_VALUE; } if (!mBuffer) { status_t err = GraphicBufferMapper::get().importBuffer( mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount, mFormat, mGrallocUsage, mStride, &mBuffer); if (err) { ALOGE("failed transaction: importBuffer"); return C2_CORRUPTED; } if (mBuffer == nullptr) { ALOGD("importBuffer returned null buffer"); return C2_CORRUPTED; } uint32_t generation = 0; uint64_t igbp_id = 0; uint32_t igbp_slot = 0; if (mHandle) { mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot); } mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle( mBuffer, mWidth, mHeight, mFormat, mGrallocUsage, mStride, generation, igbp_id, igbp_slot); } // 'NATIVE' on Android means LITTLE_ENDIAN constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE; // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if // possible. uint32_t format = mFormat; uint32_t fourCc; if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && !GraphicBufferMapper::get().getPixelFormatFourCC(mBuffer, &fourCc)) { !GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &fourCc)) { switch (fourCc) { case DRM_FORMAT_XBGR8888: format = static_cast<uint32_t>(PixelFormat4::RGBX_8888); Loading @@ -505,7 +354,7 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; // TODO: fence status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(RGBA_1010102)"); return C2_CORRUPTED; Loading @@ -521,7 +370,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_Y] = { C2PlaneInfo::CHANNEL_Y, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -534,7 +383,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_U] = { C2PlaneInfo::CHANNEL_CB, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -547,7 +396,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_V] = { C2PlaneInfo::CHANNEL_CR, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -560,7 +409,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_A] = { C2PlaneInfo::CHANNEL_A, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 32, // allocatedDepth Loading @@ -580,7 +429,7 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; // TODO: fence status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(RGBA_8888)"); return C2_CORRUPTED; Loading @@ -594,7 +443,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_R] = { C2PlaneInfo::CHANNEL_R, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -607,7 +456,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_G] = { C2PlaneInfo::CHANNEL_G, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -620,7 +469,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_B] = { C2PlaneInfo::CHANNEL_B, // channel 4, // colInc static_cast<int32_t>(4 * mStride), // rowInc static_cast<int32_t>(4 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -637,7 +486,7 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; // TODO: fence status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(BLOB)"); return C2_CORRUPTED; Loading @@ -658,7 +507,7 @@ c2_status_t C2AllocationGralloc::map( android_ycbcr ycbcrLayout; status_t err = GraphicBufferMapper::get().lockYCbCr( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout); if (err) { ALOGE("failed transaction: lockYCbCr (err=%d)", err); return C2_CORRUPTED; Loading Loading @@ -728,20 +577,20 @@ c2_status_t C2AllocationGralloc::map( // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes, // try locking with the gralloc4 mapper first. c2_status_t status = Gralloc4Mapper_lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr); const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr); if (status == C2_OK) { break; } void *pointer = nullptr; status_t err = GraphicBufferMapper::get().lock( const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(YCBCR_P010)"); return C2_CORRUPTED; } addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer; addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height(); addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + stride * 2 * rect.height(); addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2; layout->type = C2PlanarLayout::TYPE_YUV; layout->numPlanes = 3; Loading @@ -749,7 +598,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_Y] = { C2PlaneInfo::CHANNEL_Y, // channel 2, // colInc static_cast<int32_t>(2 * mStride), // rowInc static_cast<int32_t>(2 * stride), // rowInc 1, // mColSampling 1, // mRowSampling 16, // allocatedDepth Loading @@ -762,7 +611,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_U] = { C2PlaneInfo::CHANNEL_CB, // channel 4, // colInc static_cast<int32_t>(2 * mStride), // rowInc static_cast<int32_t>(2 * stride), // rowInc 2, // mColSampling 2, // mRowSampling 16, // allocatedDepth Loading @@ -775,7 +624,7 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_V] = { C2PlaneInfo::CHANNEL_CR, // channel 4, // colInc static_cast<int32_t>(2 * mStride), // rowInc static_cast<int32_t>(2 * stride), // rowInc 2, // mColSampling 2, // mRowSampling 16, // allocatedDepth Loading @@ -793,7 +642,7 @@ c2_status_t C2AllocationGralloc::map( android_ycbcr ycbcrLayout; if (isAtLeastT()) { c2_status_t status = Gralloc4Mapper_lock( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr); const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr); if (status == C2_OK) { break; } Loading @@ -801,7 +650,7 @@ c2_status_t C2AllocationGralloc::map( // fallback to lockYCbCr status_t err = GraphicBufferMapper::get().lockYCbCr( const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout); const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout); if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr && ycbcrLayout.ystride > 0 && ycbcrLayout.cstride > 0 Loading Loading @@ -859,7 +708,7 @@ c2_status_t C2AllocationGralloc::map( // unlock previous allocation if it was successful if (err == OK) { err = GraphicBufferMapper::get().unlock(mBuffer); err = GraphicBufferMapper::get().unlock(buffer); if (err) { ALOGE("failed transaction: unlock"); return C2_CORRUPTED; Loading @@ -868,9 +717,9 @@ c2_status_t C2AllocationGralloc::map( void *pointer = nullptr; err = GraphicBufferMapper::get().lock( const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer); const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer); if (err) { ALOGE("failed transaction: lock(??? %x)", mFormat); ALOGE("failed transaction: lock(??? %x)", format); return C2_CORRUPTED; } addr[0] = (uint8_t *)pointer; Loading @@ -881,7 +730,7 @@ c2_status_t C2AllocationGralloc::map( // TODO: CHANNEL_UNKNOWN? C2PlaneInfo::channel_t(0xFF), // channel 1, // colInc int32_t(mStride), // rowInc int32_t(stride), // rowInc 1, // mColSampling 1, // mRowSampling 8, // allocatedDepth Loading @@ -894,9 +743,11 @@ c2_status_t C2AllocationGralloc::map( break; } } mLocked = true; return C2_OK; } // handle interleaved formats static void HandleInterleavedPlanes( C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) { if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) { intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U]; intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc; Loading @@ -910,6 +761,173 @@ c2_status_t C2AllocationGralloc::map( layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset; } } } } // unnamed namespace native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) { return C2HandleGralloc::UnwrapNativeHandle(handle); } C2Handle *WrapNativeCodec2GrallocHandle( const native_handle_t *const handle, uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride, generation, igbp_id, igbp_slot); } bool MigrateNativeCodec2GrallocHandle( native_handle_t *handle, uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) { return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot); } class C2AllocationGralloc : public C2GraphicAllocation { public: virtual ~C2AllocationGralloc() override; virtual c2_status_t map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override; virtual c2_status_t unmap( uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override; virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; } virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; } virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override; // internal methods // |handle| will be moved. C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId); int dup() const; c2_status_t status() const; private: const uint32_t mWidth; const uint32_t mHeight; const uint32_t mFormat; const uint32_t mLayerCount; const uint64_t mGrallocUsage; const uint32_t mStride; const hidl_handle mHidlHandle; const C2HandleGralloc *mHandle; buffer_handle_t mBuffer; const C2HandleGralloc *mLockedHandle; bool mLocked; C2Allocator::id_t mAllocatorId; std::mutex mMappedLock; }; C2AllocationGralloc::C2AllocationGralloc( uint32_t width, uint32_t height, uint32_t format, uint32_t layerCount, uint64_t grallocUsage, uint32_t stride, hidl_handle &hidlHandle, const C2HandleGralloc *const handle, C2Allocator::id_t allocatorId) : C2GraphicAllocation(width, height), mWidth(width), mHeight(height), mFormat(format), mLayerCount(layerCount), mGrallocUsage(grallocUsage), mStride(stride), mHidlHandle(std::move(hidlHandle)), mHandle(handle), mBuffer(nullptr), mLockedHandle(nullptr), mLocked(false), mAllocatorId(allocatorId) { } C2AllocationGralloc::~C2AllocationGralloc() { if (mBuffer && mLocked) { // implementation ignores addresss and rect uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {}; unmap(addr, C2Rect(), nullptr); } if (mBuffer) { status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer); if (err) { ALOGE("failed transaction: freeBuffer"); } } if (mHandle) { native_handle_delete( const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle))); } if (mLockedHandle) { native_handle_delete( const_cast<native_handle_t *>( reinterpret_cast<const native_handle_t *>(mLockedHandle))); } } c2_status_t C2AllocationGralloc::map( C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence, C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) { const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top, (int32_t)(c2Rect.left + c2Rect.width) /* right */, (int32_t)(c2Rect.top + c2Rect.height) /* bottom */}; uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage(); ALOGV("mapping buffer with usage %#llx => %#llx", (long long)usage.expected, (long long)grallocUsage); // TODO (void)fence; std::lock_guard<std::mutex> lock(mMappedLock); if (mBuffer && mLocked) { ALOGD("already mapped"); return C2_DUPLICATE; } if (!layout || !addr) { ALOGD("wrong param"); return C2_BAD_VALUE; } if (!mBuffer) { status_t err = GraphicBufferMapper::get().importBuffer( mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount, mFormat, mGrallocUsage, mStride, &mBuffer); if (err) { ALOGE("failed transaction: importBuffer"); return C2_CORRUPTED; } if (mBuffer == nullptr) { ALOGD("importBuffer returned null buffer"); return C2_CORRUPTED; } uint32_t generation = 0; uint64_t igbp_id = 0; uint32_t igbp_slot = 0; if (mHandle) { mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot); } mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle( mBuffer, mWidth, mHeight, mFormat, mGrallocUsage, mStride, generation, igbp_id, igbp_slot); } c2_status_t ret = PopulatePlaneLayout( mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr); if (ret != C2_OK) { return ret; } mLocked = true; HandleInterleavedPlanes(layout, addr); ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d", layout->type, layout->numPlanes, layout->rootPlanes); Loading