apitrace原理分析及改进
作者:hws000(hws.000#163.com)
声明:版权所有,转载请联系作者。
出处:https://blog.simbot.net/index.php/2018/01/28/apitrace2/
前文对apitrace的使用方法做了简单介绍,本文将介绍它的实现原理,及对时戳系统的改进。
1.原理
1.1采集并记录数据
通过源码中的specs/glapi.py、retrace/glretrace.py等脚本,在编译时生成build/wrappers/glxtrace.cpp文件。此文件包含所有gl+glx的函数接口(内容见下图),这些函数会被编译成glxtrace.so,apitrace trace运行时glxtrace.so成为应用和OpenGL驱动之间的桥梁,同时将所有gl函数调用记录到.trace文件中。.trace文件中会记录各个参数的数值,包括指针类参数的内存数据。
1.2重现并记录执行时间
执行replay或qapitrace时会直接从.trace中读取数据,并依次执行记录的函数,从而将运行情况重现。在重现的过程中通过glGetQueryObjecti64vEXT(query.ids[GPU_DURATION], GL_QUERY_RESULT, &gpuDuration)函数获取gl函数的执行时间。CPU时戳通过query.cpuStart = getCurrentTime(),query.cpuEnd = getCurrentTime()获取,这个时戳是replay程序运行的当前时间。
1.3问题
由于CPU时戳是replay时获取的,实际上是从文件中读取记录数据并重放的时间,不是程序运行时真正调用gl函数时的时戳,不能表示CPU逻辑花费的时间。
2.改进
2.1对时戳的改进
知道了时戳不准确的原因改进其实很简单,采集数据的时间就是正确的CPU时戳,将此时戳记录到.trace文件中,replay时再从文件中读取即可。
2.2对qapitrace显示结果的改进
利用CPU时戳的改进结果,增加显示函数的耗时和每帧耗时。
2.3其它的改进
apitrace记录和重放数据时,会对每帧的结束做标识,认为glFlush、glFinish、glXSwapBuffers等函数是一帧的结束,在这些函数执行时调用frame_complete函数。到firefox56(貌似是。。。)时,不会调用glXSwapBuffers,不能正确识别每帧的结束位置,需要修改retrace/glretrace.py脚本并重新编译apitrace才行。
本文的修改可在目前最新的源码上编译通过,此处提供修改后的diff文件,从github上同步源码后执行git apply命令就会将修改合并,重新编译即可。
cputime-diff
gui-diff
other-diff