summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2019-11-06 11:38:37 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2019-11-06 17:16:23 +0200
commit0281f19937bc31b43276c68aff27af1e291cdd97 (patch)
treeb753e64b61479b16549f1d049f7ee42d13becd9c
parent37a76a53ddf8c740b479f773d7d10ad7ca074d83 (diff)
fb: add begin_cpu_access & end_cpu_access
-rw-r--r--kms++/inc/kms++/dmabufframebuffer.h5
-rw-r--r--kms++/inc/kms++/framebuffer.h10
-rw-r--r--kms++/src/dmabufframebuffer.cpp48
3 files changed, 63 insertions, 0 deletions
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 <stdexcept>
#include <sys/mman.h>
+#include <sys/ioctl.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include <linux/dma-buf.h>
#include <kms++/kms++.h>
@@ -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;
+}
+
}