推荐下载Android71 GUI系统中的本地窗口二.docx

上传人:b****1 文档编号:1285369 上传时间:2022-10-20 格式:DOCX 页数:19 大小:22.35KB
下载 相关 举报
推荐下载Android71 GUI系统中的本地窗口二.docx_第1页
第1页 / 共19页
推荐下载Android71 GUI系统中的本地窗口二.docx_第2页
第2页 / 共19页
推荐下载Android71 GUI系统中的本地窗口二.docx_第3页
第3页 / 共19页
推荐下载Android71 GUI系统中的本地窗口二.docx_第4页
第4页 / 共19页
推荐下载Android71 GUI系统中的本地窗口二.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

推荐下载Android71 GUI系统中的本地窗口二.docx

《推荐下载Android71 GUI系统中的本地窗口二.docx》由会员分享,可在线阅读,更多相关《推荐下载Android71 GUI系统中的本地窗口二.docx(19页珍藏版)》请在冰豆网上搜索。

推荐下载Android71 GUI系统中的本地窗口二.docx

推荐下载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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 冶金矿山地质

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1