android Gui系统之SurfaceFlinger(3)---SurfaceFlinger

7.SurfaceFlinger

SurfaceFlinger在前面的篇幅了,多有涉及。android

SurfaceFlinger是GUI刷新UI的核心,因此任何关于SurfaceFlinger的改进都会对android UI系统有重大影响。app

SurfaceFlinger主要分为4个部分函数

1)黄油计划---project butteroop

2)启动过程post

3)SurfaceFlinger & BufferQueue的关系性能

4)Vsync信号的处理ui

7.1黄油计划

就是给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

咱们看看这张图。

刚开始buffer里面有数据A,这时候,能够直接显示在屏幕上。
过了16ms之后,数据B还没准备好,屏幕只能继续显示A。这样就浪费了依次交换的机会。
到下一次交换,B被显示在屏幕上。 这里有段时间被浪费了。
等到下一次A的时候,过了16ms,仍是没有准备好,继续浪费。因此双缓冲区技术,也有很大浪费。
有没有办法规避呢,
好比上图 B & A之间的这段时间,若是我增长一个buffer,C。
这样B准备好之后,虽然C没有好,可是B能够显示在屏幕上,等到下一次16ms到了之后,C已经准备好了,这样能够很大程度上减小CPU时间的浪费。
也就是空间换时间的一种思想。
因此多缓冲区就是,就是能够根据系统的实际内存状况,来判断buffer的数量。
 

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内核设计思想》 林学森

相关文章
相关标签/搜索