App显示在屏幕上完整流程:
android12开始,producer,consumer,BufferQueue以及Buffer的dequeue,queue,acquire,release都从SurfaceFlinger移到了App端实现,如下图
View上屏流程:
- view.invalidate/requestlayout发出绘制请求
- vsync会触发绘制请求任务(uithread调用syncframestate把界面元素传递给RenderThread生成displaylist)
- RenderThread调用opengl接口把displaylist绘制成像素放到graphicbuffer,然后再调用queuebuffer放到App的bufferqueue(release fence)
App queueBuffer→ frameAvailableListener.onFrameAvailable→BufferQueueConsumer::processNextBufferLocked binder通知SurfaceFlinger.BufferQueueConsumer::acquireBuffer 获取一个graphicbuffer调用SurfaceComposerClient::Transaction.setBuffer保存到surfaceflinger layer中,并向hwc发送vsync请求 |
- SurfaceFlinger在下一个vsync到来后询问hwc每个layer是否需要gpu合成
- gpu合成:renderengine模块把所有window的bufferqueue调用aquirebuffer拿到要合成buffer,调用gpu合成之后放到framebuffer,hwc再根据framebuffer合成1个layer走device合成过程,并释放fence( gpu合成原理是通过拿到可用buffer合成帧数据放到framebufferlayers合成_surfaceflinger 合成是通过hwc还是gpu-CSDN博客)
- device合成:layer直接透传到hwc,透传给display,display从每个layer的bufferqueue中读取像素显示到屏幕
SurfaceFlinger消费bufferqueque |
onVsync -> SurfaceFlinger::onMessageInvalidate() -> BufferLayer::latchBuffer() -> BufferQueueLayer::updateTexImage() { BufferLayerConsumer::acquireBufferLocked() } |
- Surfaceflinger RenderEngine负责把每个texture合成生成framebuffer之后交给hwc消费
SkiaGLRenderEngine.cpp文件在native/libs/renderengine 目录下 |
多个App在屏幕上显示流程:
1个App Window从SurfaceFlinger申请1个surface时,会创建1个window对应的BufferQueue,每个BufferQueue包含3个buffer(SF合成图像也是在Gpu完成的)
关键流程
一,App完成1帧数据时把生产的buffer通过binder传给SurfaceFlinger去消费 | |
---|---|
queueBuffer→frameAvailableListener.onFrameAvailable →BufferQueueConsumer::processNextBufferLocked→BufferQueueConsumer::acquireBuffer (像app要buffer来消费) →BLASTBufferQueue#SurfaceComposerClient::Transaction.setBuffer(mSurfaceControl, buffer, releaseCallbackId, releaseBufferCallback) | |
二,SurfaceFlinger消费完之后releasebuffer | |
Surfaceflinger E TransactionCallbackInvoker: TransactionCallbackInvoker ITransactionCompletedListener onTransactionCompleted 调用stack如下
|
12-15 10:46:54.793667 2959 3319 E BufferQueueProducer: [SurfaceView[com.jidu.renderframe/com.jidu.renderframe.MainActivity]#1(BLAST Consumer)1](id:b8f00000001,api:1,p:2959,c:2959) queueBuffer: slot=0/19261 time=652049692092 dataSpace=0 validHdrMetadataTypes=0x0 crop=[0,0,0,0] transform=0 scale=SCALE_TO_WINDOW 12-15 10:46:54.793705 2959 3319 E BufferQueueConsumer: [SurfaceView[com.jidu.renderframe/com.jidu.renderframe.MainActivity]#1(BLAST Consumer)1](id:b8f00000001,api:1,p:2959,c:2959) acquireBuffer: acquiring { slot=0/19261 buffer=0x74f1a1b440 } notify_all queuesize:1 12-15 10:46:54.802876 2959 3319 E BufferQueueProducer: [SurfaceView[com.jidu.renderframe/com.jidu.renderframe.MainActivity]#1(BLAST Consumer)1](id:b8f00000001,api:1,p:2959,c:2959) dequeueBuffer 12-15 10:46:54.742224 2959 3028 E BufferQueueConsumer: [SurfaceView[com.jidu.renderframe/com.jidu.renderframe.MainActivity]#1(BLAST Consumer)1](id:b8f00000001,api:1,p:2959,c:2959) releaseBuffer: releasing slot 2 DequeueCondition.notify_all 源码如下: void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) override { callRemoteAsync<decltype( &ITransactionCompletedListener::onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER, callbackId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } |
releaseBuffer流程:
BufferStateLayer::~BufferStateLayer onReleaseBuffer 12-25 21:00:18.606 603 603 E ITransactionCompletedListener: -----------------------onTransact BpTransactionCompletedListener onTransactionCompleted 12-25 21:00:18.606 12674 14754 E ITransactionCompletedListener: -----------------------onTransact BnTransactionCompletedListener onTransactionCompleted 12-25 21:00:18.606 12674 14754 E BLASTBufferQueue: releaseBufferCallbackThunk BufferQueueConsumer:releaseBuffer: releasing slot x |
Systrace全流程:
- App绘制到dequeue到buffer
- Consumer aquirebuffer之后把buffer设置给Surfaceflinger
- Surfaceflinger 消费完了 releaseBuffer
关键概念:
- sf合成layer方式:优先硬件合成,合成失败才用gpu合成兜底
1种:hwc(高通开发的屏幕芯片dpu做)硬件合成,但是不能合成alpha,高斯模糊这种复杂图像
1种:soft (client/gpu)不会出错, cpu占用高
- SurfaceFlinger的线程:acquire,queue,dequeue采用主线程,releaseBuffer采用子线程
- BBQ(BufferQueue的增强类BlastBufferQueue)【BufferQueue中是BufferSlot来保存Buffer状态,1个Buffer有四种状态: Dequeued, Queued, Acquired, Free】
- QueuedBuffer - X 生产者队列,sf会从这个队列中获取buffer
- BLAST Consumer - X 消费者队列
- SurfaceFlinger为每个surface创建的BufferStateLayer,封装在mSurfaceControl暴露给客户端,mSurfaceControl中新建了BLASTBufferQueue
- BLASTBufferQueue分别又创建BufferQueueCore,BufferQueueProducer,BufferQueueConsumer持有相同的BufferQueueCore:
-
BufferQueueCore是graphicbuffer存储的数据结构,包含如下2个变量:
mSlots:包含了默认大小为64的BufferSlot数组,但一个surface默认初始化3个buffrer,
mQueue :BufferItem类型的数组,生产者和消费者按照Fifo规则消费queque中的数据
Producer调用queueBuffer后会修改mSlots,mQueue(但不知道这2个的区别在哪里)
BufferSlot是1个graphicbuffer封装,成员变量有mGraphicBuffer,mBufferState(buffer的状态是free,queued,aquired,dequeue), mFence(前主人是否用完的标志),SurfaceTexture可以对Graphic Buffers做自定义特效处理
- 将图形内存Graphic Buffer送到LCD显示的2种方法:gpu合成gralloc.post()和hwcomposer的硬件合成
- 从view.invalide()提交绘制请求到display显示至少隔3帧(一个surface和SurfaceFlinger有3个buffer轮流使用)
- dequeueBuffer阻塞之后有timeout(默认是4s) W OpenGLRenderer: dequeueBuffer failed, error = -110; switching to fallback
- 关于dequeueBuffer等buffer相关bug,搜索:SurfaceFlinger,dequeueBuffer关键字
- fence机制:fence对象通过fd在3个进程之间共享
- 释放fence时机:App在gpu绘制一帧完毕,SurfaceFlinger在updateTexImage,HWC在合成完毕(HWC合成开始前提是gpu和device合成用到的fence都可用)
- 错误汇总:
- 04-20 15:05:56.217276 597 597 E SurfaceFlinger: Attempted to create an ExternalTexture for layer lrc#0 that exceeds render target size limit.
- 12-14 15:55:53.495030 583 583 E BpTransactionCompletedListener: Failed to transact (-2147483646) surfaceflinger通知释放buffer失败了
-
RenderThread: BufferQueueProducer: setDequeueTimeout:4000(
但注意!UnityMain Thread:一直阻塞不会Timeout,BufferQueueProducer: [SurfaceView[com.cottongame.triangleAdventure.jidu/com.unity3d.player.MainActivity]#1(BLAST Consumer)1]
-
trace分析卡顿,Davey! duration主线程卡顿
debuyg测试surfaceflinger方法
编译:make surfaceflinger
替换车机中的文件:将out/target/product/msmnile_gvmq/system/bin/surfaceflinger 文件
替换车机中的system/bin/surfaceflinger文件
重启Android系统:adb shell reboot
参考文献
aosp源码路径 Android/lagvm/LINUX/android/frameworks/native/libs/gui#
native/services/surfaceflinger/
surface Android 图形系统之 SurfaceTexture