SurfaceFlinger学习之路(二)Surface的创建详解手机开发

上一篇《SurfaceFlinger学习之路 (一) 》 介绍了View的绘制流程,最后讲到了WMS与SurfaceSession、Surface之间关系。

SurfaceComposeClient

上一层说到,Surface在ViewRootImpl被new出了一个空壳:

// ViewRootImpl.java 
Surface mSurface = new Surface() 

我们在创建window都调用了WMS.addWindow()

// WindowManagerService.java 
public int addWindow(...) {
    
	 final WindowState win = new WindowState(...) 
	  
	 win.attach(); 
	  
	 mWindowMap.put(client.asBinder(), win); 
} 

在WMS中,每一个Window都会对应一个WindowState,表示具体窗口信息,而mWindowMap保存着WindowState。

最后,调用了WindowState的attach()

// WindowState.java 
void attach() {
    
    mSession.windowAddedLocked(mAttrs.packageName); 
} 
 
// Session.java 
void windowAddedLocked(String packageName) {
    
    if (mSurfaceSession == null) {
    
        mSurfaceSession = new SurfaceSession(); 
        mService.mSessions.add(this); 
    } 
    mNumWindow++; 
} 

Session中创建了SurfaceSession,Session通过SurfaceSession可以跟SurfaceFlinger通信,SurfaceSession只是在java层的代表,类似于Session和WMS的关系。

其实SurfaceSession是个壳,内部持有者一个native对象,就是SurfaceComposerClient,他是由SurfaceFlinger创建的,

// SurfaceSession.java 
private static native long nativeCreate(); 
 
private long mNativeClient; // SurfaceComposerClient* 
  
public SurfaceSession() {
    
    mNativeClient = nativeCreate(); 
} 

nativeCreate是个native方法,我们得到android_view_SurfaceSession.cpp继续追

// android_view_SurfaceSession.cpp 
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    
    SurfaceComposerClient* client = new SurfaceComposerClient(); 
    client->incStrong((void*)nativeCreate); 
    return reinterpret_cast<jlong>(client); 
} 

nativeCreate创建了一个SurfaceComposerClient对象

// android_view_SurfaceSession.cpp 
void SurfaceComposerClient::onFirstRef() {
    
    sp<ISurfaceComposer> sf(ComposerService::getComposerService()); 
    if (sf != 0 && mStatus == NO_INIT) {
    
        auto rootProducer = mParent.promote(); 
        sp<ISurfaceComposerClient> conn; 
        conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : 
                sf->createConnection(); 
        if (conn != 0) {
    
            mClient = conn; 
            mStatus = NO_ERROR; 
        } 
    } 
} 

在分析SurfaceComposerClient初始化onFirstRef具体做了什么功能之前,先看sf是谁?

 sp<ISurfaceComposer> sf(ComposerService::getComposerService()); 

ComposerService 为单例模式,负责与surfaceflinger建立binder连接

// android_view_SurfaceSession.cpp 
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    
    ComposerService& instance = ComposerService::getInstance(); 
    Mutex::Autolock _l(instance.mLock); 
    if (instance.mComposerService == NULL) {
    
        ComposerService::getInstance().connectLocked(); 
    } 
    return instance.mComposerService; 
} 

所以上诉的sf就是SurfaceFlinger的binder对象ComposerService,ComposerService跨进程创建了一个ISurfaceComposerClient对象,ISurfaceComposerClient对象代表了surface在surfaceFlinger端的代理。类似于ViewRootImpl和WindowSession,跟WindowManagerService的关系。

conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : 
                sf->createConnection(); 

至于SurfaceFlinger内部做了什么动作,后面再继续分析。

小结

在WindowManagerService中,每添加一个Window,就会添加对应的WindowState,native层会对应的创建一个SurfaceComposerClient,与此同时,SurfaceFlinger端会为Session创建一个对应的ISurfaceComposerClient对象,他是一个binder对象,供外部与SurfaceFlinger交流。

Client

现在我们来到了SurfaceFlinger进程这一端,来看SurfaceFlinger为SurfaceComposerClient做了什么动作。

首先,SurfaceFlinger为SurfaceComposerClient创建了一个Client,他是一个binder对象,这样SurfaceComposerClient可以通过他来跟SurfaceFlinger跨进程交流。

这里其实还有个问题,SurfaceFlinger和Service_Manager不是都是由init进程启动的吗,那么SurfaceFlinger如何保证能够添加到Service_Manager中呢?还有SurfaceFlinger也有对应的binder线程池吗?

// SurfaceFlinger.cpp 
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    
    return initClient(new Client(this)); 
} 

Client端提供的几个私有方法就可以看出,他跟Surface的创建、销毁有着密切的关系:createSurface、destroySurface。

再看下Client的私有变量中,他保存着对应的Layer,Layer是Surface在SurfaceFlinger的表示,代表一个显示层,每一个Client可以有多个Surface也就可以有多个Layer。

至于Surface跟Layer是怎么样的关系,先提出问题后面再继续解决。

// Client.cpp 
class Client : public BnSurfaceComposerClient {
    
private: 
    virtual status_t createSurface(...); 
     
    virtual status_t destroySurface(const sp<IBinder>& handle); 
   
    virtual status_t onTransact( 
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); 
         
    DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers; 
    wp<Layer> mParentLayer; 
} 

小结

SurfaceFlinger会为客户端SurfaceComposerClient创建一个Client,可以跨进程通信、提供Surface的创建、销毁的功能

SurfaceControl

上述过程主要讲述了一个window的创建,关于WMS、Session、SurfaceFlinger端各自为这次创建活动做了哪些初始化的动作。

回到Surface的创建流程中来,从ViewRootImpl的relayoutWindow()开始,一直到WMS中来。

// ViewRootImpl.java 
private int relayoutWindow(...) {
    
    int relayoutResult = mWindowSession.relayout(mWindow, ..., mSurface); 
} 
 
// Session.java 
public int relayout( 
    int res = mService.relayoutWindow(this, window, ..., outSurface); 
} 
 
// WindowManagerService.java 
public int relayoutWindow(..., Surface outSurface) {
    
    result = createSurfaceControl(outSurface, result, win, winAnimator); 
} 

这里WMS中会创建一个WindowSurfaceController,上面的类已经够多了,怎么又出现了一个WindowSurfaceController。

WindowSurfaceController只是作为一个中间代理者而已,不用太关注他

// WindowManagerService.java 
private int createSurfaceControl(Surface outSurface, int result, WindowState win, 
    WindowStateAnimator winAnimator) {
    
    WindowSurfaceController surfaceController; 
    // 1 创建WindowSurfaceController 
    surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid); 
    // 2 拷贝Surface 
    surfaceController.getSurface(outSurface); 
} 

1. 创建 WindowSurfaceController

// WindowStateAnimator.java 
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
    
    if (mSurfaceController != null) {
    
        return mSurfaceController; 
    } 
 
    mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession, ...); 
} 

WindowSurfaceController作为一个中间者,内部创建并持有SurfaceControl,我的天,怎么又来一个SurfaceControl。硬着头皮先继续看下。

// WindowSurfaceController.java 
private SurfaceControl mSurfaceControl; 
 
class WindowSurfaceController {
    
    public WindowSurfaceController() {
    
        mSurfaceControl = new SurfaceControl( 
            s, name, w, h, format, flags, windowType, ownerUid); 
    } 
} 

哈哈,不要当心!SurfaceControl其实就是Surface在java层的表示。我们看SurfaceControl 的java类。

// SurfaceControl.java 
public class SurfaceControl {
    
    private static native long nativeCreate(...) 
    private static native void nativeRelease(long nativeObject); 
    private static native void nativeDestroy(long nativeObject); 
    private static native void nativeDisconnect(long nativeObject);         
 
    long mNativeObject; 
    public SurfaceControl() {
    
        mNativeObject = nativeCreate(session, name, w, h, format, flags, 
            parent != null ? parent.mNativeObject : 0, windowType, ownerUid); 
    } 
} 

终于松了一口气,SurfaceControl的mNativeObject,其实就是SurfaceControl的指针。而且提供了Create、Release等方法,应该就是Surface的操作有关系。

但是这里还是有个问题,上面我们说SurfaceFlinger会为客户端窗口一个Client对象,他内部提供了创建Surface的方法,但是那SurfaceControl是怎么跟SurfaceComposerClient、Client等等怎么关联起来的?

带着这个问题往下看nativeCreate()方法。

// 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, 
        jint windowType, jint ownerUid) {
    
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); 
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject); 
    sp<SurfaceControl> surface; 
    status_t err = client->createSurfaceChecked( 
            String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid); 
     
    surface->incStrong((void *)nativeCreate); 
    return reinterpret_cast<jlong>(surface.get()); 
} 

上文我们知道SurfaceComposerClient跟SurfaceControl在客户端这边,可以直接获取,这里不分析怎么获取的了。

这里的Client并不是SurfaceFlinger内部的Client,而是表示SurfaceComposerClient。

我们先看下native层的SurfaceControl类的重要变量:

// SurfaceControl 
sp<SurfaceComposerClient>   mClient; 
sp<IGraphicBufferProducer>  mGraphicBufferProducer; 
mutable sp<Surface>         mSurfaceData; 

很明显,mClient对应着SurfaceComposerClient,mSurfaceData对应着真正的Surface,后续会被Client创建(SurfaceFlinger创建的Client类),而mGraphicBufferProducer是什么?

首先,app需要绘制到surface中,绘制UI内容都需要一个GraphicBuffer,而GraphicBuffer是需要Surface去申请和绘制、而由SurfaceFlinger消费和合成,这套生产消费者机制就是BufferQueue机制,平衡协调SurfaceFlinger和Surface。

IGraphicBufferProducer就是Surface和BufferQueue交流的渠道,他也是一个binder对象。Surface通过IGraphicBufferProducer跟BufferQueue申请和填充GraphicBuffer。

继续看SurfaceComposerClient怎么创建createSurfaceChecked()。

// SurfaceComposerClient.cpp 
status_t SurfaceComposerClient::createSurfaceChecked( 
    ... 
    sp<SurfaceControl>* outSurface, 
    ...)  
{
    
    sp<SurfaceControl> sur; 
    err = mClient->createSurface(name, w, h, format, flags, parentHandle, 
                windowType, ownerUid, &handle, &gbp); 
        *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); 
    return err; 
} 

上文我们知道SurfaceFlinger创建了Client,供给SurfaceComposerClient跨进程交流,哈哈哈,这里就调用Client的createSurface。

上面说的SurfaceControl怎么跟SurfaceFlinger、Client关联起来?

SurfaceControl利用SurfaceComposerClient同Client交流,调用了createSurface()方法,

surfaceFlinger对应创建了一个Layer。

// Client.cpp 
status_t Client::createSurface(... , sp<IGraphicBufferProducer>* gbp) 
{
    
    result = flinger->createLayer(name, client, w, h, format, flags, 
        windowType, ownerUid, handle, gbp, parent);         
} 

2. Surface 创建拷贝

上述说了SurfaceComposerClient如何创建surfaceControl,但是跟java层的Surface还是没有直接的关系,此时SurfaceFlinger已经为Surface创建了一层Layer,但Java层的Surface依然是一个空壳。

下面说明了Java层Surface如何真正被赋值的了。

// WindowManagerService.java 
surfaceController.getSurface(outSurface); 
 
// WindowSurfaceController.java 
void getSurface(Surface outSurface) {
    
    outSurface.copyFrom(mSurfaceControl); 
} 
 
// Surface.java 
public void copyFrom(SurfaceControl other) {
    
    long surfaceControlPtr = other.mNativeObject;	 
    long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);  
    mNativeObject = ptr;  
} 
 
// android_view_Surface.cpp 
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
    
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));  
    sp<Surface> surface(ctrl->getSurface());  
    return reinterpret_cast<jlong>(surface.get()); 
} 
 
// SurfaceControl.cpp 
sp<Surface> SurfaceControl::getSurface() const {
    
    Mutex::Autolock _l(mLock); 
    if (mSurfaceData == 0) {
    
        return generateSurfaceLocked(); 
    } 
    return mSurfaceData; 
} 
 
// SurfaceControl.cpp 
sp<Surface> SurfaceControl::generateSurfaceLocked() const {
    
    mSurfaceData = new Surface(mGraphicBufferProducer, false); 
    return mSurfaceData; 
} 

上面只是抽取了一部分的重要的代码,可以直接跟着过来,到了SurfaceControl类的内部我们才看到new Surface(),并且将mGraphicBufferProducer赋值给Surface。

到这里,Surface才真正被赋值,完成了Surface的创建。

小结

WMS中,主要通过ComposeSurfaceClient向SurfaceFlinger创建Client。

后续根据java层的Surface在SurfaceFlinger创建对应的Layer,Client创建GraphicBufferProducer跟BufferQueue交互、创建native层的Surface并赋值给java层的Surface。

总结

1.流程图
在这里插入图片描述
在这里插入图片描述
2.存在问题:

BufferQueue机制是什么?

Layer在SurfaceFlinger的作用是什么?

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/app/6249.html

(0)
上一篇 2021年7月17日 00:44
下一篇 2021年7月17日 00:44

相关推荐

发表回复

登录后才能评论