AOSP15 WMS/AMS系统开发 - WindowManagerService finishDraw与prepareSurface流程详解

基于 AOSP 15 (Android 15) 源码分析

摘要: 本文从relayout完成后的performDraw()出发,沿mDrawState状态机 (DRAW_PENDING → COMMIT_DRAW_PENDING → READY_TO_SHOW → HAS_DRAWN)和prepareSurface显示链路两条主线,完整梳理窗口从"有Surface"到"用户可见"的全过程。包括客户端finishDrawing通知、服务端状态流转、prepareSurfaceLocked Surface显示控制、以及ActivityRecord多窗口协同显示机制。站在Framework开发视角,分析每个状态的进入条件、阻塞点和调试方法。


目录

  • [1. 整体架构概览](#1. 整体架构概览 "#1-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84%E6%A6%82%E8%A7%88")
  • [2. mDrawState状态机总览](#2. mDrawState状态机总览 "#2-mdrawstate%E7%8A%B6%E6%80%81%E6%9C%BA%E6%80%BB%E8%A7%88")
  • [3. 完整调用链路](#3. 完整调用链路 "#3-%E5%AE%8C%E6%95%B4%E8%B0%83%E7%94%A8%E9%93%BE%E8%B7%AF")
  • [4. 客户端侧: performDraw → finishDrawing](#4. 客户端侧: performDraw → finishDrawing "#4-%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BE%A7-performdraw--finishdrawing")
    • [4.1 performTraversals中的draw触发](#4.1 performTraversals中的draw触发 "#41-performtraversals%E4%B8%AD%E7%9A%84draw%E8%A7%A6%E5%8F%91")
    • [4.2 createSyncIfNeeded --- BLAST同步组创建](#4.2 createSyncIfNeeded — BLAST同步组创建 "#42-createsyncifneeded--blast%E5%90%8C%E6%AD%A5%E7%BB%84%E5%88%9B%E5%BB%BA")
    • [4.3 performDraw → draw --- 绘制执行](#4.3 performDraw → draw — 绘制执行 "#43-performdraw--draw--%E7%BB%98%E5%88%B6%E6%89%A7%E8%A1%8C")
    • [4.4 BLAST Buffer同步 --- registerCallbacksForSync](#4.4 BLAST Buffer同步 — registerCallbacksForSync "#44-blast-buffer%E5%90%8C%E6%AD%A5--registercallbacksforsync")
    • [4.5 reportDrawFinished --- 通知WMS绘制完成](#4.5 reportDrawFinished — 通知WMS绘制完成 "#45-reportdrawfinished--%E9%80%9A%E7%9F%A5wms%E7%BB%98%E5%88%B6%E5%AE%8C%E6%88%90")
  • [5. Binder IPC: IWindowSession.finishDrawing](#5. Binder IPC: IWindowSession.finishDrawing "#5-binder-ipc-iwindowsessionfinishdrawing")
  • [6. 服务端核心: mDrawState状态流转](#6. 服务端核心: mDrawState状态流转 "#6-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%A0%B8%E5%BF%83-mdrawstate%E7%8A%B6%E6%80%81%E6%B5%81%E8%BD%AC")
    • [6.1 阶段一: WMS.finishDrawingWindow --- 入口分发](#6.1 阶段一: WMS.finishDrawingWindow — 入口分发 "#61-%E9%98%B6%E6%AE%B5%E4%B8%80-wmsfinishdrawingwindow--%E5%85%A5%E5%8F%A3%E5%88%86%E5%8F%91")
    • [6.2 阶段二: WindowState.finishDrawing --- 同步与绘制完成处理](#6.2 阶段二: WindowState.finishDrawing — 同步与绘制完成处理 "#62-%E9%98%B6%E6%AE%B5%E4%BA%8C-windowstatefinishdrawing--%E5%90%8C%E6%AD%A5%E4%B8%8E%E7%BB%98%E5%88%B6%E5%AE%8C%E6%88%90%E5%A4%84%E7%90%86")
    • [6.3 阶段三: finishDrawingLocked --- DRAW_PENDING → COMMIT_DRAW_PENDING](#6.3 阶段三: finishDrawingLocked — DRAW_PENDING → COMMIT_DRAW_PENDING "#63-%E9%98%B6%E6%AE%B5%E4%B8%89-finishdrawinglocked--draw_pending--commit_draw_pending")
    • [6.4 阶段四: commitFinishDrawingLocked --- COMMIT_DRAW_PENDING → READY_TO_SHOW](#6.4 阶段四: commitFinishDrawingLocked — COMMIT_DRAW_PENDING → READY_TO_SHOW "#64-%E9%98%B6%E6%AE%B5%E5%9B%9B-commitfinishdrawinglocked--commit_draw_pending--ready_to_show")
    • [6.5 阶段五: performShowLocked --- READY_TO_SHOW → HAS_DRAWN](#6.5 阶段五: performShowLocked — READY_TO_SHOW → HAS_DRAWN "#65-%E9%98%B6%E6%AE%B5%E4%BA%94-performshowlocked--ready_to_show--has_drawn")
  • [7. prepareSurface链路: Surface显示控制](#7. prepareSurface链路: Surface显示控制 "#7-preparesurface%E9%93%BE%E8%B7%AF-surface%E6%98%BE%E7%A4%BA%E6%8E%A7%E5%88%B6")
    • [7.1 prepareSurface调用入口 --- 两条路径](#7.1 prepareSurface调用入口 — 两条路径 "#71-preparesurface%E8%B0%83%E7%94%A8%E5%85%A5%E5%8F%A3--%E4%B8%A4%E6%9D%A1%E8%B7%AF%E5%BE%84")
    • [7.2 prepareSurfaceLocked核心逻辑](#7.2 prepareSurfaceLocked核心逻辑 "#72-preparesurfacelocked%E6%A0%B8%E5%BF%83%E9%80%BB%E8%BE%91")
    • [7.3 showRobustly --- Surface真正显示](#7.3 showRobustly — Surface真正显示 "#73-showrobustly--surface%E7%9C%9F%E6%AD%A3%E6%98%BE%E7%A4%BA")
    • [7.4 computeShownFrameLocked --- 透明度计算](#7.4 computeShownFrameLocked — 透明度计算 "#74-computeshownframelocked--%E9%80%8F%E6%98%8E%E5%BA%A6%E8%AE%A1%E7%AE%97")
    • [7.5 prepareSurface与mDrawState的关系](#7.5 prepareSurface与mDrawState的关系 "#75-preparesurface%E4%B8%8Emdrawstate%E7%9A%84%E5%85%B3%E7%B3%BB")
  • [8. ActivityRecord与窗口可见性协同](#8. ActivityRecord与窗口可见性协同 "#8-activityrecord%E4%B8%8E%E7%AA%97%E5%8F%A3%E5%8F%AF%E8%A7%81%E6%80%A7%E5%8D%8F%E5%90%8C")
    • [8.1 canShowWindows --- Activity何时允许窗口显示](#8.1 canShowWindows — Activity何时允许窗口显示 "#81-canshowwindows--activity%E4%BD%95%E6%97%B6%E5%85%81%E8%AE%B8%E7%AA%97%E5%8F%A3%E6%98%BE%E7%A4%BA")
    • [8.2 updateAllDrawn --- 所有窗口绘制完成](#8.2 updateAllDrawn — 所有窗口绘制完成 "#82-updatealldrawn--%E6%89%80%E6%9C%89%E7%AA%97%E5%8F%A3%E7%BB%98%E5%88%B6%E5%AE%8C%E6%88%90")
    • [8.3 onFirstWindowDrawn --- StartingWindow移除时机](#8.3 onFirstWindowDrawn — StartingWindow移除时机 "#83-onfirstwindowdrawn--startingwindow%E7%A7%BB%E9%99%A4%E6%97%B6%E6%9C%BA")
  • [9. Surface显示与上屏全流程](#9. Surface显示与上屏全流程 "#9-surface%E6%98%BE%E7%A4%BA%E4%B8%8E%E4%B8%8A%E5%B1%8F%E5%85%A8%E6%B5%81%E7%A8%8B")
  • [10. 调试方法](#10. 调试方法 "#10-%E8%B0%83%E8%AF%95%E6%96%B9%E6%B3%95")
  • [11. Framework开发常见场景](#11. Framework开发常见场景 "#11-framework%E5%BC%80%E5%8F%91%E5%B8%B8%E8%A7%81%E5%9C%BA%E6%99%AF")
  • [12. 完整时序图](#12. 完整时序图 "#12-%E5%AE%8C%E6%95%B4%E6%97%B6%E5%BA%8F%E5%9B%BE")
  • [13. 源码文件索引](#13. 源码文件索引 "#13-%E6%BA%90%E7%A0%81%E6%96%87%E4%BB%B6%E7%B4%A2%E5%BC%95")

1. 整体架构概览

finishDraw流程发生在relayout之后。relayout为窗口创建了Surface并计算了帧,但Surface此时是隐藏 的(mLastHidden = truemDrawState = DRAW_PENDING)。窗口需要完成第一帧绘制并通过一系列状态转换后,Surface才最终显示。

整个过程涉及两条主线:

  1. mDrawState状态机 --- 控制窗口绘制的逻辑状态流转
  2. prepareSurface链路 --- 控制Surface的物理显示/隐藏
scss 复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                          应用进程 (App Process)                          │
│                                                                         │
│  relayout返回后:                                                         │
│  performMeasure() → performLayout() → performDraw()                     │
│                                            │                            │
│  ┌──────────────────────────────────────────┘                           │
│  │                                                                      │
│  │  performDraw()                                                       │
│  │    ├── createSyncIfNeeded()          创建SurfaceSyncGroup             │
│  │    ├── draw()                        硬件渲染器绘制 → 提交Buffer        │
│  │    ├── registerCallbacksForSync()    注册BLAST Buffer同步回调          │
│  │    │     └── mBlastBufferQueue.syncNextTransaction()                 │
│  │    └── [Buffer就绪后回调]                                              │
│  │          └── reportDrawFinished()                                    │
│  │                └── IWindowSession.finishDrawing()                    │
│  │                                                                      │
│  ═════════════════════════ Binder IPC ═══════════════════════════╪═══   │
│                                                                  │      │
└──────────────────────────────────────────────────────────────────┼──────┘
                                                                   │
┌──────────────────────────────────────────────────────────────────┼─────────┐
│                       system_server 进程                          │         │
│                                                                  │         │
│  Session.finishDrawing() ◀───────────────────────────────────────┘         │
│       │                                                                    │
│       ▼                                                                    │
│  ┌────────────── mDrawState状态机 ────────────────┐                         │
│  │                                                │                        │
│  │  WMS.finishDrawingWindow()                     │                        │
│  │       ▼                                        │                        │
│  │  WindowState.finishDrawing()                   │                        │
│  │       │  BLAST同步 / 旋转 / DrawHandler         │                        │
│  │       ▼                                        │                        │
│  │  finishDrawingLocked()                         │                        │
│  │       │  DRAW_PENDING → COMMIT_DRAW_PENDING  ★①                        │
│  │       ▼                                        │                        │
│  │  requestTraversal() → performSurfacePlacement  │                        │
│  │       ▼                                        │                        │
│  │  commitFinishDrawingLocked()                   │                        │
│  │       │  COMMIT_DRAW_PENDING → READY_TO_SHOW  ★②                       │
│  │       │  → performShowLocked()                 │                        │
│  │       │      READY_TO_SHOW → HAS_DRAWN        ★③                       │
│  │       │                                        │                        │
│  └────────────────────────────────────────────────┘                        │
│       │                                                                    │
│       ▼                                                                    │
│  ┌────────────── prepareSurface显示链路 ───────────┐                        │
│  │                                                │                        │
│  │  WindowAnimator.animate()                      │                        │
│  │       ▼                                        │                        │
│  │  DisplayContent.prepareSurfaces()              │                        │
│  │       │  递归调用子容器                          │                        │
│  │       ▼                                        │                        │
│  │  WindowState.prepareSurfaces()                 │                        │
│  │       │  位置/缩放/刷新率                        │                        │
│  │       ▼                                        │                        │
│  │  WindowStateAnimator.prepareSurfaceLocked(t)   │                        │
│  │       │                                        │                        │
│  │       ├── mDrawState==HAS_DRAWN?               │                        │
│  │       │     && mLastHidden?                    │                        │
│  │       │         ↓ Yes                          │                        │
│  │       │   showRobustly(t) → t.show(surface)  ★ 上屏                     │
│  │       │                                        │                        │
│  │       └── 否则: hide(t) 或 只更新alpha           │                        │
│  │                                                │                        │
│  └────────────────────────────────────────────────┘                        │
│       │                                                                    │
│       ▼                                                                    │
│  SurfaceFlinger合成 → 显示到屏幕                                             │
└───────────────────────────────────────────────────────────────────────────┘

核心类职责

类名 路径 finishDraw/prepareSurface中的角色
ViewRootImpl core/.../view/ViewRootImpl.java 客户端绘制完成通知入口,管理BLAST同步
SurfaceSyncGroup core/.../view/SurfaceSyncGroup.java 客户端同步组,协调多个Surface的绘制完成
BLASTBufferQueue core/.../graphics/ Buffer同步机制,syncNextTransaction
Session services/.../wm/Session.java per-process,透传finishDrawing到WMS
WindowManagerService services/.../wm/ finishDrawingWindow入口,触发布局
WindowState services/.../wm/WindowState.java finishDrawing处理,prepareSurfaces入口,performShow
WindowStateAnimator services/.../wm/WindowStateAnimator.java mDrawState状态机所有者,prepareSurfaceLocked,showRobustly
WindowAnimator services/.../wm/WindowAnimator.java 动画驱动器,触发prepareSurfaces递归
ActivityRecord services/.../wm/ActivityRecord.java canShowWindows决策,allDrawn管理
DisplayContent services/.../wm/DisplayContent.java commitFinishDrawingLocked调用者,prepareSurfaces递归分发

2. mDrawState状态机总览

mDrawState定义在WindowStateAnimator.java中,是窗口从创建到可见的核心状态机。prepareSurfaceLocked的显示/隐藏决策依赖此状态。

状态定义

java 复制代码
// WindowStateAnimator.java
/** 没有Surface */
static final int NO_SURFACE = 0;

/** Surface已创建但窗口未绘制,Surface隐藏 */
static final int DRAW_PENDING = 1;

/** 窗口完成首次绘制但Surface未显示,等下次布局时显示 */
static final int COMMIT_DRAW_PENDING = 2;

/** 绘制已提交,等Token中所有窗口就绪后统一显示 */
static final int READY_TO_SHOW = 3;

/** 窗口已首次在屏幕上显示 */
static final int HAS_DRAWN = 4;

状态转换图

scss 复制代码
                        relayout
                        createSurfaceLocked()
                           │
                           │ resetDrawState()
                           ▼
┌──────────┐    客户端finishDrawing     ┌──────────────────┐
│  DRAW_   │ ─────────────────────────▶│  COMMIT_DRAW_    │
│ PENDING  │  finishDrawingLocked()    │  PENDING         │
│   (1)    │  ★ mDrawState核心转换      │    (2)           │
└──────────┘                           └───────┬──────────┘
    │                                           │
    │ mLastHidden=true                  performSurfacePlacement
    │ Surface不可见                     commitFinishDrawingLocked()
    │                                           │
    │                                           ▼
    │                                   ┌──────────────────┐
    │            performShowLocked()    │  READY_TO_SHOW   │
    │            条件全部满足             │      (3)         │
    │                                   └───────┬──────────┘
    │                                           │
    │                            performShowLocked()
    │                            isReadyForDisplay() ✓
    │                            canShowWindows() ✓
    │                                           │
    │                                           ▼
    │                                   ┌──────────────────┐
    │                                   │    HAS_DRAWN     │
    │      prepareSurfaceLocked()       │      (4)         │
    │      → showRobustly(t)            │  Surface可见!    │
    │      → t.show(surface)            └──────────────────┘
    │                                           │
    ▼                                           ▼
  Surface隐藏                              Surface显示

 异常路径:
 ┌──────────┐  Surface创建失败/销毁    ┌──────────┐
 │  NO_     │ ◀──────────────────────│ 任何状态  │
 │ SURFACE  │  destroySurface()      │          │
 │   (0)    │                        └──────────┘
 └──────────┘

每个状态的进入条件、Surface状态与prepareSurface行为

状态 进入条件 Surface状态 prepareSurfaceLocked行为
NO_SURFACE 0 初始 / Surface销毁 不存在 直接return
DRAW_PENDING 1 createSurfaceLocked()resetDrawState() 存在,隐藏 hide(t)
COMMIT_DRAW_PENDING 2 finishDrawingLocked() 隐藏 hide(t)
READY_TO_SHOW 3 commitFinishDrawingLocked() 隐藏→准备显示 可能hide(t)(因performShow未执行)
HAS_DRAWN 4 performShowLocked() 可见 showRobustly(t)t.show()

3. 完整调用链路

scss 复制代码
[应用进程] relayout完成后
performTraversals()
  │
  ├── performMeasure() → performLayout()
  │
  ▼
performDraw(surfaceSyncGroup)                         // ViewRootImpl.java line 5383
  │
  ├── draw(fullRedrawNeeded, surfaceSyncGroup, syncBuffer)  
  │     └── ThreadedRenderer.draw(mView, ...)               // 提交GPU绘制命令
  │           └── registerCallbacksForSync()                
  │                 └── mBlastBufferQueue.syncNextTransaction()  // Buffer同步
  │                       └── [GPU完成渲染回调]
  │                             └── surfaceSyncGroup.markSyncReady()
  │                                   └── [SurfaceSyncGroup完成回调]
  │                                         │
  ═══════════════════ Binder IPC ════════════════════════════
  │                                           
reportDrawFinished(transaction, seqId)         
  └── IWindowSession.finishDrawing(window, t, seqId)
                                              
[system_server]                               
Session.finishDrawing()                       
  └── WMS.finishDrawingWindow()            
        │                                      
        ▼                                     
WindowState.finishDrawing()                
  │  ├── BLAST同步处理
  │  ├── 旋转控制器处理
  │  └── executeDrawHandlers()
  │
  ▼
WindowStateAnimator.finishDrawingLocked() 
  │  ★ mDrawState: DRAW_PENDING → COMMIT_DRAW_PENDING
  │
  ▼
requestTraversal() → performSurfacePlacement()
  │
  ▼
DisplayContent.mApplySurfaceChangesTransaction  
  │
  ├── commitFinishDrawingLocked()              
  │     ★ mDrawState: COMMIT_DRAW_PENDING → READY_TO_SHOW
  │     └── performShowLocked()              
  │           ★ mDrawState: READY_TO_SHOW → HAS_DRAWN
  │           mLastAlpha = -1  // 强制下次prepareSurface刷新
  │           applyEnterAnimationLocked()
  │
  └── activity.updateDrawnWindowStates(w)   
        └── updateAllDrawn() → allDrawn=true → setLayoutNeeded()

│ 动画循环触发
▼
WindowAnimator.animate()                       
  └── dc.prepareSurfaces()                    
        └── WindowState.prepareSurfaces()       
              ├── updateSurfacePositionNonOrganized()
              ├── updateFrameRateSelectionPriorityIfNeeded()
              ├── updateScaleIfNeeded()
              └── mWinAnimator.prepareSurfaceLocked(t) 
                    │
                    ├── computeShownFrameLocked()  // 计算alpha
                    ├── t.setAlpha(surface, alpha)
                    │
                    ├── mDrawState == HAS_DRAWN && mLastHidden?
                    │     └── YES: showRobustly(t)
                    │           ├── setShown(true)
                    │           └── t.show(mSurfaceControl)  ★ Surface上屏
                    │
                    └── 否则: hide(t) 或 仅更新属性

4. 客户端侧: performDraw → finishDrawing

4.1 performTraversals中的draw触发

relayout返回后,performTraversals()依次执行measure、layout,最后执行draw:

java 复制代码
// ViewRootImpl.java performTraversals() 
if (!cancelDraw) {
    if (mReportNextDraw) {
        if (mActiveSurfaceSyncGroup != null) {
            mSyncBuffer = true;
        }
        // ★ 创建WMS同步组(如果需要)
        createSyncIfNeeded();
        notifyDrawStarted(isInWMSRequestedSync());
        mDrewOnceForSync = true;
    }

    if (!performDraw(mActiveSurfaceSyncGroup)) {
        handleSyncRequestWhenNoAsyncDraw(mActiveSurfaceSyncGroup, ...);
    }
}

Framework开发关注:

  • mReportNextDraw是WMS请求"下次绘制时通知我"的标记,在relayout返回RELAYOUT_RES_FIRST_TIME或WMS通过setReportNextDraw设置
  • createSyncIfNeeded()在draw之前创建,确保draw完成后能回调通知WMS
  • cancelDraw为true时(BLAST cancelAndRedraw),跳过本帧,等下一帧

4.2 createSyncIfNeeded --- BLAST同步组创建

java 复制代码
// ViewRootImpl.java
private void createSyncIfNeeded() {
    if (isInWMSRequestedSync() || !mReportNextDraw) {
        return;
    }

    final int seqId = mSyncSeqId;
    mWmsRequestSyncGroupState = WMS_SYNC_PENDING;

    // ★ 创建同步组,完成回调中调用 reportDrawFinished
    mWmsRequestSyncGroup = new SurfaceSyncGroup("wmsSync-" + mTag, t -> {
        mWmsRequestSyncGroupState = WMS_SYNC_MERGED;

        // 系统进程需要post到主线程避免死锁
        if (mWindowSession instanceof Binder) {
            Transaction transactionCopy = new Transaction();
            transactionCopy.merge(t);
            mHandler.postAtFrontOfQueue(
                () -> reportDrawFinished(transactionCopy, seqId));
        } else {
            reportDrawFinished(t, seqId);
        }
    });

    mWmsRequestSyncGroup.add(this, null /* runnable */);
}

WMS同步状态:

状态 含义
WMS_SYNC_NONE 0 没有WMS请求的同步
WMS_SYNC_PENDING 1 同步组已创建,等待绘制完成
WMS_SYNC_RETURNED 2 reportDrawFinished已发送到WMS
WMS_SYNC_MERGED 3 同步事务已合并

Framework开发关注:

  • SurfaceSyncGroup的回调是整个客户端finishDraw的触发点------当GPU完成渲染、Buffer就绪后回调触发
  • 系统进程需要post到Handler执行,避免finishDrawing在WMS持锁线程上被调用导致死锁
  • seqId来自relayout返回的syncSeqId,WMS用它匹配是哪次同步请求

4.3 performDraw → draw --- 绘制执行

java 复制代码
// ViewRootImpl.java
private boolean performDraw(@Nullable SurfaceSyncGroup surfaceSyncGroup) {
    if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
        return false;
    }

    mIsDrawing = true;
    boolean usingAsyncReport;
    try {
        usingAsyncReport = draw(fullRedrawNeeded, surfaceSyncGroup, mSyncBuffer);
    } finally {
        mIsDrawing = false;
    }

    if (mReportNextDraw) {
        if (mWindowDrawCountDown != null) {
            mWindowDrawCountDown.await();
        }
        if (mSurfaceHolder != null && mSurface.isValid()) {
            usingAsyncReport = true;
            SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
                handleSyncRequestWhenNoAsyncDraw(surfaceSyncGroup, ...);
            });
            sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
        }
    }

    if (!usingAsyncReport) {
        handleSyncRequestWhenNoAsyncDraw(surfaceSyncGroup, ...);
    }
    return true;
}

draw()方法(line 5601)硬件加速关键路径:

java 复制代码
if (isHardwareEnabled()) {
    useAsyncReport = true;
    if (activeSyncGroup != null) {
        registerCallbacksForSync(syncBuffer, activeSyncGroup);
        if (syncBuffer) {
            mAttachInfo.mThreadedRenderer.forceDrawNextFrame();
        }
    }
    // ★ 提交GPU绘制命令
    mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
}

4.4 BLAST Buffer同步 --- registerCallbacksForSync

java 复制代码
// ViewRootImpl.java
private void registerCallbacksForSync(boolean syncBuffer,
        final SurfaceSyncGroup surfaceSyncGroup) {

    mAttachInfo.mThreadedRenderer.registerRtFrameCallback(new FrameDrawingCallback() {
        @Override
        public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) {
            // Surface丢失/上下文停止 → 直接完成
            if ((syncResult & (SYNC_LOST_SURFACE_REWARD_IF_FOUND
                    | SYNC_CONTEXT_IS_STOPPED)) != 0) {
                surfaceSyncGroup.markSyncReady();
                return null;
            }

            if (syncBuffer) {
                // ★ BLAST Buffer同步: 等Buffer就绪后再标记完成
                mBlastBufferQueue.syncNextTransaction(transaction -> {
                    surfaceSyncGroup.addTransaction(transaction);
                    surfaceSyncGroup.markSyncReady();
                });
            }

            return didProduceBuffer -> {
                if (!didProduceBuffer) {
                    mBlastBufferQueue.clearSyncTransaction();
                    surfaceSyncGroup.markSyncReady();
                    return;
                }
                if (!syncBuffer) {
                    surfaceSyncGroup.markSyncReady();
                }
            };
        }
    });
}

BLAST Buffer同步时序:

scss 复制代码
ThreadedRenderer.draw(mView) → GPU命令提交
  │
  ▼
onFrameDraw(syncResult, frame)           ← 渲染线程回调
  │
  ├── syncBuffer=true:
  │     mBlastBufferQueue.syncNextTransaction(callback)
  │       → Buffer就绪 → callback → markSyncReady()
  │
  └── syncBuffer=false:
        frameCommitCallback → markSyncReady()
  │
  ▼
SurfaceSyncGroup完成回调 → reportDrawFinished()

4.5 reportDrawFinished --- 通知WMS绘制完成

java 复制代码
// ViewRootImpl.java line 5289-5303
private void reportDrawFinished(@Nullable Transaction t, int seqId) {
    try {
        mWindowSession.finishDrawing(mWindow, t, seqId);
    } catch (RemoteException e) {
        if (t != null) t.apply();
    } finally {
        if (t != null) t.clear();
    }
}

5. Binder IPC: IWindowSession.finishDrawing

java 复制代码
// IWindowSession.aidl
void finishDrawing(IWindow window,
    @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId);
参数 说明 Framework关注
window 客户端窗口标识 WMS通过windowForClientLocked找到WindowState
postDrawTransaction 绘制事务(可能包含Buffer) WMS会merge到同步事务中
seqId 同步序列号 匹配mPrepareSyncSeqId,旧seqId的Buffer会被丢弃

6. 服务端核心: mDrawState状态流转

6.1 阶段一: WMS.finishDrawingWindow --- 入口分发

java 复制代码
// Session.java
public void finishDrawing(IWindow window,
        @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
    mService.finishDrawingWindow(this, window, postDrawTransaction, seqId);
}
java 复制代码
// WindowManagerService.java
void finishDrawingWindow(Session session, IWindow client,
        @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
    if (postDrawTransaction != null) {
        postDrawTransaction.sanitize(Binder.getCallingPid(), Binder.getCallingUid());
    }

    final long origId = Binder.clearCallingIdentity();
    try {
        synchronized (mGlobalLock) {
            WindowState win = windowForClientLocked(session, client, false);
            ProtoLog.d(WM_DEBUG_ADD_REMOVE,
                    "finishDrawingWindow: %s mDrawState=%s",
                    win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));

            if (win != null && win.finishDrawing(postDrawTransaction, seqId)) {
                if (win.hasWallpaper()) {
                    win.getDisplayContent().pendingLayoutChanges |=
                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                }
                win.setDisplayLayoutNeeded();
                // ★ 触发布局循环 → 后续commitFinishDrawingLocked在此循环中执行
                mWindowPlacerLocked.requestTraversal();
            }
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
}

Framework开发关注:

  • finishDrawingWindowmGlobalLock同步块内执行
  • win.finishDrawing()返回true → 需要重新布局 → requestTraversal()
  • 这个requestTraversal()走到performSurfacePlacement,在那里执行commitFinishDrawingLocked
  • 如果返回false(drawState已经不是DRAW_PENDING),不触发额外操作

6.2 阶段二: WindowState.finishDrawing --- 同步与绘制完成处理

java 复制代码
// WindowState.java
boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
    // ① 方向变更耗时统计
    if (mOrientationChangeRedrawRequestTime > 0) {
        Slog.i(TAG, "finishDrawing of orientation change: " + this
                + " " + (SystemClock.elapsedRealtime()
                - mOrientationChangeRedrawRequestTime) + "ms");
        mOrientationChangeRedrawRequestTime = 0;
    }

    // ② Activity重启动时通知
    if (mActivityRecord != null && mActivityRecord.mRelaunchStartTime != 0
            && mActivityRecord.findMainWindow(false) == this) {
        mActivityRecord.finishOrAbortReplacingWindow();
    }

    // ③ StartingWindow绘制通知
    if (mActivityRecord != null && mAttrs.type == TYPE_APPLICATION_STARTING) {
        mWmService.mAtmService.mTaskSupervisor.getActivityMetricsLogger()
                .notifyStartingWindowDrawn(mActivityRecord);
    }

    // ④ ★ BLAST同步序列号匹配
    final boolean syncActive = mPrepareSyncSeqId > 0;
    final boolean syncStillPending = syncActive && mPrepareSyncSeqId > syncSeqId;
    if (syncStillPending && postDrawTransaction != null) {
        // 旧seqId的Buffer已过时,丢弃
        dropBufferFrom(postDrawTransaction);
    }

    // ⑤ 执行DrawHandler
    final boolean hasSyncHandlers = executeDrawHandlers(postDrawTransaction, syncSeqId);

    // ⑥ 异步旋转控制器处理
    boolean skipLayout = false;
    boolean layoutNeeded = false;
    final AsyncRotationController asyncRotationController =
            mDisplayContent.getAsyncRotationController();
    if (asyncRotationController != null
            && asyncRotationController.handleFinishDrawing(this, postDrawTransaction)) {
        postDrawTransaction = null;
        skipLayout = true;
    } else if (syncActive) {
        // BLAST同步模式
        if (!syncStillPending) {
            layoutNeeded = onSyncFinishedDrawing();
        }
        if (postDrawTransaction != null) {
            mSyncTransaction.merge(postDrawTransaction);
            postDrawTransaction = null;
        }
    } else if (syncNextBuffer()) {
        // 非BLAST同步模式
        layoutNeeded = onSyncFinishedDrawing();
    }

    // ⑦ ★ 核心状态转换
    layoutNeeded |= mWinAnimator.finishDrawingLocked(postDrawTransaction);

    return !skipLayout && (hasSyncHandlers || layoutNeeded);
}

四个关键路径:

路径 条件 行为
异步旋转 asyncRotationController != null 控制器消费事务,skipLayout=true
BLAST同步 syncActive 合并到mSyncTransaction,同步组完成后统一显示
非BLAST同步 syncNextBuffer() 直接标记同步完成
普通路径 无同步 直接到finishDrawingLocked()

6.3 阶段三: finishDrawingLocked --- DRAW_PENDING → COMMIT_DRAW_PENDING

java 复制代码
// WindowStateAnimator.java
boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
    boolean layoutNeeded = false;

    // ★ 只有DRAW_PENDING时才转换
    if (mDrawState == DRAW_PENDING) {
        ProtoLog.v(WM_DEBUG_DRAW,
                "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s",
                mWin, mSurfaceControl);
        mDrawState = COMMIT_DRAW_PENDING;  // ★ 状态转换
        layoutNeeded = true;
    }

    // 合并客户端的绘制事务
    if (postDrawTransaction != null) {
        mWin.getSyncTransaction().merge(postDrawTransaction);
        layoutNeeded = true;
    }

    return layoutNeeded;
}

Framework开发关注:

  • 只有mDrawState == DRAW_PENDING时才会转换。如果已是HAS_DRAWN(后续重绘),此方法是空操作
  • layoutNeeded = truerequestTraversal() → 触发commitFinishDrawingLocked执行
  • 后续重绘(resize等)走relayout路径,不经过这个状态机

6.4 阶段四: commitFinishDrawingLocked --- COMMIT_DRAW_PENDING → READY_TO_SHOW

此方法在performSurfacePlacementmApplySurfaceChangesTransaction中被调用:

java 复制代码
// DisplayContent.java
private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
    if (w.mHasSurface) {
        final boolean committed = w.mWinAnimator.commitFinishDrawingLocked();
        // ...
    }
    // ...
    // ★ 更新Activity的窗口绘制状态
    if (activity != null && activity.isVisibleRequested()) {
        activity.updateDrawnWindowStates(w);  // → updateAllDrawn()
    }
};

commitFinishDrawingLocked实现:

java 复制代码
// WindowStateAnimator.java 
boolean commitFinishDrawingLocked() {
    if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
        return false;
    }

    mDrawState = READY_TO_SHOW;  // ★ COMMIT_DRAW_PENDING → READY_TO_SHOW

    boolean result = false;
    final ActivityRecord activity = mWin.mActivityRecord;

    // ★ 判断是否可以立即显示
    if (activity == null || activity.canShowWindows()
            || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
        result = mWin.performShowLocked();  // → READY_TO_SHOW → HAS_DRAWN
    }
    // 否则: 保持在READY_TO_SHOW,等allDrawn后统一显示

    return result;
}

三种显示时机:

条件 行为
activity == null 系统窗口,立即performShow
activity.canShowWindows() Activity所有窗口已绘制完,统一显示
TYPE_APPLICATION_STARTING StartingWindow不等其他窗口
否则 保持在READY_TO_SHOW,等updateAllDrawn

6.5 阶段五: performShowLocked --- READY_TO_SHOW → HAS_DRAWN

java 复制代码
// WindowState.java
boolean performShowLocked() {
    // ① 用户可见性
    if (!showToCurrentUser()) {
        clearPolicyVisibilityFlag(VISIBLE_FOR_USER);
        return false;
    }

    // ② 通知ActivityRecord(在状态检查之前)
    final int drawState = mWinAnimator.mDrawState;
    if ((drawState == HAS_DRAWN || drawState == READY_TO_SHOW)
            && mActivityRecord != null) {
        if (mAttrs.type != TYPE_APPLICATION_STARTING) {
            mActivityRecord.onFirstWindowDrawn(this);  // → 移除StartingWindow
        } else {
            mActivityRecord.onStartingWindowDrawn();
        }
    }

    // ③ 前置条件检查
    if (mWinAnimator.mDrawState != READY_TO_SHOW || !isReadyForDisplay()) {
        return false;
    }

    // ④ ★ 状态转换: READY_TO_SHOW → HAS_DRAWN
    mWinAnimator.applyEnterAnimationLocked();  // 入场动画

    // ★★★ 关键: 设置mLastAlpha=-1,强制下次prepareSurfaceLocked刷新 ★★★
    mWinAnimator.mLastAlpha = -1;

    mWinAnimator.mDrawState = HAS_DRAWN;  // ★ 最终状态
    mWmService.scheduleAnimationLocked();

    // ⑤ 递归显示子窗口
    if (mHidden) {
        mHidden = false;
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final WindowState c = mChildren.get(i);
            if (c.mWinAnimator.mSurfaceControl != null) {
                c.performShowLocked();
                if (displayContent != null) {
                    displayContent.setLayoutNeeded();
                }
            }
        }
    }

    return true;
}

isReadyForDisplay检查:

java 复制代码
// WindowState.java
boolean isReadyForDisplay() {
    final boolean parentAndClientVisible = !isParentWindowHidden()
            && mViewVisibility == View.VISIBLE;

    return mHasSurface
            && isVisibleByPolicy()
            && !mDestroying
            && mToken.isVisible()
            && (parentAndClientVisible
                || isAnimating(TRANSITION | PARENTS));
}

isOnScreen检查(prepareSurfaceLocked使用):

java 复制代码
// WindowState.java
boolean isOnScreen() {
    if (!mHasSurface || mDestroying || !isVisibleByPolicy()) {
        return false;
    }
    final ActivityRecord atoken = mActivityRecord;
    if (atoken != null) {
        final boolean isVisible = isStartingWindowAssociatedToTask()
                ? mStartingData.mAssociatedTask.isVisible() : atoken.isVisible();
        return ((!isParentWindowHidden() && isVisible)
                || isAnimationRunningSelfOrParent());
    }
    // ...
}

7. prepareSurface链路: Surface显示控制

prepareSurface是mDrawState状态机之外的另一条关键链路------它负责在每次动画帧中根据窗口状态实际控制Surface的显示/隐藏。

7.1 prepareSurface调用入口 --- 两条路径

路径一: commitFinishDrawing后的即时调用

java 复制代码
// WindowState.java
boolean commitFinishDrawing(SurfaceControl.Transaction t) {
    boolean committed = mWinAnimator.commitFinishDrawingLocked();
    if (committed) {
        // ★ commitFinishDrawingLocked返回true后,立即prepareSurface
        // 但此时mDrawState=READY_TO_SHOW(还没到HAS_DRAWN)
        // prepareSurfaceLocked不会show------要等performShowLocked后
        mWinAnimator.prepareSurfaceLocked(t);
    }
    // 递归子窗口
    for (int i = mChildren.size() - 1; i >= 0; i--) {
        committed |= mChildren.get(i).commitFinishDrawing(t);
    }
    return committed;
}

路径二: 动画循环中的递归调用(主要路径,Surface真正显示的地方)

java 复制代码
// WindowAnimator.java
private void animate(long frameTimeNs) {
    // ...
    for (int i = 0; i < numDisplays; i++) {
        final DisplayContent dc = root.getChildAt(i);
        dc.updateWindowsForAnimator();
        dc.prepareSurfaces();  // ★ 递归调用所有窗口的prepareSurfaces
    }
}

递归调用链:

java 复制代码
WindowAnimator.animate()
  └── DisplayContent.prepareSurfaces()          
        └── super.prepareSurfaces()              // WindowContainer --- 递归children
              └── WindowState.prepareSurfaces()   
                    ├── updateSurfacePositionNonOrganized()
                    ├── updateFrameRateSelectionPriorityIfNeeded()
                    ├── updateScaleIfNeeded()
                    ├── mWinAnimator.prepareSurfaceLocked(t)  ★ 核心
                    ├── applyDims()
                    └── super.prepareSurfaces()  → 子窗口递归
java 复制代码
// WindowState.java
void prepareSurfaces() {
    mIsDimming = false;
    if (mHasSurface) {
        updateSurfacePositionNonOrganized();     // 更新Surface位置
        updateFrameRateSelectionPriorityIfNeeded(); // 刷新率优先级
        updateScaleIfNeeded();                    // 缩放
        mWinAnimator.prepareSurfaceLocked(getSyncTransaction());  // ★ 核心
        applyDims();                              // Dim效果
    }
    super.prepareSurfaces();  // 递归子容器
}

7.2 prepareSurfaceLocked核心逻辑

java 复制代码
// WindowStateAnimator.java
void prepareSurfaceLocked(SurfaceControl.Transaction t) {
    final WindowState w = mWin;
    if (!hasSurface()) {
        if (w.getOrientationChanging() && w.isGoneForLayout()) {
            w.setOrientationChanging(false);
        }
        return;
    }

    // ① 计算当前帧的透明度
    computeShownFrameLocked();

    // ② ★ 核心决策: 显示 or 隐藏
    if (!w.isOnScreen()) {
        // 窗口不在屏幕上 → 隐藏
        hide(t, "prepareSurfaceLocked");
        mWallpaperControllerLocked.hideWallpapers(w);
    } else if (mLastAlpha != mShownAlpha || mLastHidden) {
        // alpha变化 或 之前隐藏 → 更新
        mLastAlpha = mShownAlpha;
        t.setAlpha(mSurfaceControl, mShownAlpha);

        // ③ ★★★ 关键: 只有HAS_DRAWN状态才show Surface ★★★
        if (mDrawState == HAS_DRAWN) {
            if (mLastHidden) {
                showRobustly(t);           // ★ Surface.show()
                mLastHidden = false;
                if (!displayContent.getLastHasContent()) {
                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
                }
            }
        }
        // mDrawState < HAS_DRAWN → 只更新alpha,不show
    }

    // ④ 方向变更完成检查
    if (w.getOrientationChanging()) {
        if (!w.isDrawn()) {
            w.mWmService.mRoot.mOrientationChangeComplete = false;
        } else {
            w.setOrientationChanging(false);
        }
    }
}

prepareSurfaceLocked决策流程图:

ini 复制代码
prepareSurfaceLocked(t)
  │
  ├── hasSurface()? ──── No → return
  │
  ├── computeShownFrameLocked()  → mShownAlpha = mAlpha
  │
  ├── isOnScreen()? ──── No → hide(t)
  │
  └── Yes:
        │
        ├── alpha变了 或 mLastHidden?
        │     │
        │     ├── t.setAlpha(surface, mShownAlpha)
        │     │
        │     ├── mDrawState == HAS_DRAWN?  ─── No → 只更新alpha,不show
        │     │
        │     └── Yes:
        │           │
        │           ├── mLastHidden == true?
        │           │     │
        │           │     └── ★ showRobustly(t) ★
        │           │           t.show(mSurfaceControl)
        │           │           setShown(true)
        │           │           mLastHidden = false
        │           │
        │           └── mLastHidden == false → 已显示,只更新alpha
        │
        └── 方向变更检查

7.3 showRobustly --- Surface真正显示

java 复制代码
// WindowStateAnimator.java
private void showRobustly(SurfaceControl.Transaction t) {
    if (mSurfaceShown) {
        return;  // 已经显示
    }

    ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", mTitle);

    setShown(true);                       // mSurfaceShown = true
    t.show(mSurfaceControl);              // ★ SurfaceControl.show() → SurfaceFlinger

    if (mWin.mIsWallpaper) {
        EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE, ...);
    }
}
java 复制代码
// WindowStateAnimator.java line 224-229
private void setShown(boolean surfaceShown) {
    mSurfaceShown = surfaceShown;
    mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, surfaceShown);
    mWin.onSurfaceShownChanged(surfaceShown);       // 通知WindowState → Input系统
    mSession.onWindowSurfaceVisibilityChanged(mWin, mSurfaceShown);
}

Framework开发关注:

  • showRobustly是Surface真正显示 的地方------t.show(mSurfaceControl)发送给SurfaceFlinger
  • setShown(true)触发onSurfaceShownChanged,影响Input系统(窗口开始接收触摸事件)
  • mSurfaceShown防止重复show

7.4 computeShownFrameLocked --- 透明度计算

java 复制代码
// WindowStateAnimator.java
void computeShownFrameLocked() {
    if (mWin.mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
        return;
    } else if (mWin.isDragResizeChanged()) {
        // drag-resize中 → 不更新shownFrame(等新Surface的draw)
        return;
    }
    mShownAlpha = mAlpha;
}

7.5 prepareSurface与mDrawState的关系

mDrawState和prepareSurface是两条独立的控制线,协同工作:

mDrawState performShowLocked动作 prepareSurfaceLocked行为
DRAW_PENDING 未执行 hide(t) --- Surface隐藏
COMMIT_DRAW_PENDING 未执行 hide(t) --- Surface隐藏
READY_TO_SHOW 如果通过检查 → 设置HAS_DRAWN, mLastAlpha=-1 可能hide(t)(因mDrawState还不是HAS_DRAWN)
HAS_DRAWN 已执行 showRobustly(t) --- Surface显示!

关键连接点:

  1. performShowLocked设置mDrawState = HAS_DRAWN同时 设置mLastAlpha = -1
  2. 下次prepareSurfaceLocked被调用时,检测到mLastAlpha != mShownAlpha(因为-1 != mAlpha)
  3. 进入alpha更新分支,检测到mDrawState == HAS_DRAWNmLastHidden == true
  4. 调用showRobustly(t)t.show(surface) → SurfaceFlinger显示

这就是为什么performShowLocked之后需要scheduleAnimationLocked ------动画循环触发prepareSurfaces()递归,最终执行prepareSurfaceLocked完成Surface显示。


8. ActivityRecord与窗口可见性协同

8.1 canShowWindows --- Activity何时允许窗口显示

java 复制代码
// ActivityRecord.java
boolean canShowWindows() {
    return mTransitionController.isShellTransitionsEnabled()
            ? mSyncState != SYNC_STATE_WAITING_FOR_DRAW
            : allDrawn;
}
模式 条件 含义
Shell Transition mSyncState != SYNC_STATE_WAITING_FOR_DRAW 现代过渡模式,同步完成即可
传统模式 allDrawn == true 所有关注窗口都已绘制完成

8.2 updateAllDrawn --- 所有窗口绘制完成

java 复制代码
// ActivityRecord.java
void updateAllDrawn() {
    if (!allDrawn) {
        final int numInteresting = mNumInterestingWindows;
        if (numInteresting > 0 && allDrawnStatesConsidered()
                && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
            allDrawn = true;
            // ★ 强制额外布局 --- commitFinishDrawingLocked会在其中执行
            // 此前READY_TO_SHOW的窗口此时能通过canShowWindows检查
            if (mDisplayContent != null) {
                mDisplayContent.setLayoutNeeded();
            }
            mWmService.mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, this).sendToTarget();
        }
    }
}

Framework开发关注:

  • mNumInterestingWindows ≠ 所有子窗口,只有"感兴趣的"窗口才计入
  • mNumDrawnWindows在每个窗口finishDrawingLocked后通过updateDrawnWindowStates递增
  • allDrawn = true后,commitFinishDrawingLocked中的canShowWindows()变为true
  • 这是同Activity多窗口协同显示的机制------保证不会只显示部分窗口

8.3 onFirstWindowDrawn --- StartingWindow移除时机

java 复制代码
// ActivityRecord.java 
void onFirstWindowDrawn(WindowState win) {
    firstWindowDrawn = true;
    mSplashScreenStyleSolidColor = true;

    if (mStartingWindow != null) {
        win.cancelAnimation();
    }

    final Task associatedTask = task.mSharedStartingData != null ? task : null;
    if (associatedTask == null) {
        removeStartingWindow();  // 独立Task → 直接移除
    } else if (associatedTask.getActivity(
            r -> r.isVisibleRequested() && !r.firstWindowDrawn) == null) {
        // 共享Task → 所有Activity的首窗口都绘制完才移除
        final ActivityRecord r = associatedTask.getActivity(ar -> ar.mStartingData != null);
        if (r != null) {
            r.removeStartingWindow();
        }
    }
}

9. Surface显示与上屏全流程

从mDrawState=HAS_DRAWN到Surface真正上屏,涉及的完整流程:

scss 复制代码
performShowLocked()
  │
  ├── mDrawState = HAS_DRAWN
  ├── mLastAlpha = -1  (强制prepareSurface刷新)
  ├── scheduleAnimationLocked()
  │
  ▼
WindowAnimator.animate()                       // 下一个动画帧
  │
  ├── dc.updateWindowsForAnimator()
  └── dc.prepareSurfaces()                     // 递归
        │
        └── WindowState.prepareSurfaces()       
              │
              └── mWinAnimator.prepareSurfaceLocked(t)  
                    │
                    ├── computeShownFrameLocked()  → mShownAlpha = mAlpha
                    │
                    ├── isOnScreen() → true
                    │
                    ├── mLastAlpha(-1) != mShownAlpha → 进入更新分支
                    │     ├── t.setAlpha(surface, alpha)
                    │     │
                    │     ├── mDrawState == HAS_DRAWN → YES
                    │     │     └── mLastHidden == true → YES
                    │     │           │
                    │     │           ▼
                    │     │     showRobustly(t)
                    │     │       ├── setShown(true)
                    │     │       │     ├── mSurfaceShown = true
                    │     │       │     ├── onSurfaceShownChanged(true) → Input系统
                    │     │       │     └── onWindowSurfaceVisibilityChanged()
                    │     │       └── t.show(mSurfaceControl) ★ SurfaceFlinger
                    │     │
                    │     └── mLastHidden = false
                    │
                    └── 方向变更完成检查

│ SurfaceFlinger合成
▼
屏幕显示!

applyEnterAnimationLocked:

java 复制代码
// WindowStateAnimator.java 
void applyEnterAnimationLocked() {
    final int transit;
    if (mEnterAnimationPending) {
        mEnterAnimationPending = false;
        transit = WindowManagerPolicy.TRANSIT_ENTER;
    } else {
        transit = WindowManagerPolicy.TRANSIT_SHOW;
    }

    // 基应用窗口由ActivityRecord控制动画
    if (mAttrType != TYPE_BASE_APPLICATION && !mWin.mIsWallpaper
            && !(mWin.mActivityRecord != null
                    && mWin.mActivityRecord.hasStartingWindow())) {
        applyAnimationLocked(transit, true);
    }
}

10. 调试方法

ProtoLog开关

bash 复制代码
# finishDraw + prepareSurface相关
adb shell dumpsys activity logging enable WM_DEBUG_DRAW
adb shell dumpsys activity logging enable WM_DEBUG_ADD_REMOVE
adb shell dumpsys activity logging enable WM_DEBUG_ANIM
adb shell dumpsys activity logging enable WM_DEBUG_VISIBILITY
adb shell dumpsys activity logging enable WM_DEBUG_SYNC_ENGINE
adb shell dumpsys activity logging enable WM_DEBUG_STARTING_WINDOW

# Surface显示
adb shell dumpsys activity logging enable WM_SHOW_TRANSACTIONS
adb shell dumpsys activity logging enable WM_SHOW_SURFACE_ALLOC

dumpsys

bash 复制代码
# 查看mDrawState
adb dumpsys window windows | grep -A 30 "Window #"

# 查看allDrawn状态
adb dumpsys activity activities | grep -E "allDrawn|firstWindowDrawn"

# 查看Surface状态
adb dumpsys SurfaceFlinger --list
adb dumpsys SurfaceFlinger | grep -A 5 "<window_name>"

关键日志

ini 复制代码
# DRAW_PENDING → COMMIT_DRAW_PENDING
finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING <window> in <surface>

# COMMIT_DRAW_PENDING → READY_TO_SHOW
commitFinishDrawingLocked: mDrawState=READY_TO_SHOW <surface>

# READY_TO_SHOW → HAS_DRAWN
performShowLocked: mDrawState=HAS_DRAWN in <window>

# Surface显示!
SURFACE SHOW (performLayout): <window_title>

# allDrawn触发
allDrawn: <activity> interesting=N drawn=M

# Buffer丢弃
Got a buffer for request id=X but latest request is id=Y. drop it.

perfetto

bash 复制代码
atrace -b 32768 wm view am gfx input sched freq --async_time > trace.bin
# 搜索: finishDrawingWindow / performShow / prepareSurfaceLocked
# 搜索: showRobustly / commitFinishDrawing / wmUpdateFocus

11. Framework开发常见场景

场景1: 窗口显示白屏/黑屏 --- 按mDrawState逐级排查

arduino 复制代码
1. mDrawState停在DRAW_PENDING
   → 客户端没有调用finishDrawing
   → 检查: performDraw是否执行?createSyncIfNeeded是否创建?
   → 常见: BLAST同步卡住, GPU渲染失败, SyncGroup回调未触发

2. mDrawState停在COMMIT_DRAW_PENDING
   → performSurfacePlacement没有执行
   → 检查: requestTraversal是否被调用?mDeferDepth > 0?
   → 常见: deferLayout阻塞, mInLayout递归保护

3. mDrawState停在READY_TO_SHOW
   → canShowWindows()返回false
   → 检查: allDrawn? mSyncState? mNumDrawnWindows vs mNumInterestingWindows?
   → 常见: 同Activity其他窗口未完成绘制

4. mDrawState == HAS_DRAWN 但Surface不可见
   → prepareSurfaceLocked没被调用(动画循环没触发)
   → 检查: scheduleAnimationLocked是否执行?
   → 或: isOnScreen()返回false
   → 检查: isVisibleByPolicy? isParentWindowHidden?

场景2: prepareSurfaceLocked没有show Surface

css 复制代码
前提: mDrawState已经是HAS_DRAWN

1. isOnScreen()返回false?
   → mHasSurface? mDestroying? isVisibleByPolicy?
   → atoken.isVisible()? isParentWindowHidden?

2. mLastHidden已经是false?
   → 之前已经show过了

3. mLastAlpha == mShownAlpha && !mLastHidden?
   → alpha没变化且已显示 → 不需要操作

4. 动画循环没运行?
   → scheduleAnimationLocked没被调用?
   → WindowAnimator.animate()没被执行?

场景3: StartingWindow不消失

markdown 复制代码
1. performShowLocked是否执行? → onFirstWindowDrawn触发
2. mStartingWindow != null?
3. 共享StartingData: 其他Activity是否都绘制完?
4. removeStartingWindow动画是否完成?

场景4: BLAST同步超时/ANR

markdown 复制代码
1. syncSeqId匹配? → mPrepareSyncSeqId > syncSeqId → Buffer丢弃
2. syncNextTransaction回调是否触发? → GPU卡住?
3. 系统进程死锁: createSyncIfNeeded的Binder检查

场景5: 多窗口协同显示问题

markdown 复制代码
1. allDrawn不为true? → mNumDrawnWindows < mNumInterestingWindows
2. canShowWindows()? → Shell Transition查mSyncState / 传统查allDrawn
3. 某窗口被错误排除? → isGoneForLayout检查

场景6: 窗口resize后闪烁

scss 复制代码
1. computeShownFrameLocked中isDragResizeChanged() → 跳过shownFrame更新
2. resize过程中旧帧在新位置显示? → mDrawState被重置为DRAW_PENDING?
3. prepareSurfaceLocked在HAS_DRAWN和DRAW_PENDING间切换?

场景7: 异步旋转时窗口显示异常

scss 复制代码
1. AsyncRotationController拦截了finishDrawing?
   → handleFinishDrawing返回true → skipLayout=true
2. 旋转完成后prepareSurfaces是否重新执行?
3. 方向变更卡住? → getOrientationChanging()一直为true → isDrawn()检查

12. 完整时序图

scss 复制代码
App Process                              system_server
──────────                               ─────────────
    │
    │ [relayout已完成]
    │ [Surface已创建, mDrawState=DRAW_PENDING, mLastHidden=true]
    │
    ▼
performTraversals()
    ├── performMeasure() → performLayout()
    ├── createSyncIfNeeded()
    ├── performDraw(surfaceSyncGroup)
    │     ├── draw() → ThreadedRenderer.draw(mView)
    │     └── registerCallbacksForSync()
    │           └── mBlastBufferQueue.syncNextTransaction()
    │
    │ ... GPU异步渲染 ...
    │
    │ onFrameDraw → markSyncReady → [SSG回调]
    │     │
    │   reportDrawFinished(t, seqId)
    │     │
    │     │  finishDrawing(window, t, seqId)
    │     │──────────────────────────────▶│
    │     │                               │
    │     │                        WMS.finishDrawingWindow()
    │     │                               │
    │     │                        WindowState.finishDrawing()
    │     │                        [BLAST同步/旋转/seqId匹配]
    │     │                               │
    │     │                        finishDrawingLocked()
    │     │                        ★ mDrawState = COMMIT_DRAW_PENDING
    │     │                               │
    │     │                        requestTraversal()
    │     │                               │
    │     │                        performSurfacePlacement()
    │     │                               │
    │     │                        mApplySurfaceChangesTransaction
    │     │                               │
    │     │                        commitFinishDrawingLocked()
    │     │                        ★ mDrawState = READY_TO_SHOW
    │     │                               │
    │     │                        canShowWindows()?
    │     │                        ┌──Yes─────┤────No──────┐
    │     │                        │          │            │
    │     │                  performShowLocked()    等allDrawn
    │     │                        │
    │     │                  isReadyForDisplay()?
    │     │                  ┌──Yes───┤───No───┐
    │     │                  │        │        │
    │     │            applyEnterAnimationLocked()
    │     │                  │        等下次布局循环
    │     │            mLastAlpha = -1
    │     │            ★ mDrawState = HAS_DRAWN
    │     │            scheduleAnimationLocked()
    │     │                  │
    │     │                  │    ┌──────── 动画循环 ─────────┐
    │     │                  │    │ WindowAnimator.animate() │
    │     │                  │    │ dc.prepareSurfaces()     │
    │     │                  │    │ 递归到每个WindowState:     │
    │     │                  │    │ prepareSurfaceLocked(t)  │
    │     │                  │    │   │                      │
    │     │                  │    │   ├── isOnScreen()? YES  │
    │     │                  │    │   ├── mLastAlpha != alpha? YES(-1)
    │     │                  │    │   ├── mDrawState == HAS_DRAWN? YES
    │     │                  │    │   └── mLastHidden? YES   │
    │     │                  │    │       │                  │
    │     │                  │    │       ▼                  │
    │     │                  │    │   showRobustly(t)        │
    │     │                  │    │   t.show(mSurfaceControl)│
    │     │                  │    │   mLastHidden = false    │
    │     │                  │    │   mSurfaceShown = true   │
    │     │                  │    │         │                │
    │     │                  │    └─────────┼────────────────┘
    │     │                  │              │
    │     │                  │         SurfaceFlinger合成上屏 ★
    │     │                  │
    │  mReportNextDraw = false
    │  mActiveSurfaceSyncGroup = null
    │
    ▼
[窗口可见, 用户看到内容]

13. 源码文件索引

文件 路径 关键方法/行号
ViewRootImpl.java core/java/android/view/ performDraw() ~5383, draw() ~5601, reportDrawFinished() ~5289, createSyncIfNeeded() ~4489, registerCallbacksForSync() ~12702
IWindowSession.aidl core/java/android/view/ finishDrawing() --- Binder接口
Session.java services/.../wm/ finishDrawing() ~314
WindowManagerService.java services/.../wm/ finishDrawingWindow() ~2803
WindowState.java services/.../wm/ finishDrawing() ~5884, performShowLocked() ~4467, commitFinishDrawing() ~4438, prepareSurfaces() ~5337, isReadyForDisplay() ~1983, isOnScreen() ~1917, isDrawn() ~2073, isDisplayed() ~2026
WindowStateAnimator.java services/.../wm/ mDrawState常量 ~129-152, finishDrawingLocked() ~231, commitFinishDrawingLocked() ~261, resetDrawState() ~282, prepareSurfaceLocked() ~440, computeShownFrameLocked() ~420, showRobustly() ~514, setShown() ~224, applyEnterAnimationLocked() ~548, createSurfaceLocked() ~294, destroySurface() ~707
WindowAnimator.java services/.../wm/ animate() ~113 --- prepareSurfaces的触发者
DisplayContent.java services/.../wm/ mApplySurfaceChangesTransaction ~1002, prepareSurfaces() ~5606
ActivityRecord.java services/.../wm/ canShowWindows() ~4877, updateAllDrawn() ~5308, onFirstWindowDrawn() ~6918, prepareSurfaces() ~7831
WindowContainer.java services/.../wm/ prepareSurfaces() ~2934 --- 递归分发, SYNC_STATE_* ~329-342
BLASTSyncEngine.java services/.../wm/ METHOD_*常量 ~87-94
相关推荐
梦想三三7 分钟前
LangChain Output Parser 实战:从字符串到结构化数据的完整指南
android·服务器·langchain·github·uv
爱笑鱼2 小时前
Binder(八):远端进程死了,BinderProxy 为什么还能收到通知?
android
Android-Flutter3 小时前
Kotlin 冷流与热流详解
android·kotlin
zhangphil3 小时前
Android ContentProvider/ContentResolver读图片,跨进程 IPC慢
android
yueqc13 小时前
Android .so 文件压缩
android·so·包体积
龚礼鹏4 小时前
深入解析 Android Automotive (AAOS) 启动流程与 CarService 核心机制(基于 Android 16 最新源码视角)
android
rosmis4 小时前
agent各指标定义
android·java·开发语言
风样滴男人哟5 小时前
PHP特性之反射类ReflectionClass机制
android·开发语言·php
小孔龙6 小时前
RenderNode 与 DisplayList:Android 硬件加速的绘制记录与复用
android·性能优化
qizayaoshuap6 小时前
鸿蒙 ArkTS 实战:搜索列表 城市实时过滤(示例 94)
android·华为·harmonyos