之前我在 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", ],
}
|