Activity研究报告

本文详细探讨了Android中Activity的创建过程,从进程创建到Surface显示的每一步骤。首先,通过ActivityManagerService启动进程,接着ActivityThread.main开始运行,然后通过ActivityThread.attach与服务端交互。在Activity创建阶段,涉及到PhoneWindow、DecorView的生成以及View的添加。Window、WindowManager和ViewRootImpl之间的关系也进行了剖析,最后讲解了内存分配和SurfaceTexture的工作原理,揭示了客户端与SurfaceFlinger如何共享内存来实现数据同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Activity与Surface
这篇文章主要描述从Activity的创建,直到Surface显示的过程
一.Activity的创建
1.进程的创建
创建Activity的过程,首先要从创建Activity所在的进程说起。在用户请求启动某个应用程序的时候,会调用ActivityManagerService.startProcessLocked
ActivityManagerService.startProcessLocked
---->newProcessRecordLocked//创建新的ProcessRecord,每个经过ActivityManagerService启动的进程都有一个ProcessRecord,其中存储了进程相关的一切信息
---->Process.start//向SystemServer发起请求创建新的进程,并运行ActivityThread.main
---->在mPidsSelfLocked中添加新创建的ProcessRecord,该变量负责管理ProcessRecord
ActivityThread.main
----->ActivityThread.attach
	----->IActivityManager mgr = ActivityManagerNative.getDefault();
	----->mgr.attachApplication(mAppThread);//注意,这里向服务端发起了一次请求
				------>ActivityManagerService.attachApplicationLocked(IApplicationThread thread, int pid)
							----->ActivityThread.realStartActivityLocked
									   ----->ActivityThread.scheduleLaunchActivity
													----->queueOrSendMessage(H.LAUNCH_ACTIVITY, r);//这里只是向消息队列中加入了LAUNCH_ACTIVITY的消息
												        ---->ActivityThread.handleLaunchActivity
从上述调用过程,我们可以看到所谓ActivityThread.attach的过程,就是向它绑定的消息队列中添加消息的过程,但是这个添加的过程是通过服务端ActivityManagerService完成的。ActivityThread中有一个ApplicationThread实例,这个类的定义如下:
private class ApplicationThread extends ApplicationThreadNative 
其中ApplicationThreadNative的定义如下:
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
由此可见,ApplicationThread是一个服务端,mgr.attachApplication(mAppThread);把它作为参数发送给ActivityManagerService,ActivityManagerService把它存储在ProcessRecord的thread中,最后通过它向ActivityThread的消息队列中添加消息来启动和shedule Activity
特别说明的是ActivityManagerService是在创建进程得到pid并把ProcessRecord加入到mPidsSelfLocked中之后,再在新创建的进程中运行ActivityThread.main的
2.创建Activity
frameworks/base/core/java/android/app/ActivityThread.java
handleLaunchActivity
----->performLaunchActivity
                    ------>activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
                    ----->activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);
                                   ----->mWindow = PolicyManager.makeNewWindow(this);//mWindow是Window类实例
                                                ----->com.android.internal.policy.impl.Policy.makeNewWindow
                                                                      ------>return new PhoneWindow(context);//PhoneWindow继承自Window
                                   ----->mWindow.setWindowManager(null, mToken, mComponent.flattenToString()...
                                                           ----->Window.setWindowManager
                                                                                ----->wm = WindowManagerImpl.getDefault();
                                                                                ----->mWindowManager = new LocalWindowManager(wm, hardwareAccelerated);

----->handleResumeActivity
                r.window = r.activity.getWindow();这里get得到的Window就是在activity.attach中创建的mWindow,即PhoneWindow
                View decor = r.window.getDecorView();//window.getDecorView接口的实现实际就是PhoneWindow.getDecorView
                         frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java
				   PhoneWindow.getDecorView
                   ----->PhoneWindow.installDecor
                          ----->mDecor = generateDecor();
                                          ----->return new DecorView(getContext(), -1);
                          ----->mContentParent = generateLayout(mDecor);
								----->View in = mLayoutInflater.inflate(layoutResource, null);
										 decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
										 ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
    这一句比较奇怪,凭空从哪里冒出来一个ID_ANDROID_CONTENT,这就需要看layoutResource变量了,它一定是layoutResource中定义的某个id,该值在不同情况下,有不同的赋值,它表示一个layout,这些文件都定义在frameworks/base/core/res/res/layout/目录,他们有一个共同点就是,都有一个FrameLayout,且android.id属性都是"@android.id/content"。这里的findViewById显然是查找这个的,也就是说它返回的是一个FrameLayout,也就是一个ViewGroup。
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();//从上面attach的过程就可以看到这里的WindowManager就是LocalWindowManager
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);//这里的wm就是LocalWindowManager类的实例,从下面的类图结构中,我们知道它继承自WindowManagerImpl.CompatModeWrapper类,它的addView的实现就是调用WindowManagerImpl.addView。WindowManagerImpl类中包含有一组View对象,一组ViewRootImpl对象,每个View和ViewRootImpl都是一一对应的。
                           ----->ViewRootImpl.setView//每个ViewRootImpl对象中只有一个View对象
                }

3.Window,WindowManager,ViewRootImpl
下面总结一下上述过程中类之间的关系,他们的类关系图如下:


首先,Activity中有一个PhoneWindow,它从Window抽象类继承而来,它持有一个DecorView,这里就要说道Window和View之间的关系,Window类的注释如下:
 * Abstract base class for a top-level window look and behavior policy.  An
 * instance of this class should be used as the top-level view added to the
 * window manager. It provides standard UI policies such as a background, title
 * area, default key processing, etc.
 * The only existing implementation of this abstract class is
 * android.policy.PhoneWindow, which you should instantiate when needing a
 * Window.  Eventually that class will be refactored and a factory method
 * added for creating Window instances without knowing about a particular
 * implementation.
Window是一个抽象类,它应该作为top-level view添加到Window Manager中,PhoneWindow是它的唯一实现,PhoneWindow持有一个DecorView实例,它是这个Window的top-level view,它定义在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java,从类图中我们知道它是一个FrameLayout,所以可以包含其他view。FrameLayout继承自ViewGroup,ViewGroup继承自View,并实现了ViewManager和ViewParent接口,这两个接口是有区别的,ViewManager提供了addView,removeView的接口,用于管理View,ViewParent则用于和parent打交道,例如向parent发送某种请求,如requestLayout。
View当然是所有显示单元的基类。

4.ViewRootImpl.setView
Window类还有一个WindowManager的引用,WindowManager类注释中说明context.getSystemService(Context.WINDOW_SERVICE)得到的就是一个WindowManager,它与WindowService服务通信,但是WindowManager并没有从Binder继承,这是怎么回事呢,原来,WindowManager的派生类WindowManagerImpl.CompatModeWrapper中有一个Display类,Display中有一个IWindowManager引用,显然这才是真正与Window service通信的类。
WindowManagerImpl在进程中只有一个实例,在WindowManagerImpl类中,包含有一组ViewRootImpl和View的映射,ViewRootImpl.setView方法中使用了sWindowSession.add方法,其中sWindowSession是一个static IWindowSession,由于它是static的,所以在进程中它也只有一个实例。显然这个类是用于与服务器端通信的,它是与谁通信,它的功能如何呢?
在ViewRootImpl的构造函数中调用了getWindowSession函数,ViewRootImpl.getWindowSession定义如下:
public static IWindowSession getWindowSession(Looper mainLooper) {
        synchronized (mStaticInit) {
            if (!mInitialized) {
                try {
                    InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
                    sWindowSession = Display.getWindowManager().openSession(
                            imm.getClient(), imm.getInputContext());
                    mInitialized = true;
                } catch (RemoteException e) {
                }
            }
            return sWindowSession;
        }
    }
其中的sWindowSession是IWindowSession类型,这里显然是创建sWindowSession的地方,Display.getWindowManager的定义如下:
static IWindowManager getWindowManager() {
        synchronized (sStaticInit) {
            if (sWindowManager == null) {
                sWindowManager = IWindowManager.Stub.asInterface(
                        ServiceManager.getService("window"));
            }
            return sWindowManager;
        }
    }
这里的sWindowManager是IWindowManager类型,IWindowManager.openSession定义如下:
public android.view.IWindowSession openSession(com.android.internal.view.IInputMethodClient client, com.android.internal.view.IInputContext inputContext) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.view.IWindowSession _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((client!=null))?(client.asBinder()):(null)));
_data.writeStrongBinder((((inputContext!=null))?(inputContext.asBinder()):(null)));
mRemote.transact(Stub.TRANSACTION_openSession, _data, _reply, 0);//这里显然是发送请求,并得到reply响应。
_reply.readException();
_result = android.view.IWindowSession.Stub.asInterface(_reply.readStrongBinder());//这里得到IWindowSession的BpBinder,通过asInterface得到BpProxy
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
我们再来看在同一个文件中的服务器端的代码
case TRANSACTION_openSession:
{
data.enforceInterface(DESCRIPTOR);
com.android.internal.view.IInputMethodClient _arg0;
_arg0 = com.android.internal.view.IInputMethodClient.Stub.asInterface(data.readStrongBinder());
com.android.internal.view.IInputContext _arg1;
_arg1 = com.android.internal.view.IInputContext.Stub.asInterface(data.readStrongBinder());
android.view.IWindowSession _result = this.openSession(_arg0, _arg1);//调用服务端的openSession得到IWindowSession
reply.writeNoException();
reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
return true;
}
显然this.openSession(_arg0, _arg1);是我们要找的代码,这里的this就是WindowManagerService类,因为它是从IWindowManager.Stub继承的,在该类中
public IWindowSession openSession(IInputMethodClient client,
            IInputContext inputContext) {
        if (client == null) throw new IllegalArgumentException("null client");
        if (inputContext == null) throw new IllegalArgumentException("null inputContext");
        Session session = new Session(this, client, inputContext);
        return session;
    }
该函数返回了一个Session,该类定义在frameworks/base/services/java/com/android/server/wm/Session.java,它继承自IWindowSession.Stub,也就是说它是一个服务器端,当然通过Binder之后,在客户端得到的是一个客户端Binder。Session中包含有WindowManagerService的引用,这样,在客户端发起请求,在服务器端收到后,可以通过该引用调用WindowManagerService的方法。
这样,ViewRootImpl.getWIndowSession就得到了一个进程唯一的IWindowSession实例。
让我们从ViewRootImpl.setView重新看起,sWindowSession.add方法,会调用到服务端的add代码,Session.add代码如下
public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
        return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets,
                outInputChannel);
    }
也即调用了WindowManagerService.addWindow方法,在该方法中,
win = new WindowState(this, session, client, token,
                    attachedWindow, seq, attrs, viewVisibility);
。。。
win.attach();
     ----->mSession.windowAddedLocked();
                      ----->mSurfaceSession = new SurfaceSession();
                      ----->mService.mSessions.add(this);
。。。
mWindowMap.put(client.asBinder(), win);
WindowState是window manager管理的window对象。它其中包含了WindowManagerService引用,Session引用,IWindow引用。WindowManagerService引用显然是为了调用它提供的方法的,Session引用是为了表示进程的,因为它是进程唯一的,那么IWindow引用的作用是什么呢?
我们从ViewRootImpl.setView看起,它调用res = sWindowSession.add(mWindow, mSeq, mWindowAttributes,。。。)。这里的mWindow的类型是W,它在ViewRootImpl的构造函数中初始化
        mWindow = new W(this);
W继承自IWindow.Stub,IWindow.Stub在IWindow.java中定义,它显然是个服务器端类,这样IWindow的作用就很明显了,在addWindow的时候,它被添加到WindowManagerService的WindowState中,当然,在binder传递的过程中,它变成了一个客户端类,在WindowManagerService需要通知客户端程序发生某种事件的时候,就会调用IWindow的接口,在这里有resized,dispatchAppVisibility,dispatchGetNewSurface,windowFocusChanged,显然这种方法是Android的Service中经常采用的策略。IWindow.Stub接口在每个ViewRootImpl实例中,只有一个实例,它与ViewRootImpl和View都是一一对应的。也就是说WindowState通过它就唯一标识了一个窗口。每个客户端进程对应一个Session实例
在创建了WindowState之后,调用了它的attach函数,其中调用了Session.windowAddedLocked方法,它实际上就是创建了一个SurfaceSession实例。这个实例后面创建Surface的时候会用到,现在只要知道,它是Session持有的,并且是一对一的关系,即一个客户进程是对应一个SurfaceSession的。
5.Surface的传递
ViewRootImpl.setView
----->requestLayout
  ----->scheduleTraversals
	   ----->sendEmptyMessage(DO_TRAVERSAL);
		   ----->handleMessage()//这里需要特别说以下,因为ViewRootImpl是从Handler派生的,所以在创建的时候,就与当前线程的Looper绑定了,在投放消息后,会调用Handler的handleMessage进行处理
				---->performTraversals
					   ----->relayoutWindow
							  ----->sWindowSession.relayout(mWindow, mSeq, params, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending, mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface);
这里的sWindowSession.relayout实际上就是发起一次请求,需要特别注意两个参数,一个是第一个参数mWindow,它是IWindow.Stub类型,在服务器端收到这个请求后,就是根据这个参数来查找WindowState对象的,另外一个参数,是最后一个参数mSurface,它是Surface类型,它在JNI层会被绑定从服务器端传递的SurfaceControl对象。
在IWindowSession中,我们可以看到这个客户端的请求,在服务器端的响应就是调用Session.relayout
Session.relayout
----->WindowManagerService.relayoutWindow
                  ----->Surface surface = win.createSurfaceLocked();//该函数会在WindowState对象中创建一个Surface对象
					   ----->mSurface = new Surface( mSession.mSurfaceSession, mSession.mPid, mAttrs.getTitle().toString(), 0, w, h, format, flags); 
				  ----->outSurface.copyFrom(surface);
看到这里就涉及Surface对象在进程间的传递了,在客户端这一侧,sWindowSession.relayout中的参数ViewRootImpl.mSurface是在定义的时候就初始化了的
    private final Surface mSurface = new Surface();
因为sWindowSession是IWindowSession类型,我们接着看它对应的relayout函数
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IWindowSession.java
public int relayout(android.view.IWindow window, int seq, android.view.WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, boolean insetsPending, android.graphics.Rect outFrame, android.graphics.Rect outContentInsets, android.graphics.Rect outVisibleInsets, android.content.res.Configuration outConfig, android.view.Surface outSurface) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((window!=null))?(window.asBinder()):(null)));
_data.writeInt(seq);
if ((attrs!=null)) {
_data.writeInt(1);
attrs.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
_data.writeInt(requestedWidth);
_data.writeInt(requestedHeight);
_data.writeInt(viewVisibility);
_data.writeInt(((insetsPending)?(1):(0)));
mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
if ((0!=_reply.readInt())) {
outFrame.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outContentInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outVisibleInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outConfig.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outSurface.readFromParcel(_reply);
}
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
我们需要特别主要mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);调用后返回的_reply,outSurface.readFromParcel(_reply);其中outSurface就是传递的最后一个参数,即ViewRootImpl.mSurface。在继续分析Surface.readFromParcel之前,我们先来看看服务器端是如何处理的
在服务器端的relayout过程中,也会创建Surface对象,其构造函数会调用native函数init,对应Surface_init函数
frameworks/base/core/jni/android_view_Surface.cpp
static void Surface_init(
        JNIEnv* env, jobject clazz,
        jobject session,
        jint, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
            (SurfaceComposerClient*)env->GetIntField(session, sso.client);
----->    SurfaceComposerClient* client =
            (SurfaceComposerClient*)env->GetIntField(session, sso.client);
----->sp surface;
----->surface = client->createSurface(dpy, w, h, format, flags);
                                    ----->sp surface = mClient->createSurface(&data, name,display, w, h, format, flags);//
                                    ----->result = new SurfaceControl(this, surface, data);
----->setSurfaceControl(env, clazz, surface);
这里的参数session对应着mSurface.mSurfaceSession对象,在前面的分析中,WindowState.attach的时候创建了SurfaceSession对象,它也是进程唯一的,实际上它的构造函数中调用了native函数init,对应SurfaceSession_init函数,该函数也定义在android_view_Surface.cpp中
static void SurfaceSession_init(JNIEnv* env, jobject clazz)
{
    sp client = new SurfaceComposerClient;
    client->incStrong(clazz);
    env->SetIntField(clazz, sso.client, (int)client.get());
}
这里创建了一个SurfaceComposerClient对象,并把这个对象与SurfaceSession对象绑定。在Surface_init函数中,从SurfaceSession java对象上获取的就是这个client,然后使用这个client创建一个surfacecontrol,并把它与Surface java对象绑定,而这一切的动作都是在WindowManagerService所在进程进行的。所谓的Surface.copyFrom实际上传递的就是与Surface对象绑定的SurfaceControl native对象,在进程间传递的也是SurfaceControl对象。
SurfaceControl native对象中包含的最重要的就是ISurface native实例,它被传递到客户端进程后,与ViewRootImpl.mSurface java对象绑定,该对象是一个Surface类型。

5.ISurface的创建
在上面的代码中SurfaceComposerClient创建了ISurface实例
mClient是SurfaceComposerClient对象的成员变量,它是sp类型的,它是在如下的代码中初始化的,也就是在SurfaceComposerClient对象第一次被引用的时候
void SurfaceComposerClient::onFirstRef() {
    sp sm(getComposerService());
    if (sm != 0) {
        sp conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}
其中getComposerService()定义如下:
static inline sp getComposerService() {
    return ComposerService::getComposerService();
}
sp ComposerService::getComposerService() {
    return ComposerService::getInstance().mComposerService;
}
ComposerService的类定义如下:
class ComposerService : public Singleton
{
    // these are constants
    sp mComposerService;
    sp mServerCblkMemory;
    surface_flinger_cblk_t volatile* mServerCblk;
    ComposerService();
    friend class Singleton;
public:
    static sp getComposerService();
    static surface_flinger_cblk_t const volatile * getControlBlock();
};
它是一个单件,从Singleton模板继承而来,只有一个实例,它的构造函数如下:
ComposerService::ComposerService()
: Singleton() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    mServerCblkMemory = mComposerService->getCblk();
    mServerCblk = static_cast(
            mServerCblkMemory->getBase());
}
其中getService(name, &mComposerService)函数是定义在IServiceManager.h中的函数,功能是根据名称获取Servcie的客户端,显然,这里是根据SurfaceFlinger名称得到了该服务的客户端,其接口类型是ISurfaceComposer,也就是说,上述createConnection函数,是客户端向服务器端发起的请求,显然返回的类型是一个ISurfaceComposerClient类型,那么服务器端是如何处理的呢?首先,我们就要找到这个Service
在init.rc中,启动了surfaceflinger服务,
service surfaceflinger /system/bin/surfaceflinger
这个可执行文件是在frameworks/base/cmds/surfaceflinger/main_surfaceflinger.cpp编译出来的,该文件的内容非常简单,如下所示:
int main(int argc, char** argv) {
    SurfaceFlinger::publishAndJoinThreadPool();
    return 0;
}
我们来看SurfaceFlinger类的定义
frameworks/base/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger :
        public BinderService,
        public BnSurfaceComposer,
        public IBinder::DeathRecipient,
        protected Thread
在它的基类BinderService类中,定义了publishAndJoinThreadPool函数,它是一个模板类,该函数定义如下:
static void publishAndJoinThreadPool() {
        sp proc(ProcessState::self());
        sp sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }
这与我们在前面分析Binder的时候,添加服务的过程是相同的,同时,我们看到SurfaceFlinger类也从是BnSurfaceComposer继承的,BnSurfaceComposer是在frameworks/base/include/surfaceflinger/ISurfaceComposer.h定义的,它从BnInterface继承而来,也就是说SurfaceFlinger就是我们要找的服务器端类,
sp SurfaceFlinger::createConnection()
{
    sp bclient;
    sp client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}
这样SurfaceComposerClient在收到这个返回的ISurfaceComposerClient实例之后,将一直持有它。由于SurfaceComposerClient实例与SurfaceSession是一一对应的,ISurfaceComposerClient与SurfaceComposerClient也是一一对应的,而SurfaceSession是进程唯一的,所以SurfaceComposerClient实例,与ISurfaceComposerClient实例也是进程唯一的
在上述代码中Client的类型定义如下:
class Client : public BnSurfaceComposerClient,也就是说,它也是一个服务器端类,它的createSurface函数如下:
sp Client::createSurface(
        ISurfaceComposerClient::surface_data_t* params,
        const String8& name,
        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
        uint32_t flags)
{
    /*
     * createSurface must be called from the GL thread so that it can
     * have access to the GL context.
     */

    class MessageCreateSurface : public MessageBase {
        sp result;
        SurfaceFlinger* flinger;
        ISurfaceComposerClient::surface_data_t* params;
        Client* client;
        const String8& name;
        DisplayID display;
        uint32_t w, h;
        PixelFormat format;
        uint32_t flags;
    public:
        MessageCreateSurface(SurfaceFlinger* flinger,
                ISurfaceComposerClient::surface_data_t* params,
                const String8& name, Client* client,
                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
                uint32_t flags)
            : flinger(flinger), params(params), client(client), name(name),
              display(display), w(w), h(h), format(format), flags(flags)
        {
        }
        sp getResult() const { return result; }
        virtual bool handler() {
            result = flinger->createSurface(params, name, client,
                    display, w, h, format, flags);
            return true;
        }
    };

    sp msg = new MessageCreateSurface(mFlinger.get(),
            params, name, this, display, w, h, format, flags);
    mFlinger->postMessageSync(msg);
    return static_cast( msg.get() )->getResult();
}
显然,上面的代码是创建一个消息,然后把它投放到一个消息队列中,其中关键的是mFlinger->postMessageSync(msg),其代码如下:
status_t SurfaceFlinger::postMessageSync(const sp& msg,
        nsecs_t reltime, uint32_t flags)
{
    status_t res = mEventQueue.postMessage(msg, reltime, flags);
    if (res == NO_ERROR) {
        msg->wait();
    }
    return res;
}
也就是说,msg消息会被放入到EventQueue消息队列中,进行处理,msg->wait表示等待消息处理完成,这就说明问题了,postMessage所在的线程,与消息处理的线程必然是两个线程,那么这些线程又是如何创建的呢?
从前面创建SurfaceFlinger服务的时候,我们知道SufaceFlinger的类继承结构,SurfaceFlinger继承自Thread,看下面的代码
void SurfaceFlinger::onFirstRef()
{
    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);

    // Wait for the main thread to be done with its initialization
    mReadyToRunBarrier.wait();
}
我们从这里可以看到,它调用了Thread.run函数,该函数会启动一个新的线程,在线程中将运行threadLoop函数,mReadyToRunBarrier.wait();是为了等待线程启动起来,也就是说,在init进程启动SurfaceFlinger服务进程之后,创建SurfaceFlinger实例,并在该实例第一次得到引用的时候,会启动一个新的线程,这个线程就是调用的就是SurfaceFlinger.threadLoop函数,该函数代码如下:
bool SurfaceFlinger::threadLoop()
{
    waitForEvent();
           ----->while(true)
           ----->sp msg = mEventQueue.waitMessage(timeout);
													----->msg->handler()
													----->msg->notify
    。。。
}
注意,我们在SurfaceFlinger::postMessageSync中,在把消息投入消息队列之后,调用了msg->wait,也就是说该函数所在的线程被阻塞了,而上面的函数调用中,msg->notify显然是用来恢复这个阻塞的,这也就是postMessageSync中Sync的含义了。而在这里handler的内容就是创建Surface
result = flinger->createSurface(params, name, client,display, w, h, format, flags);
该函数返回一个ISurface的实例,并被保存在msg的result变量中,最后返回给客户端进程,下面我们来看一下整体的创建流程
SurfaceFlinger service的创建流程如下:
SystemServer进程创建WindowState的过程如下:
SystemServer创建Surface的过程如下:
SurfaceFlinger进程使用到的类关系如下:
SystemServer使用到的类关系如下:
ISurfaceComposer接口是SurfaceFlinger提供的服务接口
ISurfaceComposerClient是客户端进程与SurfaceFlinger进程链接的通道,客户端进程并不直接使用ISurfaceComposer接口,而是通过ISurfaceComposerClient接口,在服务器端进程调用SurfaceFlinger实例的服务,由于ISurfaceComposerClient实例是保存在SurfaceComposerClient中,它与SurfaceSession是一一对应的,而SurfaceSession与Session又是一一对应的,Session在进程中是只有一个实例的,所以这个ISurfaceComposerClient在进程中也是只有一个实例的。

SurfaceFlinger::createSurface
----->SurfaceFlinger::createSurface(
----->ssize_t token = addClientLayer(client, layer);
                         ----->size_t name = client->attachLayer(lbc);
                                         ----->Client.mLayers.add(name,layer);
                         ----->addLayer_l(lbc);
                                         ----->ssize_t i = mCurrentState.layersSortedByZ.add(layer);
----->surfaceHandle = layer->getSurface();
                         ----->s = createSurface();
                         ---->mClientSurfaceBinder = s->asBinder();
sp LayerBaseClient::createSurface()
{
    class BSurface : public BnSurface, public LayerCleaner {
        wp mOwner;
        virtual sp getSurfaceTexture() const {
            sp res;
            sp that( mOwner.promote() );
            if (that != NULL) {
                res = that->mSurfaceTexture;
            }
            return res;
        }
    public:
        BSurface(const sp& flinger,
                const sp& layer)
            : LayerCleaner(flinger, layer), mOwner(layer) { }
    };
    sp sur(new BSurface(mFlinger, this));
    return sur;
}
从这里我们可以看到返回给客户端进程的ISurface实例是如何创建的,同时,ISurface接口只有一个功能就是getSurfaceTexture,从这里也可以看到,它的作用就是返回这个Layer的ISurefaceTexture实例。另外,从上述过程中,我们可以看到在创建了Surface之后,这个实例被保存在layerbaseclient中。另外,LayerBaseClient类本身就有createSurface函数,如下:
sp LayerBaseClient::createSurface()
{
    class BSurface : public BnSurface, public LayerCleaner {
        virtual sp getSurfaceTexture() const { return 0; }
    public:
        BSurface(const sp& flinger,
                const sp& layer)
            : LayerCleaner(flinger, layer) { }
    };
    sp sur(new BSurface(mFlinger, this));
    return sur;
}
从这里看到它的getSufaceTexture方法返回的是0,这是什么意思呢?LayerBaseClient除了有Layer这个派生类之外,还有LayerDim,LayerScreenshot派生类,他们都没有实现createSurface方法,而是使用父类的函数,也就是说,只有创建了Layer,才能得到ISurfaceTexture接口,如果创建了其他两种LayerBaseClient,则得不到这个接口。


我们以客户端进程add一个View,重新回顾整个创建过程,一个View对应一个ViewRootImpl,ViewRootImpl中有一个IWindowSession接口实例,它是进程唯一的,通过它的add方法,在SurfaceFlinger进程中,使用与这个Session绑定的ISurfaceComposerClient接口,来创建一个ISurface接口,这个实例被保存在SurfaceControl实例中,这个native层的实例与java层的Surface实例绑定到一起,并通过IWindowSession接口传递给客户端进程。也就是说,一个View对应了一个ISurface接口,又对应一个Layer,对应一个SurfaceTexture

---------------------------------------------------------------------------------------------------------------------------------------
二.Surface的使用
上面我们看到了ISurface接口是如何创建的,以及它是如何与Surface java对象绑定到一起的,下面我们将要看到客户端进程是如何使用Surface显示内容的。
我们从Surface.lockCanvas看起
1.Surface.lockCanvas
从Surface.java中的Surface.lockCanvas知道,它调用了native函数lockCanvasNative函数,即frameworks/base/core/jni/android_view_Surface.cpp文件中的Surface_lockCanvas函数
static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
{
    const sp& surface(getSurface(env, clazz));
。。。。。。

    Surface::SurfaceInfo info;
    status_t err = surface->lock(&info, &dirtyRegion);
。。。。。。
    SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
    SkBitmap bitmap;
。。。。。。
    if (info.w > 0 && info.h > 0) {
        bitmap.setPixels(info.bits);
    } else {
        // be safe with an empty bitmap.
        bitmap.setPixels(NULL);
    }
    nativeCanvas->setBitmapDevice(bitmap);
。。。。。。
    return canvas;
}
这段代码的主要功能是使用surface->lock得到SurfaceInfo,然后把info.bits设置给SkBitmap,这个bitmap最后设置给nativeCanvas,也就是说,在这个Canvas上画的数据都会被写道其中的bitmap上,也就是info.bits指定的地址上,这个地址上的数据就是显示数据。所以这段代码的关键是Surface->lock函数。
2.Surface::lock
下面我们将从Surface::lock开始,分析Surface对象是如何与SurfaceTexture通信的
frameworks/base/libs/gui/Surface.cpp
status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion)
------>status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
Surface继承自SurfaceTextureClient,它直接调用了基类的lock函数
status_t SurfaceTextureClient::lock(
        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
{
    if (mLockedBuffer != 0) {
        LOGE("Surface::lock failed, already locked");
        return INVALID_OPERATION;
    }

    if (!mConnectedToCpu) {
        int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
                           ----->int err = mSurfaceTexture->connect(api,&mDefaultWidth, &mDefaultHeight, &mTransformHint);//---------------
        if (err) {
            return err;
        }
        // we're intending to do software rendering from this point
        setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
    }

    ANativeWindowBuffer* out;
    status_t err = dequeueBuffer(&out);
                         ------>status_t result = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,mReqFormat, mReqUsage);--------------

    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
    if (err == NO_ERROR) {
        sp backBuffer(GraphicBuffer::getSelf(out));
        err = lockBuffer(backBuffer.get());
        LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
                backBuffer->handle, strerror(-err));
        if (err == NO_ERROR) {
            const Rect bounds(backBuffer->width, backBuffer->height);

            Region newDirtyRegion;
            if (inOutDirtyBounds) {
                newDirtyRegion.set(static_cast(*inOutDirtyBounds));
                newDirtyRegion.andSelf(bounds);
            } else {
                newDirtyRegion.set(bounds);
            }

            // figure out if we can copy the frontbuffer back
            const sp& frontBuffer(mPostedBuffer);
            const bool canCopyBack = (frontBuffer != 0 &&
                    backBuffer->width  == frontBuffer->width &&
                    backBuffer->height == frontBuffer->height &&
                    backBuffer->format == frontBuffer->format);

            if (canCopyBack) {
                // copy the area that is invalid and not repainted this round
                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
                if (!copyback.isEmpty())
                    copyBlt(backBuffer, frontBuffer, copyback);--------------
            } else {
                // if we can't copy-back anything, modify the user's dirty
                // region to make sure they redraw the whole buffer
                newDirtyRegion.set(bounds);
            }

            // keep track of the are of the buffer that is "clean"
            // (ie: that will be redrawn)
            mOldDirtyRegion = newDirtyRegion;

            if (inOutDirtyBounds) {
                *inOutDirtyBounds = newDirtyRegion.getBounds();
            }

            void* vaddr;
            status_t res = backBuffer->lock(
                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                    newDirtyRegion.bounds(), &vaddr);--------------

            LOGW_IF(res, "failed locking buffer (handle = %p)",
                    backBuffer->handle);

            mLockedBuffer = backBuffer;
            outBuffer->width  = backBuffer->width;
            outBuffer->height = backBuffer->height;
            outBuffer->stride = backBuffer->stride;
            outBuffer->format = backBuffer->format;
            outBuffer->bits   = vaddr;
        }
    }
    return err;
}
下面依次对上面4个函数进行分析
connect
这里显然是客户端发起请求,其中api参数是NATIVE_WINDOW_API_CPU,对应的,在SurfaceTexture的connect,实际上就是记录这个api,并返回它保存的defaultWidth和defaultHeight
dequeueBuffer
同样的是客户端发起请求,关键是看SurfaceTexture::dequeueBuffer函数,该函数实际上就是在其成员变量mSlots数组中查找一个合适的位置,并返回数组的序号,特别需要说明的是,如果这个合适位置的buffer是经过重新分配得到的话,那么客户端还需要调用requestBuffer方法才能重新得到新的GraphicBuffer。
copyBlt
先说明frontBuffer和backBuffer,这是两个逻辑概念,上次使用的buffer被称为frontBuffer,它保存在mPostedbuffer,而现在将要使用的称为backBuffer,在lock之后,将使用mLockedBuffer来保存它。在后面说明的unlockAndPost函数之中,将把这个buffer变成frontBuffer,即PostedBuffer。
lock
status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
{
    if (rect.left < 0 || rect.right  > this->width || 
        rect.top  < 0 || rect.bottom > this->height) {
        LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
                rect.left, rect.top, rect.right, rect.bottom, 
                this->width, this->height);
        return BAD_VALUE;
    }
    status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
    return res;
}
getBufferMapper()函数得到的是一个GraphicBufferMapper实例,实际上这个类是个单件,只有一个实例
status_t GraphicBufferMapper::lock(buffer_handle_t handle,
        int usage, const Rect& bounds, void** vaddr)
{
    status_t err;

    err = mAllocMod->lock(mAllocMod, handle, usage,
            bounds.left, bounds.top, bounds.width(), bounds.height(),
            vaddr);

    LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
    return err;
}
其中mAllocMod是在构造函数中得到的
GraphicBufferMapper::GraphicBufferMapper()
    : mAllocMod(0)
{
    hw_module_t const* module;
    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
    if (err == 0) {
        mAllocMod = (gralloc_module_t const *)module;
    }
}
该函数通过加载gralloc.so得到hw_module_t,也就是gralloc_module_t,其定义如下:
hardware/libhardware/include/hardware/gralloc.h
/**
 * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
 * and the fields of this data structure must begin with hw_module_t
 * followed by module specific information.
 */
typedef struct gralloc_module_t {
    struct hw_module_t common;
    int (*registerBuffer)(struct gralloc_module_t const* module,
            buffer_handle_t handle);
    int (*unregisterBuffer)(struct gralloc_module_t const* module,
            buffer_handle_t handle);
    int (*lock)(struct gralloc_module_t const* module,
            buffer_handle_t handle, int usage,
            int l, int t, int w, int h,
            void** vaddr);
    int (*unlock)(struct gralloc_module_t const* module,
            buffer_handle_t handle);
    void* reserved_proc[7];
} gralloc_module_t;
这里我们可以看到上面调用的lock函数,显然GraphicBufferMapper类是对这些方法的封装,在GraphicBuffer类中使用了这些函数,那么这些函数的具体实现如何?他们的功能又是如何呢?这就要看看gralloc模块的实现了。
Gralloc module
gralloc module涉及两个文件
hardware/libhardware/modules/gralloc/gralloc.cpp中定义了服务器端用于分配内存的代码,
hardware/libhardware/modules/gralloc/mapper.cpp中定义了客户端用于注册的代码,下面我们分别来看看他们是如何实现的

上图给出了module和device相关的结构之间的关系,他们的定义分别如下:
hardware/libhardware/modules/gralloc/gralloc_priv.h
struct private_module_t {
    gralloc_module_t base;

    private_handle_t* framebuffer;
    uint32_t flags;
    uint32_t numBuffers;
    uint32_t bufferMask;
    pthread_mutex_t lock;
    buffer_handle_t currentBuffer;
    int pmem_master;
    void* pmem_master_base;

    struct fb_var_screeninfo info;
    struct fb_fix_screeninfo finfo;
    float xdpi;
    float ydpi;
    float fps;
};
hardware/libhardware/include/hardware/hardware.h
/**
 * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
 * and the fields of this data structure must begin with hw_module_t
 * followed by module specific information.
 */
typedef struct hw_module_t {
    /** tag must be initialized to HARDWARE_MODULE_TAG */
    uint32_t tag;

    /** major version number for the module */
    uint16_t version_major;

    /** minor version number of the module */
    uint16_t version_minor;

    /** Identifier of module */
    const char *id;

    /** Name of this module */
    const char *name;

    /** Author/owner/implementor of the module */
    const char *author;

    /** Modules methods */
    struct hw_module_methods_t* methods;

    /** module's dso */
    void* dso;

    /** padding to 128 bytes, reserved for future use */
    uint32_t reserved[32-7];

} hw_module_t;

hardware/libhardware/include/hardware/hardware.h
/**
 * Every device data structure must begin with hw_device_t
 * followed by module specific public methods and attributes.
 */
typedef struct hw_device_t {
    /** tag must be initialized to HARDWARE_DEVICE_TAG */
    uint32_t tag;

    /** version number for hw_device_t */
    uint32_t version;

    /** reference to the module this device belongs to */
    struct hw_module_t* module;

    /** padding reserved for future use */
    uint32_t reserved[12];

    /** Close this device */
    int (*close)(struct hw_device_t* device);

} hw_device_t;

/**
 * Every device data structure must begin with hw_device_t
 * followed by module specific public methods and attributes.
 */

typedef struct alloc_device_t {
    struct hw_device_t common;

    /*
     * (*alloc)() Allocates a buffer in graphic memory with the requested
     * parameters and returns a buffer_handle_t and the stride in pixels to
     * allow the implementation to satisfy hardware constraints on the width
     * of a pixmap (eg: it may have to be multiple of 8 pixels).
     * The CALLER TAKES OWNERSHIP of the buffer_handle_t.
     *
     * Returns 0 on success or -errno on error.
     */
    
    int (*alloc)(struct alloc_device_t* dev,
            int w, int h, int format, int usage,
            buffer_handle_t* handle, int* stride);

    /*
     * (*free)() Frees a previously allocated buffer.
     * Behavior is undefined if the buffer is still mapped in any process,
     * but shall not result in termination of the program or security breaches
     * (allowing a process to get access to another process' buffers).
     * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes
     * invalid after the call.
     *
     * Returns 0 on success or -errno on error.
     */
    int (*free)(struct alloc_device_t* dev,
            buffer_handle_t handle);

    /* This hook is OPTIONAL.
     *
     * If non NULL it will be caused by SurfaceFlinger on dumpsys
     */
    void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);

    void* reserved_proc[7];
} alloc_device_t;
上面给出了图中列明的各种结构的定义,看起来挺复杂,让我们从GraphicBufferMapper说起,它的构造函数中的GRALLOC_HARDWARE_MODULE_ID就是"gralloc"字符串,通过hw_get_module函数,得到了hw_module_t结构,实际上它是一个private_module结构,该结构都是以hw_module_t结构开始的,所以在上图中,我们把它们认为是继承关系,对于gralloc模块来说,这个private_module定义如下:
hardware/libhardware/modules/gralloc/gralloc.cpp,
struct private_module_t HAL_MODULE_INFO_SYM = {
    base: {
        common: {
            tag: HARDWARE_MODULE_TAG,
            version_major: 1,
            version_minor: 0,
            id: GRALLOC_HARDWARE_MODULE_ID,
            name: "Graphics Memory Allocator Module",
            author: "The Android Open Source Project",
            methods: &gralloc_module_methods
        },
        registerBuffer: gralloc_register_buffer,
        unregisterBuffer: gralloc_unregister_buffer,
        lock: gralloc_lock,
        unlock: gralloc_unlock,
    },
    framebuffer: 0,
    flags: 0,
    numBuffers: 0,
    bufferMask: 0,
    lock: PTHREAD_MUTEX_INITIALIZER,
    currentBuffer: 0,
};
其中
static struct hw_module_methods_t gralloc_module_methods = {
        open: gralloc_device_open
};
这里的gralloc_register_buffer,gralloc_unregister_buffer,gralloc_lock,gralloc_unlock,定义在hardware/libhardware/modules/gralloc/mapper.cpp,在GraphicBufferMapper中调用的mAllocMod->lock就是这里的gralloc_lock函数,其定义如下:
int gralloc_lock(gralloc_module_t const* module,
        buffer_handle_t handle, int usage,
        int l, int t, int w, int h,
        void** vaddr)
{
    // this is called when a buffer is being locked for software
    // access. in thin implementation we have nothing to do since
    // not synchronization with the h/w is needed.
    // typically this is used to wait for the h/w to finish with
    // this buffer if relevant. the data cache may need to be
    // flushed or invalidated depending on the usage bits and the
    // hardware.

    if (private_handle_t::validate(handle) < 0)
        return -EINVAL;

    private_handle_t* hnd = (private_handle_t*)handle;
    *vaddr = (void*)hnd->base;
    return 0;
}
从这里我们看到,实际上只是取出了handle中的一个地址,作为返回地址,这个地址的作用是什么,又是在哪里赋值的呢?首先,这个地址是从handle中取出的,这个handle是从哪里来的呢?它是GraphicBuffer调用lock函数的时候,作为参数传递进来的,也就是说它是存储在GraphicBuffer中的,那么GraphicBuffer又是从何而来的呢?是从服务器端通过Binder传递过来的,在GraphicBuffer中的GraphicBuffer::unflatten函数中读取到的
status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
        int fds[], size_t count)
{
    if (size < 8*sizeof(int)) return NO_MEMORY;

    int const* buf = static_cast(buffer);
    if (buf[0] != 'GBFR') return BAD_TYPE;

    const size_t numFds  = buf[6];
    const size_t numInts = buf[7];

    const size_t sizeNeeded = (8 + numInts) * sizeof(int);
    if (size < sizeNeeded) return NO_MEMORY;

    size_t fdCountNeeded = 0;
    if (count < fdCountNeeded) return NO_MEMORY;

    if (handle) {
        // free previous handle if any
        free_handle();
    }

    if (numFds || numInts) {
        width  = buf[1];
        height = buf[2];
        stride = buf[3];
        format = buf[4];
        usage  = buf[5];
        native_handle* h = native_handle_create(numFds, numInts);
        memcpy(h->data,          fds,     numFds*sizeof(int));
        memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
        handle = h;
    } else {
        width = height = stride = format = usage = 0;
        handle = NULL;
    }

    mOwner = ownHandle;

    if (handle != 0) {
        mBufferMapper.registerBuffer(handle);
    }

    return NO_ERROR;
}
要想读懂这段代码,首先要了解native_handle的结构
system/core/include/cutils/native_handle.h
typedef struct native_handle
{
    int version;        /* sizeof(native_handle_t) */
    int numFds;         /* number of file-descriptors at &data[0] */
    int numInts;        /* number of ints at &data[numFds] */
    int data[0];        /* numFds + numInts ints */
} native_handle_t;
system/core/include/system/window.h
typedef const native_handle_t* buffer_handle_t;
native_handle_t的data字段,比较特别,它在native_handle_t中并不占用内存,但是它指向numInts后的内存,按照说明,numFds表示从data[0]处开始,有几个fd,numInts表示从data[numFds]开始有几个int数据,总体的大小就是numFds+numInts个int,实际上,data是一个指向私有结构的指针,对于gralloc来说,这个结构定义如下:
hardware/libhardware/modules/gralloc/gralloc_priv.h
struct private_handle_t {
    struct native_handle nativeHandle;
    
    enum {
        PRIV_FLAGS_FRAMEBUFFER = 0x00000001
    };

    // file-descriptors
    int     fd;
    // ints
    int     magic;
    int     flags;
    int     size;
    int     offset;

    // FIXME: the attributes below should be out-of-line
    int     base;
    int     pid;

    static const int sNumInts = 6;
    static const int sNumFds = 1;
    static const int sMagic = 0x3141592;
。。。
}
也就是说,在native_handle之后,紧接着这样一个private_handel_t结构,在这里只有一个fd,除此之外还有6个int。这样我们就从服务器端跨进程,得到了native_handle。
unflatten的最后动作是调用了registerBuffer ,这个函数实际上调用了gralloc模块的registerBuffer函数,即gralloc_register函数,该函数定义如下:
int gralloc_register_buffer(gralloc_module_t const* module,
        buffer_handle_t handle)
{
    if (private_handle_t::validate(handle) < 0)
        return -EINVAL;

    // if this handle was created in this process, then we keep it as is.
    int err = 0;
    private_handle_t* hnd = (private_handle_t*)handle;
    if (hnd->pid != getpid()) {
        void *vaddr;
        err = gralloc_map(module, handle, &vaddr);
    }
    return err;
}
其中调用的gralloc_map函数定义如下:
static int gralloc_map(gralloc_module_t const* module,
        buffer_handle_t handle,
        void** vaddr)
{
    private_handle_t* hnd = (private_handle_t*)handle;
    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
        size_t size = hnd->size;
        void* mappedAddress = mmap(0, size,
                PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);
        if (mappedAddress == MAP_FAILED) {
            LOGE("Could not mmap %s", strerror(errno));
            return -errno;
        }
        hnd->base = intptr_t(mappedAddress) + hnd->offset;
        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
    }
    *vaddr = (void*)hnd->base;
    return 0;
}
看到这里,我们就明白了,原来所谓注册的动作,实际上是根据从Binder传递过来的handle中的size和fd,做了一个内存映射的操作,并把系统返回的地址保存在handle中,并作为返回值被返回出去。特别说明的是,fd之所以能够在进程间传递,也是因为在Binder中对其进行了特殊处理,具体方法在前文中已经说明。
现在我们对客户端的lock过程已经很清楚了,但是还有一个流程我们还不清楚,即服务器端是如何进行GraphicBuffer的分配的呢?
在GraphicBuffer.cpp中,我们看到所谓reallocate的过程,实际上是通过GraphicBufferAllocator进行真实的分配的,GraphicBuffer得到的只是一个handle,所以我们看看GraphicBufferAllocator是如何完成分配动作的,先看看它的构造函数
GraphicBufferAllocator::GraphicBufferAllocator()
    : mAllocDev(0)
{
    hw_module_t const* module;
    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
    if (err == 0) {
        gralloc_open(module, &mAllocDev);
    }
}
其中的gralloc_open的定义如下:
hardware/libhardware/include/hardware/gralloc.h
static inline int gralloc_open(const struct hw_module_t* module,
        struct alloc_device_t** device) {
    return module->methods->open(module,
            GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
}
这里使用到了module中method的open函数,从上面module的定义,我们知道这个open函数就是gralloc_device_open
hardware/libhardware/modules/gralloc/gralloc.cpp
int gralloc_device_open(const hw_module_t* module, const char* name,
        hw_device_t** device)
{
    int status = -EINVAL;
    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
        gralloc_context_t *dev;
        dev = (gralloc_context_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = 0;
        dev->device.common.module = const_cast(module);
        dev->device.common.close = gralloc_close;

        dev->device.alloc   = gralloc_alloc;
        dev->device.free    = gralloc_free;

        *device = &dev->device.common;
        status = 0;
    } else {
        status = fb_device_open(module, name, device);
    }
    return status;
}
从这里我们知道,这个device设备是通过module打开的,这就是module和device之间的关系。在GraphicBufferAllocator中调用的alloc函数,就是gralloc_alloc函数,
hardware/libhardware/modules/gralloc/gralloc.cpp
static int gralloc_alloc(alloc_device_t* dev,
        int w, int h, int format, int usage,
        buffer_handle_t* pHandle, int* pStride)
{
    if (!pHandle || !pStride)
        return -EINVAL;

    size_t size, stride;

    int align = 4;
    int bpp = 0;
    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
            bpp = 4;
            break;
        case HAL_PIXEL_FORMAT_RGB_888:
            bpp = 3;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_RGBA_5551:
        case HAL_PIXEL_FORMAT_RGBA_4444:
            bpp = 2;
            break;
        default:
            return -EINVAL;
    }
    size_t bpr = (w*bpp + (align-1)) & ~(align-1);
    size = bpr * h;
    stride = bpr / bpp;

    int err;
    if (usage & GRALLOC_USAGE_HW_FB) {
        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
    } else {
        err = gralloc_alloc_buffer(dev, size, usage, pHandle);
    }

    if (err < 0) {
        return err;
    }

    *pStride = stride;
    return 0;
}
我们以软件分配为例,它将调用gralloc_alloc_buffer
hardware/libhardware/modules/gralloc/gralloc.cpp
static int gralloc_alloc_buffer(alloc_device_t* dev,
        size_t size, int usage, buffer_handle_t* pHandle)
{
    int err = 0;
    int fd = -1;

    size = roundUpToPageSize(size);
    
    fd = ashmem_create_region("gralloc-buffer", size);
    if (fd < 0) {
        LOGE("couldn't create ashmem (%s)", strerror(-errno));
        err = -errno;
    }

    if (err == 0) {
        private_handle_t* hnd = new private_handle_t(fd, size, 0);
        gralloc_module_t* module = reinterpret_cast(
                dev->common.module);
        err = mapBuffer(module, hnd);
        if (err == 0) {
            *pHandle = hnd;
        }
    }
    
    LOGE_IF(err, "gralloc failed err=%s", strerror(-err));
    
    return err;
}
hardware/libhardware/modules/gralloc/mapper.cpp
int mapBuffer(gralloc_module_t const* module,
        private_handle_t* hnd)
{
    void* vaddr;
    return gralloc_map(module, hnd, &vaddr);
}
ashmem_create_region函数根据size创建了匿名的共享内存块,以文件名fd来标识,最后还是通过mapper.cpp中的gralloc_map函数映射到内存中,其过程与客户端是一样的,这样,我们对整个的分配过程就很清晰了,其过程可描述如下:
--------------------PICTURE_HERE--------------------


frameworks/base/include/ui/GraphicBufferAllocator.h
GraphicBufferAllocator类只有一个实例,它在构造函数中加载并打开了gralloc.so,得到了alloc_device_t 类型的设备,从该设备中,可以分配和释放内存,
typedef struct alloc_device_t {
    struct hw_device_t common;
    int (*alloc)(struct alloc_device_t* dev,
            int w, int h, int format, int usage,
            buffer_handle_t* handle, int* stride);
    int (*free)(struct alloc_device_t* dev,
            buffer_handle_t handle);
    void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);
    void* reserved_proc[7];
} alloc_device_t;
以alloc为例,它分配的内存结构,是buffer_handle_t*,由此得到下面两个结构定义
typedef const native_handle_t* buffer_handle_t;
system/core/include/system/window.h

GraphicBuffer类持有这个buffer_handle_t实例,用于封装这个handle,同时它还提供了flatten和unflatten的功能,即这个GraphicBuffer类是可以在进程间通过Binder传递的。

SurfaceTexture中有一个BufferSlot类型的数组mSlots[32],BufferSlot类型中有一个GraphicBuffer指针
 
development/tools/emulator/opengl/system/gralloc/gralloc.cpp
hardware/libhardware/modules/gralloc/gralloc.cpp

system/core/include/system/window.h
struct ANativeWindow
{
    struct android_native_base_t common;
    const uint32_t flags;
    const int   minSwapInterval;
    const int   maxSwapInterval;
    const float xdpi;
    const float ydpi;
    intptr_t    oem[4];
    int     (*setSwapInterval)(struct ANativeWindow* window,
                int interval);
    int     (*dequeueBuffer)(struct ANativeWindow* window,
                struct ANativeWindowBuffer** buffer);
    int     (*lockBuffer)(struct ANativeWindow* window,
                struct ANativeWindowBuffer* buffer);
    int     (*queueBuffer)(struct ANativeWindow* window,
                struct ANativeWindowBuffer* buffer);
    int     (*query)(const struct ANativeWindow* window,
                int what, int* value);
    int     (*perform)(struct ANativeWindow* window,
                int operation, ... );
    int     (*cancelBuffer)(struct ANativeWindow* window,
                struct ANativeWindowBuffer* buffer);
    void* reserved_proc[2];
};
class SurfaceTextureClient
    : public EGLNativeBase

class Surface : public SurfaceTextureClient

typedef struct ANativeWindowBuffer
{
    struct android_native_base_t common;
    int width;
    int height;
    int stride;
    int format;
    int usage;
    void* reserved[2];
    buffer_handle_t handle;
    void* reserved_proc[8];
} ANativeWindowBuffer_t;

typedef ANativeWindowBuffer_t android_native_buffer_t;

--------------------------------------------------------

这张图从何说起呢?在上面的分析中,我们知道SurfaceControl中有一个ISurface接口实例,Surface对象从SurfaceTextureClient继承而来,它在构造的时候,可以通过SurfaceControl实例配置它的ISurface成员变量,而这个成员变量又配置了基类中ISurfaceTexture成员变量,实际上ISurface接口只有一个方法就是GetSurfaceTexture,它就是为了得到ISurfaceTexure而存在的。ISurfaceTexture的服务器端是运行在SurfaceFlinger进程中的SurfaceTexure类实例,如上面的分析这个实例是保存在Layer中的,SurfaceTexture构造函数中使用getService得到ISurfaceComposer接口,通过它得到IGraphicBufferAlloc实例,在后面的代码中,又通过它创建GraphicBuffer实例,如上图所示,GraphicBuffer是可以通过序列化,在进程间传递的,它继承自ANativeWind
owBuffer,其中最重要的字段是buffer_handle_t,它是一个指向native_handle_t的指针。
为GraphicBuffer创建这个native_handle的是GraphicBufferAllocator,它是一个单件,也就是只有一个实例,我们来看它的构造函数
GraphicBufferAllocator::GraphicBufferAllocator()
    : mAllocDev(0)
{
    hw_module_t const* module;
    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
    if (err == 0) {
        gralloc_open(module, &mAllocDev);
    }
}
其中#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
static inline int gralloc_open(const struct hw_module_t* module,
        struct alloc_device_t** device) {
    return module->methods->open(module,
            GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
}
#define GRALLOC_HARDWARE_GPU0 "gpu0"
从上面的代码中,我们可以看到加载了gralloc.so,并且使用它的open方法得到了alloc_device_t指针,alloc_device_t的定义如下:

/**
 * Every device data structure must begin with hw_device_t
 * followed by module specific public methods and attributes.
 */

typedef struct alloc_device_t {
    struct hw_device_t common;

    /*
     * (*alloc)() Allocates a buffer in graphic memory with the requested
     * parameters and returns a buffer_handle_t and the stride in pixels to
     * allow the implementation to satisfy hardware constraints on the width
     * of a pixmap (eg: it may have to be multiple of 8 pixels).
     * The CALLER TAKES OWNERSHIP of the buffer_handle_t.
     *
     * Returns 0 on success or -errno on error.
     */
    
    int (*alloc)(struct alloc_device_t* dev,
            int w, int h, int format, int usage,
            buffer_handle_t* handle, int* stride);

    /*
     * (*free)() Frees a previously allocated buffer.
     * Behavior is undefined if the buffer is still mapped in any process,
     * but shall not result in termination of the program or security breaches
     * (allowing a process to get access to another process' buffers).
     * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes
     * invalid after the call.
     *
     * Returns 0 on success or -errno on error.
     */
    int (*free)(struct alloc_device_t* dev,
            buffer_handle_t handle);

    /* This hook is OPTIONAL.
     *
     * If non NULL it will be caused by SurfaceFlinger on dumpsys
     */
    void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);

    void* reserved_proc[7];
} alloc_device_t;
GraphicBufferAllocator分配GraphicBuffer的过程就是调用了这个结构中的alloc函数,返回buffer_handle_t,后面我们将看到这个alloc函数是如何实现的。
继续前面对Surface::lock的分析,在得到了一个GraphicBuffer,也就是一个ANativeWindow_Buffer之后,该函数把ANativeWindow_Buffer.bits传递给传出参数SurfaceInfo,
从这里我们知道,通过内存映射得到的地址,被设置给bitmap,后面draw的数据都将存储在这里。
综上所述,我们知道客户进程和SurfaceFlinger进程实际上并不传递buffer,而是通过内存映射的方式,共享内存,这样在客户端进程对内存进行写操作的时候,SurfaceFlinger进程就得到了数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值