标签:重写 exce 按键处理 二维 rename field 接收 对象 ror
本篇针对Surface模块进行分析,从Java层的Activity创建开始,到ViewRoot、WindowsManagerService,再到JNI层和Native层。
首先推荐一个Android源码查看的网站:http://androidxref.com/
Surface的创建涉及三个部分:
App 进程
App需要将自己的内容显示在屏幕上,所以App负责发起Surface创建请求,创建好Surface后, 就可以直接可以在canvas上画图等,最终都会保存到Surface里的buffer里,最后由SurfaceFlinger合成并显示。
System_Server进程
主要是其中的WindowManagerService, 负责接收APP请求,向SurfaceFlinger发起具体的请求创建Surface, 且WMS需要创建Surface的辅助管理类,如SurfaceControl。
SurfaceFlinger
为App进程创建具体的Surface, 在SurfaceFlinger里对应成Layer, 然后负责管理、合成显示。
总体流程(参考《深入理解Android》,源码较旧):
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的关系:
Surface像是UI的画布,APP就像是在Surface上作画,通过i使用Skia绘制二维图像,或是用OpenGL绘制三维图像,最终APP和Surfacea都要进行交互。
SUrface和SurfaceFlinger(SF)的关系:
surface向SF提供数据,SF进行混合数据。
1、应用程序的显示和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 }
2、 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); ... }
实现了:
3、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
总结:
1、大致涉及的方法、类的大体流程(回车表示前一方法内调用):
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
2、要点:
(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进行跨进程调用通信的。
1、在JNI层,首先被调用的时Surface的无参构造函数,代码:
// Surface.java Public Surface() { ... mCanvas = new CompatibleCanvas(); // CompatibleCanvaso从Canvas类派生 }
Canvas:
画图需要:
一般情况下,Canvas会封装一块Bitmap。
2、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()); }
3、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); }
4、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); } }
5、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函数。
调用流程总结:
总结:
1、一个Activity一般都会对应到一个Window, 对应了一个DecorView, ViewRoot
2、ViewRoot中有一个Surface, 就是App可以用于绘制UI的Surface了,在Native层也对应了一个Surface, 在SurfaceFlinger对应的是一个Layer,通过Layer中的Producer可以真正的申请Buffer用于绘制。App中通过Surface中的Canvas的类似lockcanvas接口触发dequeue buffer流程。
3、 一个ViewRoot在WMS端对应了一个WindowState, WindowState又通过一系列引用关联到一个SurfaceControl, Native层也有一个SurfaceControl。这个可以用于控制窗口的一些属性。
4、 WMS native层的SurfaceComposerClient与SurfaceFlinger之间通过ISurfaceComposerClient建立联系。一个App在SurfaceFlinger端对应了一个Client,用于处理该App layer的创建等请求。
5、当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(画面交换),用于图像、图形数据的生产和消费
操作过程:
1、分配一个能容纳两帧数据的缓冲Buffer,前面一个缓冲叫FrontBuffer,后一个叫BackBuffer;
2、消费者使用FontBuffer中的旧数据,而生产者使用新数据填充BackBuffer,二者互不干扰;
3、当需要更新显示时,BackBuffer变成oFrontBuffer,FrontBuffer变成BackBuffer。如此循环。
标签:重写 exce 按键处理 二维 rename field 接收 对象 ror
原文地址:https://www.cnblogs.com/1996swg/p/9834892.html