android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论
GUI 是任何系统都很重要的一块。
android GUI大体分为4大块。
1)SurfaceFlinger
2)WMS
3)View机制
4)InputMethod
这块内容非常之多,但是理解后,可以触类旁通,其实现在主流的系统,包括andorid,ios在构架上,都是有很多相识之处。
我们先来讲SurfaceFlinger
1.OpenGL & OpenGL ES
OPenGL ES 是android系统绘画的基础。关于OpenGL部分,可以百度了解下。
先来看一个OpenGL & SurfaceFlinger之间的框架图:
2.Android的硬件接口HAL
2.1硬件接口的抽象
2.2接口的稳定性
Android已经把各个硬件都接口都统一定义在:
libhardware/include/hardware/ 具体代码可以参考:https://github.com/CyanogenMod/android_hardware_libhardware/tree/cm-12.0/include/hardware
3.Android显示设备:Gralloc & FrameBuffer
3.1Gralloc模块的加载
FramebufferNativeWindow::FramebufferNativeWindow() : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false) {hw_module_t const* module;if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {int stride;int err;int i;err = framebuffer_open(module, &fbDev);ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));err = gralloc_open(module, &grDev);ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));// bail out if we can't initialize the modulesif (!fbDev || !grDev)return;mUpdateOnDemand = (fbDev->setUpdateRect != 0);// initialize the buffer FIFOif(fbDev->numFramebuffers >= MIN_NUM_FRAME_BUFFERS &&fbDev->numFramebuffers <= MAX_NUM_FRAME_BUFFERS){mNumBuffers = fbDev->numFramebuffers;} else {mNumBuffers = MIN_NUM_FRAME_BUFFERS;}mNumFreeBuffers = mNumBuffers;mBufferHead = mNumBuffers-1;/** This does not actually change the framebuffer format. It merely* fakes this format to surfaceflinger so that when it creates* framebuffer surfaces it will use this format. It's really a giant* HACK to allow interworking with buggy gralloc+GPU driver* implementations. You should *NEVER* need to set this for shipping* devices.*/ #ifdef FRAMEBUFFER_FORCE_FORMAT*((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT; #endiffor (i = 0; i < mNumBuffers; i++){buffers[i] = new NativeBuffer(fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);}for (i = 0; i < mNumBuffers; i++){err = grDev->alloc(grDev,fbDev->width, fbDev->height, fbDev->format,GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",i, fbDev->width, fbDev->height, strerror(-err));if (err){mNumBuffers = i;mNumFreeBuffers = i;mBufferHead = mNumBuffers-1;break;}}const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval;const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval;} else {ALOGE("Couldn't get gralloc module");}ANativeWindow::setSwapInterval = setSwapInterval;ANativeWindow::dequeueBuffer = dequeueBuffer;ANativeWindow::queueBuffer = queueBuffer;ANativeWindow::query = query;ANativeWindow::perform = perform;ANativeWindow::dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED;ANativeWindow::lockBuffer_DEPRECATED = lockBuffer_DEPRECATED;ANativeWindow::queueBuffer_DEPRECATED = queueBuffer_DEPRECATED; }
FramebufferNativeWindow
我们继续深入看:
galloc的父类,最终是:
libhardware\include\hardware\hardware.h
typedef struct hw_module_methods_t {/** Open a specific device */int (*open)(const struct hw_module_t* module, const char* id,struct hw_device_t** device);} hw_module_methods_t;
只有一个open方法,也就是所有的厂商都需要实现开启设备的方法。
看下fb的打开的代码:
libhardware\modules\gralloc\framebuffer.cpp
int fb_device_open(hw_module_t const* module, const char* name,hw_device_t** device) {int status = -EINVAL;if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {/* initialize our state here */fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));memset(dev, 0, sizeof(*dev));/* initialize the procs */dev->device.common.tag = HARDWARE_DEVICE_TAG;dev->device.common.version = 0;dev->device.common.module = const_cast<hw_module_t*>(module);dev->device.common.close = fb_close;dev->device.setSwapInterval = fb_setSwapInterval;dev->device.post = fb_post;dev->device.setUpdateRect = 0;private_module_t* m = (private_module_t*)module;status = mapFrameBuffer(m);if (status >= 0) {int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);int format = (m->info.bits_per_pixel == 32)? (m->info.red.offset ? HAL_PIXEL_FORMAT_BGRA_8888 : HAL_PIXEL_FORMAT_RGBX_8888): HAL_PIXEL_FORMAT_RGB_565;const_cast<uint32_t&>(dev->device.flags) = 0;const_cast<uint32_t&>(dev->device.width) = m->info.xres;const_cast<uint32_t&>(dev->device.height) = m->info.yres;const_cast<int&>(dev->device.stride) = stride;const_cast<int&>(dev->device.format) = format;const_cast<float&>(dev->device.xdpi) = m->xdpi;const_cast<float&>(dev->device.ydpi) = m->ydpi;const_cast<float&>(dev->device.fps) = m->fps;const_cast<int&>(dev->device.minSwapInterval) = 1;const_cast<int&>(dev->device.maxSwapInterval) = 1;*device = &dev->device.common;}}return status; }
首先check设备名是否正确。
status = mapFrameBuffer(m);
然后是建立壳 & 核心间的关系。
这样就打开了fb设备。
在回到FrameBufferNativeWindow 可以看到:
err = framebuffer_open(module, &fbDev);ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));err = gralloc_open(module, &grDev);ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
fb打开的驱动信息在fbDev,gralloc打开的信息在grDev中。
fbDev负责的是主屏幕,grDev负责图形缓冲去的分配和释放。
所以FrameBufferNativeWindow控制这SurfaceFlinger的基础。
4.FrameBufferNativeWindow
4.1FramebufferNativeWindow
在OpenGL中,我们不断提及本地窗口的概念,在Android中,native window一共由2个。
首先看下定义的地方:
class FramebufferNativeWindow : public ANativeObjectBase<ANativeWindow, FramebufferNativeWindow, LightRefBase<FramebufferNativeWindow> > {
ANativeWindow是什么东西?
ANativeWindow是OpenGL 在android平台的显示类型。
所以FramebufferNativeWindow就是一种Open GL可以显示的类型。
FramebufferNativeWindow的构造函数上面已经贴出来了,进一步分析如下:
1)加载module,上面已经分析过了。
2)打开fb & gralloc,也已经分析过了。
3)根据fb的设备属性,获得buffer数。这个buffer后面会解释。
4)给每个buffer初始化,并分配空间。这里new NativeBuffer只是指定buffer的类型,或者分配了一个指针,但是没有分配内存,所以还需要alloc操作。
5)为本地窗口属性赋值。
目前buffer默认值是在2~3,后面会介绍3缓冲技术,就会用到3个buffer。
双缓冲技术:
把一组图画,画到屏幕上,画图是需要时间的,如果时间间隔比较长,图片就是一个一个的画在屏幕的,看上去就会卡。
如果先把图片放在一个缓冲buffer中,待全部画好后,把buffer直接显示在屏幕上,这就是双缓冲技术。
4.2dequeuebuffer
int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) {FramebufferNativeWindow* self = getSelf(window);Mutex::Autolock _l(self->mutex);framebuffer_device_t* fb = self->fbDev;int index = self->mBufferHead++;if (self->mBufferHead >= self->mNumBuffers)self->mBufferHead = 0;// wait for a free non-front bufferwhile (self->mNumFreeBuffers < 2) {self->mCondition.wait(self->mutex);}ALOG_ASSERT(self->buffers[index] != self->front);// get this bufferself->mNumFreeBuffers--;self->mCurrentBufferIndex = index;*buffer = self->buffers[index].get();*fenceFd = -1;return 0; }
代码不多,但是却是核心功能,通过它来获取一块可渲染的buffer。
1)获取FramebufferNativeWindow对象。为什么没有使用this 而是使用了传入ANativeWindow的方式,此处我们并不关心。
2)获得一个Autolock的锁,函数结束,自动解锁。
3)获取mBufferHead变量,这里自增,也就是使用下一个buffer,一共只有3个,(原因上面已经解释),所以循环取值。
4)如果没有可用的缓冲区,等待bufferqueue释放。一旦获取后,可用buffer就自减
5.Surface
Surface是另一个本地窗口,主要和app这边交互。注意:app层java代码无法直接调用surface,只是概念上surface属于app这一层的。
首先Surface是ANativeWindow的一个子类。
可以推测,surface需要解决如下几个问题:
1)面向上层(java层)提供画板。由谁来分配这块内存
2)与SurfaceFlinger是什么关系
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer,bool controlledByApp)
sp<IGraphicBufferProducer>& bufferProducer 是分配surface内存的。它到底是什么呢?
SurfaceFlinger::SurfaceFlinger(): BnSurfaceComposer(),
SurfaceFlinger是BnSurfaceComposer的一个子类。也就是ISurfaceComposer的一个实现。
surface虽然是为app层服务的,但是本质上还是由SurfaceFlinger来管理的。
SurfaceFlinger怎么创建和管理surface,需要通过BufferQueue,将在下一篇讨论。
参考:
《深入理解android内核设计思想》 林学森
转载于:https://www.cnblogs.com/deman/p/5584198.html
android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论相关推荐
- Android GUI系统之SurfaceFlinger(01)显示系统框架
该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录 本章关键点总结 & 说明: 本章节思维导图如上.主要讲述了显示系统的基础,了解FrameBuffer ...
- 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)
Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...
- Android GUI系统框架介绍
这个又是内部技术分享时准备的PPT,Android GUI框架是一个非常庞大的系统,也是Android最重要的系统之一,其决定了一个Android界面究竟如何显示出来,显示效果/效率怎样,也一直是An ...
- 图解Android - Android GUI 系统 (1) - 概论
http://www.cnblogs.com/samchen2009/p/3364327.html Android的GUI系统是Android最重要也最复杂的系统之一.它包括以下部分: 窗口和图形系统 ...
- android ams wms view,android Gui系统之WMS(1)
SurfaceFlinger 前面说的,就是一个surface的合成.SurfaceFlinger就是一个默默的记录着,它不会对surface的内容有什么改动. WMS(WindowsManagerS ...
- android 系统的组成,简析Android 的GUI 系统组成
GUI是图形用户界面,是Graphical User Interface的缩写,又称图形用户接口,其是指采用图形方式显示的计算机操作用户界面.与早期计算机使用的命令行界面相比,图形界面对于用户来说在视 ...
- android 输入法框架,Android输入系统(2)——输入系统框架(Android+Linux)
1.优秀文档 android输入系统官方文档:http://source.android.com/devices/input/index.html 中文官方文档 <深入理解Android 卷II ...
- android dispatch input输入子系统,10.12 android输入系统_InputStage理论
android应用程序对输入系统的处理分为多个阶段,我们把这些阶段称为InputStage 理论处理流程: (1)activity发给window,如果window不能处理,再由activity处理; ...
- c语言调用android surface,Android GUI SurfaceFlinger
本文涉及的源代码基于 Android-7.1.1r. 一.Android GUI 框架 SurfaceFlinger 是 Android GUI 的核心,但是从 OpenGL_ES 的角度来看,它也只 ...
最新文章
- 搭建nginx服务、nginx的升级安装、Nginx配置文件的解析、web页面用户认证
- 图书资料管理课程设计(附源码和连接)
- oracle怎么判断是裸设备安装,Oracle 9i下以裸设备方式安装数据库
- 实战Kaggle比赛(1):树叶分类
- jdbctype 对应java_MyBatis配置Mapping,JavaType和JDBCType的对应关系
- mysql全文索引中文问题的解决(转)
- python三方库之paramiko
- 李廷伟:可穿戴技术引领物联网创新新浪潮
- 【elasticsearch】You AutoComplete Me
- 可靠的Windows版Redis
- hdu 6129	 Just do it
- 【上外青年】人物 ‖ 何晗:天才都是异类
- 华为+android+root权限获取root,华为emui5.0系统如何root?华为荣耀v8 emui5.0获取7.0系统的root权限方法...
- Python基础学习笔记-第一章
- kali永久获取root权限
- linux 下进入root
- debian/ubuntu 64bit 安装 android sdk时adb无法编译的问题
- 洛阳理工学院linux实验报告,谁来给我抄实验报告啊!这一张又一张写得。。。。...
- 海思入门笔记二:HiBurn工具实现镜像烧写
- 机器学习概述----机器学习并没有那么深奥,它很有趣(2)
热门文章
- 互联网日报 | 4月19日 星期一 | 华为将持续加大汽车行业投入;瑞幸首家咖啡烘焙基地投产;2021年中国电影票房突破200亿...
- css:块元素、行内元素、行内块元素以及三种元素之间的转换
- 科技科幻风格的RPG像素游戏室内地图素材包
- 独特画风-rpgmaker复古像素游戏素材
- Pytorch | yolov3原理及代码详解(二)
- SAR图像飞机目标检测识别进展
- ios手机访问服务器文件共享,iOS/iPhone访问Windows/Mac的共享文件(网上邻居)
- linux获取中括号内容,shell里使用正则表达式提取括号中的内容
- scratch编程 蓝桥杯编程题 红绿灯
- python监视电脑桌面_Python爬虫练习:爬取高清壁纸,让你电脑桌面一天一换