/* * Copyright (c) 2021 Amlogic, Inc. All rights reserved. * * This source code is subject to the terms and conditions defined in the * file 'LICENSE' which is part of this source code package. * * Description: */ #define LOG_NDEBUG 1 #include #include #include #include #include "UvmDev.h" #define UVM_DEV_PATH "/dev/uvm" #define UVM_IOC_MAGIC 'U' #define UVM_IOC_SET_PID _IOWR(UVM_IOC_MAGIC, 2, struct uvm_pid_data) #define UVM_IOC_SET_FD _IOWR(UVM_IOC_MAGIC, 3, struct uvm_fd_data) #define UVM_IOC_SET_INFO _IOWR(UVM_IOC_MAGIC, 7, struct uvm_hook_data) #define UVM_IOC_DETACH _IOWR(UVM_IOC_MAGIC, 8, struct uvm_hook_data) #define UVM_IOC_GET_VIDEO_INFO _IOWR(UVM_IOC_MAGIC, 11, struct uvm_fd_info) #ifndef LINUX_COMPILE ANDROID_SINGLETON_STATIC_INSTANCE(UvmDev) #else std::mutex UvmDev::sLock; UvmDev * UvmDev::sInstance(nullptr); UvmDev &UvmDev::getInstance() { std::lock_guard lock(sLock); UvmDev *instance = sInstance; if (instance == nullptr) { instance = new UvmDev(); sInstance = instance; } return *instance; } #endif UvmDev::UvmDev() { mDrvFd = open(UVM_DEV_PATH, O_RDWR); MESON_ASSERT(mDrvFd > 0, "/dev/uvm device open failed: %s", strerror(errno)); } UvmDev::~UvmDev() { if (mDrvFd > 0) close(mDrvFd); } int UvmDev::setPid(int pid) { struct uvm_pid_data { int pid; } pid_data; pid_data.pid = pid; MESON_LOGD("setUVM with pid %d", pid); if (ioctl(mDrvFd, UVM_IOC_SET_PID, &pid_data) != 0) { MESON_LOGE("setUVM pid %d ioctl error %s", pid, strerror(errno)); return -1; } return 0; } int UvmDev::commitDisplay(const int fd, const int commit) { struct uvm_fd_data fd_data; fd_data.fd = fd; fd_data.data = commit; if (ioctl(mDrvFd, UVM_IOC_SET_FD, &fd_data) != 0) return -1; return 0; } // detach uvm hooked buffer int UvmDev::detachBuffer(int fd) { struct uvm_hook_data hook_data = { 1 << VF_PROCESS_DI, fd, "dettach", }; if (ioctl(mDrvFd, UVM_IOC_DETACH, &hook_data) != 0) return -1; return 0; } int UvmDev::attachBuffer(const int fd) { struct uvm_hook_data hook_data = { PROCESS_HWC, fd, "detach_flag=1", }; if (ioctl(mDrvFd, UVM_IOC_SET_INFO, &hook_data) != 0) { MESON_LOGV("set uvm %d detach flag failed: %s", fd, strerror(errno)); return -1; } return 0; } /* fd is must be video buffer fd */ int UvmDev::getVideoInfo(struct uvm_fd_info & videoInfo) { if (videoInfo.fd < 0) return -1; if (ioctl(mDrvFd, UVM_IOC_GET_VIDEO_INFO, &videoInfo) != 0) { MESON_LOGV("get %d video info failed: %s", videoInfo.fd, strerror(errno)); return -1; } return 0; }