From 0281f19937bc31b43276c68aff27af1e291cdd97 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 6 Nov 2019 11:38:37 +0200 Subject: fb: add begin_cpu_access & end_cpu_access --- kms++/inc/kms++/dmabufframebuffer.h | 5 ++++ kms++/inc/kms++/framebuffer.h | 10 ++++++++ kms++/src/dmabufframebuffer.cpp | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/kms++/inc/kms++/dmabufframebuffer.h b/kms++/inc/kms++/dmabufframebuffer.h index 494aa97..95460cb 100644 --- a/kms++/inc/kms++/dmabufframebuffer.h +++ b/kms++/inc/kms++/dmabufframebuffer.h @@ -27,6 +27,9 @@ public: uint8_t* map(unsigned plane); int prime_fd(unsigned plane); + void begin_cpu_access(CpuAccess access); + void end_cpu_access(); + private: struct FramebufferPlane { uint32_t handle; @@ -41,6 +44,8 @@ private: struct FramebufferPlane m_planes[4]; PixelFormat m_format; + + uint32_t m_sync_flags = 0; }; } diff --git a/kms++/inc/kms++/framebuffer.h b/kms++/inc/kms++/framebuffer.h index 3d43d08..6f90541 100644 --- a/kms++/inc/kms++/framebuffer.h +++ b/kms++/inc/kms++/framebuffer.h @@ -5,6 +5,13 @@ namespace kms { +enum class CpuAccess +{ + Read, + Write, + ReadWrite, +}; + class IFramebuffer { public: virtual ~IFramebuffer() { } @@ -20,6 +27,9 @@ public: virtual uint32_t offset(unsigned plane) const { throw std::runtime_error("not implemented"); } virtual uint8_t* map(unsigned plane) { throw std::runtime_error("not implemented"); } virtual int prime_fd(unsigned plane) { throw std::runtime_error("not implemented"); } + + virtual void begin_cpu_access(CpuAccess access) { } + virtual void end_cpu_access() { } }; class Framebuffer : public DrmObject, public IFramebuffer diff --git a/kms++/src/dmabufframebuffer.cpp b/kms++/src/dmabufframebuffer.cpp index cdf7a74..00ab94e 100644 --- a/kms++/src/dmabufframebuffer.cpp +++ b/kms++/src/dmabufframebuffer.cpp @@ -4,8 +4,10 @@ #include #include +#include #include #include +#include #include @@ -78,4 +80,50 @@ int DmabufFramebuffer::prime_fd(unsigned plane) return p.prime_fd; } +void DmabufFramebuffer::begin_cpu_access(CpuAccess access) +{ + if (m_sync_flags != 0) + throw runtime_error("begin_cpu sync already started"); + + switch (access) { + case CpuAccess::Read: + m_sync_flags = DMA_BUF_SYNC_READ; + break; + case CpuAccess::Write: + m_sync_flags = DMA_BUF_SYNC_WRITE; + break; + case CpuAccess::ReadWrite: + m_sync_flags = DMA_BUF_SYNC_RW; + break; + } + + dma_buf_sync dbs { + .flags = DMA_BUF_SYNC_START | m_sync_flags + }; + + for (uint32_t p = 0; p < m_num_planes; ++p) { + int r = ioctl(prime_fd(p), DMA_BUF_IOCTL_SYNC, &dbs); + if (r) + throw runtime_error("DMA_BUF_IOCTL_SYNC failed"); + } +} + +void DmabufFramebuffer::end_cpu_access() +{ + if (m_sync_flags == 0) + throw runtime_error("begin_cpu sync not started"); + + dma_buf_sync dbs { + .flags = DMA_BUF_SYNC_END | m_sync_flags + }; + + for (uint32_t p = 0; p < m_num_planes; ++p) { + int r = ioctl(prime_fd(p), DMA_BUF_IOCTL_SYNC, &dbs); + if (r) + throw runtime_error("DMA_BUF_IOCTL_SYNC failed"); + } + + m_sync_flags = 0; +} + } -- cgit v1.2.3