monado性能分析系列文章索引汇总:
XR VR AR monado oculus quest pico性能分析工具综述
Monado timing frame pacing frame timing 时间点分析
monado metrics tool离线性能指标工具分析
vr ar xr monado性能分析工具 percetto编译和monado集成
作用
对安卓性能分析工具Perfetto的C代码封装,用于丰富的性能跟踪、可视化展示和分析。
注意事项
- 建议在ubuntu20环境下编译,windows会遇到各种坑
- 最大坑点:官网只给了ubuntu X86-64系统编译和运行说明,我们需要交叉编译安卓版本
TODO
- percetto库可以在monado集成运行,并单步调试,但某些配置没配置正确,导致U_TRACE_CATEGORY_IS_ENABLED(timing)返回false,记录动作未完成。
- 指标收集、可视化分析
代码库
https://github.com/olvaffe/percetto
Percetto编译
X86-64 vs AArch64
坑点:官网给出的编译文档是linux运行环境的X86-64产出,安卓需要AArch64产出
# 查看.a arch格式
readelf -h libpercetto.a | grep Machine
Machine: Advanced Micro Devices X86-64
readelf -h libaux_util.a | grep Machine
Machine: AArch64
# 查看.so arch格式
file libpercetto.so
libpercetto.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=6e2358577575be17878617ea7a60b3b9b510300b, with debug_info, not stripped
libvulkan.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=cb2f1deac083ae64b01c17e99e69ca4e, with debug_info, not stripped
Shared library(.so) vs Static Library(.a)
坑点
1 默认产出so,导致runtime loader发现不了libpercetto.so,需要修改loader源码(不讨论)
2 产出.a文件,loader不变,修改percetto编译和打包方式(本文讨论方式)
percetto/meson.build
编译错误:werror=true,改成werror=false
project(
'percetto',
['c', 'cpp'],
version: '0.1.6',
license: 'Apache-2.0',
meson_version: '>=0.54.0',
default_options: ['buildtype=debug',
'warning_level=2',
'werror=false',
'c_std=c11',
'cpp_std=c++2a'],
)
percetto/src/meson.build
原配置是产出so文件,修改为如下产出.a文件配置
percetto_static_lib = static_library(
'percetto',
'percetto.cc',
'perfetto-port.cc',
dependencies: dep_perfetto,
cpp_args : ['-fvisibility=hidden', '-fdata-sections', '-ffunction-sections', '-Os'],
link_args : ['-Wl,--gc-sections', '-Wl,--exclude-libs,ALL'],
install : true,
)
percetto_static_dep = declare_dependency(
include_directories: '.',
link_with: percetto_static_lib,
)
atrace_static_lib = static_library(
'percetto-atrace',
'percetto-atrace.c',
dependencies: percetto_static_dep,
c_args : ['-fvisibility=hidden', '-fdata-sections', '-ffunction-sections', '-Os'],
link_args : ['-Wl,--gc-sections', '-Wl,--exclude-libs,ALL'],
install : true,
)
atrace_static_dep = declare_dependency(
include_directories: '.',
link_with: atrace_static_lib,
)
install_headers('percetto.h', 'percetto-atrace.h')
pkg = import('pkgconfig')
pkg.generate(percetto_static_lib, description : 'C API wrapper static library for perfetto')
pkg.generate(atrace_static_lib, description : 'Android ATRACE wrapper static library for percetto')
arm64交叉编译配置meson-cross-arm64.ini
根据需要准备特定交叉编译配置文件
meson-cross-arm64.ini
[binaries]
c = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang'
cpp = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang++'
ar = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar'
strip = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip'
cmake = '/usr/local/bin/cmake'
ld = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld.gold'
#pkgconfig = '/usr/bin/x86_64-pc-linux-gnu-pkg-config'
#pcap-config = ''
[properties]
skip_sanity_check = true
sys_root = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/sysroot'
root = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/29'
[built-in options]
c_args = ['-O2', '-pipe', '-g', '-feliminate-unused-debug-types']
c_link_args = ['-Wl,-O1', '-Wl,--hash-style=gnu', '-Wl,--as-needed']
cpp_args = ['-O2', '-pipe', '-g', '-feliminate-unused-debug-types']
cpp_link_args = ['-Wl,-O1', '-Wl,--hash-style=gnu', '-Wl,--as-needed','-llog']
#sys_root = '/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/sysroot'
#pkg_config_libdir ='/home/liuzx/Android/Sdk/ndk/21.4.7075529/prebuilt/linux-x86_64/lib/pkgconfig'
#pkg_config_libdir ='/home/liuzx/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/29'
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
[target_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8a'
endian = 'little'
执行交叉编译
- --cross-file meson-cross-arm64.ini 使用交叉编译配置文件
- --prefix 指定install目录
# 生成配置信息到build目录
meson setup build --cross-file meson-cross-arm64.ini --prefix ~/open_source/percetto/install/
# 编译
meson compile -C build
# .h .a安装到install指定目录
meson install -C build
多个.a文件打包成统一libpercetto.a文件
坑点:默认产出libpercetto.a和libperfetto.a两个库,monado侧默认识别libpercetto.a库,为了最小化改动monado侧代码,需要合并.a库。
# 解压.a库
ar x libpercetto.a
perfetto-port.cc.o
sdk_perfetto.cc.o
# 解压.a库
ar x libperfetto.a
sdk_perfetto.cc.o
# 重新打包成libpercetto.a
ar crsv ../libpercetto.a *.o
至此,产生可以供monado集成的.a文件和.h文件。
Monado侧重要注意事项
节约编译时间
目前percetto只交叉编译arm64版本,对应monado只产出arm64-v8a版本,否则编译失败
// monado/src/xrt/targets/openxr_android/build.gradle
ndk {
abiFilters 'arm64-v8a'
}
// armeabi-v7a: 第7代及以上的 32位ARM 处理器
// arm64-v8a: 第8代、64位ARM处理器
// armeabi: 第5代、第6代的32位ARM处理器,早期的手机在使用,现在基本很少了。
// x86: Intel 32位处理器,在平板、模拟器用得比较多。
// x86_64: Intel 64位处理器,在平板、模拟器用得比较多。
FindPercetto.cmake
设置Percetto_ROOT_DIR路径后,默认FindPercetto.cmake依然找不到so库,因此手动设置.h和.so全路径,后续优化这个问题。
set(Percetto_ROOT_DIR /home/liuzx/open_source/percetto/install/)
find_library(
Percetto_LIBRARY
NAMES percetto
PATHS ${Percetto_ROOT_DIR}
HINTS ${PC_percetto_LIBRARY_DIRS}
PATH_SUFFIXES lib)
message(STATUS "Percetto_INCLUDE_DIR before: ${Percetto_INCLUDE_DIR}")
message(STATUS "Percetto_LIBRARY before: ${Percetto_LIBRARY}")
set(Percetto_INCLUDE_DIR "${Percetto_ROOT_DIR}/include/")
set(Percetto_LIBRARY "${Percetto_ROOT_DIR}/lib/libpercetto.so")
message(STATUS "#Percetto_INCLUDE_DIR: ${Percetto_INCLUDE_DIR}")
message(STATUS "#Percetto_LIBRARY: ${Percetto_LIBRARY}")
monado/CMakeLists.txt
打开宏开关:XRT_FEATURE_TRACING OFF --> ON
option_with_deps(XRT_FEATURE_TRACING "Enable debug tracing on supported platforms" DEFAULT ON DEPENDS "XRT_HAVE_PERCETTO OR XRT_HAVE_TRACY")
monado/src/xrt/auxiliary/util/u_trace_marker.h
默认为false,没有落记录,改成true依然返回,需要进一步研究
#define U_TRACE_CATEGORY_IS_ENABLED(_) (false)
monado/src/xrt/auxiliary/util/u_trace_marker.c
手动把false改成true,需要进一步研究通过环境变量、启动参数等方式传参
DEBUG_GET_ONCE_BOOL_OPTION(tracing, "XRT_TRACING", false)
monado/src/xrt/compositor/main/comp_window_android.c
COMP_TARGET_FORCE_FAKE_DISPLAY_TIMING
改成
COMP_TARGET_USE_DISPLAY_IF_AVAILABLE
comp_target_swapchain_init_and_set_fnptrs(&w->base, COMP_TARGET_USE_DISPLAY_IF_AVAILABLE);
monado/src/xrt/target/service-lib/service_target.c
monado默认在linux环境运行时启动percetto性能记录,因此需要修改安卓服务入口
#include "util/u_metrics.h"
#include "util/u_trace_marker.h"
void
startServer()
{
std::unique_lock lock(server_mutex);
if (!server && !server_thread) {
server_thread = std::make_unique
(
[&]() {
u_trace_marker_init(); // 增加代码
u_metrics_init(); // 增加代码
ipc_server_main_android(&server, signalStartupCompleteTrampoline, this);
u_metrics_close(); // 增加代码
});
}
}
TODO
经过以上步奏,代码可以运行,并且可以单步调试,但:
参考资料:meson 交叉编译aarch64
https://blog.csdn.net/xys616/article/details/116756444
https://android.googlesource.com/platform/external/igt-gpu-tools/+/7cb599fb0e2e9fed3c1ad9adc819e478cd40ae71/meson-cross-arm64.txt
https://gensoft.pasteur.fr/docs/mesa/19.0.8/meson.html