广州浪奇官网,天雷地王,黑客免费送qq号
本篇针对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。如此循环。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android studio 解决logcat无过滤工具栏的操作
Android Studio 恢复小窗口停靠模式(Docked Mode)
Android studio保存logcat日志到本地的操作
Android Studio快捷键生成TAG、Log.x日志输出介绍
网友评论