mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-12 23:09:45 +03:00
DmaBufAllocator: Add Dma Buffer synchronization function & helper class
To synchronize CPU access with mmap and hardware access on DMA buffers, using `DMA_BUF_IOCTL_SYNC` is required. This patch adds a function and a helper class to allow users to sync buffers more easily. Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org> Co-developed-by: Harvey Yang <chenghaoyang@chromium.org> Signed-off-by: Harvey Yang <chenghaoyang@chromium.org> Reviewed-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
562b6335d9
commit
39482d59fe
2 changed files with 95 additions and 0 deletions
|
@ -12,6 +12,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <libcamera/base/flags.h>
|
||||
#include <libcamera/base/shared_fd.h>
|
||||
#include <libcamera/base/unique_fd.h>
|
||||
|
||||
namespace libcamera {
|
||||
|
@ -48,6 +49,26 @@ private:
|
|||
DmaBufAllocatorFlag type_;
|
||||
};
|
||||
|
||||
class DmaSyncer final
|
||||
{
|
||||
public:
|
||||
enum class SyncType {
|
||||
Read = 0,
|
||||
Write,
|
||||
ReadWrite,
|
||||
};
|
||||
|
||||
explicit DmaSyncer(SharedFD fd, SyncType type = SyncType::ReadWrite);
|
||||
|
||||
~DmaSyncer();
|
||||
|
||||
private:
|
||||
void sync(uint64_t step);
|
||||
|
||||
SharedFD fd_;
|
||||
uint64_t flags_ = 0;
|
||||
};
|
||||
|
||||
LIBCAMERA_FLAGS_ENABLE_OPERATORS(DmaBufAllocator::DmaBufAllocatorFlag)
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
|
|
@ -262,4 +262,78 @@ DmaBufAllocator::createBuffer(std::string name,
|
|||
return std::make_unique<FrameBuffer>(planes);
|
||||
}
|
||||
|
||||
/**
|
||||
* \class DmaSyncer
|
||||
* \brief Helper class for dma-buf's synchronization
|
||||
*
|
||||
* This class wraps a userspace dma-buf's synchronization process with an
|
||||
* object's lifetime.
|
||||
*
|
||||
* It's used when the user needs to access a dma-buf with CPU, mostly mapped
|
||||
* with MappedFrameBuffer, so that the buffer is synchronized between CPU and
|
||||
* ISP.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \enum DmaSyncer::SyncType
|
||||
* \brief Read and/or write access via the CPU map
|
||||
* \var DmaSyncer::Read
|
||||
* \brief Indicates that the mapped dma-buf will be read by the client via the
|
||||
* CPU map
|
||||
* \var DmaSyncer::Write
|
||||
* \brief Indicates that the mapped dm-buf will be written by the client via the
|
||||
* CPU map
|
||||
* \var DmaSyncer::ReadWrite
|
||||
* \brief Indicates that the mapped dma-buf will be read and written by the
|
||||
* client via the CPU map
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Construct a DmaSyncer with a dma-buf's fd and the access type
|
||||
* \param[in] fd The dma-buf's file descriptor to synchronize
|
||||
* \param[in] type Read and/or write access via the CPU map
|
||||
*/
|
||||
DmaSyncer::DmaSyncer(SharedFD fd, SyncType type)
|
||||
: fd_(fd)
|
||||
{
|
||||
switch (type) {
|
||||
case SyncType::Read:
|
||||
flags_ = DMA_BUF_SYNC_READ;
|
||||
break;
|
||||
case SyncType::Write:
|
||||
flags_ = DMA_BUF_SYNC_WRITE;
|
||||
break;
|
||||
case SyncType::ReadWrite:
|
||||
flags_ = DMA_BUF_SYNC_RW;
|
||||
break;
|
||||
}
|
||||
|
||||
sync(DMA_BUF_SYNC_START);
|
||||
}
|
||||
|
||||
DmaSyncer::~DmaSyncer()
|
||||
{
|
||||
sync(DMA_BUF_SYNC_END);
|
||||
}
|
||||
|
||||
void DmaSyncer::sync(uint64_t step)
|
||||
{
|
||||
struct dma_buf_sync sync = {
|
||||
.flags = flags_ | step
|
||||
};
|
||||
|
||||
int ret;
|
||||
do {
|
||||
ret = ioctl(fd_.get(), DMA_BUF_IOCTL_SYNC, &sync);
|
||||
} while (ret && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
if (ret) {
|
||||
ret = errno;
|
||||
LOG(DmaBufAllocator, Error)
|
||||
<< "Unable to sync dma fd: " << fd_.get()
|
||||
<< ", err: " << strerror(ret)
|
||||
<< ", flags: " << sync.flags;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue