Skip to content

Instantly share code, notes, and snippets.

@YuKongA
Last active September 23, 2023 12:39
Show Gist options
  • Save YuKongA/81924b5685338645ee8e672fe4c2e5a0 to your computer and use it in GitHub Desktop.
Save YuKongA/81924b5685338645ee8e672fe4c2e5a0 to your computer and use it in GitHub Desktop.
From 1ce73bbf93f3fecf43cf669fff6eb49c42bbe3ae Mon Sep 17 00:00:00 2001
From: YuKongA <1348547200@qq.com>
Date: Fri, 1 Sep 2023 11:45:45 +0800
Subject: [PATCH] Add simple FEAS support
Change-Id: I80871bc38df86f76135fcd8bf32f0fe2b3aa98da
---
libs/gui/Surface.cpp | 190 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 190 insertions(+)
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 4c8079265a..60a04c7527 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -47,6 +47,11 @@
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
+#include <string>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <android-base/properties.h>
+
namespace android {
using ui::Dataspace;
@@ -63,6 +68,178 @@ bool isInterceptorRegistrationOp(int op) {
} // namespace
+namespace {
+
+typedef struct _FEAS_BUFFER_PACKAGE {
+ __u32 pid;
+ union {
+ __u32 start;
+ __u32 connectedAPI;
+ };
+ union {
+ __u64 frame_time;
+ __u64 bufID;
+ };
+ __u64 frame_id;
+ __s32 queue_SF;
+ __u64 identifier;
+} FEAS_BUFFER_PACKAGE;
+
+#define FEAS_QUEUE_BEG _IOW('g', 1, FEAS_BUFFER_PACKAGE)
+#define FEAS_CONNECT _IOW('g', 15, FEAS_BUFFER_PACKAGE)
+
+#define ALOGTI(TAG_NAME, ...) do{((void)ALOG(LOG_INFO, TAG_NAME, __VA_ARGS__));}while(0)
+#define ALOGTD(TAG_NAME, ...) do{((void)ALOG(LOG_DEBUG, TAG_NAME, __VA_ARGS__));}while(0)
+
+#define FEAS_IOCTL_PATH "/proc/perfmgr/perf_ioctl"
+
+static Mutex mFEASMutex;
+
+int mFEASDevFd = -1;
+inline static bool checkFEASDev() {
+ if (mFEASDevFd >= 0) {
+ return true;
+ } else if (mFEASDevFd == -1) {
+ mFEASDevFd = open(FEAS_IOCTL_PATH, O_RDONLY);
+ if (mFEASDevFd >= 0)
+ return true;
+ if (mFEASDevFd < 0) {
+ mFEASDevFd = -2;
+ ALOGTD("FEAS", "Can't open %s: %s", FEAS_IOCTL_PATH, strerror(errno));
+ return false;
+ }
+ }
+ return false;
+}
+
+static inline void getProcessNameByPid(int pid, std::string &processName) {
+ char buf[64] = {0};
+ const char *statusPath = "/proc/%d/status";
+ snprintf(buf, 64, statusPath, pid);
+ FILE *file = fopen(buf, "r");
+ if (file) {
+ while (fgets(buf, 64, file) != nullptr) {
+ if (strncmp(buf, "Name:", 5) == 0) {
+ sscanf(buf, "%*s%s", buf);
+ processName.assign(buf);
+ break;
+ }
+ }
+ fclose(file);
+ }
+}
+
+inline static void getProcessNameByPid2(int pid, std::string &processName) {
+ char buf[64] = {0};
+ int cnt = 0;
+ const char *statusPath = "/proc/%d/cmdline";
+ snprintf(buf, 64, statusPath, pid);
+ FILE *file = fopen(buf, "r");
+ if (file) {
+ if (fgets(buf, sizeof(buf), file)) {
+ cnt = (int) strlen(buf);
+ while (cnt >= 0 && buf[cnt] != '/') cnt--;
+ cnt++;
+ processName.assign(&buf[cnt]);
+ }
+ fclose(file);
+ }
+}
+
+bool mFEASInitialized = false;
+bool mFEASEnable = false;
+static bool checkFEASEnable() {
+ if (mFEASInitialized) return mFEASEnable;
+ pid_t pid = getpid();
+ mFEASEnable = android::base::GetBoolProperty("ro.feas.enable", false);
+ if (mFEASEnable) {
+ std::string processName;
+ getProcessNameByPid2(pid, processName);
+ const char *processNameCStr = processName.c_str();
+ if (strncmp(processNameCStr, "surfaceflinger", 14) == 0 ||
+ strncmp(processNameCStr, "com.android.systemui", 20) == 0 ||
+ strncmp(processNameCStr, "com.tencent.mobileqq", 20) == 0 ||
+ strncmp(processNameCStr, "com.tencent.mm", 14) == 0 ||
+ strncmp(processNameCStr, "com.tencent.qqmusic", 19) == 0 ||
+ strncmp(processNameCStr, "com.taobao.", 11) == 0 ||
+ strncmp(processNameCStr, "com.eg.android.AlipayGphone", 27) == 0 ||
+ strncmp(processNameCStr, "com.jingdong", 12) == 0 ||
+ strncmp(processNameCStr, "com.jd.", 7) == 0 ||
+ strncmp(processNameCStr, "tv.danmaku.bili", 15) == 0 ||
+ strncmp(processNameCStr, "com.bilibili.app.in", 19) == 0 ||
+ strncmp(processNameCStr, "org.telegram.messenger", 22) == 0 ||
+ strncmp(processNameCStr, "com.baidu.", 10) == 0 ||
+ strncmp(processNameCStr, "com.autonavi.minimap", 20) == 0 ||
+ strncmp(processNameCStr, "com.coolapk.market", 18) == 0 ||
+ strstr(processNameCStr, "magisk") != nullptr)
+ mFEASEnable = false;
+ }
+ std::string processName;
+ getProcessNameByPid(pid, processName);
+ ALOGTI(processName.c_str(), "Support FEAS: %s", mFEASEnable ? "true" : "false");
+ mFEASInitialized = true;
+ return mFEASEnable;
+}
+
+inline static void feasConnect(const int32_t& api, const uint64_t& identifier) {
+ FEAS_BUFFER_PACKAGE msg;
+ Mutex::Autolock lock(mFEASMutex);
+ msg.pid = getpid();
+ msg.connectedAPI = api;
+ msg.identifier = identifier;
+ if (checkFEASDev()) ioctl(mFEASDevFd, FEAS_CONNECT, &msg);
+ /*
+ std::string processName;
+ getProcessNameByPid(getpid(), processName);
+ if (checkFEASDev()) {
+ int ret = ioctl(mFEASDevFd, FEAS_CONNECT, &msg);
+ ALOGTI(processName.c_str(), "FEAS conn ioctl: %d", ret);
+ } else {
+ ALOGTD(processName.c_str(), "checkFEASDev: %s", "false");
+ }
+ */
+}
+
+inline static void feasQueueBEG(const uint64_t& identifier) {
+ FEAS_BUFFER_PACKAGE msg;
+ Mutex::Autolock lock(mFEASMutex);
+ msg.pid = getpid();
+ msg.start = 1;
+ msg.identifier = identifier;
+ if (checkFEASDev()) ioctl(mFEASDevFd, FEAS_QUEUE_BEG, &msg);
+ /*
+ std::string processName;
+ getProcessNameByPid(getpid(), processName);
+ if (checkFEASDev()) {
+ int ret = ioctl(mFEASDevFd, FEAS_QUEUE_BEG, &msg);
+ ALOGTI(processName.c_str(), "FEAS queue ioctl: %d", ret);
+ } else {
+ ALOGTD(processName.c_str(), "checkFEASDev: %s", "false");
+ }
+ */
+}
+
+inline static void feasDisconnect(const uint64_t& identifier) {
+ FEAS_BUFFER_PACKAGE msg;
+ Mutex::Autolock lock(mFEASMutex);
+ msg.pid = getpid();
+ msg.identifier = identifier;
+ msg.connectedAPI = 0;
+ if (checkFEASDev()) ioctl(mFEASDevFd, FEAS_CONNECT, &msg);
+ /*
+ std::string processName;
+ getProcessNameByPid(getpid(), processName);
+ if (checkFEASDev()) {
+ int ret = ioctl(mFEASDevFd, FEAS_CONNECT, &msg);
+ ALOGTI(processName.c_str(), "FEAS disconn ioctl: %d", ret);
+ } else {
+ ALOGTD(processName.c_str(), "checkFEASDev: %s", "false");
+ }
+ */
+}
+
+} // namespace
+
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
const sp<IBinder>& surfaceControlHandle)
: mGraphicBufferProducer(bufferProducer),
@@ -1165,6 +1342,10 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
ALOGV("Surface::queueBuffer");
Mutex::Autolock lock(mMutex);
+ if (checkFEASEnable()) {
+ feasQueueBEG(static_cast<uint64_t>(reinterpret_cast<intptr_t>(this)));
+ }
+
int i = getSlotFromBufferLocked(buffer);
if (i < 0) {
if (fenceFd >= 0) {
@@ -1925,6 +2106,10 @@ int Surface::connect(
mDirtyRegion = Region::INVALID_REGION;
}
+ if (checkFEASEnable()) {
+ feasConnect(api, static_cast<uint64_t>(reinterpret_cast<intptr_t>(this)));
+ }
+
return err;
}
@@ -1955,6 +2140,10 @@ int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
mConnectedToCpu = false;
}
}
+
+ if (checkFEASEnable()) {
+ feasDisconnect(static_cast<uint64_t>(reinterpret_cast<intptr_t>(this)));
+ }
return err;
}
@@ -2654,3 +2843,4 @@ void Surface::destroy() {
}
}; // namespace android
+
--
2.39.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment