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

水深无声 2022-06-05 11:11 382阅读 0赞

先看下Android中本地窗口的定义:

  1. system/core/include/system/window.h
  2. struct AnativeWindow{
  3. //所支持的最小和最大交换间隔时间。
  4. const int minSwapInterval;
  5. const int maxSwapInterval;
  6. //水平方向和垂直方向的密度。
  7. const float xdpi;
  8. const float ydpi;
  9. //这是一个函数指针,egl通过这个接口来申请一个buffer。
  10. int (*dequeueBuffer)(struct ANativeWindow* window,
  11. struct ANativeWindowBuffer** buffer, int* fenceFd);
  12. //egl对一块buffer渲染完成后,调用这个接口来unlock和postbuffer。
  13. int (*queueBuffer)(struct ANativeWindow* window,
  14. struct ANativeWindowBuffer* buffer, int fenceFd);
  15. }

framebuffer ,对应真实的物理设备,它的buffer 来自于帧缓冲区,由gralloc 模块负责管理。

surfaceflinger是系统中UI界面的管理者,它直接或间接的持有本地窗口,在老的android版本中,面向surfaceFlinger的本地窗口是framebuffernativewindow,但是后来的版本framebuffernativewindow被丢弃了,现在只有一种本地窗口surface,继承了ANativeWindow,履行了窗口协议。

面向应用程序端的本地窗口-surface,surface的主要组成部分是Bufferqueue。

Surface.h中可以看到surface的继承关系:

  1. class Surface: public ANativeObjectBase<ANativeWindow, Surface, RefBase>{…}

既然是本地窗口,就要实现ANativeWindow所规范的接口。在它的构造函数中会给ANativeWindow的函数指针赋值。

  1. Frameworks/native/libs/gui/Surface.cpp
  2. //变量很多,没有全部列出,注意其初始化列表中给 mGraphicBufferProducer赋值bufferProducer 。
  3. Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer,bool controlledByApp)
  4. : mGraphicBufferProducer(bufferProducer),
  5. {
  6. //给 ANativeWindow的函数指针赋值。
  7. ANativeWindow::setSwapInterval = hook_setSwapInterval;
  8. ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
  9. ANativeWindow::queueBuffer = hook_queueBuffer;
  10. }

surface是面向系统中所有UI应用程序的,承担着应用程序中的UI显示需求。所以它在面向上层实现(主要java层)时要提供绘制图像的“画板”,这里绘制图像的内存空间是由mGraphicBufferProducer管理的。

还有一点,Surfaceflinger要收集系统中所有应用程序绘制的图像数据,然后合成显示到屏幕,这个过程中Surface需要做些什么呢?

先看下surface中一些成员变量:

这个是surface的核心,管理着内存空间。

spmGraphicBufferProducer;

这是surface内部用于存储buffer的地方,容量由NUM_BUFFER_SLOTS决定,目前是64,BufferQueue会跟踪这个缓冲区的最大值,如果试图在运行时增加这个数量将会失败。

mSlots存储的是为每个bufferslot已经分配的buffers,并初始化为null,当客户端dequeues一个buffer时,使用IGraphicBufferProducer::requestBuffer的返回值来做填充。

BufferSlotmSlots[NUM_BUFFER_SLOTS];

接下来重点看下surface中的dequeueBuffer的过程:

  1. int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd)@Surface.cpp {
  2. // dequeueBuffer会请求一个给客户端使用的buffer slot,也就是buf变量,代表了mSlots数组序号,然后这个slot的所有权就转到了客户端,意味着服务端不在使用跟这个slot相关的buffer的内容。返回的这个slot索引可能包含、也可能不包含buffer,如果不包含客户端就要调用requestBuffer为这个slot分配新的buffer。
  3. 一旦客户端填充了这个buffer,接下来期望是通过两种操作把这个buffer的所有权转给服务端,一种操作是调用cancelBuffer移除这个slot,另一种操作是填充了跟buffer内容相关的内容,然后调用queuebuffer
  4. 如果dequeuebuffer返回的是 BUFFER_NEEDS_REALLOCATION 这个flag,那么客户端立即 调用requestbuffer
  5. status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
  6. reqWidth, reqHeight, reqFormat, reqUsage);
  7. // mGraphicBufferProducer->dequeueBuffer()返回后, buf变量就是mSlots数组中可用成员的序号,接下来就可以通过这个序号来获取真正的buffer的地址,即 mSlots[buf].buffer。
  8. sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
  9. // dequeueBuffer返回了 BUFFER_NEEDS_REALLOCATION,所以调用 requestBuffer申请空间,如果 requestBuffer失败了,调用 cancelBuffer。
  10. if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
  11. result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
  12. if (result != NO_ERROR) {
  13. mGraphicBufferProducer->cancelBuffer(buf, fence);
  14. return result;
  15. }
  16. }
  17. }

执行缓冲区的申请、释放的都是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重新赋值后才有意义。

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

通过Session.java的relayout,调用到Windowmanagerservice的relayoutwindow()。

  1. WindowManagerService.java
  2. public int relayoutWindow(...Surface outSurface) {
  3. result = createSurfaceControl(outSurface, result, win, winAnimator);
  4. }

//这里先让WindowStateAnimator创建一个WindowSurfaceController,在WindowSurfaceController的构造函数中创建了mSurfaceControl(SurfaceControl),然后通过outSurface.copyFrom(mSurfaceControl);把mSurfaceControl复制到mSurface中。

  1. private int createSurfaceControl(Surface outSurface,...){
  2. WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
  3. surfaceController.getSurface(outSurface);
  4. }

//这里通过native接口,创建一个本地的surface(c++)对象。

  1. public void copyFrom(SurfaceControl other) @Surface.java{
  2. long surfaceControlPtr = other.mNativeObject;
  3. long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
  4. }

//这个函数中并没有直接生成surface(c++)对象,而是从SurfaceControl(c++)中提取的。然后通过surface.get()返回一个指向surface(c++)对象的指针。这个get()是强指针(StrongPointer.h)里面的。

那么SurfaceControl(c++)对象是谁来创建的呢?这要追踪surfaceControlNativeObj的来源了。

  1. static jlong nativeCreateFromSurfaceControl(...surfaceControlPtr){
  2. sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
  3. sp<Surface> surface(ctrl->getSurface());
  4. return reinterpret_cast<jlong>(surface.get());
  5. }

/先把SurfaceControl.cpp中生成Surface(c++)的地方列出来,然后在去追踪SurfaceControl(c++)是由谁创建的。

  1. SurfaceControl.cpp
  2. mutable sp<Surface> mSurfaceData;
  3. sp<Surface> SurfaceControl::getSurface() const{
  4. //注意这里的 mGraphicBufferProducer对象,来自与 SurfaceControl的构造函数,如果追到了创建SurfaceControl(c++)对象的地方,也就知道了 mGraphicBufferProducer的来源。
  5. mSurfaceData = new Surface(mGraphicBufferProducer, false);
  6. return mSurfaceData;
  7. }

要追踪SurfaceControl(c++)对象的来源,就是知道surfaceControlNativeObj是怎么来的?再返回到surface.java的copyFrom()函数中。从这个函数中longsurfaceControlPtr =other.mNativeObject;看到,surfaceControlNativeObj来自于SurfaceControl(java)中的mNativeObject。

  1. SurfaceControl.java
  2. long mNativeObject;
  3. public SurfaceControl(...){
  4. mNativeObject = nativeCreate(session, name, w, h, format, flags);
  5. }

mNativeObject是通过native函数创建的。

可以看到SurfaceControl实际是由SurfaceComposerClient来创建的。

  1. static jlong nativeCreate(...)@android_view_SurfaceControl.cpp{
  2. sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
  3. sp<SurfaceControl> surface = client->createSurface(
  4. String8(name.c_str()), w, h, format, flags);
  5. return reinterpret_cast<jlong>(surface.get());
  6. }

//这里生成了本地的surfacecontrol对象,前面在分析SurfaceControl(c++)的getSurface()方法说过找到了创建SurfaceControl(c++)对象的地方,也就找到了IGraphicBufferProducer对象的来源,这个IGraphicBufferProducer实例也是传入到surface(c++)构造函数中对象参数mGraphicBufferProducer,gbp(IGraphicBufferProducer)对象也是在这里传入的

  1. sp<SurfaceControl> SurfaceComposerClient::createSurface(...){
  2. sp<IGraphicBufferProducer> gbp;
  3. //后面会追踪 mClient的来源,进一步分析其 createSurface()。
  4. status_t err = mClient->createSurface(name, w, h, format, flags,
  5. &handle, &gbp);
  6. sur = new SurfaceControl(this, handle, gbp);
  7. return sur;
  8. }

分析到这里其实还没结束,在上面的函数中,虽然看到了SurfaceControl(c++)生成的地方,spgbp这个实例虽然是在这里获取的,但是并不是在创建的,而是由mClient的createSurface()生成的,所以还要接着追踪mClient的由来。

SurfaceComposerClient.cpp

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

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

ComposerService::getComposerService()。

  1. void SurfaceComposerClient::onFirstRef() {
  2. //这里得到的其实是一个 ISurfaceComposer对象。
  3. sp<ISurfaceComposer> sm(ComposerService::getComposerService());
  4. sp<ISurfaceComposerClient> conn = smcreateConnection();
  5. mClient = conn;
  6. }

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

//重点看instance.mComposerService为null时的调用connectLocked();

  1. sp<ISurfaceComposer> ComposerService::getComposerService() {
  2. ComposerService& instance = ComposerService::getInstance();
  3. if (instance.mComposerService == NULL) {
  4. ComposerService::getInstance().connectLocked();
  5. }
  6. return instance.mComposerService;
  7. }

//这个函数回去ServiceManager中查询名字为”SurfaceFlinger”的服务,然后通过mComposerService返回查询结果。mComposerService的类型是ISurfaceComposer。

spmComposerService;

  1. void ComposerService::connectLocked() {
  2. const String16 name("SurfaceFlinger");
  3. while (getService(name, &mComposerService) != NO_ERROR) {
  4. usleep(250000);
  5. }
  6. }

这里有点乱点的是,SurfaceFlinger虽然在ServiceManager中的注册名字是”SurfaceFlinger”,但是它对应的Binder接口却是ISurfaceComposer。这个可以从它的继承关系看出:

SurfaceFlinger.h

  1. class SurfaceFlinger : public BnSurfaceComposer,private Ibinder::DeathRecipient,
  2. private HWComposer::EventHandler{
  3. }

从上面可以看出SurfaceFlinger继承了BnSurfaceComposer。

IsurfaceComposer.h

//BnInterface是模板类,这里是多继承,BnSurfaceComposer继承了ISurfaceComposer。

  1. class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {}

代码再次回到SurfaceComposerClient.cpp中的onFirstRef(),其中的sm->createConnection()调用的就转到了ISurfaceComposer.cpp中,

  1. IsurfaceComposer.cpp
  2. //通过binder把 createConnection的请求发到服务端。
  3. class BpSurfaceComposer : public BpInterface<ISurfaceComposer>{
  4. virtual sp<ISurfaceComposerClient> createConnection(){
  5. remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
  6. return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
  7. }
  8. }

前面分析了SurfaceFlinger继承了BnSurfaceComposer,所以对应的服务端的实现就在SurfaceFlinger中。

  1. SurfaceFlinger.cpp
  2. sp<ISurfaceComposerClient> SurfaceFlinger::createConnection(){
  3. sp<ISurfaceComposerClient> bclient;
  4. //这里创建的 Client对象,就是SurfaceComposerClient.cpp的onFirstRef() 中获取的mClient(mClient = conn;),也可以认为Client是SurfaceComposerClient对应的server端的实现。
  5. sp<Client> client(new Client(this));
  6. bclient = client;
  7. return bclient;
  8. }

还记得我们分析这一段的目的是为了查找在创建一个surface(c++)对象时,传入的IGraphicBufferProducer类型的对象是在哪里生成的,起源是在:spSurfaceComposerClient::createSurface()@SurfaceComposerClient.cpp这个方法中吗?

现在可以接着看其中的mClient->createSurface()的实现了。

Client.cpp

//创建的IGraphicBufferProducer对象,通过指针参数返回。

  1. status_t Client::createSurface(...sp<IGraphicBufferProducer>* gbp){
  2. //函数内部定义了一个MessageBase,
  3. class MessageCreateLayer : public MessageBase {
  4. SurfaceFlinger* flinger;
  5. MessageCreateLayer(SurfaceFlinger* flinger,...sp<IGraphicBufferProducer>* gbp){
  6. virtual bool handler() {
  7. //在它的handler中调用了surfaceFinger的方法。
  8. result = flinger->createLayer(name, client, w, h, format, flags,
  9. handle, gbp);
  10. return true;
  11. }
  12. };
  13. //这里发送的是一个同步的消息,以为这函数结束时,就得到了handler的处理结果。
  14. sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),...gbp);
  15. mFlinger->postMessageSync(msg);
  16. return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
  17. }
  18. status_t SurfaceFlinger::createLayer(...sp<IGraphicBufferProducer>* gbp)@SurfaceFlinger.cpp{
  19. sp<Layer> layer;
  20. result = createNormalLayer(client,...handle, gbp, &layer);
  21. }
  22. status_t SurfaceFlinger::createNormalLayer(…
  23. sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer){
  24. *outLayer = new Layer(this, client, name, w, h, flags);
  25. status_t err = (*outLayer)->setBuffers(w, h, format, flags);
  26. //把控制layer的句柄取出,赋值给handle,这个handle是应用程序端传过来的(在SurfaceComposerClient.cpp的SurfaceComposerClient::createSurface()方法中的sp<IBinder> handle,这个handle还会传给应用程序端的surfaceControl(cpp))。
  27. *handle = (*outLayer)→getHandle();
  28. //生成一个 IGraphicBufferProducer对象,(MonitoredProducer)
  29. *gbp = (*outLayer)->getProducer();
  30. }
  31. void Layer::onFirstRef()@Layer.cpp {
  32. sp<IGraphicBufferProducer> producer;
  33. mProducer = new MonitoredProducer(producer, mFlinger);
  34. }

上面的代码,surfaceflinger会去创建一个layer,代表了一个画面,屏幕上显示的图像就是一个一个画面的叠加,同时在创建layer的onFirstRef()中,生成了IGraphicBufferProducer对象。Layer中除了生成IGraphicBufferProducer外,这里还创建bufferqueue,IGraphicBufferConsumer实例。

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

整个过程实在有点绕。

发表评论

表情:
评论列表 (有 0 条评论,382人围观)

还没有评论,来说两句吧...

相关阅读