#ifdef DRV_MEDIATEK
// clang-format off
+#include <fcntl.h>
+#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
+#include <unistd.h>
#include <xf86drm.h>
#include <mediatek_drm.h>
// clang-format on
struct mediatek_private_map_data {
void *cached_addr;
void *gem_addr;
+ int prime_fd;
};
static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
{
- int ret;
+ int ret, prime_fd;
struct drm_mtk_gem_map_off gem_map;
struct mediatek_private_map_data *priv;
return MAP_FAILED;
}
+ ret = drmPrimeHandleToFD(bo->drv->fd, gem_map.handle, DRM_CLOEXEC, &prime_fd);
+ if (ret) {
+ drv_log("Failed to get a prime fd\n");
+ return MAP_FAILED;
+ }
+
void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
gem_map.offset);
vma->length = bo->total_size;
+ priv = calloc(1, sizeof(*priv));
+ priv->prime_fd = prime_fd;
+ vma->priv = priv;
+
if (bo->use_flags & BO_USE_RENDERSCRIPT) {
- priv = calloc(1, sizeof(*priv));
priv->cached_addr = calloc(1, bo->total_size);
priv->gem_addr = addr;
- vma->priv = priv;
addr = priv->cached_addr;
}
if (vma->priv) {
struct mediatek_private_map_data *priv = vma->priv;
vma->addr = priv->gem_addr;
+ close(priv->prime_fd);
free(priv->cached_addr);
free(priv);
vma->priv = NULL;
static int mediatek_bo_invalidate(struct bo *bo, struct mapping *mapping)
{
- if (mapping->vma->priv) {
- struct mediatek_private_map_data *priv = mapping->vma->priv;
- memcpy(priv->cached_addr, priv->gem_addr, bo->total_size);
+ struct mediatek_private_map_data *priv = mapping->vma->priv;
+
+ if (priv) {
+ struct pollfd fds = {
+ .fd = priv->prime_fd,
+ };
+
+ if (mapping->vma->map_flags & BO_MAP_WRITE)
+ fds.events |= POLLOUT;
+
+ if (mapping->vma->map_flags & BO_MAP_READ)
+ fds.events |= POLLIN;
+
+ poll(&fds, 1, -1);
+ if (fds.revents != fds.events)
+ drv_log("poll prime_fd failed\n");
+
+ if (priv->cached_addr)
+ memcpy(priv->cached_addr, priv->gem_addr, bo->total_size);
}
return 0;
static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping)
{
struct mediatek_private_map_data *priv = mapping->vma->priv;
- if (priv && (mapping->vma->map_flags & BO_MAP_WRITE))
+ if (priv && priv->cached_addr && (mapping->vma->map_flags & BO_MAP_WRITE))
memcpy(priv->gem_addr, priv->cached_addr, bo->total_size);
return 0;