外观
Surface、BufferQueue、GraphicBuffer、Fence 是什么关系?
标准回答
Surface 可以理解为内容生产者向目标提交图像的入口,它本身不是一个按钮,也不是一张固定截图。GraphicBuffer 等图形缓冲区承载图像数据,BufferQueue 则协调生产者和消费者之间的缓冲区使用与交接。
以典型队列模型看,生产者先取出可写缓冲区,写入内容后提交;消费者取得可用内容,使用结束再归还,让缓冲区可以复用。这样能减少频繁重新分配,也能把产帧与显示安排成流水线。
CPU 提交完任务时,GPU 可能还没真正写完。Fence 用来表达异步工作何时完成,帮助避免消费者过早读取,或生产者过早复用还在使用的资源。现代 Android 还会通过 BLAST、事务等机制协调窗口缓冲区与图层状态,不能把所有版本都画成完全相同的直连调用。
关键机制
- 缓冲区通常通过句柄共享,并非每一帧都把整张图逐字节经 Binder 拷贝一次。
- dequeue 可能因没有可复用缓冲区而等待,需要结合消费者进度与同步信息继续分析。
- Surface 的有效期与尺寸需要管理,持有 Java 对象不等于其底层输出目标永远有效。
通俗例子
播放器继续向旧 Surface 输出,即使解码正常,新窗口也可能没有视频;这时应检查输出目标交接与生命周期,而不是先怀疑网络。
追问与回答
Fence 为什么有必要?
因为图形任务跨 CPU、GPU 和显示硬件异步执行。某个函数返回只说明任务已经提交,不能证明像素已经可安全读取。Fence 把“工作完成”变成可以等待和传递的同步条件,让各阶段知道何时能读取或复用缓冲区。
易混淆点
队列长度与缓冲区数量并非所有场景固定为三;Fence 也不是普通业务线程锁的另一种名称。
参考资料
内容来源
- Android 技术札记 · 原条目
surface-buffer