问题现象

哨兵视频播放卡住问题分析中描述的「应用窗口卡住」现象一样。

IMG_1204.mov

问题分析

sequenceDiagram

box App
participant r as Renderer
participant bq as BlastBufferQueue
participant sc as SurfaceComposerClient
end

box SurfaceFlinger
participant sf as SurfaceFlinger
participant l as Layer
end

r ->> bq: dequeueBuffer
r ->> r: render
r ->> bq: queueBuffer
bq ->> bq: acquireBuffer
bq ->> sc: setBuffer
sc ->> sf: setTransactionState
Note over sf: Cache full

alt Absent
sf ->> l: setBuffer
Note over l: Release previous buffer
l ->> sc: onReleaseBuffer
sc ->> bq: releaseBuffer
end

应用进程的 BufferCache 和 SurfaceFlinger 的 ClientCache 共同工作的,当 BufferCache 中缓存个数超过了 64 个时,会先 uncache,并通知 SurfaceFlinger,之后再 cache。

但是我们修复另一个问题时提交的 CL 会在 binder 线程处理 cache 请求,但是 uncache 请求先入队后在主线程处理。这导致了 BufferCache 超限后在很快的时间 uncache 再 cache,在 SurfaceFlinger 中 uncache 处理之前 cache 在 binder 线程先处理,这时 ClientCache 超限了,导致无法处理该 buffer,最终不会释放该 buffer。

问题修复

Uncache 请求也在 binder 线程处理,保证 BufferCache 请求的 cache 和 uncache 顺序和 ClientCache 中处理的顺序一致。

http://gerrit.it.chehejia.com:8080/c/hmi/mercury/platform/frameworks/native/+/971268