推荐下载Android71 GUI系统中的本地窗口二.docx
《推荐下载Android71 GUI系统中的本地窗口二.docx》由会员分享,可在线阅读,更多相关《推荐下载Android71 GUI系统中的本地窗口二.docx(19页珍藏版)》请在冰豆网上搜索。
推荐下载Android71GUI系统中的本地窗口二
Android7.1GUI系统中的本地窗口
(二)
//这是一个函数指针,egl通过这个接口来申请一个buffer。
int
(*dequeueBuffer)(structANativeWindow*window,structANativeWindowBuffer**
buffer,int*fenceFd);//egl对一块buffer渲染完成后,调用这个接口来unlock和
postbuffer。
int(*queueBuffer)(structANativeWindow*window,struct
ANativeWindowBuffer*buffer,intfenceFd);}framebuffer,对应真实的物理设备,它
的buffer来自于帧缓冲区,由gralloc模块负责管理。
surfaceflinger是系统中UI界面的管理者,它直接或间接的持有本地窗口,在老
的android版本中,面向surfaceFlinger的本地窗口是framebuffernativewindow,但是
后来的版本framebuffernativewindow被丢弃了,现在只有一种本地窗口surface,继
承了ANativeWindow,履行了窗口协议。
面向应用程序端的本地窗口-surface,surface的主要组成部分是Bufferqueue。
Surface.h中可以看到surface的继承关系:
classSurface:
publicANativeObjectBaseANativeWindow,Surface,RefBase{…}既
然是本地窗口,就要实现ANativeWindow所规范的接口。
在它的构造函数中会给
ANativeWindow的函数指针赋值。
Frameworks/native/libs/gui/Surface.cpp//变量很多,没有全部列出,注意其初始化
列表中给mGraphicBufferProducer赋值bufferProducer。
Surface:
:
Surface(constsp
IGraphicBufferProducerbufferProducer,boolcontrolledByApp):
mGraphicBufferProducer(bufferProducer),//给ANativeWindow的函数指针赋值。
ANativeWindow:
:
setSwapInterval=hook_setSwapInterval;
ANativeWindow:
:
dequeueBuffer=hook_dequeueBuffer;ANativeWindow:
:
queueBuffer
=hook_queueBuffer;}surface是面向系统中所有UI应用程序的,承担着应用程序
中的UI显示需求。
因此它在面向上层实现(主要java层)时要提供绘制图像的“画
板”,这里绘制图像的内存空间是由mGraphicBufferProducer管理的。
还有一点,Surfaceflinger要收集系统中所有应用程序绘制的图像数据,然后合成
显示到屏幕,这个过程中Surface需要做些什么呢?
先看下surface中一些成员变量:
这个是surface的核心,管理着内存空间。
spIGraphicBufferProducermGraphicBufferProducer;
这是surface内部用于存储buffer的地方,容量由NUM_BUFFER_SLOTS决定,
目前是64,BufferQueue会跟踪这个缓冲区的最大值,如果试图在运行时增加这个
数量将会失败。
mSlots存储的是为每个bufferslot已经分配的buffers,并初始化为null,当客户
端dequeues一个buffer时,使用IGraphicBufferProducer:
:
requestBuffer的返回值来做
填充。
BufferSlotmSlots[NUM_BUFFER_SLOTS];
接下来重点看下surface中的dequeueBuffer的过程:
intSurface:
:
dequeueBuffer(android_native_buffer_t**buffer,int*
fenceFd)@Surface.cpp{//dequeueBuffer会请求一个给客户端使用的bufferslot,也就
是buf变量,代表了mSlots数组序号,然后这个slot的所有权就转到了客户端,意
味着服务端不在使用跟这个slot相关的buffer的内容。
返回的这个slot索引可能包
含、也可能不包含buffer,如果不包含客户端就要调用requestBuffer为这个slot分
配新的buffer。
一旦客户端填充了这个buffer,接下来期望是通过两种操作把这个
buffer的所有权转给服务端,一种操作是调用cancelBuffer移除这个slot,另一种操
作是填充了跟buffer内容相关的内容,然后调用queuebuffer。
如果dequeuebuffer返
回的是BUFFER_NEEDS_REALLOCATION这个flag,那么客户端立即调用
requestbuffer。
status_tresult=mGraphicBufferProducer-dequeueBuffer(buf,fence,
reqWidth,reqHeight,reqFormat,reqUsage);//mGraphicBufferProducer-dequeueBuffer()
返回后,buf变量就是mSlots数组中可用成员的序号,接下来就可以通过这个序号
来获取真正的buffer的地址,即mSlots[buf].buffer。
spGraphicBuffer
gbuf(mSlots[buf].buffer);//dequeueBuffer返回了
BUFFER_NEEDS_REALLOCATION,因此调用requestBuffer申请空间,如果
requestBuffer失败了,调用cancelBuffer。
if((result
IGraphicBufferProducer:
:
BUFFER_NEEDS_REALLOCATION)||gbuf==0){result=
mGraphicBufferProducer-requestBuffer(buf,gbuf);if(result!
=NO_ERROR){
mGraphicBufferProducer-cancelBuffer(buf,fence);returnresult;}
执行缓冲区的申请、释放的都是mGraphicBufferProducer
(IGraphicBufferProducer),那么surface中的这个mGraphicBufferProducer是怎么来
的?
前面在说surface的构造函数时,提到在它的初始化列表中给
mGraphicBufferProducer赋的值,因此就要跟踪谁创建了这个surface(cpp)实例。
大致过程:
在应用程序启动时把view树注册到Windowmanagerservice之前,或
者是窗口的可见性、大小属性发生了变化,都会执行一次view树的遍历,在这个过
程中会调用relayoutWindow(ViewRootImpl.java)重新布局窗口,其中会调用
mWindowSession.relayout()来让Windowmanagerservice向surfaceflinger申请“画
板”,然后通过relayout()中的出参mSurface将结果值返回。
下面就来看下这个过程,主要想弄清楚两点:
一是谁创建了本地层的
surface(cpp),二是谁创建了IGraphicBufferProducer实例。
下面代码省略无关的参数,代码段。
ViewRootImpl.java
//这里虽然创建了一个surface实例,其实是一个空壳,因为它内部没有承载UI
数据的画板。
要通过relayout重新赋值后才有意义。
finalSurfacemSurface=newSurface();privateintrelayoutWindow(...){int
relayoutResult=mWindowSession.relayout(...mSurface);}
通过Session.java的relayout,调用到Windowmanagerservice的
relayoutwindow()。
WindowManagerService.javapublicintrelayoutWindow(...SurfaceoutSurface){result
=createSurfaceControl(outSurface,result,win,winAnimator);}
//这里先让WindowStateAnimator创建一个WindowSurfaceController,在
WindowSurfaceController的构造函数中创建了mSurfaceControl(SurfaceControl),然
后通过outSurface.copyFrom(mSurfaceControl);把mSurfaceControl复制到mSurface
中。
privateintcreateSurfaceControl(SurfaceoutSurface,...){WindowSurfaceController
surfaceController=winAnimator.createSurfaceLocked();
surfaceController.getSurface(outSurface);}
//这里通过native接口,创建一个本地的surface(c++)对象。
publicvoidcopyFrom(SurfaceControlother)@Surface.java{longsurfaceControlPtr=
other.mNativeObject;longnewNativeObject=
nativeCreateFromSurfaceControl(surfaceControlPtr);}
//这个函数中并没有直接生成surface(c++)对象,而是从SurfaceControl(c++)中提
取的。
然后通过surface.get()返回一个指向surface(c++)对象的指针。
这个get()是强
指针(StrongPointer.h)里面的。
那么SurfaceControl(c++)对象是谁来创建的呢?
这要追踪surfaceControlNativeObj
的来源了。
staticjlongnativeCreateFromSurfa