surfaceflinger 原理
surfaceflinger负责图层的叠加,在各个图层叠加数据完成后,通过fb_post将显示数据刷新到framebuffer中去。
layer1——–|
surfaceflinger 【layer(1+2+…+n)】 —>fb_post ——>framebuffer—>LCD显示
layer 2——-|
… ————|
layer-n —– |
4.4之前dump 图层方法:
surfaceflinger中绘制图像,会把每一层的图像进行叠加,处理后的图像会显示在屏幕上。如果是某一层的图像出错导致,就必须把surfaceflinger每一层的图像单独dump出来。
具体方法:
在surfaceflinger目录下创建文件dump.cpp,此文件负责绘制。再在Layer.cpp中的onDraw函数中加入如下代码:
#if defined(LAYER_DUMP_BMP)
{
FILE* fp;
if(fp = fopen("/data/dump_bmp/d_test", "r"))
{
char filename[256];
extern void dump_bmp(const char* filename, const sp<GraphicBuffer>& buffer);
sprintf(filename, "/data/dump_bmp/fm%04d_lay%04d_F%04d.bmp", frame_count, layer_count,mActiveBuffer->format);
dump_bmp(filename, mActiveBuffer);
fclose(fp);
}
else
{
//LOGD("layer dump file d_test open fail");
}
}
#endif/*LAYER_DUMP_BMP*/
并在SurfaceFlinger.cpp中加入控制帧数和层数的变量。
即可调用绘制图层的命令。
(附件里附上相应的修改dump_bmp,Layer,SurfaceFlinger)
手机连上USB后,输入如下命令:
adb root
adb shell
mkdir /data/dump_bmp
touch /data/dump_bmp/d_test
这时系统就会开始dump图片
想要停止dump就删除d_test这个文件
rm /data/dump_bmp/d_test
所有的图片都在/data/dump_bmp/中
这样就可以得到每一帧每一层的图像,对比相应层的图像,即可获知是否由于某一层的绘制出了问题。
5.0 之后surfaceflinger dump 显示
在5.0后,dump_bmp.cpp默认没有加到surfaceflinger中去,但是android4.4 之后已经集成了screenrecord命令来录制合成好之后的显示数据。
screenrecord使用
录制命令
adb shell screenrecord /sdcard/test.mp4
视频保存目录可以自己指定,如上面的/sdcard/test.mp4,
命令执行后会一直录制180s,按下ctrl+c可以提前结束录制
设定视频分辨率
对于高分辨率的手机,录制的视频很大,我们分享又不需要这么大的
我们可以设置录制的视频分辨率
adb shell screenrecord –size 848x480 /sdcard/test.mp4
设定视频比特率
默认比特率是4M/s,为了分享方便,我们可以调低比特率为2M
adb shell screenrecord –bit-rate 2000000 /sdcard/test.mp4
获取视频文件
使用adb pull 即可把手机SD卡中视频获取到本地
adb pull /sdcard/test.mp4 .
通过screenrecord来定位问题
通过使用screenrecord可以初步定位显示问题中,是上层绘制的问题,还是底层LCD显示的问题。如果record的数据正常,说明LCD显示有问题,如果record的数据不正常,说明上层绘制有问题。