libuvm: add libuvm code [2/2]
PD#SWPL-104040
Problem:
move libuvm from android-hwc to common lib
Solution:
add libuvm code in meson_display
Verify:
t3x
Change-Id: Ia4df8e75487e73d674058a6026680ddbf4930b72
Signed-off-by: leng.fang <leng.fang@amlogic.com>
diff --git a/common/include/MesonLog.h b/common/include/MesonLog.h
new file mode 100644
index 0000000..4f1b9ee
--- /dev/null
+++ b/common/include/MesonLog.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 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:
+ */
+
+#ifndef MESON_LOG_H
+#define MESON_LOG_H
+
+#ifndef LOG_TAG
+#define LOG_TAG "UVM"
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef UVM_RELEASE
+#define MESON_DEBUG_LEVEL 0
+#else
+#define MESON_DEBUG_LEVEL 1
+#endif
+
+#define ALOGV(fmt, ...) fprintf(stderr, "[V] %s: " fmt "\n", LOG_TAG, ##__VA_ARGS__)
+#define ALOGD(fmt, ...) fprintf(stderr, "[D] %s: " fmt "\n", LOG_TAG, ##__VA_ARGS__)
+#define ALOGI(fmt, ...) fprintf(stderr, "[I] %s: " fmt "\n", LOG_TAG, ##__VA_ARGS__)
+#define ALOGW(fmt, ...) fprintf(stderr, "[W] %s: " fmt "\n", LOG_TAG, ##__VA_ARGS__)
+#define ALOGE(fmt, ...) fprintf(stderr, "[E] %s: " fmt "\n", LOG_TAG, ##__VA_ARGS__)
+
+#if MESON_DEBUG_LEVEL > 0
+#define MESON_LOGV(fmt,...) ALOGV(fmt, ##__VA_ARGS__)
+#define MESON_LOGD(fmt,...) ALOGD(fmt, ##__VA_ARGS__)
+#define MESON_LOGI(fmt,...) ALOGI(fmt, ##__VA_ARGS__)
+#define MESON_LOGW(fmt,...) ALOGW(fmt, ##__VA_ARGS__)
+#else
+#define MESON_LOGV(fmt,...) ((void)0)
+#define MESON_LOGD(fmt,...) ((void)0)
+#define MESON_LOGI(fmt,...) ((void)0)
+#define MESON_LOGW(fmt,...) ((void)0)
+#endif
+#define MESON_LOGE(fmt,...) ALOGE(fmt, ##__VA_ARGS__)
+
+#if MESON_DEBUG_LEVEL > 0
+#define MESON_ASSERT(condition,fmt,...) \
+ if (!(condition)) { \
+ ALOGE(fmt, ##__VA_ARGS__); \
+ abort(); \
+ }
+#else
+#define MESON_ASSERT(condition,fmt,...) \
+ if (!(condition)) { \
+ ALOGE(fmt, ##__VA_ARGS__); \
+ }
+#endif
+
+#if MESON_DEBUG_LEVEL > 2
+#define MESON_LOG_FUN_ENTER() ALOGV("Enter %s", __func__)
+#define MESON_LOG_FUN_LEAVE() ALOGV("Leave %s", __func__)
+#else
+#define MESON_LOG_FUN_ENTER() ((void)0)
+#define MESON_LOG_FUN_LEAVE() ((void)0)
+#endif
+
+#define MESON_LOG_EMPTY_FUN() \
+ ALOGD("ERR: PLEASE FIX NON-IMPLEMENT FUN(%s).", __func__);
+
+#endif/*MESON_LOG_H*/
diff --git a/common/include/utils/Errors.h b/common/include/utils/Errors.h
new file mode 100644
index 0000000..3cf2fc1
--- /dev/null
+++ b/common/include/utils/Errors.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <string>
+
+namespace android {
+
+/**
+ * The type used to return success/failure from frameworks APIs.
+ * See the anonymous enum below for valid values.
+ */
+typedef int32_t status_t;
+
+/*
+ * Error codes.
+ * All error codes are negative values.
+ */
+
+enum {
+ OK = 0, // Preferred constant for checking success.
+#ifndef NO_ERROR
+ // Win32 #defines NO_ERROR as well. It has the same value, so there's no
+ // real conflict, though it's a bit awkward.
+ NO_ERROR = OK, // Deprecated synonym for `OK`. Prefer `OK` because it doesn't conflict with Windows.
+#endif
+
+ UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value
+
+ NO_MEMORY = -ENOMEM,
+ INVALID_OPERATION = -ENOSYS,
+ BAD_VALUE = -EINVAL,
+ BAD_TYPE = (UNKNOWN_ERROR + 1),
+ NAME_NOT_FOUND = -ENOENT,
+ PERMISSION_DENIED = -EPERM,
+ NO_INIT = -ENODEV,
+ ALREADY_EXISTS = -EEXIST,
+ DEAD_OBJECT = -EPIPE,
+ FAILED_TRANSACTION = (UNKNOWN_ERROR + 2),
+#if !defined(_WIN32)
+ BAD_INDEX = -EOVERFLOW,
+ NOT_ENOUGH_DATA = -ENODATA,
+ WOULD_BLOCK = -EWOULDBLOCK,
+ TIMED_OUT = -ETIMEDOUT,
+ UNKNOWN_TRANSACTION = -EBADMSG,
+#else
+ BAD_INDEX = -E2BIG,
+ NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3),
+ WOULD_BLOCK = (UNKNOWN_ERROR + 4),
+ TIMED_OUT = (UNKNOWN_ERROR + 5),
+ UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),
+#endif
+ FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7),
+ UNEXPECTED_NULL = (UNKNOWN_ERROR + 8),
+};
+
+// Human readable name of error
+std::string statusToString(status_t status);
+
+} // namespace android
diff --git a/common/include/utils/Mutex.h b/common/include/utils/Mutex.h
new file mode 100644
index 0000000..6331629
--- /dev/null
+++ b/common/include/utils/Mutex.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_MUTEX_H
+#define _LIBS_UTILS_MUTEX_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if !defined(_WIN32)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+
+// Enable thread safety attributes only with clang.
+// The attributes can be safely erased when compiling with other compilers.
+#if defined(__clang__) && (!defined(SWIG))
+#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
+#else
+#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
+#endif
+
+#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
+
+#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+
+#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
+
+#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
+
+#define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
+
+#define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
+
+#define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
+
+#define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
+
+#define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
+
+#define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
+
+#define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
+
+#define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
+
+#define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
+
+#define TRY_ACQUIRE_SHARED(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
+
+#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
+
+#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
+
+#define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
+
+#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+
+#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Condition;
+
+/*
+ * NOTE: This class is for code that builds on Win32. Its usage is
+ * deprecated for code which doesn't build for Win32. New code which
+ * doesn't build for Win32 should use std::mutex and std::lock_guard instead.
+ *
+ * Simple mutex class. The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it. They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class CAPABILITY("mutex") Mutex {
+ public:
+ enum {
+ PRIVATE = 0,
+ SHARED = 1
+ };
+
+ Mutex();
+ explicit Mutex(const char* name);
+ explicit Mutex(int type, const char* name = nullptr);
+ ~Mutex();
+
+ // lock or unlock the mutex
+ status_t lock() ACQUIRE();
+ void unlock() RELEASE();
+
+ // lock if possible; returns 0 on success, error otherwise
+ status_t tryLock() TRY_ACQUIRE(0);
+
+#if defined(__ANDROID__)
+ // Lock the mutex, but don't wait longer than timeoutNs (relative time).
+ // Returns 0 on success, TIMED_OUT for failure due to timeout expiration.
+ //
+ // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep
+ // capabilities consistent across host OSes, this method is only available
+ // when building Android binaries.
+ //
+ // FIXME?: pthread_mutex_timedlock is based on CLOCK_REALTIME,
+ // which is subject to NTP adjustments, and includes time during suspend,
+ // so a timeout may occur even though no processes could run.
+ // Not holding a partial wakelock may lead to a system suspend.
+ status_t timedLock(nsecs_t timeoutNs) TRY_ACQUIRE(0);
+#endif
+
+ // Manages the mutex automatically. It'll be locked when Autolock is
+ // constructed and released when Autolock goes out of scope.
+ class SCOPED_CAPABILITY Autolock {
+ public:
+ inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { mLock.lock(); }
+ inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) { mLock.lock(); }
+ inline ~Autolock() RELEASE() { mLock.unlock(); }
+
+ private:
+ Mutex& mLock;
+ // Cannot be copied or moved - declarations only
+ Autolock(const Autolock&);
+ Autolock& operator=(const Autolock&);
+ };
+
+ private:
+ friend class Condition;
+
+ // A mutex cannot be copied
+ Mutex(const Mutex&);
+ Mutex& operator=(const Mutex&);
+
+#if !defined(_WIN32)
+ pthread_mutex_t mMutex;
+#else
+ void _init();
+ void* mState;
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+#if !defined(_WIN32)
+
+inline Mutex::Mutex() {
+ pthread_mutex_init(&mMutex, nullptr);
+}
+inline Mutex::Mutex(__attribute__((unused)) const char* name) {
+ pthread_mutex_init(&mMutex, nullptr);
+}
+inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
+ if (type == SHARED) {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_mutex_init(&mMutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ } else {
+ pthread_mutex_init(&mMutex, nullptr);
+ }
+}
+inline Mutex::~Mutex() {
+ pthread_mutex_destroy(&mMutex);
+}
+inline status_t Mutex::lock() {
+ return -pthread_mutex_lock(&mMutex);
+}
+inline void Mutex::unlock() {
+ pthread_mutex_unlock(&mMutex);
+}
+inline status_t Mutex::tryLock() {
+ return -pthread_mutex_trylock(&mMutex);
+}
+#if defined(__ANDROID__)
+inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
+ timeoutNs += systemTime(SYSTEM_TIME_REALTIME);
+ const struct timespec ts = {
+ /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
+ /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
+ };
+ return -pthread_mutex_timedlock(&mMutex, &ts);
+}
+#endif
+
+#endif // !defined(_WIN32)
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Automatic mutex. Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+
+typedef Mutex::Autolock AutoMutex;
+
+// ---------------------------------------------------------------------------
+} // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_MUTEX_H
diff --git a/common/include/utils/Singleton.h b/common/include/utils/Singleton.h
new file mode 100644
index 0000000..c869344
--- /dev/null
+++ b/common/include/utils/Singleton.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UTILS_SINGLETON_H
+#define ANDROID_UTILS_SINGLETON_H
+
+#include <stdint.h>
+
+// some vendor code assumes they have atoi() after including this file.
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <utils/Mutex.h>
+#include <cutils/compiler.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+// Singleton<TYPE> may be used in multiple libraries, only one of which should
+// define the static member variables using ANDROID_SINGLETON_STATIC_INSTANCE.
+// Turn off -Wundefined-var-template so other users don't get:
+// instantiation of variable 'android::Singleton<TYPE>::sLock' required here,
+// but no definition is available
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundefined-var-template"
+#endif
+
+// DO NOT USE: Please use scoped static initialization. For instance:
+// MyClass& getInstance() {
+// static MyClass gInstance(...);
+// return gInstance;
+// }
+template <typename TYPE>
+class ANDROID_API Singleton
+{
+public:
+ static TYPE& getInstance() {
+ Mutex::Autolock _l(sLock);
+ TYPE* instance = sInstance;
+ if (instance == nullptr) {
+ instance = new TYPE();
+ sInstance = instance;
+ }
+ return *instance;
+ }
+
+ static bool hasInstance() {
+ Mutex::Autolock _l(sLock);
+ return sInstance != nullptr;
+ }
+
+protected:
+ ~Singleton() { }
+ Singleton() { }
+
+private:
+ Singleton(const Singleton&);
+ Singleton& operator = (const Singleton&);
+ static Mutex sLock;
+ static TYPE* sInstance;
+};
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+/*
+ * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file
+ * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
+ * and avoid to have a copy of them in each compilation units Singleton<TYPE>
+ * is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
+ */
+
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
+ template<> ::android::Mutex \
+ (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \
+ template<> TYPE* ::android::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \
+ template class ::android::Singleton< TYPE >;
+
+
+// ---------------------------------------------------------------------------
+} // namespace android
+
+#endif // ANDROID_UTILS_SINGLETON_H
+
diff --git a/libuvm/CMakeLists.txt b/libuvm/CMakeLists.txt
new file mode 100644
index 0000000..cb6b553
--- /dev/null
+++ b/libuvm/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required (VERSION 2.6)
+
+project (uvm)
+
+SET(SRC_LIST UvmDev.cpp Uvm.cpp)
+
+add_compile_options(-fPIC -Wl,--no-as-needed)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/../common/include)
+
+LINK_DIRECTORIES(${PROJECT_SOURCE_DIR})
+
+if (${UVM_LIB_MODE} MATCHES "static")
+ add_library(uvm STATIC ${SRC_LIST})
+else()
+ add_library(uvm SHARED ${SRC_LIST})
+endif()
+TARGET_LINK_LIBRARIES(uvm pthread)
+
+set_target_properties(uvm PROPERTIES SOVERSION 0 VERSION 0.0.0)
+
+install(TARGETS uvm LIBRARY DESTINATION ${LIB_DIR})
+install(DIRECTORY include/ DESTINATION ${INCLUDE_DIR})
diff --git a/libuvm/Uvm.cpp b/libuvm/Uvm.cpp
new file mode 100644
index 0000000..88e3ab0
--- /dev/null
+++ b/libuvm/Uvm.cpp
@@ -0,0 +1,26 @@
+#include <UvmDev.h>
+
+int setPid(int pid)
+{
+ return UvmDev::getInstance().setPid(pid);
+}
+
+int commitDisplay(const int fd, const int commit)
+{
+ return UvmDev::getInstance().commitDisplay(fd, commit);
+}
+
+int32_t attachUvmBuffer(int bufferFd)
+{
+ return UvmDev::getInstance().attachBuffer(bufferFd);
+}
+
+int32_t dettachUvmBuffer(int bufferFd)
+{
+ return UvmDev::getInstance().dettachBuffer(bufferFd);
+}
+
+int32_t getVideoType(int bufferFd)
+{
+ return UvmDev::getInstance().getVideoType(bufferFd);
+}
diff --git a/libuvm/UvmDev.cpp b/libuvm/UvmDev.cpp
new file mode 100644
index 0000000..2a09a76
--- /dev/null
+++ b/libuvm/UvmDev.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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 <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_TYPE _IOWR(UVM_IOC_MAGIC, 11, struct uvm_fd_data)
+
+ANDROID_SINGLETON_STATIC_INSTANCE(UvmDev)
+
+UvmDev::UvmDev() {
+ mDrvFd = open(UVM_DEV_PATH, O_RDWR);
+ MESON_ASSERT(mDrvFd > 0, "UVM dev open failed");
+}
+
+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;
+}
+
+// dettach uvm hooked buffer
+int UvmDev::dettachBuffer(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;
+}
+
+int UvmDev::getVideoType(const int fd) {
+ struct uvm_fd_data fd_data;
+ fd_data.fd = fd;
+ fd_data.data = 0;
+
+ if (ioctl(mDrvFd, UVM_IOC_GET_TYPE, &fd_data) != 0) {
+ MESON_LOGV("get %d video type failed: %s", fd, strerror(errno));
+ return 0;
+ }
+
+ return fd_data.data;
+}
diff --git a/libuvm/include/Uvm.h b/libuvm/include/Uvm.h
new file mode 100644
index 0000000..4591264
--- /dev/null
+++ b/libuvm/include/Uvm.h
@@ -0,0 +1,15 @@
+
+#ifndef UVM_H
+#define UVM_H
+
+__BEGIN_DECLS
+
+int setPid(int pid);
+int commitDisplay(const int fd, const int commit);
+int32_t attachUvmBuffer(int bufferFd);
+int32_t dettachUvmBuffer(int bufferFd);
+int32_t getVideoType(int bufferFd);
+
+__END_DECLS
+
+#endif
diff --git a/libuvm/include/UvmDev.h b/libuvm/include/UvmDev.h
new file mode 100644
index 0000000..742762b
--- /dev/null
+++ b/libuvm/include/UvmDev.h
@@ -0,0 +1,67 @@
+/*
+ * 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:
+ */
+
+#ifndef HWC_UVMDEV_H
+#define HWC_UVMDEV_H
+
+#include <utils/Singleton.h>
+
+#define META_DATA_SIZE (512)
+
+/**
+ * please sync the file in kernel UVM module
+ * if you change uvm_hook_mod_type.
+ * include/linux/amlogic/meson_uvm_core.h
+ */
+enum uvm_hook_mod_type {
+ VF_SRC_DECODER,
+ VF_SRC_VDIN,
+ VF_PROCESS_V4LVIDEO,
+ VF_PROCESS_DI,
+ VF_PROCESS_VIDEOCOMPOSER,
+ VF_PROCESS_DECODER,
+ PROCESS_NN,
+ PROCESS_GRALLOC,
+ PROCESS_AIPQ,
+ PROCESS_DALTON,
+ PROCESS_AIFACE,
+ PROCESS_AICOLOR,
+ PROCESS_HWC,
+ PROCESS_INVALID,
+};
+
+struct uvm_fd_data {
+ int fd;
+ int data;
+};
+
+struct uvm_hook_data {
+ int mode_type;
+ int shared_fd;
+ char data_buf[META_DATA_SIZE + 1];
+};
+
+class UvmDev : public android::Singleton<UvmDev> {
+public:
+ UvmDev();
+ ~UvmDev();
+
+ // set SF fd to uvm
+ int setPid(int pid);
+ // set UVM buffer fd to driver
+ int commitDisplay(const int fd, const int commit);
+ int dettachBuffer(const int fd);
+ int attachBuffer(const int fd);
+ int getVideoType(const int fd);
+
+private:
+ int mDrvFd;
+};
+
+#endif /* HWC_UVMDEV_H */