Files
BPI-CM9-Linux/aml-comp/vendor/amlogic/meson_display/libs/libuvm/UvmDev.cpp
T
2026-08-24 10:03:24 +08:00

120 lines
2.8 KiB
C++

/*
* 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 <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <MesonLog.h>
#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<std::mutex> 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;
}