深入Android系统(十二)Android图形显示系统-2-SurfaceFlinger与图像输出

OpenGL ESEGL

OpenGL

一般OpenGL被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。

OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现的,将由OpenGL库的开发者自行决定

实际的OpenGL库的开发者通常是显卡的生产商

OpenGL ES(OpenGL for Embedded Systems) 是从OpenGL裁剪的定制而来的,去除了一些复杂图元等许多非绝对必要的特性

OpenGL还是很值得学习的,大家可以参考:LearnOpenGL教程的中文翻译

EGL

我们知道OpenGL ES定义了一个渲染图形的API,但没有定义窗口系统。

为了让OpenGL ES能够适合各种平台,OpenGL ES需要与一个知道如何通过操作系统创建和访问窗口的库结合使用

Android中的这个库就是EGL。(没有什么问题是不能通过增加一个中间层来解决的,有的话那就再增加一个。。。。。)

整体结构如下(网上盗图): image

EGL的用法

使用EGL绘制的一般步骤如下:

  • 获取 EGL Display 对象:eglGetDisplay()
  • 初始化与 EGLDisplay 之间的连接:eglInitialize()
  • 获取 EGLConfig 对象:eglChooseConfig()
  • 创建 EGLContext 实例:eglCreateContext()
  • 创建 EGLSurface 实例:eglCreateWindowSurface()
  • 连接 EGLContext 和 EGLSurface:eglMakeCurrent()
  • 使用 OpenGL ES API 绘制图形:gl_*()
  • 切换 front buffer 和 back buffer 送显:eglSwapBuffer()
  • 断开并释放与 EGLSurface 关联的 EGLContext 对象:eglRelease()
  • 删除 EGLSurface 对象
  • 删除 EGLContext 对象
  • 终止与 EGLDisplay 之间的连接

Android中的封装

前面的章节我们介绍过,无论开发者使用什么渲染API,一切内容都会渲染到Surface

  • 此处的Surface指的是framework/native/libs/gui/Surface.cpp对应的业务逻辑

SurfaceFlinger以消费者的角色获取到显示数据后,会开始进行渲染操作,在过程中也存在一个Surface

  • 定义在framework/native/services/surfaceflinger/RenderEngine/Surface.cpp
Surface::Surface(const RenderEngine& engine)
mEGLDisplay(engine.getEGLDisplay()), mEGLConfig(engine.getEGLConfig()) {

}
Surface::~Surface() {
setNativeWindow(nullptr);
}
void Surface::setNativeWindow(ANativeWindow* window) {

if (mWindow) {
mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mWindow, nullptr);
}
}
void Surface::swapBuffers() const {
if (!eglSwapBuffers(mEGLDisplay, mEGLSurface)) {

}
}
EGLint Surface::queryConfig(EGLint attrib) const {
EGLint value;
if (!eglGetConfigAttrib(mEGLDisplay, mEGLConfig, attrib, &value)) {
value = 0;
}
return value;
}
EGLint Surface::querySurface(EGLint attrib) const {
EGLint value;
if (!eglQuerySurface(mEGLDisplay, mEGLSurface, attrib, &value)) {
value = 0;
}
return value;
}

接口定义结合上面EGL的知识应该很容易理解,下面我们开始SurfaceFlinger学习吧

SurfaceFlinger的启动过程

Android 4.4开始SurfaceFlinger服务运行在一个独立的守护进程中(以前在SystemServer中),这样系统的图像绘制性能会得到一定的提升。frameworks/native/services/surfaceflinger/surfaceflinger.rc中关于SurfaceFlinger的定义如下:

service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote

可以看到surfaceflinger放到了core组里,这个组的服务会在系统初始化时启动。SurfaceFlinger启动的入口函数main()代码如下:

int main(int, char**) {

// 启动 Gralloc 服务
startGraphicsAllocatorService();
// 设置当前Binder服务可连接最大线程数
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// 通过 startThreadPool 通知 Binder 驱动当前线程已准备完成
sp ps(ProcessState::self());
ps->startThreadPool();
// 初始化 SurfaceFlinger
sp flinger = new SurfaceFlinger();
// 调整进程优先级为 PRIORITY_URGENT_DISPLAY
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
// 调整调度策略,将其设置为前台进程
// 这两种标志涉及了内核的 完全公平调度算法,感兴趣的同学可以百度一下
// 在这里的目的是保证 SurfaceFlinger 的较高优先级,方便快速响应更新图像的请求
set_sched_policy(0, SP_FOREGROUND);

// 注册 Service 前的初始化部分
flinger->init();
// 注册 SurfaceFlinger 服务
sp sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// 注册 GpuService 服务
sp gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
// 启动 DisplayService 服务
startDisplayService(); // dependency on SF getting registered above

// run surface flinger in this thread
flinger->run();
return 0;
}

main()方法中注释比较详细就不细说了,方法总结下来有三点:

  • 初始化GraphicsAllocatorServiceDisplayServiceGpuService服务
  • set_sched_policysched_setscheduler设置进程优先级
  • SurfaceFlinger对象的初始化以及initrun方法的调用

SurfaceFlinger的初始化过程设计的模块比较多,我们先简单看下类关系图:
image

SurfaceFlinger对象初始化

SurfaceFlinger的类定义如下:

class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback
{}

  • BnSurfaceComposer类:类图中该类实现的是ISurfaceComposer接口,而ISurfaceComposer又是一套定义好的Binder
  • Binder篇提到过,当出现Bn*开头的类就可以把它看做Binder服务类了,所以SurfaceFlinger这里是作为一个Binder服务对象
  • 上一篇在SurfaceSession初始化时,SurfaceComposerClient对象就是通过ServiceManager获取了SurfaceFlinger服务
  • 然后通过服务提供的createConnection()方法获取了ISurfaceComposerClient对象,也就是上面类图中提到的Client
  • HWC2::ComposerCallback类:面向底层硬件状态的监听回调接口,包括
  • onHotplugReceived,显示屏热插拔事件回调
  • onRefresh
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值