0%

Android可执行文件imgui绘制

之前我在 Android 外部 imgui 绘制 (二) 里说过
在 Android 外部 imgui 绘制 (一) 里介绍了怎么实现一个外部 imgui, 其实还有一种方法,就是在 aosp 环境下编译一个可执行文件出来,有点类似于
可执行文件 + skia 绘制
但这个其实很麻烦,需要下载 android 源码 (100 多 g), 然后还要自己编译,最后还得修改代码。所以不太建议这么做。虽然效率可能确实会有提升.
好吧,我来填坑了.

过程

下载 Android12, 编译 Android12.

这些网上有很多教学,值得一提的是,相比 Android5, 新版本编译的时候没有什么错误,基本上一次过。很爽.

Android 系统开发系列(1):Android 12 源代码下载、编译和刷机

死磕 Android_AOSP 编译过程

注意:硬盘剩余空间一定要大于 250g, 硬盘剩余空间一定要大于 250g, 硬盘剩余空间一定要大于 250g
否则失败了会很麻烦.

复制源文件到 Android 源码里

把 imgui 的相关代码丢到 external 里.


文件结构如上图.

imgui

1. 新建 SurfaceComposerClient, 并从 SurfaceComposerClient 中创建 surface, 这个 SurfaceComposerClient 其实是 surfaceflinger 进程的代理对象.

1
2
3
4
5
6
7
8
9
10
11
12
13
sp<SurfaceComposerClient> client = new SurfaceComposerClient();
sp<IBinder> mDisplay = SurfaceComposerClient::getInternalDisplayToken();

ui::DisplayMode mode;
status_t result = SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode);

sp<SurfaceControl> control = client->createSurface(
String8("Shocker"),
mode.resolution.getWidth(),
mode.resolution.getHeight(),
PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState,
nullptr);

这其实非常重要,对于 imgui 来说,它只需要绑定一个窗口 (NativeWindow), 就可以在上面绘制.

2. 获取 NativeWindow, 绑定到 imgui 上

1
2
3
4
5
6
7
sp<Surface> mSurface = control->getSurface();
sp<ANativeWindow> mANW = mSurface;
ANativeWindow *g_EglNativeWindowType(mANW.get());
LOGD("initSurface finish");
LOGD("g_EglNativeWindowType:%llx", g_EglNativeWindowType);

init(g_EglNativeWindowType);

3.imgui 初始化

1
2
3
4
5
6
7
8
9
void init(ANativeWindow *g_EglNativeWindowType)
{
if (g_Initialized)
return;

ANativeWindow_acquire(g_EglNativeWindowType);
............................
(把源码里的g_App->window全部替换成g_EglNativeWindowType,其余不变)
}

4.imgui 循环渲染

1
2
3
4
5
while (true)
{
handleInputEvent(); //处理触摸事件,获取触摸可以参考我之前的文章.
tick(); //渲染画面
}

最后一点

安卓 12 要用 Android.bp 文件来编写编译文件,貌似之前的 Android.mk 可以用,但有 bug.
附上我编译 imgui 用的 Android.bp 文件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cc_binary {
name: "ImGuiTest",
srcs: ["src/**/*.cpp"],

local_include_dirs: [
"src",
"src/imgui",
"src/backends",
],

cppflags: [
"-Wno-error",
"-Wno-sign-conversion",
"-Wno-unused-parameter",
"-Wno-sign-conversion",
],

shared_libs: [
"liblog",
"libandroid",
"libgui",
"libEGL",
"libGLESv2",
"libbinder",
"libui",
"libutils",
"libinput",
"libinputflinger",
],

}