Android绘制流程 —— Surface

2,044 阅读15分钟

前言

本篇是Android绘制流程记录的第二篇,在Window连接中分析了应用是如何与SurfaceFlinger关联的。

接下来就继续向下分析,看看在Window建立起显示基础后,是如何开始绘制的。

作为复习记录总结,同样只是进行一个粗略的流程上的探究。

这里暂且先忽略一些难懂的细节,以建立起一个大致的概念为目标。

如果有误,欢迎指出,共同进步

源码解析

以下代码基于 Android 11 (Android R),限于篇幅,只保留重要核心代码。

1. 请求绘制视图

还记得上一篇ViewRootImpl.setWindow的方法中,调用的requestLayout吗?我们以此为出发点展开分析。

// ========== android.view.ViewRootImpl ===========

@Override
public void requestLayout() {
    if (!mHandlingLayoutInLayoutRequest) {
        checkThread();
        mLayoutRequested = true;
        scheduleTraversals();
    }
}

//此处是在构造函数中初始化,非实际代码
//获取当前线程的实例,用于管理发送异步消息给当前线程的消息队列
//每个线程都有一个对应的Choreographer单例对象
final Choreographer mChoreographer = Choreographer.getInstance();

void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        //添加主线程Handler的同步屏障到消息队列,阻塞所有的同步消息,优先处理异步消息(绘制)
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        //将绘制任务作为异步消息添加到当前线程(主线程)的消息队列中优先执行
        mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        ...
    }
}

final TraversalRunnable mTraversalRunnable = new TraversalRunnable();

final class TraversalRunnable implements Runnable {
    @Override
    public void run() {
        //执行UI绘制操作
        doTraversal();
    }
}

1.1 Choreographer

Choreographer是由ThreadLocal创建的线程单例,这里即为主线程的单例对象。

// ============= android.view.Choreographer =====================
public final class Choreographer {
    
    // Thread local storage for the choreographer.
    private static final ThreadLocal<Choreographer> sThreadInstance =
            new ThreadLocal<Choreographer>() {
        @Override
        protected Choreographer initialValue() {
            Looper looper = Looper.myLooper();
            if (looper == null) {
                throw new IllegalStateException("The current thread must have a looper!");
            }
            Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
            if (looper == Looper.getMainLooper()) {
                mMainInstance = choreographer;
            }
            return choreographer;
        }
    };
    
    public static Choreographer getInstance() {
        return sThreadInstance.get();
    }
}

Choreographer中封装了一系列异步消息任务发送与处理逻辑,主要用于管理视图绘制、Input事件、动画等相关任务回调(调用外部Runnable)的时机。

这里主要关注的是向native发送Vsync同步信号请求,并利用Handler同步屏障尽可能确保在接收到Vsync同步信号后,能够立即执行绘制任务。

关于Handler的同步屏障与异步消息

在调用postSyncBarrier()添加同步屏障后,会阻塞当前线程消息队列,遍历消息队列,将异步任务取出来优先执行

同步屏障相关方法使用@hide注解,外部要使用只能通过反射调用。

// ================== android.view.Choreographer =====================

public final class Choreographer {
    //用于发送与接收Sync信号通知
    private final FrameDisplayEventReceiver mDisplayEventReceiver;
    //处理异步消息的主线程Handler
    private final FrameHandler mHandler;
    private boolean mFrameScheduled;
    
    
    private Choreographer(Looper looper, int vsyncSource) {
        mLooper = looper;
        //当前线程(主线程)的处理视图重绘消息的Handler
        mHandler = new FrameHandler(looper);
        //非实际代码
        mDisplayEventReceiver = new FrameDisplayEventReceiver(looper, vsyncSource);
    }
    
    private final class FrameHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_DO_FRAME:
                    //执行绘制runnable
                    doFrame(System.nanoTime(), 0);
                    break;
                case MSG_DO_SCHEDULE_VSYNC:
                    //内部调用nativeScheduleVsync的native方法,发送申请下一个Vsync信号通知
                    doScheduleVsync();
                    break;
                case MSG_DO_SCHEDULE_CALLBACK:
                    //实际内部还是去执行请求Vsync信号的操作
                    doScheduleCallback(msg.arg1);
                    break;
            }
        }
    }
    
    //接收从native层返回的Vsync同步信号的接收器
    private final class FrameDisplayEventReceiver extends DisplayEventReceiver
            implements Runnable {
        private int mFrame;
        private long mTimestampNanos;
        
        
        @Override
        public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
            //接收到native层发送的Vsync信号(如16ms一次)
            long now = System.nanoTime();
            ...
            //保存当次Vsync同步信号的时间戳    
            mTimestampNanos = timestampNanos;
            mFrame = frame;
            //发送执行异步消息,执行内部run()方法
            Message msg = Message.obtain(mHandler, this);
            msg.setAsynchronous(true);
            mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);    
        }
        
        @Override
        public void run() {
            mHavePendingVsync = false;
            //调用外部绘制Runnable
            doFrame(mTimestampNanos, mFrame);
        }
    }
    
    //外部调用的入口在这里,发送一个绘制请求
    public void postCallback(int callbackType, Runnable action, Object token) {
        postCallbackDelayed(callbackType, action, token, 0);
    }
    
    public void postCallbackDelayed(int callbackType,
            Runnable action, Object token, long delayMillis) {
        ...
        postCallbackDelayedInternal(callbackType, action, token, delayMillis);
    }
    
    
    //postCallback最终调用到postCallbackDelayedInternal
    private void postCallbackDelayedInternal(int callbackType,
            Object action, Object token, long delayMillis) {
        synchronized (mLock) {
            final long now = SystemClock.uptimeMillis();
            final long dueTime = now + delayMillis;
            //异步消息绘制任务的队列,将action添加到队列内,等待指定时间(屏幕刷新时间,如16ms)执行绘制任务
            mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);

            if (dueTime <= now) {
                //根据是否使用USE_VSYNC,发送MSG_DO_SCHEDULE_VSYNC或者MSG_DO_FRAME的异步消息
                scheduleFrameLocked(now);
            } else {
                Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
                msg.arg1 = callbackType;
                //设置消息为异步消息
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, dueTime);
            }
        }
    }
    
    //最终都是为了调用scheduleVsyncLocked申请Vsync同步信号
    private void scheduleFrameLocked(long now) {
        if (!mFrameScheduled) {
            mFrameScheduled = true;
            if (USE_VSYNC) {
                ...
                if (isRunningOnLooperThreadLocked()) {
                    //内部调用nativeScheduleVsync的native方法,发送申请Vsync同步信号通知
                    scheduleVsyncLocked();
                } else {
                    Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                    msg.setAsynchronous(true);
                    //强制添加消息到消息队列顶部,立即执行
                    mHandler.sendMessageAtFrontOfQueue(msg);
                }
            } else {
                final long nextFrameTime = Math.max(
                        mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
                ...
                Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, nextFrameTime);
            }
        }
    }
    
    void doScheduleCallback(int callbackType) {
        synchronized (mLock) {
            if (!mFrameScheduled) {
                final long now = SystemClock.uptimeMillis();
                if (mCallbackQueues[callbackType].hasDueCallbacksLocked(now)) {
                    //还是去调用Vsync请求
                    scheduleFrameLocked(now);
                }
            }
        }
    }
    
    
    void doFrame(long frameTimeNanos, int frame) {
        
        //还处理了其他CallBack,
        //如CALLBACK_INPUT 是处理Input事件,也就是View的onTouch事件分发
        //还有CALLBACK_ANIMATION 是处理动画相关事务
        ...
        //调用指定类型的CallBack内部的Runnable执行
        doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
        ...
    }
    
    private void scheduleVsyncLocked() {
        //调用native方法,请求Vsync同步信号
        mDisplayEventReceiver.scheduleVsync();
    }
    
}

// ============ android.view.DisplayEventReceiver ================
public abstract class DisplayEventReceiver {
    //请求发送Vsync同步信号的通知
	@FastNative
    private static native void nativeScheduleVsync(long receiverPtr);
   
    public void scheduleVsync() {
        ...
        nativeScheduleVsync(mReceiverPtr);  
    }
    
    // Called from native code.
    //源码在native层实际调用的该方法,分发Vsync同步信号
    private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
        onVsync(timestampNanos, physicalDisplayId, frame);
    }
}

PS :在其内部还用到了个Handler.sendMessageAtFrontOfQueue方法,能够立刻将消息添加到消息队列的顶部,获得优先执行权。

参见: 消息机制的冷门知识点

个人能力有限,且本文主要注意力还是放在整体流程上,nativeScheduleVsync先暂时不继续深入了。

更多关于 Choreographer、Vsync同步信号传递机制参见:

Android Systrace 基础知识(7) - Vsync 解读

Android基于 Choreographer 的渲染机制详解

关于重绘时机与Vsync请求

Android消息机制Looper与VSync的传播

应用层Vsync信号的注册与接收

Android屏幕刷新机制—VSync、Choreographer 全面理解!

1.2 小结

在绘制流程中,Choreographer实际上扮演了相当重要的承上启下的角色,相当于一个沟通枢纽。

与视图相关的机制指令基本都是由Choreographer来控制执行分发任务的。

2. Surface创建

既然requestLayout内部是通过给主线程Handler发送任务消息并在Vsync同步信号返回后执行Runable

那我们就继续看看Runable内部执行的doTraversal方法做了些什么。

// ========== android.view.ViewRootImpl ===========

void doTraversal() {
    if (mTraversalScheduled) {
        mTraversalScheduled = false;
        //移除同步屏障,已经开始执行View绘制任务,允许后续继续执行同步消息
        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
		...
		//执行遍历视图树操作
        performTraversals();
		...
    }
}

private void performTraversals() {
    //实际上就是最顶层的DecorView
    final View host = mView;
    ...
    //关键代码,检查Surface图像缓冲区队列建立连接
    relayoutResult = relayoutWindow(...);    
    ...
    //window的宽高    
    if (mWidth != frame.width() || mHeight != frame.height()) {
        mWidth = frame.width();
        mHeight = frame.height();
    }    
    ...
    // 最外层的测量宽高   
    int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
    int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
    //测量尺寸,内部执行View.measure()方法
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    ...
    //布局排版,内部执行View.layout()方法
    performLayout(lp, mWidth, mHeight);   
    ...
    //开始绘制View,内部执行View.draw()方法
    performDraw();
    ...
}

视图绘制请求最终都在performTraversals方法内,依次执行measurelayoutdraw等方法。

而在这些操作调用之前,会最先调用了一个relayoutWindow方法,这里先以此展开继续分析。

2.1 java层 SurfaceControl创建

// ============== android.view.ViewRootImpl ================
final IWindowSession mWindowSession;

//Surface的句柄类,默认构造为空对象,只是一个指针,没有实际引用
private final SurfaceControl mSurfaceControl = new SurfaceControl();
private SurfaceControl mBlastSurfaceControl = new SurfaceControl();
//默认构造函数是个空对象,只是一个指针,没有实际引用
public final Surface mSurface = new Surface();


private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,...)...{
    ...
    //跨进程Binder代理调用,内部创建了native的SurfaceControl,并赋值给jave层内部变量对象引用地址
    int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f),
                ..., mSurfaceControl, mSurfaceSize, mBlastSurfaceControl);
    ...
    if (mSurfaceControl.isValid()) {  
        //此时mSurfaceControl已经有实际引用
        ...
        //从SurfaceControl拷贝native Surface对象引用    
        mSurface.copyFrom(mSurfaceControl);
        ...
    }
    
}

// ============ android.view.SurfaceControl =================

public final class SurfaceControl implements Parcelable {
    // native层的SurfaceControl 的对象引用地址
    public long mNativeObject;
    // 默认实现为空对象
    public SurfaceControl() {
    }
    
	public boolean isValid() {
        return mNativeObject != 0;
    }
}

// android.view.Surface
public class Surface implements Parcelable {
   	//默认为空对象
    public Surface() {
    }
}

relayoutWindow内部通过Binder机制跨进程调用了system_service进程内的Session.relayout方法,并传入了mSurfaceControl对象。

紧接着就开始判断该对象内部的mNativeObject变量不为0,然后让mSurface从该对象内拷贝赋值。

mSurfaceControl默认构造函数又为空实现,所以可能就是在relayout方法内部被赋值了。

// ============== com.android.server.wm.Session =======================
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
	@Override
    public int relayout(IWindow window, ...
            SurfaceControl outSurfaceControl, ... , Point outSurfaceSize
            SurfaceControl outBLASTSurfaceControl) {
        ...
        int res = mService.relayoutWindow(this, window, ... , 
                                          outSurfaceControl, outSurfaceSize,
                                          outBLASTSurfaceControl);
        ...
        return res;
    }
}

//================== com.android.server.wm.WindowManagerService ===================

public int relayoutWindow(Session session, IWindow client, ... ,
            SurfaceControl outSurfaceControl, ... , Point outSurfaceSize,
            SurfaceControl outBLASTSurfaceControl) {
    ...
    //获取addWindow时创建的WindowState对象
    final WindowState win = windowForClientLocked(session, client, false);
    ...
    WindowStateAnimator winAnimator = win.mWinAnimator;
    ...
    int result = 0;    
    ...
    //判断是否需要重新建立关联的SurfaceControl    
    final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
        (win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
         || win.mActivityRecord.isClientVisible());
    ...
    //窗口内第一次启动    
    if(shouldRelayout){    
        //创建native的SurfaceControl
        result = createSurfaceControl(outSurfaceControl, outBLASTSurfaceControl,
                                result, win, winAnimator);
    }else{
        ...
    }
    
    ...
    return result    
}

final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
    //获取当前App进程的View与system_service进程关联,addWindow时创建的WindowState,
    //其持有与SurfaceFLinger连接的Client
    WindowState win = mWindowMap.get(client);
    ...
    return win;    
}

Session作为一个中间类,会转交给WindowManagerService.relayoutWindow处理。

而且在relayoutWindow中,传入了一个outSurfaceControl参数,看变量命名就知道这是一个输出的对象了。

在其内部调用了createSurfaceControl方法,并将该参数传入。

//================== com.android.server.wm.WindowManagerService ===================

private int createSurfaceControl(SurfaceControl outSurfaceControl,
            SurfaceControl outBLASTSurfaceControl, int result,
            WindowState win, WindowStateAnimator winAnimator) {
    ...    
    WindowSurfaceController surfaceController = 
        winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
    ...
    //内部调用copyFrom方法,即拷贝到outSurfaceControl
    surfaceController.getSurfaceControl(outSurfaceControl);
    surfaceController.getBLASTSurfaceControl(outBLASTSurfaceControl);    
}

为了避免迷失在源码中,我们暂且忽略WindowStateAnimator.createSurfaceLocked()的创建,从getSurfaceControl方法作为切入点。

// ============ com.android.server.wm.WindowSurfaceController ====================
class WindowSurfaceController {
    SurfaceControl mSurfaceControl;
    
    WindowSurfaceController(String name, int w, int h, ...,
                            WindowStateAnimator animator,...) {
        final WindowState win = animator.mWin;
        ...
        //暂且忽略这一串Builder参数,Window请求Surface
        final SurfaceControl.Builder b = win.makeSurface()
                .setParent(win.getSurfaceControl())
                .setName(name)
                .setBufferSize(w, h)
                .setFormat(format)
                .setFlags(flags)
                .setMetadata(METADATA_WINDOW_TYPE, windowType)
                .setMetadata(METADATA_OWNER_UID, ownerUid)
                .setCallsite("WindowSurfaceController");
        ...
        mSurfaceControl = b.build();
        ...
    }
    
    void getSurfaceControl(SurfaceControl outSurfaceControl) {
        outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
    }
    
    void getBLASTSurfaceControl(SurfaceControl outSurfaceControl) {
        if (mBLASTSurfaceControl != null) {
            outSurfaceControl.copyFrom(mBLASTSurfaceControl, "WindowSurfaceController.getBLASTSurfaceControl");
        }
    }
}

getSurfaceControl实际上就是从WindowSurfaceController内部拷贝了一份SurfaceControl,并赋值给传入的outSurfaceControl

而且在WindowSurfaceController的构造函数内,通过SurfaceControl.Builder.build方法请求并创建了这个原始SurfaceControl

// ============ android.view.SurfaceControl ====================
public final class SurfaceControl implements Parcelable {
    
    public static class Builder {
        private SurfaceSession mSession;
        
        public SurfaceControl build() {
            return new SurfaceControl(mSession, mName, mWidth, mHeight,...);
        }
    }
    //native 的 SurfaceControl 对象引用地址
    public long mNativeObject;
    
    //空实现
    public SurfaceControl() {
    }
    
    private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
            SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
            String callsite) ... {
        ...
        //关键代码    
        mNativeObject = nativeCreate(session, name, w, h, format, flags,
                                     parent != null ? parent.mNativeObject : 0, metaParcel);
        ...
    }
    
    //native方法,实际创建了native层的Surface
    private static native long nativeCreate(SurfaceSession session, ... ) ...;
    
    private static native long nativeCopyFromSurfaceControl(long nativeObject);
    
    private static native long nativeGetHandle(long nativeObject);
    
    
    public void copyFrom(@NonNull SurfaceControl other, String callsite) {
        ...
        //实际是复制了这个mNativeObject对象引用
        assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
    }
    
    private void assignNativeObject(long nativeObject, String callsite) {
        ...
        mNativeObject = nativeObject;
        mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
    }
}

可以看到SurfaceControl.copyFrom方法中,实际是通过native方法nativeCopyFromSurfaceControlmNativeObject进行拷贝,且这个变量在Builder.build()方法调用的私有构造函数中同样由native方法nativeCreate创建。

2.2 native层 SurfaceControl创建

以下native方法通过Android Search Code查看,需要翻墙。

代码基于Android11-rc3,限于篇幅有限,只保留关键核心代码。

我们先来看nativeCreate方法

// ========== frameworks/base/core/jni/android_view_SurfaceControl.cpp ===============

static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
        jobject metadataParcel) {
    ...
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        //SurfaceSession不为空的情况,也就是前面建立连接时创建的SurfaceComposerClient
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        client = SurfaceComposerClient::getDefault();
    }
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    sp<SurfaceControl> surface;
    LayerMetadata metadata;
    Parcel* parcel = parcelForJavaObject(env, metadataParcel);
    if (parcel && !parcel->objectsCount()) {
        status_t err = metadata.readFromParcel(parcel);
        ...
    }   
    //通过SurfaceComposerClient创建native SurfaceControl
    status_t err = client->createSurfaceChecked(
            String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
    ...
    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());
}

// =========== frameworks/base/core/jni/android_view_SurfaceSession.cpp =================

sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
        JNIEnv* env, jobject surfaceSessionObj) {
    return reinterpret_cast<SurfaceComposerClient*>(
            env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}

其内部是返回了一个native的SurfaceControl对象引用地址。

而且我们在这里又看到了熟悉的SurfaceComposerClient

随后通过SurfaceComposerClient.createSurfaceChecked创建这个native层的SurfaceControl对象。

// ================= frameworks/native/libs/gui/SurfaceComposerClient.cpp ===================

sp<ISurfaceComposerClient>  mClient;

status_t SurfaceComposerClient::createSurfaceChecked(...,
                                                     sp<SurfaceControl>* outSurface, ...,
                                                     SurfaceControl* parent, LayerMetadata metadata,
                                                     ...) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;
    ...
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
    	sp<IGraphicBufferProducer> gbp;
        ...
        // 跨进程Binder代理调用Client的createSurface方法,
        // 内部并最终调用到SurfaceFlinger.createLayer,创建Layer
        // 传入了两个代理类对象引用
        err = mClient->createSurface(...&handle,&gbp,...);
        if (outTransformHint) {
            *outTransformHint = transformHint;
        }
        ...
        if (err == NO_ERROR) {
            //创建一个新的SurfaceControl对象,并将引用赋值给外部传入的SurfaceControl
            *outSurface = new SurfaceControl(this, handle, gbp, transformHint);
        }
    }
    return err;
}

是否还记得SurfaceComposerClient内部的mClient对象呢?

实际就是在Window建立连接中分析的,与SurfaceFlinger连接时,创建Client的Binder代理类。

Client.createSurface最终会调用到SurfaceFlinger.createLayer方法创建Layer

LayerSurfaceFlinger的基本操作单元。

// =========== frameworks/native/services/surfaceflinger/Client.cpp ==================

sp<SurfaceFlinger> mFlinger;

status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle, nullptr, outTransformHint);
}

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

status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
                                     uint32_t* outTransformHint) {
    status_t result = NO_ERROR;
    sp<Layer> layer;
    //根据flags创建不同的Layer
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
            //常用的BufferQueueLayer
            result = createBufferQueueLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), format, handle, gbp, &layer);
            break;
        //还有好几种Layer    
        ...
    }
    ...
    //保存新创建的Layer    
    mInterceptor->saveSurfaceCreation(layer);
    return result;
}

个人能力有限,这里暂时只关注其中的BufferQueueLayer

更多关于SurfaceFlinger创建Layer过程可以参见:

SurfaceFlinger之Layer和Bufferqueue的创建过程

图形系统之创建 Layer

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

status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, PixelFormat& format,
                                                sp<IBinder>* handle,
                                                sp<IGraphicBufferProducer>* gbp,
                                                sp<Layer>* outLayer) {
    sp<BufferQueueLayer> layer;
    ...
    //通过工厂模式创建BufferQueueLayer
    layer = getFactory().createBufferQueueLayer(args);
    ...
    //设置一些Layer内部的属性
    status_t err = layer->setDefaultBufferProperties(w, h, format);
    if (err == NO_ERROR) {
        // 注意这两个对象引用,是会传到外部SurfaceControl构造函数的
        *handle = layer->getHandle();
        *gbp = layer->getProducer();
        *outLayer = layer;
    }  
    return err;
}

SurfaceFlinger创建出Layer后,引出了 IGraphicBufferProducerIBinder的代理类,并传入到SurfaceControl的构造函数。

// =========== frameworks/native/libs/gui/SurfaceControl.cpp ===============
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
                               const sp<IGraphicBufferProducer>& gbp,
                               uint32_t transform)
      : mClient(client),
        mHandle(handle),
        mGraphicBufferProducer(gbp),
        mTransformHint(transform) {}

也就是说SurfaceFlinger中创建的Layer是通过其内部的Producer代理对象Handle代理对象SurfaceControl进行关联

就以此为切入点,来看下getProducergetHandle究竟获取到了什么?

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

sp<IBinder> Layer::getHandle() {
    ...
    return new Handle(mFlinger, this);
}

class Handle : public BBinder, public LayerCleaner {
    public:
    Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
        : LayerCleaner(flinger, layer), owner(layer) {}
    wp<Layer> owner;
};

// ============== frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp =================

sp<IGraphicBufferProducer> BufferQueueLayer::getProducer() const {
    return mProducer;
}

getHandle是新创建了一个Handle对象,属于BBinder实现类,内部包含了SurfaceFlingerLayer的引用,作为Surface操作Layer句柄类。

getProducer返回的内部对象引用又是什么呢?我们继续来看其构造函数

BufferQueueLayer是继承自BufferLayerBufferLayer继承自LayerLayer又是继承自RefBase

// ============= frameworks/native/services/surfaceflinger/BufferQueueLayer.h ==============
class BufferQueueLayer : public BufferLayer {
    private {
	    sp<IGraphicBufferProducer> mProducer;
    }
    ...
}

// ============== frameworks/native/services/surfaceflinger/BufferLayer.h ============
class BufferLayer : public Layer {
    ...
}

// ============== frameworks/native/services/surfaceflinger/Layer.h ================
class Layer : public virtual RefBase, compositionengine::LayerFE {
    ...
}

// ============== frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp ================

void BufferQueueLayer::onFirstRef() {
    BufferLayer::onFirstRef();
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    //创建了一个生产者和消费者模型,
    sp<IGraphicBufferProducer> producer; //生产者缓冲区
    sp<IGraphicBufferConsumer> consumer; //消费者缓冲区
    //创建了一个BufferQueueCore管理BufferQueue队列,并以此为核心创建赋值生产者与消费者
    mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
    mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
    mConsumer = mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
                                                             	 mTextureName, this);
    ...
    // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
    if (!mFlinger->isLayerTripleBufferingDisabled()) {
        //如果没有开启3级缓冲区,则设置为2级缓冲区
        mProducer->setMaxDequeuedBufferCount(2);
    }
}

既然是RefBase的子类,在第一次获取到强引用时就会触发onFirstRef方法,其在内部创建了一个基于BufferQueue生产者与消费者模型

而通过getProducer方法获取到的正是其作为生产者BufferQueueProducer,用于从BufferQueueCore中获取图像缓冲区buffer对象,交由客户端写入显示内容。

// ============ frameworks/native/libs/gui/BufferQueue.cpp ===============

// getFactory().createBufferQueue
// 最终会调用到BufferQueue.createBufferQueue方法
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                                    sp<IGraphicBufferConsumer>* outConsumer,
                                    bool consumerIsSurfaceFlinger) {
    LOG_ALWAYS_FATAL_IF(outProducer == nullptr,
            "BufferQueue: outProducer must not be NULL");
    LOG_ALWAYS_FATAL_IF(outConsumer == nullptr,
            "BufferQueue: outConsumer must not be NULL");
	//图形缓冲区队列的中枢类
    sp<BufferQueueCore> core(new BufferQueueCore());
    ...
    //用core类创建生产者,用于从队列中获取缓冲区并写入绘制内容
    //返回为Binder代理类    
    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
    ...
    //用core类创建消费者,用于从队列中获取缓冲区数据,并交由Surfaceflinger处理
    //返回为Binder代理类
    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
    ...
    *outProducer = producer;
    *outConsumer = consumer;
}

个人能力有限,本文还是更多关注于主要流程上,Surfaceflinger的生产者消费者模型,这里暂时不深入分析了。

可以参见:Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类

每个需要显示功能的进程都会与SurfaceFlinger间建立起一个独立的生产者消费者模型BufferQueue。

PS :Producer是处于SurfaceFlinger进程内的,需要通过Binder机制通信。

  • 小结:

至此,native层SurfaceControl创建就出来了,通过BufferQueueProducer的Binder代理类,和SurfaceFlinger创建的Layer进行关联。

并最终将native层的SurfaceControl对象引用,赋值给java层的SurfaceControl

另:

前面提到relayoutWindow中的SurfaceControl,调用SurfaceControl.copyFrom方法从WindowSurfaceController中通过native方法拷贝。

// ============= frameworks/base/core/jni/android_view_SurfaceControl.cpp ================
static jlong nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
 sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
 if (surface == nullptr) {
     return 0;
 }

 sp<SurfaceControl> newSurface = new SurfaceControl(surface);
 newSurface->incStrong((void *)nativeCreate);
 return reinterpret_cast<jlong>(newSurface.get());
}

static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
 SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
 return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
}

2.3 java层 Surface创建

接下来就是通过Surface.copyFrom对这个新的SurfaceControl拷贝出可用的Surface了。

// ============= android.view.Surface ================

public class Surface implements Parcelable {
    long mNativeObject; // package scope only for SurfaceControl access
    
    private static native long nativeGetFromSurfaceControl(long surfaceObject,
            long surfaceControlNativeObject);
    private static native void nativeRelease(long nativeObject);
    
    
    public void copyFrom(SurfaceControl other) {
        ...
        long surfaceControlPtr = other.mNativeObject;
        ...
        //从SurfaceControl内创建Surface
        long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
        synchronized (mLock) {
            if (newNativeObject == mNativeObject) {
                return;
            }
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);
        }
    }
    
    private void setNativeObjectLocked(long ptr) {
        if (mNativeObject != ptr) {
            ...
            mNativeObject = ptr;
            mGenerationId += 1;
            if (mHwuiContext != null) {
                mHwuiContext.updateSurface();
            }
        }
    }
}

2.4 native层 Surface创建

Surface.copyFrom方法内,同样也是通过native方法,赋值native对象引用地址。

通过调用native层的SurfaceControl.generateSurfaceLocked方法创建了native层Surface

然后将native层Surface的对象引用指针,赋值给java层SurfacemNativeObject

// ============== frameworks/base/core/jni/android_view_Surface.cpp ====================

static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong nativeObject,
        jlong surfaceControlNativeObj) {
    Surface* self(reinterpret_cast<Surface *>(nativeObject));
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));

    // If the underlying IGBP's are the same, we don't need to do anything.
    if (self != nullptr &&
            IInterface::asBinder(self->getIGraphicBufferProducer()) ==
            IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {
        //实际持有的Producer代理对象是同一个,不做任何处理
        return nativeObject;
    }
	//通过SurfaceControl创建native层的Surface
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
	//返回native层surface对象的引用地址
    return reinterpret_cast<jlong>(surface.get());
}

// =========== frameworks/native/libs/gui/SurfaceControl.cpp ==================

mutable sp<Surface>         mSurfaceData;

sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == nullptr) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}

sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
    // mGraphicBufferProducer就是Layer的中图形缓冲区域对应的生产者
    // 创建native层的Surface
    mSurfaceData = new Surface(mGraphicBufferProducer, false);
    return mSurfaceData;
}


2.5 小结

至此,ViewRootImpl内持有的Suface就转变为可用状态,并指向正确的native层Surface对象引用,进而关联到SurfaceFlinger创建的BufferQueue

总结

最后来简要概括一下Surface创建的过程

  1. 首先由ViewRootImpl.requestLayout通过Choreographer向native申请Vsync同步信号。

  2. App进程的Choreographer接收到Vsync同步信号后,通过SurfaceControl内部创建并持有对应的native层SurfaceControl对象引用地址。

  3. 在native层 中用SurfaceSession中持有的SurfaceComposerClient通过Binder跨进程调用,在SurfaceFlinger进程内中创建一个独立的,基于BufferQueue的生产者消费者模型。

    在native层SurfaceControl创建时,会将BufferQueue的生产者Producer的Binder代理类对象赋值给其内部变量。

  4. 由java层Surface.copyFrom藉由native层SurfaceControl创建native层的Surface对象,后者持有来自native层SurfaceControlProducer的对象引用。

    native层SurfaceControl内部会缓存native层Surface到内部变量引用,只会在第一次获取时创建。

    将该native层Surface对象引用地址赋值给jave层的Surface对象,使后者指向正确对象引用地址。

    java层的SurfaceSurfaceControl都是空壳,实际做事的都是native层的SurfaceSurfaceControl

下一篇继续分析View的绘制流程。

参考资料

Android Java层UI渲染实现 四 Surface的创建和View绘制

Android绘制机制以及Surface家族源码全解析

探究Android View 绘制流程,Canvas 的由来

Android Surface创建

Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl