本篇针对Surface模块进行分析,从Java层的Activity建立开始,到ViewRoot、WindowsManagerService,再到JNI层和Native层。java
首先推荐一个Android源码查看的网站:http://androidxref.com/android
Surface的建立涉及三个部分:canvas
App 进程
App须要将本身的内容显示在屏幕上,因此App负责发起Surface建立请求,建立好Surface后, 就能够直接能够在canvas上画图等,最终都会保存到Surface里的buffer里,最后由SurfaceFlinger合成并显示。数组
System_Server进程
主要是其中的WindowManagerService, 负责接收APP请求,向SurfaceFlinger发起具体的请求建立Surface, 且WMS须要建立Surface的辅助管理类,如SurfaceControl。session
SurfaceFlinger
为App进程建立具体的Surface, 在SurfaceFlinger里对应成Layer, 而后负责管理、合成显示。app
整体流程(参考《深刻理解Android》,源码较旧):composer
Surface建立过程: ActivityThread.java 调用handleLaunchActivity 调用handleResumeActivity函数 addView调用到LocalWindowManager.java的addView函数 而后调用WindowManagerImpl.java的addView函数 建立ViewRoot(分红两个分支): 1、执行ViewRoot的构造函数,建立mSurface(!实现ViewRoot的Surface建立)(建立IWindow) 2、调用ViewRoot的setView函数(分红两个分支): 1、setView调用WMS的add函数(IWindowSession) 调用WMS的addWindow函数 调用WMS.java::WindowState的attach函数 调用WMS.java::Session的windowAddedLocked函数,建立SurfaceSession(!实现WMS的SurfaceSession建立) 执行SurfaceSession的构造器,调用native函数init JNI层实现init函数,建立一个SurfaceComposerClient(分红两步): 1、SurfaceComposerClient构造函数调用SurfaceFlinger的createConnection(!和SF创建交互通道) 建立Client(建立共享内存)(一个Client最多支持31个显示层) Client构造函数建立SharedClient对象 SharedClient定义SharedBufferStack数组对象(有31个元素) 建立BClient(接受客户端请求,将处理提交给SF) 2、再调用_init(初始化SurfaceComposerClient一些成员变量) 2、调用requestLayout函数,向ViewRoot发送DO_TRAVERSAL消息 调用handleMessage函数 调用performTraversal函数(分红两个分支): 1、调用ViewRoot的relayoutWindow函数(调用IWindowSession的relayout函数) 调用createSurfaceControl建立一个SurfaceControl ?在SurfaceComposerClient的createSurface建立一个SurfaceControl(请求端) ?SurfaceComposerClient调用createSurface建立一个Surface(SurfaceControl类型) ? 调用SurfaceControl的writeToParcel将信息写入Parcel包中 ? 在readFromParcel中经过Parcel信息构造一个Surface对象,保存到mSurface ? ViewRoot得到一个Native的Surface对象 调用WMS.java::Session的relayout函数(!此和上这两步跨进程)(分红三步): 1、在IWindowSession.adil的Bn端调用onTransact,writeToParcel写入信息 2、在IWindowSession.adil的Bp端,relayout中传入outSurface,readFormParcel读取信息填充outSurface 3、调用WMS的relayoutWindow 》》调用WMS.java::WindowState的createSurfaceLocked,建立本地Surface(SurfaceSession) 》》调用copyForm,将本地surface信息拷贝到outSurface(即mSurface) 2、调用draw()函数开始绘制(lockCanvas、调用draw、unlockCanvasAndPost) 调用DecorView的draw函数(!实现UI绘制)
Surface和APP的关系:tcp
Surface像是UI的画布,APP就像是在Surface上做画,经过i使用Skia绘制二维图像,或是用OpenGL绘制三维图像,最终APP和Surfacea都要进行交互。ide
SUrface和SurfaceFlinger(SF)的关系:函数
surface向SF提供数据,SF进行混合数据。
一、应用程序的显示和surface有关,而应用程序的外表经过Activity展现的,那么Activity如何建立的呢?
App对应的进程,它的入口函数是ActivityThread类的main函数。
ActivityThread类中有一个handleLaunchActivity函数(建立Activity),代码以下:
private void handleLaunchActivity(ActivityClientRecord r , Intent customIntent , String reason) { ... Activity a = performLaunchActivity(r, customIntent); ... if (a != null) { ... handleResumeActivity(r.token , false , r.isForward ,!r.activity.mFinished && !r.startsNotResumed , r.lastProcessedSeq, reason); //Activity建立成功就往onResume()走了! ... } }
这个函数涉及了两个关键函数:
(1)performLaunchActivity
返回一个activity(即App中的Activity),该方法 建立了Activity:
private Activity performLaunchActivity(ActivityClientRecord r , Intent customIntent) { ... // newActivity函数根据Activity的类名经过Java反射机制建立对应的Activity activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ... Application app = r.packageInfo.makeApplication(false , mInstrumentation); //在获取Application ... activity.attach(appContext , this , getInstrumentation() , r.token ,.ident , app , r.intent , r.activityInfo , title , r.parent , r.embeddedID , r.lastNonConfigurationInstances , config ,r.referrer , r.voiceInteractor , window); ... if (r.isPersistable()) { mInstrumentation.callActivityOnCreate( activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); //调用Activity的onCreate函数 } ...
}
所以,performLaunchActivity的做用以下:
(2)handleResumeActivity
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ... // 与调用Activity的onResume相关 ActivityClientRecord r = performResumeActivity(token, clearHide); ... // PhoneWindow r.window = r.activity.getWindow(); // 获取Activity的DecorView View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); // WindowManagerImpl,其实就是LocalWindowManager ViewManager wm = a.getWindowManager(); 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); // 将刚才的dector对象加入到ViewManagerg中 } ... }
> 在Activity.java中Activity在onCreate函数中经过setContentView设置UI界面。
Activity.java部分代码:
public void setContentView(View view) { getWindow().setContentView(view); // 传入一个view } public Window getWindow() { return mWindow; //返回一个类型为Window的对象 }
> 分析出现的两个和UI相关的类:
Window:一个抽象基类,用于控制顶层窗口的外观和行为。职能多是绘制背景、标题栏、默认的按键处理等。
它将做为一个顶层的view加入到Window Manager中。
View:一个基本的UI单元,占据屏幕的一块矩形区域,可用于绘制,能处理事件。(设置的view其实只是DecorView的子view,DecorView还处理了标题栏显示等一系列操做)
也能够看作:
> 分析addView,wm类型其实是LocalWindowManager,查看LocalWindowManager.java的addView函数:
public final void addView(View view , ViewGroup.LayoutParams params) { .............. mWindowManager.addView(view, params); // mWindowManager对象实际是WindowManagerImpl类型 }
接着查看WindowManagerImpl.java类的addView函数:
private void addView(View view, ViewGroup.LayoutParams params, boolean nest) { ... ViewRoot root; ... root = new ViewRoot(view.getContext()); // 建立viewRoot ... ①root.setView(view, wparams, panelParentView); // view即刚刚介绍的DectorView }
二、 viewRoot: viewRoot实现了ViewParent接口,ViewParent不处理绘画,由于它没有onDraw函数(因此和Android基本绘画单元的view不太同样)
//查看ViewRoot.java::ViewRoot定义 public final class ViewRoot extends Handler implements ViewParent, View.AttachInfo.Callbacks // 从Handler 派生 { private final Suface mSurface = new Surface(); // 建立了一个Surface 对象 Final W mWindow; View mView; }
分析得出ViewRoot的做用:
View、DectorView是UI单元,绘画工做在OnDraw函数中完成。若是onDraw是画图过程,那么画布就是Surface。
Surface:有一块Raw Buffer,Surface操做这块Raw Buffer,Screen Compositor(即SurfaceFlinger)管理这块Raw Buffer。
结论:
在①的setView中,调用的时ViewRoot.java的setView函数:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { ... ... res = sWindowSession.add(mWindow, mWindowAttributes, getHostVisibility(), mAttachInfo.mContentInsets, mInputChannel); ... }
实现了:
三、requestLayout会向ViewRoot发送一个消息,进入ViewRoot.java的handleMessage函数,调用performTraversals函数。
进入 performTraversals函数:
private void performTraversals() { final View host = mView; //即最初的DectorView ...
try{
relayoutResult = relayoutWindow(params, viewVisiblity, insetPending);
} ... host.measure(childWidthMeasureSpec, childHeightMeasureSpec); ... host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight); ... ... draw(fullRedrawNeeded); ... }
(1)relayoutWindow函数:会调用IWindowSession的Relayout函数;
(2)draw函数:从mSurface(Surface)中lock一块Canvas(画布),调用DecorView的draw函数,而后交给mView绘画,最后unlockCanvasAndPost释放这块Canvas
总结:
一、大体涉及的方法、类的大致流程(回车表示前一方法内调用):
ActivityThread.java
调用handleLaunchActivity
调用performLaunchActivity函数(建立Activity、调用onCreate)
onCreate调用setContentView函数设置UI界面,传入view,返回Window
调用handleResumeActivity函数
addView调用到LocalWindowManager.java的addView函数
而后调用WindowManagerImpl.java的addView函数
建立ViewRoot,调用ViewRoot的setView函数
ViewRoot.java(继承Handler、实现ViewParent)
构造函数建立一个Surface对象mSurface
setView函数实现:
保存传入的view为mView
调用requestLayout
调用IWindowSession的add函数
WIndowManagerServce.java::session的add函数
调用WMS.java的addWindow
调用WMS.java::WIndowState的attach函数
调用windowAnddedLocked函数并建立一个SurfaceSession对象
requestLayout(向ViewRoot发送一个消息)
进入ViewRoot.java的handleMessage函数
调用performTraversals函数
调用relayoutWindow函数
调用IWindowSession的Relayout函数
调用draw函数(从mSurface中lock一块Canvas)
调用DecorView的draw函数,交给mView绘画
最后unlockCanvasAndPost释放Canvas
二、要点:
(1)整个Activity的绘图流程就是从mSurface中lock一块Canvas,而后交给mView去绘画,最后unlockCanvasAndPost释放这块Canvas ;
(2)Activity的顶层view是DecotView,而onCreate函数中setContentView设置的View是这个DecorView的一部分。DecorView是一个FrameLayout类型的ViewGroup;
(3)Activity和UI有关,包含window(真实类型是phoneWIndow)和一个WindowManger(真实类型是LocalWindowManager)对象。这两个对象控制整个Activity的显示;
(4)LocalWindowManager使用了WindowManagerImpl.java(其中addView有一个ViewRoot对象)做为最终处理对象;
(5)ViewRoot实现了ViewParent接口,有两个变量:
mView,指向Activity顶层UI单元的DecorView
mSurface,包含一个Canvas
此外,ViewRoot还经过Binder系统和dWinowManagerService进行跨进程交互;
(6)ViewRoot可以处理Handler的消息,Activity的显示就是由ViwRoot在他的performTraversals函数中完成;
经过上面一节的分析可知:
ViewRoot的构造函数里面会建立一个Surface;
而ViewRoot经过IWindowSession和WMS交互时,WMS调用的attach函数会构造一个SurfaceSession;
ViewRoot在prformTransval的处理过程当中会调用IWindowSession的relayout函数。(WMS由SYsytem_server进程启动,SF服务也在这个进程中)
两个部分的Surface看似是毫无关系,可是实际上,在使用createSurfaceLocked() 的时候,会将creaeSurfaceLocked 建立的Surface copy到ViewRoot层的Surface中。也就是这样,将底层的Surface对象传到上层,供Activity的界面部分使用,用来绘图。整个流程大概是:
RootView.relayoutWindow,调用方,调用relayout将mSurface传进去
-> WindowManagerService.Session.relayout调用外部类对象的relayoutWindow
-> WindowManagerService.relayoutWindow,调用createSurfaceLocked
-> WindowManagerService.createSurfaceLocked(),将SurfaceSession拷贝到建立的新对象Surface
-> outSurface.copyFrom(surface),将本地Surface 的信息(即SurfaceSession)拷贝到outSurface中
最后一步是将WindowManagerService的surface与ViewRoot 的outSurface联系起来的关键点,outSurface是做为参数,从RootView传到WindowManagerService的。
ViewRoot实际上是经过Binder与WindowManagerService进行跨进程调用通讯的。
一、在JNI层,首先被调用的时Surface的无参构造函数,代码:
// Surface.java Public Surface() { ... mCanvas = new CompatibleCanvas(); // CompatibleCanvaso从Canvas类派生 }
Canvas:
画图须要:
通常状况下,Canvas会封装一块Bitmap。
二、SurfaceSession的构造
// SurfaceSession.java public SurfaceSession(){ init(); //这是一个native函数 }
init函数的实如今JNI的android_view_Surface.cpp中:
static void SurfaceSession_init(JNIEnv* env,jobject clazz) { //建立一个SurfaceComposerClient对象 sp<SurfaceComposerClient> client = new SurfaceComposerClient; client->incStrong(clazz); //在Java对象中保存这个client对象的指针,类型为SurfaceComposerClient env->SetIntField(clazz, sso.client, (int)client.get()); }
三、Surface的有参构造函数:
// Surface.java publicSurface(SurfaceSession s,//传入一个SurfaceSession对象 int pid, String name, int display, int w, int h, int format, int flags) throws OutOfResourcesException { ...... mCanvas = new CompatibleCanvas(); //又一个native函数,注意传递的参数:display之后再说,w,h表明绘图区域的宽高值 init(s,pid,name,display,w,h,format,flags); mName = name; }
Surface的init函数实如今JNI层:
static void Surface_init( JNIEnv*env, jobject clazz, jobject session, jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags) { //从SurfaceSession对象中取出以前建立的那个SurfaceComposerClient对象 SurfaceComposerClient* client = (SurfaceComposerClient*)env->GetIntField(session, sso.client); sp<SurfaceControl> surface;//注意它的类型是SurfaceControl if (jname == NULL) { /* 调用SurfaceComposerClient的createSurface函数,返回的surface是一个 SurfaceControl类型。 */ surface = client->createSurface(pid, dpy, w, h, format, flags); } else{ ...... } //把这个surfaceControl对象设置到Java层的Surface对象中,对这个函数就再也不分析了 setSurfaceControl(env, clazz, surface); }
四、copyForm分析
上一节中,outSurface.copyFrom(surface),将本地Surface 的信息(即SurfaceSession)拷贝到outSurface中
他是一个native函数,代码以下:
static void Surface_copyFrom(JNIEnv* env,jobject clazz, jobject other) { //根据JNI函数的规则,clazz是copyFrom的调用对象,而other是copyFrom的参数。 //目标对象此时尚未设置SurfaceControl,而源对象在前面已经建立了SurfaceControl constsp<SurfaceControl>& surface = getSurfaceControl(env, clazz); constsp<SurfaceControl>& rhs = getSurfaceControl(env, other); if (!SurfaceControl::isSameSurface(surface, rhs)) { //把源SurfaceControl对象设置到目标Surface中。 setSurfaceControl(env, clazz, rhs); } }
五、writeToParcel和readFromParcel分析
这两个函数调用发生在ViewRoot调用IWindowSession的relayout函数中,它发生在IWindowSession.adil(经过aidl -l ...编译成java文件可查看到relayout方法中和onTransactg中)
// android_view_Surface.cpp static void Surface_writeToParcel(JNIEnv* env,jobject clazz, jobject argParcel, jint flags) { Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel); //clazz就是Surface对象,从这个Surface对象中取出保存的SurfaceControl对象 const sp<SurfaceControl>&control(getSurfaceControl(env, clazz)); /* 把SurfaceControl中的信息写到Parcel包中,而后利用Binder通讯传递到对端, 对端经过readFromParcel来处理Parcel包。 */ SurfaceControl::writeSurfaceToParcel(control, parcel); if (flags & PARCELABLE_WRITE_RETURN_VALUE) { //lags的值就等于PARCELABLE_WRITE_RETURN_VALUE //因此本地Surface对象的SurfaceControl值被置空了 setSurfaceControl(env, clazz, 0); } } --------------------- // android_view_Surface.cpp static void Surface_readFromParcel( JNIEnv* env, jobject clazz, jobject argParcel) { Parcel* parcel = (Parcel*)env->GetIntField( argParcel,no.native_parcel); //注意下面定义的变量类型是Surface,而不是SurfaceControl const sp<Surface>&control(getSurface(env, clazz)); //根据服务端传递的Parcel包来构造一个新的surface。 sp<Surface> rhs = new Surface(*parcel); if (!Surface::isSameSurface(control, rhs)) { //把这个新surface赋给ViewRoot中的mSurface对象 setSurface(env,clazz, rhs); } }
小结:
在JNIe层建立了三个对象:SurfaceComposerClient、SurfceControl、Surface
大体流程:
(1)建立一个SurfaceComposerClient
(2)调用SurfaceComposerClient的createSurface获得一个SurfceControl对象
(3)调用SurfaceControl的writeToParcel,将一些信息写入Parcel包中
(4)根据Parcel包的信息z构造一个Surface对象,将其保存到Java层的mSurface中
(5)所以,ViewRoot获得一个Native的Surface对象
Surface和画图Canvas:
在ViewRoot的draw()函数里面(前面有提到),有两个和Surface相关的函数调用:
(1)lockCanvas:先得到一块存储区域,而后将它和Canvas绑定到一块儿,这样,UI绘画的结果就记录在这块存储区域里了,如此进Canvas进行UI画图就会有画布了;
(2)unlockCanvasAndPost:一个native函数,取出Native的Surface对象,调用Surface的unlockAndPost函数。
调用流程总结:
总结:
一、一个Activity通常都会对应到一个Window, 对应了一个DecorView, ViewRoot
二、ViewRoot中有一个Surface, 就是App能够用于绘制UI的Surface了,在Native层也对应了一个Surface, 在SurfaceFlinger对应的是一个Layer,经过Layer中的Producer能够真正的申请Buffer用于绘制。App中经过Surface中的Canvas的相似lockcanvas接口触发dequeue buffer流程。
三、 一个ViewRoot在WMS端对应了一个WindowState, WindowState又经过一系列引用关联到一个SurfaceControl, Native层也有一个SurfaceControl。这个能够用于控制窗口的一些属性。
四、 WMS native层的SurfaceComposerClient与SurfaceFlinger之间经过ISurfaceComposerClient创建联系。一个App在SurfaceFlinger端对应了一个Client,用于处理该App layer的建立等请求。
五、当ViewRootImpl请求WMS relayout时,会将ViewSurface中的Surface交给WMS初始化。在WMS中,对应每一个WindowState对象,在relayout窗口时,一样会建立一个Surface,wms中的这个Surface会真正的初始化,而后再将这个WMS Surface复制给ViewRootImpl中的Surface。这么实现的目的就是保证ViewRootImpl和WMS共享同一个Surface。ViewRootImpl对Surface进行绘制,WMS对这个Surface进行初始化及管理。
ActivityThread.java
调用handleLaunchActivity
调用performLaunchActivity函数(建立Activity、调用onCreate)
onCreate调用setContentView函数设置UI界面,传入view,返回Window
调用handleResumeActivity函数
addView调用到LocalWindowManager.java的addView函数
而后调用WindowManagerImpl.java的addView函数
建立ViewRoot,调用ViewRoot的setView函数
ViewRoot.java(继承Handler、实现ViewParent)
构造函数建立一个Surface对象mSurface
setView函数实现:
保存传入的view为mView
调用requestLayout
调用IWindowSession的add函数
WIndowManagerServce.java::session的add函数
调用WMS.java的addWindow
调用WMS.java::WIndowState的attach函数
调用windowAnddedLocked函数并建立一个SurfaceSession对象
requestLayout(向ViewRoot发送一个消息)
进入ViewRoot.java的handleMessage函数
调用performTraversals函数
调用relayoutWindow函数
调用IWindowSession的Relayout函数
调用draw函数(从mSurface中lock一块Canvas)
调用DecorView的draw函数,交给mView绘画
最后unlockCanvasAndPost释放Canvas
在应用启动时,会经过WindowManagerGlobal去添加view,添加view时会去建立viewRootImpl,而后进行设置view。
viewRootImpl.setView() —> requestLayout()申请布局—>scheduleTraversals()—>doTraversal()–>performTraversals()
利用IWindowSession和Session通讯,调用relayout,注意,这里mSurface是ViewRootImpl的成员变量,开始调用了无参的构造函数,IWindowSession.aidl文件中,参数mSurface是被out修饰,用来接受在server端建立Surface,而后再binder返回给ViewRootImpl。
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) { int res = mService.relayoutWindow(this, window, seq, attrs, requestedWidth, requestedHeight, viewFlags, flags, outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, outConfig, outSurface); return res; }
public int relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) { //新建一个SurfaceControl SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); if (surfaceControl != null) { outSurface.copyFrom(surfaceControl); if (SHOW_TRANSACTIONS) Slog.i(TAG, " OUT SURFACE " + outSurface + ": copied"); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. outSurface.release(); } }
首先建立一个SurfaceControl:
SurfaceControl createSurfaceLocked() { mSurfaceControl = new SurfaceControl( mSession.mSurfaceSession, attrs.getTitle().toString(), w, h, format, flags); } public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags) throws OutOfResourcesException { //session就是SurfaceComposerClient在java层的表明 //mNativeObject是native层SurfaceControl的指针 mNativeObject = nativeCreate(session, name, w, h, format, flags); }
static jint nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, jstring nameStr, jint w, jint h, jint format, jint flags) { ScopedUtfChars name(env, nameStr); //从上层取到SurfaceComposerClient的指针,还原一个SurfaceComposerClient sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); //调用createSurface,返回的是一个SurfaceControl对象,注意不是surface sp<SurfaceControl> surface = client->createSurface( String8(name.c_str()), w, h, format, flags); if (surface == NULL) { jniThrowException(env, OutOfResourcesException, NULL); return 0; } surface->incStrong((void *)nativeCreate); //返回给java层SurfaceControl的指针 return int(surface.get()); }
sp<SurfaceControl> SurfaceComposerClient::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<SurfaceControl> sur; if (mStatus == NO_ERROR) { sp<IBinder> handle; sp<IGraphicBufferProducer> gbp; status_t err = mClient->createSurface(name, w, h, format, flags, &handle, &gbp); //gbp就是surfacefligner中Layer的mBufferQueue的client端(IGraphicBufferProducer) if (err == NO_ERROR) { sur = new SurfaceControl(this, handle, gbp); } } return sur; }
经过ISurfaceComposerClient的binder通讯,调用服务端对应client对象的方法createSurface():
status_t Client::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { /* * createSurface must be called from the GL thread so that it can * have access to the GL context. */ class MessageCreateLayer : public MessageBase { SurfaceFlinger* flinger; Client* client; sp<IBinder>* handle; sp<IGraphicBufferProducer>* gbp; status_t result; const String8& name; uint32_t w, h; PixelFormat format; uint32_t flags; public: MessageCreateLayer(SurfaceFlinger* flinger, const String8& name, Client* client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) : flinger(flinger), client(client), handle(handle), gbp(gbp), name(name), w(w), h(h), format(format), flags(flags) { } status_t getResult() const { return result; } //MessageQueue.cpp 中方法回调MessageBase::handleMessage virtual bool handler() { result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp); return true; } }; sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), name, this, w, h, format, flags, handle, gbp); mFlinger->postMessageSync(msg); return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); }
上述可看出,将建立layer消息放入队列,以下所示:
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime, uint32_t /* flags */) { status_t res = mEventQueue.postMessage(msg, reltime); if (res == NO_ERROR) { //阻塞等待消息处理完成 msg->wait(); } return res; }
当建立layer的消息被处理时,就会回调上述MessageCreateLayer类中的handler方法。handler方法中调用flinger.createLayer(),第一次还会执行Layer.onFirstRef()
status_t SurfaceFlinger::createLayer( const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); if (int32_t(w|h) < 0) { ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", int(w), int(h)); return BAD_VALUE; } status_t result = NO_ERROR; sp<Layer> layer; switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { case ISurfaceComposerClient::eFXSurfaceNormal: result = createNormalLayer(client, name, w, h, flags, format, handle, gbp, &layer); break; case ISurfaceComposerClient::eFXSurfaceDim: result = createDimLayer(client, name, w, h, flags, handle, gbp, &layer); break; default: result = BAD_VALUE; break; } if (result != NO_ERROR) { return result; } result = addClientLayer(client, *handle, *gbp, layer); if (result != NO_ERROR) { return result; } setTransactionFlags(eTransactionNeeded); return result; }
在执行Layer::onFirstRef()会新建一个缓冲区队列的消费者与客户端APP的生产者对应:
void Layer::onFirstRef() { //surfaceflinger中新建一个缓冲区队列的消费者 mBufferQueue = new SurfaceTextureLayer(mFlinger); mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceFlingerConsumer->setFrameAvailableListener(this); mSurfaceFlingerConsumer->setName(mName); #ifdef TARGET_DISABLE_TRIPLE_BUFFERING #warning "disabling triple buffering" mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); #else mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); #endif const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); updateTransformHint(hw); }
(1)FrameBuffer(帧缓冲,存储图形、图像的缓冲):
Frame:帧,就是指一幅图像。在屏幕a上看到的一幅图像就是一帧。
Buffer:缓冲,就是一段存储区域(存储的是帧) 。
(2) PageFlipping(画面交换),用于图像、图形数据的生产和消费
操做过程:
一、分配一个能容纳两帧数据的缓冲Buffer,前面一个缓冲叫FrontBuffer,后一个叫BackBuffer;
二、消费者使用FontBuffer中的旧数据,而生产者使用新数据填充BackBuffer,两者互不干扰;
三、当须要更新显示时,BackBuffer变成oFrontBuffer,FrontBuffer变成BackBuffer。如此循环。