Android 15 View 绘制触发 BufferQueue / BLAST / SurfaceFlinger 上屏流程

本文通过AI 基于 android-15.0.0_r17 整理,并跟源码做了比对校准,请参考。

普通 View 硬件加速绘制时,Java 层不会直接 Surface.lockCanvas();而是 ViewRootImpl 触发 ThreadedRenderer,RenderThread 通过 EGL/Skia/Vulkan/OpenGL 的 ANativeWindow 路径 dequeue buffer → GPU 绘制 → queue buffer。

Android 15 应用窗口默认走 BLASTBufferQueue,Buffer 被 BBQ 在 App 进程 acquire 后封装进 SurfaceControl.Transaction,提交给 SurfaceFlinger。

SurfaceFlinger 在事务/VSync 合成阶段 latch 该 buffer 并送显。

Android 官方也明确描述 BufferQueue 的基本模型:Producer dequeueBuffer() 获取 buffer,填充后 queueBuffer(),Consumer acquireBuffer() 后使用,完成后 releaseBuffer()。

BLAST 架构下,BufferQueue 从 SurfaceFlinger 侧转移到业务进程,buffer 和图层属性通过 Transaction 一起提交给 SurfaceFlinger。 source.and...google.cn juejin.cn, jianshu.com

1. 总体调用链

bash 复制代码
1     View.invalidate() / requestLayout()
2             ↓
3     ViewRootImpl.scheduleTraversals()
4             ↓
5     Choreographer CALLBACK_TRAVERSAL,等待下一帧 VSYNC
6             ↓
7     ViewRootImpl.doTraversal()
8             ↓
9     ViewRootImpl.performTraversals()
10             ↓
11     performMeasure / performLayout / performDraw
12             ↓
13     ViewRootImpl.draw()
14             ↓
15     ThreadedRenderer.draw()
16             ↓
17     updateRootDisplayList()       // UIThread 构建 RenderNode / DisplayList
18             ↓
19     syncAndDrawFrame()            // 同步给 RenderThread
20             ↓
21     RenderThread / HWUI / Skia
22             ↓
23     ANativeWindow.dequeueBuffer()
24             ↓
25     Surface::dequeueBuffer()
26             ↓
27     BufferQueueProducer::dequeueBuffer()
28             ↓
29     Gralloc 分配 / 复用 GraphicBuffer
30             ↓
31     GPU 绘制到 GraphicBuffer
32             ↓
33     eglSwapBuffers / queueBuffer
34             ↓
35     Surface::queueBuffer()
36             ↓
37     BufferQueueProducer::queueBuffer()
38             ↓
39     BLASTBufferQueue::onFrameAvailable()
40             ↓
41     BLASTBufferQueue acquire buffer
42             ↓
43     SurfaceControl.Transaction.setBuffer()
44             ↓
45     Transaction.apply()
46             ↓
47     SurfaceFlinger 接收事务
48             ↓
49     SurfaceFlinger latch buffer / compose
50             ↓
51     HWC / Display 显示

2. View 层:invalidate / requestLayout 如何触发绘制

2.1 View.invalidate()

路径:

1 frameworks/base/core/java/android/view/View.java

关键逻辑:

1 public void invalidate() {

2 invalidate(true);

3 }

4

5 public void invalidate(boolean invalidateCache) {

6 invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop,

7 invalidateCache, true);

8 }

9

10 void invalidateInternal(int l, int t, int r, int b,

11 boolean invalidateCache, boolean fullInvalidate) {

12 if (skipInvalidate()) {

13 return;

14 }

15

16 if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN

17 || (fullInvalidate && isOpaque() != mLastIsOpaque)) {

18

19 if (fullInvalidate) {

20 mLastIsOpaque = isOpaque();

21 mPrivateFlags &= ~PFLAG_DRAWN;

22 }

23

24 mPrivateFlags |= PFLAG_DIRTY;

25

26 final AttachInfo ai = mAttachInfo;

27 final ViewParent p = mParent;

28

29 if (p != null && ai != null) {

30 final Rect damage = ai.mTmpInvalRect;

31 damage.set(l, t, r, b);

32 p.invalidateChild(this, damage);

33 }

34 }

35 }

这一步只是把 View 区域标记为 dirty,并向父节点传播,最终会到 ViewRootImpl.invalidateChildInParent(),再触发 traversal。ViewRootImpl 是 View 树与窗口 / Surface 系统之间的桥梁,负责 measure、layout、draw。 juejin.cn, jianshu.com

2.2 View.requestLayout()

路径:

1 frameworks/base/core/java/android/view/View.java

核心含义:

1 public void requestLayout() {

2 if (mMeasureCache != null) {

3 mMeasureCache.clear();

4 }

5

6 if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {

7 ViewRootImpl viewRoot = getViewRootImpl();

8 if (viewRoot != null && viewRoot.isInLayout()) {

9 if (!viewRoot.requestLayoutDuringLayout(this)) {

10 return;

11 }

12 }

13 mAttachInfo.mViewRequestingLayout = this;

14 }

15

16 mPrivateFlags |= PFLAG_FORCE_LAYOUT;

17 mPrivateFlags |= PFLAG_INVALIDATED;

18

19 if (mParent != null && !mParent.isLayoutRequested()) {

20 mParent.requestLayout();

21 }

22

23 if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {

24 mAttachInfo.mViewRequestingLayout = null;

25 }

26 }

最终也会进入 ViewRootImpl.requestLayout()。

3. ViewRootImpl:调度下一帧 Traversal

路径:

1 frameworks/base/core/java/android/view/ViewRootImpl.java

3.1 requestLayout()

1 @Override

2 public void requestLayout() {

3 if (!mHandlingLayoutInLayoutRequest) {

4 checkThread();

5 mLayoutRequested = true;

6 scheduleTraversals();

7 }

8 }

checkThread() 用来保证只有创建 ViewRootImpl 的线程能操作该 View 树,这也是常见 "Only the original thread that created a view hierarchy can touch its views" 的来源。 blog.csdn.net

3.2 scheduleTraversals()

1 void scheduleTraversals() {

2 if (!mTraversalScheduled) {

3 mTraversalScheduled = true;

4

5 mTraversalBarrier =

6 mHandler.getLooper().getQueue().postSyncBarrier();

7

8 mChoreographer.postCallback(

9 Choreographer.CALLBACK_TRAVERSAL,

10 mTraversalRunnable,

11 null);

12

13 notifyRendererOfFramePending();

14 pokeDrawLockIfNeeded();

15 }

16 }

这里做了几件关键事情:

1.设置 mTraversalScheduled = true,避免重复调度。

2.往主线程 MessageQueue 插入同步屏障。

3.向 Choreographer 注册 CALLBACK_TRAVERSAL。

4.等下一次 VSYNC 到来后执行 traversal。

Choreographer 驱动 ViewRootImpl 在 VSYNC 节奏下执行 measure/layout/draw,相关机制在 Android 渲染分析资料中也有一致描述。 blog.csdn.net, zhuanlan.zhihu.com

3.3 TraversalRunnable

1 final class TraversalRunnable implements Runnable {

2 @Override

3 public void run() {

4 doTraversal();

5 }

6 }

3.4 doTraversal()

1 void doTraversal() {

2 if (mTraversalScheduled) {

3 mTraversalScheduled = false;

4

5 mHandler.getLooper().getQueue()

6 .removeSyncBarrier(mTraversalBarrier);

7

8 performTraversals();

9 }

10 }

4. ViewRootImpl.performTraversals:measure / layout / draw

路径:

1 frameworks/base/core/java/android/view/ViewRootImpl.java

核心结构可以抽象为:

1 private void performTraversals() {

2 final View host = mView;

3

4 // 1. 与 WMS relayout,获得 SurfaceControl / BLAST surface

5 relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);

6

7 // 2. 必要时 measure

8 if (mLayoutRequested) {

9 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);

10 }

11

12 // 3. 必要时 layout

13 if (didLayout) {

14 performLayout(lp, mWidth, mHeight);

15 }

16

17 // 4. draw

18 if (!cancelDraw && !newSurface) {

19 performDraw();

20 }

21 }

在 Android 15 应用窗口中,relayoutWindow() 之后会通过 getOrCreateBLASTSurface() 创建 / 更新 BLASTBufferQueue Surface,这一点在 Android 12+ BLAST 机制分析中也有对应源码路径说明。 jianshu.com, juejin.cn

5. ViewRootImpl 创建 BLAST Surface

路径:

1 frameworks/base/core/java/android/view/ViewRootImpl.java

关键方法:

1 Surface getOrCreateBLASTSurface() {

2 if (!mSurfaceControl.isValid()) {

3 return null;

4 }

5

6 Surface ret = null;

7

8 if (mBlastBufferQueue == null) {

9 mBlastBufferQueue = new BLASTBufferQueue(

10 mTag,

11 mSurfaceControl,

12 mSurfaceSize.x,

13 mSurfaceSize.y,

14 mWindowAttributes.format);

15

16 ret = mBlastBufferQueue.createSurface();

17 } else {

18 mBlastBufferQueue.update(

19 mSurfaceControl,

20 mSurfaceSize.x,

21 mSurfaceSize.y,

22 mWindowAttributes.format);

23 }

24

25 return ret;

26 }

这一步的意义:

1 SurfaceControl // SurfaceFlinger 里的 Layer 句柄

2 ↓

3 BLASTBufferQueue // App 进程本地 BufferQueue

4 ↓

5 Surface // 给 HWUI / EGL / ANativeWindow 使用

BLASTBufferQueue 把 BufferQueue 放在 App 进程侧,SurfaceFlinger 不再直接作为该 BufferQueue 的 Consumer,而是接收 App 通过 Transaction 提交的 buffer。 juejin.cn, jianshu.com

6. performDraw / draw:进入硬件渲染

路径:

1 frameworks/base/core/java/android/view/ViewRootImpl.java

6.1 performDraw()

1 private void performDraw() {

2 boolean canUseAsync = draw(fullRedrawNeeded);

3 }

6.2 draw()

普通 View 默认硬件加速,核心会走:

1 private boolean draw(boolean fullRedrawNeeded) {

2 Surface surface = mSurface;

3

4 if (!surface.isValid()) {

5 return false;

6 }

7

8 final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer;

9

10 if (renderer != null && renderer.isEnabled()) {

11 renderer.draw(mView, mAttachInfo, this);

12 } else {

13 drawSoftware(surface, mAttachInfo, xOffset, yOffset,

14 scalingRequired, dirty);

15 }

16

17 return true;

18 }

注意:

硬件加速路径:ThreadedRenderer.draw(),不会调用 Java Surface.lockCanvas()。

软件绘制路径:drawSoftware() 会调用 mSurface.lockCanvas(dirty) 和 unlockCanvasAndPost()。

软件绘制中 Surface.lockCanvas() / unlockCanvasAndPost() 的路径和 BufferQueue dequeue / queue 对应,这在 Canvas 绘制源码分析中也有相同流程描述。 cloud.tencent.com

7. ThreadedRenderer:UIThread 构建 DisplayList,RenderThread 真正绘制 Buffer 路径:

1 frameworks/base/core/java/android/view/ThreadedRenderer.java

关键结构:

1 void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {

2 attachInfo.mIgnoreDirtyState = true;

3

4 final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;

5 choreographer.mFrameInfo.markDrawStart();

6

7 updateRootDisplayList(view, callbacks);

8

9 attachInfo.mIgnoreDirtyState = false;

10

11 int syncResult = syncAndDrawFrame(choreographer.mFrameInfo);

12 }

7.1 updateRootDisplayList()

1 private void updateRootDisplayList(View view, DrawCallbacks callbacks) {

2 updateViewTreeDisplayList(view);

3

4 if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {

5 RecordingCanvas canvas = mRootNode.beginRecording(

6 mSurfaceWidth, mSurfaceHeight);

7

8 try {

9 callbacks.onPreDraw(canvas);

10

11 canvas.drawRenderNode(view.updateDisplayListIfDirty());

12

13 callbacks.onPostDraw(canvas);

14 } finally {

15 mRootNode.endRecording();

16 }

17 }

18 }

这一步发生在 UIThread:

1 View.draw()

2 ↓

3 RenderNode / DisplayList 记录绘制命令

并不直接把像素写进 buffer。

7.2 syncAndDrawFrame()

1 private int syncAndDrawFrame(FrameInfo frameInfo) {

2 return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo,

3 frameInfo.frameInfo.length);

4 }

JNI 后进入 native HWUI:

1 android_view_ThreadedRenderer_syncAndDrawFrame

2 ↓

3 RenderProxy::syncAndDrawFrame()

4 ↓

5 DrawFrameTask::drawFrame()

6 ↓

7 CanvasContext::draw()

8 ↓

9 SkiaOpenGLPipeline / SkiaVulkanPipeline

10 ↓

11 dequeue buffer

12 ↓

13 GPU render

14 ↓

15 queue buffer / swap buffers

ThreadedRenderer 的核心职责是:UI 线程构建 DisplayList,RenderThread 负责把 DisplayList 同步并渲染到 Surface 对应的 buffer。相关资料也指出硬件渲染分为 DisplayList 构建和 RenderThread 渲染两个阶段。 blog.csdn.net

8. Surface / ANativeWindow:dequeueBuffer 锁定可绘制 buffer

路径:

1 frameworks/native/libs/gui/Surface.cpp

8.1 ANativeWindow hook

1 int Surface::hook_dequeueBuffer(

2 ANativeWindow* window,

3 ANativeWindowBuffer** buffer,

4 int* fenceFd) {

5 Surface* c = getSelf(window);

6 return c->dequeueBuffer(buffer, fenceFd);

7 }

8

9 int Surface::hook_queueBuffer(

10 ANativeWindow* window,

11 ANativeWindowBuffer* buffer,

12 int fenceFd) {

13 Surface* c = getSelf(window);

14 return c->queueBuffer(buffer, fenceFd);

15 }

EGL / Vulkan / HWUI 看到的是 ANativeWindow,最终回调到 Surface::dequeueBuffer() 和 Surface::queueBuffer()。

8.2 Surface::dequeueBuffer()

核心逻辑:

1 int Surface::dequeueBuffer(

2 ANativeWindowBuffer** buffer,

3 int* fenceFd) {

4 Mutex::Autolock lock(mMutex);

5

6 int buf = -1;

7 sp fence;

8

9 status_t result = mGraphicBufferProducer->dequeueBuffer(

10 &buf,

11 &fence,

12 reqWidth,

13 reqHeight,

14 reqFormat,

15 reqUsage,

16 &mBufferAge,

17 enableFrameTimestamps ? &mFrameEventHistory : nullptr);

18

19 if (result < 0) {

20 return result;

21 }

22

23 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION)

24 || gbuf == nullptr) {

25 result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);

26 if (result != NO_ERROR) {

27 mGraphicBufferProducer->cancelBuffer(buf, fence);

28 return result;

29 }

30 }

31

32 if (fence != nullptr && fence->isValid()) {

33 *fenceFd = fence->dup();

34 } else {

35 *fenceFd = -1;

36 }

37

38 *buffer = gbuf.get();

39 return OK;

40 }

含义:

1 Surface

2 调 IGraphicBufferProducer.dequeueBuffer()

3 ↓

4 BufferQueueProducer 找一个可用 slot

5 ↓

6 必要时分配 GraphicBuffer

7 ↓

8 返回 ANativeWindowBuffer 给 HWUI / EGL

官方 BufferQueue 文档也描述了生产方通过 dequeueBuffer() 请求可用 buffer,并指定宽高、格式和 usage。 source.and...google.cn

9. BufferQueueProducer:真正管理 buffer slot 状态

路径:

1 frameworks/native/libs/gui/BufferQueueProducer.cpp

9.1 dequeueBuffer()

核心结构:

1 status_t BufferQueueProducer::dequeueBuffer(

2 int* outSlot,

3 spandroid::Fence* outFence,

4 uint32_t width,

5 uint32_t height,

6 PixelFormat format,

7 uint64_t usage,

8 uint64_t* outBufferAge,

9 FrameEventHistoryDelta* outTimestamps) {

10 std::unique_lockstd::mutex lock(mCore->mMutex);

11

12 int found = BufferQueueCore::INVALID_BUFFER_SLOT;

13

14 status_t status = waitForFreeSlotThenRelock(

15 FreeSlotCaller::Dequeue,

16 &found);

17

18 if (status != NO_ERROR) {

19 return status;

20 }

21

22 *outSlot = found;

23

24 mSlotsfound.mBufferState.dequeue();

25

26 if (bufferNeedsReallocation) {

27 returnFlags |= BUFFER_NEEDS_REALLOCATION;

28 }

29

30 return returnFlags;

31 }

buffer 状态变化:

1 FREE → DEQUEUED

BufferQueue 的常见状态流转是:

1 FREE → DEQUEUED → QUEUED → ACQUIRED → FREE

该状态流转与 Android BufferQueue 工作流程资料一致。 cnblogs.com, zhuanlan.zhihu.com

9.2 queueBuffer()

1 status_t BufferQueueProducer::queueBuffer(

2 int slot,

3 const QueueBufferInput& input,

4 QueueBufferOutput* output) {

5 sp frameAvailableListener;

6 BufferItem item;

7

8 {

9 std::unique_lockstd::mutex lock(mCore->mMutex);

10

11 mSlotsslot.mBufferState.queue();

12

13 item.mGraphicBuffer = mSlotsslot.mGraphicBuffer;

14 item.mFence = acquireFence;

15 item.mSlot = slot;

16 item.mFrameNumber = currentFrameNumber;

17

18 mCore->mQueue.push_back(item);

19

20 frameAvailableListener = mCore->mConsumerListener;

21 }

22

23 if (frameAvailableListener != nullptr) {

24 frameAvailableListener->onFrameAvailable(item);

25 }

26

27 return NO_ERROR;

28 }

buffer 状态变化:

1 DEQUEUED → QUEUED

这一步就是"通知 buffer 可显示"的第一阶段:Producer 已经把绘制完成的 buffer queue 进 BufferQueue,并通知 Consumer。

10. BLASTBufferQueue:App 进程本地消费 BufferQueue,并通过 Transaction 交给 SurfaceFlinger

路径:

1 frameworks/native/libs/gui/BLASTBufferQueue.cpp

10.1 构造函数

1 BLASTBufferQueue::BLASTBufferQueue(

2 const std::string& name,

3 const sp& surface,

4 int width,

5 int height,

6 int32_t format)

7 : mSurfaceControl(surface),

8 mSize(width, height),

9 mRequestedSize(mSize),

10 mFormat(format) {

11

12 createBufferQueue(&mProducer, &mConsumer);

13

14 mProducer->setDequeueTimeout(

15 std::numeric_limits<int64_t>::max());

16

17 mProducer->setMaxDequeuedBufferCount(2);

18

19 mBufferItemConsumer = new BLASTBufferItemConsumer(

20 mConsumer,

21 GraphicBuffer::USAGE_HW_COMPOSER |

22 GraphicBuffer::USAGE_HW_TEXTURE,

23 1,

24 false);

25

26 mBufferItemConsumer->setFrameAvailableListener(this);

27 mBufferItemConsumer->setBufferFreedListener(this);

28 }

这里创建:

1 BufferQueueProducer

2 BufferQueueConsumer

3 BLASTBufferItemConsumer

Android 15 的 BLASTBufferQueue 分析资料也指出其构造中会 createBufferQueue(&mProducer, &mConsumer),设置 consumer listener,并设置最大 dequeue buffer 数。 jianshu.com, blog.csdn.net

10.2 创建 Surface

1 sp BLASTBufferQueue::createSurface() {

2 return new BBQSurface(mProducer, true, this);

3 }

这个 Surface 最终给 ViewRootImpl.mSurface / HWUI 使用。

10.3 onFrameAvailable()

1 void BLASTBufferQueue::onFrameAvailable(

2 const BufferItem& item) {

3 std::unique_lock lock(mMutex);

4

5 mNumFrameAvailable++;

6

7 acquireNextBufferLocked(

8 std::nullopt,

9 std::nullopt,

10 false /* dropBuffer */);

11 }

当 BufferQueueProducer::queueBuffer() 通知 frame available 后,BLASTBufferQueue 作为本地 consumer 收到回调。

10.4 acquireNextBufferLocked()

核心逻辑:

1 status_t BLASTBufferQueue::acquireNextBufferLocked(

2 const std::optionalSurfaceComposerClient::Transaction* transaction,

3 const std::optional<uint64_t> frameNumber,

4 bool dropBuffer) {

5 BufferItem bufferItem;

6

7 status_t status = mBufferItemConsumer->acquireBuffer(

8 &bufferItem,

9 0 /* presentWhen /,
10 false /
waitForFence /);
11
12 if (status != NO_ERROR) {
13 return status;
14 }
15
16 sp buffer = bufferItem.mGraphicBuffer;
17 sp fence = bufferItem.mFence;
18
19 SurfaceComposerClient::Transaction localTransaction;
20 SurfaceComposerClient::Transaction
t =

21 transaction ? *transaction : &localTransaction;

22

23 t->setBuffer(mSurfaceControl, buffer, fence);

24 t->setDataspace(mSurfaceControl, bufferItem.mDataSpace);

25 t->setCrop(mSurfaceControl, bufferItem.mCrop);

26 t->setTransform(mSurfaceControl, bufferItem.mTransform);

27

28 if (!transaction) {

29 t->apply();

30 }

31

32 return OK;

33 }

这一步非常关键:

1 BLASTBufferQueue 从本地 BufferQueue acquire buffer

2 ↓

3 把 GraphicBuffer + acquire fence 塞进 SurfaceControl.Transaction

4 ↓

5 Transaction.apply()

6 ↓

7 通过 Binder 提交给 SurfaceFlinger

所以在 Android 15 BLAST 路径下:

1 SurfaceFlinger 不直接 acquire App 窗口的 BufferQueue

2 而是接收 Transaction 里的 buffer

这一点是 Android S 以后 BLASTBufferQueue 的核心变化。 juejin.cn, jianshu.com

11. SurfaceFlinger:接收事务、latch buffer、合成显示

路径主要包括:

1 frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

2 frameworks/native/services/surfaceflinger/Layer.cpp

3 frameworks/native/services/surfaceflinger/BufferStateLayer.cpp

11.1 Transaction 到 SurfaceFlinger

客户端:

1 SurfaceComposerClient::Transaction::apply()

服务端大致进入:

1 status_t SurfaceFlinger::setTransactionState(

2 const FrameTimelineInfo& frameTimelineInfo,

3 const Vector& states,

4 const Vector& displays,

5 uint32_t flags,

6 const sp& applyToken,

7 const InputWindowCommands& inputWindowCommands,

8 int64_t desiredPresentTime,

9 bool isAutoTimestamp,

10 const client_cache_t& uncacheBuffer,

11 bool hasListenerCallbacks,

12 const std::vector& listenerCallbacks,

13 uint64_t transactionId) {

14 // 解析 Transaction

15 // 放入 transaction queue

16 // 请求下一帧 commit / composite

17 }

11.2 Layer 接收 buffer 状态

BLAST 提交的 buffer 最终进入 Layer 的 buffer state,例如:

1 bool BufferStateLayer::setBuffer(

2 const sp& buffer,

3 const sp& acquireFence,

4 nsecs_t postTime,

5 nsecs_t desiredPresentTime,

6 bool isAutoTimestamp,

7 const client_cache_t& clientCacheId,

8 uint64_t frameNumber,

9 std::optional<nsecs_t> dequeueTime,

10 const FrameTimelineInfo& info) {

11 mDrawingState.buffer = buffer;

12 mDrawingState.acquireFence = acquireFence;

13 mDrawingState.frameNumber = frameNumber;

14

15 return true;

16 }

含义:

1 SurfaceFlinger 的 Layer 状态里记录:

2 - GraphicBuffer

3 - acquire fence

4 - frame number

5 - dataspace / crop / transform 等属性

11.3 latch buffer

SurfaceFlinger 在 commit / composition 阶段检查事务、处理 LayerState,并把 pending buffer 变成当前可合成 buffer。

抽象流程:

1 void SurfaceFlinger::commit() {

2 // 处理 pending transaction

3 // 更新 Layer state

4 // latch buffer

5 }

6

7 void SurfaceFlinger::composite() {

8 // 选择 GLES / HWC 合成方式

9 // 等待 acquire fence

10 // 提交给 Hardware Composer

11 // present display

12 }

最终:

1 Layer buffer

2 ↓

3 SurfaceFlinger composition

4 ↓

5 HWC validate / present

6 ↓

7 Display 显示

SurfaceFlinger 的职责是合成所有 Layer 并送显,Android 显示系统资料中对此也有一致描述。 juejin.cn, jishuzhan.net

12. 软件绘制路径补充:Surface.lockCanvas()

如果关闭硬件加速,或者某些特殊路径走软件绘制,则 ViewRootImpl 会走:

1 private boolean drawSoftware(

2 Surface surface,

3 AttachInfo attachInfo,

4 int xoff,

5 int yoff,

6 boolean scalingRequired,

7 Rect dirty) {

8 final Canvas canvas;

9

10 try {

11 canvas = mSurface.lockCanvas(dirty);

12

13 canvas.setDensity(mDensity);

14

15 mView.draw(canvas);

16 } finally {

17 surface.unlockCanvasAndPost(canvas);

18 }

19

20 return true;

21 }

对应 native:

1 Surface.lockCanvas()

2 ↓

3 Surface::lock()

4 ↓

5 Surface::dequeueBuffer()

6 ↓

7 GraphicBufferMapper::lock()

8 ↓

9 CPU 绘制 Canvas

10 ↓

11 Surface.unlockCanvasAndPost()

12 ↓

13 GraphicBufferMapper::unlock()

14 ↓

15 Surface::queueBuffer()

也就是说:

路径 获取 buffer 绘制方式 提交方式

硬件加速 View RenderThread / EGL dequeueBuffer GPU / Skia eglSwapBuffers / queueBuffer

软件 View Surface.lockCanvas → dequeueBuffer CPU Canvas unlockCanvasAndPost → queueBuffer

13. 三个关键行为对应源码位置

13.1 "锁定 / 获取 buffer"

硬件路径不是 Java lockCanvas(),而是:

1 RenderThread

2 ↓

3 EGL / ANativeWindow

4 ↓

5 Surface::dequeueBuffer()

6 ↓

7 BufferQueueProducer::dequeueBuffer()

关键源码:

1 mGraphicBufferProducer->dequeueBuffer(...);

状态:

1 FREE → DEQUEUED

13.2 "绘制 buffer"

硬件路径:

1 ThreadedRenderer.updateRootDisplayList()

2 ↓

3 syncAndDrawFrame()

4 ↓

5 RenderThread

6 ↓

7 Skia / GLES / Vulkan

8 ↓

9 GPU 写入 GraphicBuffer

软件路径:

1 Surface.lockCanvas()

2 ↓

3 View.draw(canvas)

4 ↓

5 CPU 写入 GraphicBuffer

13.3 "通知 buffer 可显示"

第一阶段:

1 BufferQueueProducer::queueBuffer()

状态:

1 DEQUEUED → QUEUED

并回调:

1 frameAvailableListener->onFrameAvailable(item);

第二阶段,BLAST:

1 BLASTBufferQueue::onFrameAvailable()

2 ↓

3 BLASTBufferQueue::acquireNextBufferLocked()

4 ↓

5 Transaction.setBuffer()

6 ↓

7 Transaction.apply()

第三阶段,SurfaceFlinger:

1 SurfaceFlinger 接收 Transaction

2 ↓

3 Layer latch buffer

4 ↓

5 Composition

6 ↓

7 HWC present

14. Android 15 View 渲染流程时序图

1 App UIThread RenderThread / HWUI BufferQueue / BBQ SurfaceFlinger

2 | | | |

3 | View.invalidate() | | |

4 | requestLayout() | | |

5 | ViewRootImpl.scheduleTraversals() | | |

6 | Choreographer 等 VSYNC | | |

7 | doTraversal() | | |

8 | performTraversals() | | |

9 | performMeasure/Layout | | |

10 | performDraw() | | |

11 | ThreadedRenderer.draw() | | |

12 | updateRootDisplayList() | | |

13 | syncAndDrawFrame() ----------------> | | |

14 | | dequeueBuffer() ----------------> | BQP::dequeueBuffer() |

15 | | | FREE → DEQUEUED |

16 | | GPU render GraphicBuffer | |

17 | | queueBuffer() -------------------> | BQP::queueBuffer() |

18 | | | DEQUEUED → QUEUED |

19 | | | onFrameAvailable() |

20 | | | BBQ acquireBuffer() |

21 | | | Transaction.setBuffer() ----> |

22 | | | Transaction.apply() --------> |

23 | | | | receive transaction

24 | | | | latch buffer

25 | | | | compose

26 | | | | HWC present

15. 校验结论

我按 Android 15 的渲染架构对调用链做了交叉校验:

1.ViewRootImpl 调度链正确:requestLayout() / invalidate() 最终触发 scheduleTraversals(),通过 Choreographer 在 VSYNC 后执行 performTraversals()。 juejin.cn, blog.csdn.net

2.ThreadedRenderer 分工正确:UIThread 构建 DisplayList / RenderNode,RenderThread 执行 syncAndDrawFrame() 并真实渲染 buffer。 blog.csdn.net

3.BufferQueue 状态流转正确:Producer dequeueBuffer(),绘制后 queueBuffer(),Consumer acquireBuffer(),使用后 releaseBuffer(),对应状态 FREE → DEQUEUED → QUEUED → ACQUIRED → FREE。 source.and...google.cn, cnblogs.com, zhuanlan.zhihu.com

4.Android 15 BLAST 路径正确:应用窗口的 BufferQueue 在 App 进程侧,BLASTBufferQueue acquire buffer 后使用 SurfaceControl.Transaction.setBuffer() 提交给 SurfaceFlinger,而不是 SurfaceFlinger 直接作为传统 BufferQueue consumer。 juejin.cn, jianshu.com

5.SurfaceFlinger 职责正确:接收 Transaction,更新 Layer buffer state,在合成阶段 latch buffer,并通过 HWC / GLES 合成送显。 juejin.cn, jishuzhan.net

16. 最终一句话总结

Android 15 普通 View 的一次上屏,本质是:

1 View 变化

2 → ViewRootImpl 等 VSYNC 做 traversal

3 → ThreadedRenderer 构建 DisplayList

4 → RenderThread dequeue GraphicBuffer

5 → GPU 绘制

6 → queueBuffer

7 → BLASTBufferQueue acquire buffer

8 → Transaction 携带 buffer 提交给 SurfaceFlinger

9 → SurfaceFlinger latch / compose / present

其中:

1 锁定 buffer = Surface / ANativeWindow dequeueBuffer

2 绘制 buffer = RenderThread + Skia/GPU 写入 GraphicBuffer

3 通知可显示 = queueBuffer + BLAST Transaction.apply

4 最终显示 = SurfaceFlinger latch + HWC present

-------------------------------------END LINE---------------------------------------------