From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- .../libwebrtc/modules/portal/pipewire_utils.h | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'third_party/libwebrtc/modules/portal') diff --git a/third_party/libwebrtc/modules/portal/pipewire_utils.h b/third_party/libwebrtc/modules/portal/pipewire_utils.h index 8344a8cefb..c1327b85c9 100644 --- a/third_party/libwebrtc/modules/portal/pipewire_utils.h +++ b/third_party/libwebrtc/modules/portal/pipewire_utils.h @@ -11,6 +11,21 @@ #ifndef MODULES_PORTAL_PIPEWIRE_UTILS_H_ #define MODULES_PORTAL_PIPEWIRE_UTILS_H_ +#include +#include +#include +#include + +// static +struct dma_buf_sync { + uint64_t flags; +}; +#define DMA_BUF_SYNC_READ (1 << 0) +#define DMA_BUF_SYNC_START (0 << 2) +#define DMA_BUF_SYNC_END (1 << 2) +#define DMA_BUF_BASE 'b' +#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) + struct pw_thread_loop; namespace webrtc { @@ -32,6 +47,66 @@ class PipeWireThreadLoopLock { pw_thread_loop* const loop_; }; +// We should synchronize DMA Buffer object access from CPU to avoid potential +// cache incoherency and data loss. +// See +// https://01.org/linuxgraphics/gfx-docs/drm/driver-api/dma-buf.html#cpu-access-to-dma-buffer-objects +static bool SyncDmaBuf(int fd, uint64_t start_or_end) { + struct dma_buf_sync sync = {0}; + + sync.flags = start_or_end | DMA_BUF_SYNC_READ; + + while (true) { + int ret; + ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync); + if (ret == -1 && errno == EINTR) { + continue; + } else if (ret == -1) { + return false; + } else { + break; + } + } + + return true; +} + +class ScopedBuf { + public: + ScopedBuf() {} + ScopedBuf(uint8_t* map, int map_size, int fd, bool is_dma_buf = false) + : map_(map), map_size_(map_size), fd_(fd), is_dma_buf_(is_dma_buf) {} + ~ScopedBuf() { + if (map_ != MAP_FAILED) { + if (is_dma_buf_) { + SyncDmaBuf(fd_, DMA_BUF_SYNC_END); + } + munmap(map_, map_size_); + } + } + + explicit operator bool() { return map_ != MAP_FAILED; } + + void initialize(uint8_t* map, int map_size, int fd, bool is_dma_buf = false) { + map_ = map; + map_size_ = map_size; + is_dma_buf_ = is_dma_buf; + fd_ = fd; + + if (is_dma_buf_) { + SyncDmaBuf(fd_, DMA_BUF_SYNC_START); + } + } + + uint8_t* get() { return map_; } + + protected: + uint8_t* map_ = static_cast(MAP_FAILED); + int map_size_; + int fd_; + bool is_dma_buf_; +}; + } // namespace webrtc #endif // MODULES_PORTAL_PIPEWIRE_UTILS_H_ -- cgit v1.2.3