Android7.1 GUI系统中的本地窗口(二)

时间:2022-04-30 03:52:26

先看下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决定,目前是64BufferQueue会跟踪这个缓冲区的最大值,如果试图在运行时增加这个数量将会失败。


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;
		}
	}
}

执行缓冲区的申请、释放的都是mGraphicBufferProducerIGraphicBufferProducer),那么surface中的这个mGraphicBufferProducer是怎么来的?前面在说surface的构造函数时,提到在它的初始化列表中给mGraphicBufferProducer赋的值,所以就要跟踪谁创建了这个surface(cpp)实例。

大致过程:在应用程序启动时把view树注册到Windowmanagerservice之前,或者是窗口的可见性、大小属性发生了变化,都会执行一次view树的遍历,在这个过程中会调用relayoutWindow(ViewRootImpl.java)重新布局窗口,其中会调用mWindowSession.relayout()来让Windowmanagerservicesurfaceflinger申请“画板”,然后通过relayout()中的出参mSurface将结果值返回。


下面就来看下这个过程,主要想弄清楚两点:一是谁创建了本地层的surface(cpp),二是谁创建了IGraphicBufferProducer实例。

下面代码省略无关的参数,代码段。


ViewRootImpl.java

//这里虽然创建了一个surface实例,其实是一个空壳,因为它内部没有承载UI数据的画板。要通过relayout重新赋值后才有意义。


final Surface mSurface = new Surface();
private int relayoutWindow(...){
	int relayoutResult = mWindowSession.relayout(...mSurface);
}

通过Session.javarelayout,调用到Windowmanagerservicerelayoutwindow()


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.javacopyFrom()函数中。从这个函数中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++)构造函数中对象参数mGraphicBufferProducergbp(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这个实例虽然是在这里获取的,但是并不是在创建的,而是由mClientcreateSurface()生成的,所以还要接着追踪mClient的由来。


SurfaceComposerClient.cpp

//强指针对象被引用时,会执行其onFirstRef()方法。mClient实质是ISurfaceComposerClient对象。

ISurfaceComposerClient又是来自于ISurfaceComposerreateConnection(),所以还要继续回溯

ComposerService::getComposerService()


void SurfaceComposerClient::onFirstRef() {
//这里得到的其实是一个 ISurfaceComposer对象。
	sp<ISurfaceComposer> sm(ComposerService::getComposerService());
	sp<ISurfaceComposerClient> conn = sm→createConnection();
	mClient = conn;
}

代码依然在SurfaceComposerClient.cpp中,ComposerService是其子类:

//重点看instance.mComposerServicenull时的调用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,代表了一个画面,屏幕上显示的图像就是一个一个画面的叠加,同时在创建layeronFirstRef()中,生成了IGraphicBufferProducer对象。Layer中除了生成IGraphicBufferProducer外,这里还创建bufferqueueIGraphicBufferConsumer实例。

到这里总算知道了surface(c++)对象,其中的IGraphicBufferProducer对象怎么来的了。surface虽然是为应用程序服务的,本质上还是由surfaceflinger来统一管理。

整个过程实在有点绕。