概述
先看下Android中本地窗口的定义:
system/core/include/system/window.h
struct AnativeWindow{
//所支持的最小和最大交换间隔时间。
const int minSwapInterval;
const int maxSwapInterval;
//水平方向和垂直方向的密度。
const float xdpi;
const float ydpi;
//这是一个函数指针,egl通过这个接口来申请一个buffer。
int (*dequeueBuffer)(struct ANativeWindow* window,
struct ANativeWindowBuffer** buffer, int* fenceFd);
//egl对一块buffer渲染完成后,调用这个接口来unlock和postbuffer。
int (*queueBuffer)(struct ANativeWindow* window,
struct ANativeWindowBuffer* buffer, int fenceFd);
}
framebuffer
,对应真实的物理设备,它的buffer
来自于帧缓冲区,由gralloc
模块负责管理。
surfaceflinger是系统中UI界面的管理者,它直接或间接的持有本地窗口,在老的android版本中,面向surfaceFlinger的本地窗口是framebuffernativewindow,但是后来的版本framebuffernativewindow被丢弃了,现在只有一种本地窗口surface,继承了ANativeWindow,履行了窗口协议。
面向应用程序端的本地窗口-surface,surface的主要组成部分是Bufferqueue。
Surface.h中可以看到surface的继承关系:
class Surface: public ANativeObjectBase<ANativeWindow, Surface, RefBase>{…}
既然是本地窗口,就要实现ANativeWindow所规范的接口。在它的构造函数中会给ANativeWindow的函数指针赋值。
Frameworks/native/libs/gui/Surface.cpp
//变量很多,没有全部列出,注意其初始化列表中给 mGraphicBufferProducer赋值bufferProducer 。
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer,bool controlledByApp)
: mGraphicBufferProducer(bufferProducer),
{
//给 ANativeWindow的函数指针赋值。
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
ANativeWindow::queueBuffer = hook_queueBuffer;
}
surface是面向系统中所有UI应用程序的,承担着应用程序中的UI显示需求。所以它在面向上层实现(主要java层)时要提供绘制图像的“画板”,这里绘制图像的内存空间是由mGraphicBufferProducer管理的。
还有一点,Surfaceflinger要收集系统中所有应用程序绘制的图像数据,然后合成显示到屏幕,这个过程中Surface需要做些什么呢?
先看下surface中一些成员变量:
这个是surface的核心,管理着内存空间。
sp<IGraphicBufferProducer>mGraphicBufferProducer;
这是surface内部用于存储buffer的地方,容量由NUM_BUFFER_SLOTS决定,目前是64,BufferQueue会跟踪这个缓冲区的最大值,如果试图在运行时增加这个数量将会失败。
mSlots存储的是为每个bufferslot已经分配的buffers,并初始化为null,当客户端dequeues一个buffer时,使用IGraphicBufferProducer::requestBuffer的返回值来做填充。
BufferSlotmSlots[NUM_BUFFER_SLOTS];
接下来重点看下surface中的dequeueBuffer的过程:
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd)@Surface.cpp {
// dequeueBuffer会请求一个给客户端使用的buffer slot,也就是buf变量,代表了mSlots数组序号,然后这个slot的所有权就转到了客户端,意味着服务端不在使用跟这个slot相关的buffer的内容。返回的这个slot索引可能包含、也可能不包含buffer,如果不包含客户端就要调用requestBuffer为这个slot分配新的buffer。
一旦客户端填充了这个buffer,接下来期望是通过两种操作把这个buffer的所有权转给服务端,一种操作是调用cancelBuffer移除这个slot,另一种操作是填充了跟buffer内容相关的内容,然后调用queuebuffer。
如果dequeuebuffer返回的是 BUFFER_NEEDS_REALLOCATION 这个flag,那么客户端立即 调用requestbuffer。
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
reqWidth, reqHeight, reqFormat, reqUsage);
// mGraphicBufferProducer->dequeueBuffer()返回后, buf变量就是mSlots数组中可用成员的序号,接下来就可以通过这个序号来获取真正的buffer的地址,即 mSlots[buf].buffer。
sp<GraphicBuffer>& 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);
return result;
}
}
}
执行缓冲区的申请、释放的都是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重新赋值后才有意义。
final Surface mSurface = new Surface();
private int relayoutWindow(...){
int relayoutResult = mWindowSession.relayout(...mSurface);
}
通过Session.java的relayout,调用到Windowmanagerservice的relayoutwindow()。
WindowManagerService.java
public int relayoutWindow(...Surface outSurface) {
result = createSurfaceControl(outSurface, result, win, winAnimator);
}
//这里先让WindowStateAnimator创建一个WindowSurfaceController,在WindowSurfaceController的构造函数中创建了mSurfaceControl(SurfaceControl),然后通过outSurface.copyFrom(mSurfaceControl);把mSurfaceControl复制到mSurface中。
private int createSurfaceControl(Surface outSurface,...){
WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
surfaceController.getSurface(outSurface);
}
//这里通过native接口,创建一个本地的surface(c++)对象。
public void copyFrom(SurfaceControl other) @Surface.java{
long surfaceControlPtr = other.mNativeObject;
long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
}
//这个函数中并没有直接生成surface(c++)对象,而是从SurfaceControl(c++)中提取的。然后通过surface.get()返回一个指向surface(c++)对象的指针。这个get()是强指针(StrongPointer.h)里面的。
那么SurfaceControl(c++)对象是谁来创建的呢?这要追踪surfaceControlNativeObj的来源了。
static jlong nativeCreateFromSurfaceControl(...surfaceControlPtr){
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
sp<Surface> surface(ctrl->getSurface());
return reinterpret_cast<jlong>(surface.get());
}
/先把SurfaceControl.cpp中生成Surface(c++)的地方列出来,然后在去追踪SurfaceControl(c++)是由谁创建的。
SurfaceControl.cpp
mutable sp<Surface> mSurfaceData;
sp<Surface> SurfaceControl::getSurface() const{
//注意这里的 mGraphicBufferProducer对象,来自与 SurfaceControl的构造函数,如果追到了创建SurfaceControl(c++)对象的地方,也就知道了 mGraphicBufferProducer的来源。
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
}
要追踪SurfaceControl(c++)对象的来源,就是知道surfaceControlNativeObj是怎么来的?再返回到surface.java的copyFrom()函数中。从这个函数中longsurfaceControlPtr =other.mNativeObject;看到,surfaceControlNativeObj来自于SurfaceControl(java)中的mNativeObject。
SurfaceControl.java
long mNativeObject;
public SurfaceControl(...){
mNativeObject = nativeCreate(session, name, w, h, format, flags);
}
mNativeObject是通过native函数创建的。
可以看到SurfaceControl实际是由SurfaceComposerClient来创建的。
static jlong nativeCreate(...)@android_view_SurfaceControl.cpp{
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
sp<SurfaceControl> surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);
return reinterpret_cast<jlong>(surface.get());
}
//这里生成了本地的surfacecontrol对象,前面在分析SurfaceControl(c++)的getSurface()方法说过找到了创建SurfaceControl(c++)对象的地方,也就找到了IGraphicBufferProducer对象的来源,这个IGraphicBufferProducer实例也是传入到surface(c++)构造函数中对象参数mGraphicBufferProducer,gbp(IGraphicBufferProducer)对象也是在这里传入的
sp<SurfaceControl> SurfaceComposerClient::createSurface(...){
sp<IGraphicBufferProducer> gbp;
//后面会追踪 mClient的来源,进一步分析其 createSurface()。
status_t err = mClient->createSurface(name, w, h, format, flags,
&handle, &gbp);
sur = new SurfaceControl(this, handle, gbp);
return sur;
}
分析到这里其实还没结束,在上面的函数中,虽然看到了SurfaceControl(c++)生成的地方,sp<IGraphicBufferProducer>gbp这个实例虽然是在这里获取的,但是并不是在创建的,而是由mClient的createSurface()生成的,所以还要接着追踪mClient的由来。
SurfaceComposerClient.cpp
//强指针对象被引用时,会执行其onFirstRef()方法。mClient实质是ISurfaceComposerClient对象。
ISurfaceComposerClient又是来自于ISurfaceComposer的reateConnection(),所以还要继续回溯
ComposerService::getComposerService()。
void SurfaceComposerClient::onFirstRef() {
//这里得到的其实是一个 ISurfaceComposer对象。
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
sp<ISurfaceComposerClient> conn = sm→createConnection();
mClient = conn;
}
代码依然在SurfaceComposerClient.cpp中,ComposerService是其子类:
//重点看instance.mComposerService为null时的调用connectLocked();
sp<ISurfaceComposer> ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked();
}
return instance.mComposerService;
}
//这个函数回去ServiceManager中查询名字为"SurfaceFlinger"的服务,然后通过mComposerService返回查询结果。mComposerService的类型是ISurfaceComposer。
sp<ISurfaceComposer>mComposerService;
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
}
这里有点乱点的是,SurfaceFlinger虽然在ServiceManager中的注册名字是"SurfaceFlinger",但是它对应的Binder接口却是ISurfaceComposer。这个可以从它的继承关系看出:
SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer,private Ibinder::DeathRecipient,
private HWComposer::EventHandler{
}
从上面可以看出SurfaceFlinger继承了BnSurfaceComposer。
IsurfaceComposer.h
//BnInterface是模板类,这里是多继承,BnSurfaceComposer继承了ISurfaceComposer。
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {}
代码再次回到SurfaceComposerClient.cpp中的onFirstRef(),其中的sm->createConnection()调用的就转到了ISurfaceComposer.cpp中,
IsurfaceComposer.cpp
//通过binder把 createConnection的请求发到服务端。
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>{
virtual sp<ISurfaceComposerClient> createConnection(){
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
}
前面分析了SurfaceFlinger继承了BnSurfaceComposer,所以对应的服务端的实现就在SurfaceFlinger中。
SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection(){
sp<ISurfaceComposerClient> bclient;
//这里创建的 Client对象,就是SurfaceComposerClient.cpp的onFirstRef() 中获取的mClient(mClient = conn;),也可以认为Client是SurfaceComposerClient对应的server端的实现。
sp<Client> client(new Client(this));
bclient = client;
return bclient;
}
还记得我们分析这一段的目的是为了查找在创建一个surface(c++)对象时,传入的IGraphicBufferProducer类型的对象是在哪里生成的,起源是在:sp<SurfaceControl>SurfaceComposerClient::createSurface()@SurfaceComposerClient.cpp这个方法中吗?
现在可以接着看其中的mClient->createSurface()的实现了。
Client.cpp
//创建的IGraphicBufferProducer对象,通过指针参数返回。
status_t Client::createSurface(...sp<IGraphicBufferProducer>* gbp){
//函数内部定义了一个MessageBase,
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
MessageCreateLayer(SurfaceFlinger* flinger,...sp<IGraphicBufferProducer>* gbp){
virtual bool handler() {
//在它的handler中调用了surfaceFinger的方法。
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
};
//这里发送的是一个同步的消息,以为这函数结束时,就得到了handler的处理结果。
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),...gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
status_t SurfaceFlinger::createLayer(...sp<IGraphicBufferProducer>* gbp)@SurfaceFlinger.cpp{
sp<Layer> layer;
result = createNormalLayer(client,...handle, gbp, &layer);
}
status_t SurfaceFlinger::createNormalLayer(…
sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer){
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
//把控制layer的句柄取出,赋值给handle,这个handle是应用程序端传过来的(在SurfaceComposerClient.cpp的SurfaceComposerClient::createSurface()方法中的sp<IBinder> handle,这个handle还会传给应用程序端的surfaceControl(cpp))。
*handle = (*outLayer)→getHandle();
//生成一个 IGraphicBufferProducer对象,(MonitoredProducer)
*gbp = (*outLayer)->getProducer();
}
void Layer::onFirstRef()@Layer.cpp {
sp<IGraphicBufferProducer> producer;
mProducer = new MonitoredProducer(producer, mFlinger);
}
上面的代码,surfaceflinger会去创建一个layer,代表了一个画面,屏幕上显示的图像就是一个一个画面的叠加,同时在创建layer的onFirstRef()中,生成了IGraphicBufferProducer对象。Layer中除了生成IGraphicBufferProducer外,这里还创建bufferqueue,IGraphicBufferConsumer实例。
到这里总算知道了surface(c++)对象,其中的IGraphicBufferProducer对象怎么来的了。surface虽然是为应用程序服务的,本质上还是由surfaceflinger来统一管理。
整个过程实在有点绕。
最后
以上就是温婉小土豆为你收集整理的Android7.1 GUI系统中的本地窗口(二)的全部内容,希望文章能够帮你解决Android7.1 GUI系统中的本地窗口(二)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复