SurfaceFlinger在前面的篇幅了,多有涉及。android
SurfaceFlinger是GUI刷新UI的核心,因此任何关于SurfaceFlinger的改进都会对android UI系统有重大影响。app
SurfaceFlinger主要分为4个部分函数
1)黄油计划---project butteroop
2)启动过程post
3)SurfaceFlinger & BufferQueue的关系性能
4)Vsync信号的处理ui
就是给android系统,图上一层“黄油”。咱们来看看andorid是怎么给SurfaceFlinger涂上这层黄油的。this
butter 由2个组成部分,Vsync & Triple buffer。spa
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
咱们看看这张图。
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; } } }
任何有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内核设计思想》 林学森