android Gui系统之SurfaceFlinger(3)---SurfaceFlinger
7.SurfaceFlinger
SurfaceFlinger在前面的篇幅了,多有涉及。
SurfaceFlinger是GUI刷新UI的核心,所以任何关于SurfaceFlinger的改进都会对android UI系统有重大影响。
SurfaceFlinger主要分为4个部分
1)黄油计划---project butter
2)启动过程
3)SurfaceFlinger & BufferQueue的关系
4)Vsync信号的处理
7.1黄油计划
就是给android系统,图上一层“黄油”。我们来看看andorid是怎么给SurfaceFlinger涂上这层黄油的。
butter 由2个组成部分,Vsync & Triple buffer。
Triple buffer:
上面讲到双缓冲区技术,也提到FrameBufferNativeWindow 在申请buffer的时候,可以是2,或者是3.
这个3 就是马上要讲到的Triple Buffer技术。
我们先会过来看看双缓冲技术。
之前说 双缓冲,是把一个buffer放在bitmap上,等到这个所有元素都准备好以后,在把bitmap刷到屏幕上。
这样会解决卡顿的感觉。
我们考虑一种情况,假设屏幕刷新频率是66Hz,CPU频率是100Hz.
之前已经讲了双缓冲技术,这里简单过一下。
如上面的假设,UI的刷新是0.015s,而buffer的准备是0.01s
一个Frame Buffer代表一帧图像。
0.01s:
此时,buffer已经准备好数据,而显示器只显示了图像的2/3
0.015s
显示器显示了第一帧图像,而buffer已经填充了第二帧的1/3
0.02s
Buffer已经准备好了第二帧,而显示器出现了问题,1/3的内容属于第二帧,2/3的内容属于第一帧。
这就是android引入双缓冲技术的原因。
如果buffer准备的时间,比屏幕刷新图像的速度慢呢?
显示屏的每一次刷新,就是对显示器屏幕的扫描,但是它是有间隔的(物理设备嘛,肯定有这个间隔)。
典型的PC显示器屏幕刷新频率是60Hz,这是因为一秒60帧,从人的角度看,就会觉得很流畅。
所以间隔1/60秒,也就是16ms 如果我们准备时间<=16ms,那就可以做到“无缝连接”。画面就很流程。
这段空隙称为VBI。 这个时间就是交换缓冲区最佳的时间。而这个交换的动作就是Vsync 也是SurfaceFlinger的重点。
如果我们图像准备时间<=16ms. OK,画面是很流畅的,但是我们无法保证设备性能一定很very good。所以也有可能画面准备时间超过16ms
我们看看这张图。
7.2 SurfaceFlinger的启动
SurfaceFlinger 我们前面已经说了,它其实就是一个service。
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
初始化事件队列。
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
创建了looper & Handler
但是这个looper什么时候起来的呢?
void MessageQueue::waitMessage() {
do {
IPCThreadState::self()->flushCommands();
int32_t ret = mLooper->pollOnce(-1);
switch (ret) {
case Looper::POLL_WAKE:
case Looper::POLL_CALLBACK:
continue;
case Looper::POLL_ERROR:
ALOGE("Looper::POLL_ERROR");
case Looper::POLL_TIMEOUT:
// timeout (should not happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce() returned unknown status %d", ret);
continue;
}
} while (true);
}
可以看到最终会调用looper启动函数。可以看到Looper::POLL_TIMEOUT: android什么都没做,尽管它们不应该发生。
其实handler兜了一圈,发现最后还是回到surfaceflinger来处理:
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::TRANSACTION: {
handleMessageTransaction();
break;
}
case MessageQueue::INVALIDATE: {
bool refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
refreshNeeded |= mRepaintEverything;
if (refreshNeeded) {
// Signal a refresh if a transaction modified the window state,
// a new buffer was latched, or if HWC has requested a full
// repaint
signalRefresh();
}
break;
}
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}
7.3 client
任何有UI界面App都在surfaceflinger里面有client。
所以是一个app对应一个surfaceflinger里面的client(ISurfaceComposerClient)。

下面我们来分析surfaceflinger的2个重要函数:
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
返回ISurfaceComposerClient,也就是client的bind对象实体。
其实就上面标红的一句,进行必要的有效性检查,现在代码:
status_t Client::initCheck() const {
return NO_ERROR;
}
有了clinet以后,看下surface的产生。
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/ class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
}; sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
到来到去,其实就2句话:
postMessageSync,其实就是一开始不会直接创建surface,然后放入surfaceflinger队列里,这样不会打断现在的操作。
然后启动createlayer方法。这个方法之前已经分析过了。
参考:
《深入理解android内核设计思想》 林学森
android Gui系统之SurfaceFlinger(3)---SurfaceFlinger的更多相关文章
- Android GUI系统
图解Android - Android GUI 系统 (1) - 概论 图解Android - Android GUI 系统 (2) - 窗口管理系统 图解Android - Android GUI ...
- 图解Android - System Service 概论 和 Android GUI 系统
通过 图解Android - Binder 和 Service 一文中,我们已经分析了Binder 和 Service的工作原理.接下来,我们来简要分析Android 系统里面都有哪些重要的Servi ...
- 图解Android - Android GUI 系统 (1) - 概论
Android的GUI系统是Android最重要也最复杂的系统之一.它包括以下部分: 窗口和图形系统 - Window and View Manager System. 显示合成系统 - Surfac ...
- 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)
Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...
- 图解Android - Android GUI 系统 (5) - Android的Event Input System
Android的用户输入处理 Android的用户输入系统获取用户按键(或模拟按键)输入,分发给特定的模块(Framework或应用程序)进行处理,它涉及到以下一些模块: Input Reader: ...
- android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论
GUI 是任何系统都很重要的一块. android GUI大体分为4大块. 1)SurfaceFlinger 2)WMS 3)View机制 4)InputMethod 这块内容非常之多,但是理解后,可 ...
- android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论【转】
转自:https://www.cnblogs.com/deman/p/5584198.html 阅读目录 1.OpenGL & OpenGL ES 2.Android的硬件接口HAL 3.An ...
- android Gui系统之SurfaceFlinger(4)---Vsync(1)
8.Vsync 8.1概论 VSYNC(Vertical Synchronization)是一个相当古老的概念,对于游戏玩家,它有一个更加大名鼎鼎的中文名字—-垂直同步. “垂直同步(vsync)”指 ...
- android Gui系统之SurfaceFlinger(5)---Vsync(2)
9.Vsync第二部分 在上一篇中我们讲到,视图的刷新需要很多步骤, void SurfaceFlinger::handleMessageRefresh() { ATRACE_CALL(); preC ...
随机推荐
- 关于CodeFirst异常:无法确定类型'XXX'和类型‘YYY’之间的关联的主体端,必须使用关系 Fluent API 或数据注释显式配置此关联的主体端。
此错误的原因是,你配置两个实体间的关系为一对一 然而我认为的一对一关系是,两者之间必须存在一个主体, 也就是说,你不能表1的外键是表2的主键并且表1的主键是表2的外键, 这样不符合数据库式吧? 我想多 ...
- UML - 类图
在UML类图中,有以下几种常见关系: 泛化 - Generalization "is-a",继承关系,表示一般与特殊的关系: 子类(接口)特化父类(接口)的所有特征和行为,是对象之 ...
- 半连通分量--Tarjan/Kosaraju算法
一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- FMX 讯息框 FrameDialog
说明:目前 Delphi XE5 无法在 Android 平台下正常使用 ShowMessage 或 MessageDlg 功能(当失去焦点后会当机,如关闭屏幕后再开),这里展示如何使用 TFrame ...
- python signal(信号)
信号的概念 信号(signal)-- 进程之间通讯的方式,是一种软件中断.一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号. 几个常用信号: SIGINT 终止进程 中断进 ...
- NOSQL学习笔记系列之MongoDB 一 基础
主题:MongoDB 学习资料参考网址: 1.http://www.w3cschool.cc/mongodb/mongodb-tutorial.html 2.http://www.icoolxue.c ...
- [转]PHP5 session 详解
来源:http://blog.163.com/lgh_2002/blog/static/4401752620105246517509/ http协议是WEB服务器与客户 端(浏览器)相互通信的协议,它 ...
- C#微信公众平台开发者模式开启代码
using System;using System.IO;using System.Text;using System.Web.Security; namespace HPZJ.Web.sys.exc ...
- 【转】从MVC到前后端分离
1. 理解MVC MVC是一种经典的设计模式,全名为Model-View-Controller,即模型-视图-控制器. 其中,模型是用于封装数据的载体,例如,在Java中一般通过一个简单的POJO(P ...