/* * dma_buffer.cpp - DMA Buffer Implementation * * Copyright (c) 2021 Rockchip Electronics Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: Cody Xie */ #include "dma_buffer.h" #include #include #include #include #include #include "xcam_log.h" #include "xcam_std.h" namespace XCam { DmaBuffer::DmaBuffer(int fd, size_t size) : fd_(fd), size_(size), ptr_(nullptr) {} DmaBuffer::~DmaBuffer() { if (ptr_ != nullptr) { unmap(); } } XCamReturn DmaBuffer::sync(int fd, DmaBufferDirection direction, bool start) { int ret; struct dma_buf_sync sync = {0}; XCAM_ASSERT(fd >= 0); if (direction == DmaBufferDirection::kDeviceToCPU) { sync.flags = DMA_BUF_SYNC_READ; } else if (direction == DmaBufferDirection::kCPUToDevice) { sync.flags = DMA_BUF_SYNC_WRITE; } else { sync.flags = DMA_BUF_SYNC_RW; } if (start) { sync.flags |= DMA_BUF_SYNC_START; } else { sync.flags |= DMA_BUF_SYNC_END; } ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync); if (ret) { LOGE("DMA_BUF_IOCTL_SYNC ioctl failed %s", strerror(errno)); return XCAM_RETURN_ERROR_IOCTL; } LOGI("%s CPU access dir %d for BO fd %d", start ? "start" : "end", direction, fd); return XCAM_RETURN_NO_ERROR; } XCamReturn DmaBuffer::beginCpuAccess(DmaBufferDirection direction) { XCAM_ASSERT(ptr_ != nullptr); return sync(fd_.Get(), direction, true); } XCamReturn DmaBuffer::endCpuAccess(DmaBufferDirection direction) { XCAM_ASSERT(ptr_ != nullptr); return sync(fd_.Get(), direction, false); } void* DmaBuffer::map() { int ret; assert(((void)"could not map invalid dma_buf", fd_.Get() > 0 && ptr_ == nullptr && size_ > 0)); ptr_ = mmap(0, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_.Get(), 0); if (ptr_ == MAP_FAILED) { LOGE("dma_buf map failed %s", strerror(errno)); return nullptr; } return ptr_; } void DmaBuffer::unmap() { assert(((void)"unmap dma_buf in wrong state", fd_.Get() > 0 && ptr_ != nullptr)); munmap(ptr_, size_); ptr_ = nullptr; } int DmaBuffer::getFd() { return fd_.Get(); } size_t DmaBuffer::getSize() { return size_; } int DmaBuffer::release() { return fd_.Release(); } bool DmaBuffer::mapped() { return ptr_ == nullptr ? false : true; } } // namespace XCam