Android6.0 显示系统(五) SurfaceFlinger服务

SurfaceFlinger是一个独立的进程,我们来看下init.rc关于SurfaceFlinger的代码,我们可以看到SurfaceFlinger是属于core服务的。

  1. service surfaceflinger /system/bin/surfaceflinger  
  2.     class core  
  3.     user system  
  4.     group graphics drmrpc  
  5.     onrestart restart zygote  
  6.     writepid /dev/cpuset/system-background/tasks  
service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote
    writepid /dev/cpuset/system-background/tasks


一、SurfaceFlinger的启动过程

SurfaceFlinger的main函数在framework/native/services/surfaceflinger/main_surfaceflinger.cpp中

  1. int main(intchar**) {  
  2.     // When SF is launched in its own process, limit the number of  
  3.     // binder threads to 4.  
  4.     ProcessState::self()->setThreadPoolMaxThreadCount(4);//设置了Binder线程池最大线程为4  
  5.   
  6.     // start the thread pool  
  7.     sp<ProcessState> ps(ProcessState::self());  
  8.     ps->startThreadPool();  
  9.   
  10.     // instantiate surfaceflinger  
  11.     sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建SurfaceFlinger对象  
  12.   
  13.     setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);  
  14.   
  15.     set_sched_policy(0, SP_FOREGROUND);  
  16.   
  17.     // initialize before clients can connect  
  18.     flinger->init();//调用SurfaceFlinger的init函数  
  19.   
  20.     // publish surface flinger  
  21.     sp<IServiceManager> sm(defaultServiceManager());  
  22.     sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//像serviceManager注册SurfaceFlinger服务  
  23.   
  24.     // run in this thread  
  25.     flinger->run();//运行  
  26.   
  27.     return 0;  
  28. }  
int main(int, char**) {
    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);//设置了Binder线程池最大线程为4

    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();

    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建SurfaceFlinger对象

    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);

    // initialize before clients can connect
    flinger->init();//调用SurfaceFlinger的init函数

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//像serviceManager注册SurfaceFlinger服务

    // run in this thread
    flinger->run();//运行

    return 0;
}

在主函数中先设置了该进程的binder线程池最大数为4,然后创建了SurfaceFlinger对象,并且调用了其init函数,接着把SurfaceFlinger服务注册到ServiceManager中,然后调用了run方法。

我们先来看下init函数

  1. void SurfaceFlinger::init() {  
  2.     ALOGI(  "SurfaceFlinger's main thread ready to run. "  
  3.             "Initializing graphics H/W...");  
  4.   
  5.     Mutex::Autolock _l(mStateLock);  
  6.   
  7.     // initialize EGL for the default display 将EGL初始化成缺省的显示  
  8.     mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);  
  9.     eglInitialize(mEGLDisplay, NULL, NULL);  
  10.   
  11.     // start the EventThread  
  12.     sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,  
  13.             vsyncPhaseOffsetNs, true"app");  
  14.     mEventThread = new EventThread(vsyncSrc);  
  15.     sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,  
  16.             sfVsyncPhaseOffsetNs, true"sf");  
  17.     mSFEventThread = new EventThread(sfVsyncSrc);  
  18.     mEventQueue.setEventThread(mSFEventThread);  
  19.   
  20.     // Initialize the H/W composer object.  There may or may not be an  
  21.     // actual hardware composer underneath.  
  22.     mHwc = new HWComposer(this,//显示硬件抽象类  
  23.             *static_cast<HWComposer::EventHandler *>(this));  
  24.   
  25.     // get a RenderEngine for the given display / config (can't fail)  
  26.     mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());  
  27.   
  28.     // retrieve the EGL context that was selected/created  
  29.     mEGLContext = mRenderEngine->getEGLContext();  
  30.   
  31.     LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,  
  32.             "couldn't create EGLContext");  
  33.   
  34.     // initialize our non-virtual displays 初始化显示设备  
  35.     for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {  
  36.         DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);  
  37.         // set-up the displays that are already connected  
  38.         if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {  
  39.             // All non-virtual displays are currently considered secure.  
  40.             bool isSecure = true;  
  41.             createBuiltinDisplayLocked(type);  
  42.             wp<IBinder> token = mBuiltinDisplays[i];  
  43.   
  44.             sp<IGraphicBufferProducer> producer;  
  45.             sp<IGraphicBufferConsumer> consumer;  
  46.             BufferQueue::createBufferQueue(&producer, &consumer,  
  47.                     new GraphicBufferAlloc());  
  48.   
  49.             sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,  
  50.                     consumer);  
  51.             int32_t hwcId = allocateHwcDisplayId(type);  
  52.             sp<DisplayDevice> hw = new DisplayDevice(this,  
  53.                     type, hwcId, mHwc->getFormat(hwcId), isSecure, token,  
  54.                     fbs, producer,  
  55.                     mRenderEngine->getEGLConfig());  
  56.             if (i > DisplayDevice::DISPLAY_PRIMARY) {  
  57.                 // FIXME: currently we don't get blank/unblank requests  
  58.                 // for displays other than the main display, so we always  
  59.                 // assume a connected display is unblanked.  
  60.                 ALOGD("marking display %zu as acquired/unblanked", i);  
  61.                 hw->setPowerMode(HWC_POWER_MODE_NORMAL);  
  62.             }  
  63.             mDisplays.add(token, hw);  
  64.         }  
  65.     }  
  66.   
  67.     // make the GLContext current so that we can create textures when creating Layers  
  68.     // (which may happens before we render something)  
  69.     getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);  
  70.   
  71.     mEventControlThread = new EventControlThread(this);  
  72.     mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);  
  73.   
  74.     // set a fake vsync period if there is no HWComposer  
  75.     if (mHwc->initCheck() != NO_ERROR) {  
  76.         mPrimaryDispSync.setPeriod(16666667);  
  77.     }  
  78.   
  79.     // initialize our drawing state  
  80.     mDrawingState = mCurrentState;  
  81.   
  82.     // set initial conditions (e.g. unblank default device)  
  83.     initializeDisplays();//初始化显示设备  
  84.   
  85.     // start boot animation  
  86.     startBootAnim();//启动开机动画  
  87. }  
void SurfaceFlinger::init() {
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");

    Mutex::Autolock _l(mStateLock);

    // initialize EGL for the default display 将EGL初始化成缺省的显示
    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(mEGLDisplay, NULL, NULL);

    // start the EventThread
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc);
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, true, "sf");
    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);

    // Initialize the H/W composer object.  There may or may not be an
    // actual hardware composer underneath.
    mHwc = new HWComposer(this,//显示硬件抽象类
            *static_cast<HWComposer::EventHandler *>(this));

    // get a RenderEngine for the given display / config (can't fail)
    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());

    // retrieve the EGL context that was selected/created
    mEGLContext = mRenderEngine->getEGLContext();

    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
            "couldn't create EGLContext");

    // initialize our non-virtual displays 初始化显示设备
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // set-up the displays that are already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            // All non-virtual displays are currently considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<IGraphicBufferProducer> producer;
            sp<IGraphicBufferConsumer> consumer;
            BufferQueue::createBufferQueue(&producer, &consumer,
                    new GraphicBufferAlloc());

            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
                    consumer);
            int32_t hwcId = allocateHwcDisplayId(type);
            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
                    fbs, producer,
                    mRenderEngine->getEGLConfig());
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                // FIXME: currently we don't get blank/unblank requests
                // for displays other than the main display, so we always
                // assume a connected display is unblanked.
                ALOGD("marking display %zu as acquired/unblanked", i);
                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
            }
            mDisplays.add(token, hw);
        }
    }

    // make the GLContext current so that we can create textures when creating Layers
    // (which may happens before we render something)
    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);

    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

    // set a fake vsync period if there is no HWComposer
    if (mHwc->initCheck() != NO_ERROR) {
        mPrimaryDispSync.setPeriod(16666667);
    }

    // initialize our drawing state
    mDrawingState = mCurrentState;

    // set initial conditions (e.g. unblank default device)
    initializeDisplays();//初始化显示设备

    // start boot animation
    startBootAnim();//启动开机动画
}

init函数主要工作:

1.初始化OpenGL ES图形库。

2. 创建显示设备的抽象代表,负责和显示设备打交道。

3. 创建显示设备对象。

4. 启动EventThread。监听和处理SurfaceFlinger中的事件。

5.设置软件VSync信号周期。

6.初始化显示设备,调用initializeDisplays完成。

7.启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程。

  1. void SurfaceFlinger::startBootAnim() {  
  2.     // start boot animation  
  3.     property_set("service.bootanim.exit""0");  
  4.     property_set("ctl.start""bootanim");  
  5. }  
void SurfaceFlinger::startBootAnim() {
    // start boot animation
    property_set("service.bootanim.exit", "0");
    property_set("ctl.start", "bootanim");
}


二、消息和事件分发 MessageQueue和EventThread

MessageQueue和用于消息和事件的分发,这个和之前博客分析过得消息机制原理差不多。

我们先来看看MessageQueue的主要成员变量

  1. class MessageQueue {  
  2.     ......  
  3.     sp<SurfaceFlinger> mFlinger;//指向SurfaceFlinger  
  4.     sp<Looper> mLooper;//消息机制Looper对象  
  5.     sp<EventThread> mEventThread;//关联的EventThread  
  6.     sp<IDisplayEventConnection> mEvents;  
  7.     sp<BitTube> mEventTube;  
  8.     sp<Handler> mHandler;//消息处理器  
class MessageQueue {
    ......
    sp<SurfaceFlinger> mFlinger;//指向SurfaceFlinger
    sp<Looper> mLooper;//消息机制Looper对象
    sp<EventThread> mEventThread;//关联的EventThread
    sp<IDisplayEventConnection> mEvents;
    sp<BitTube> mEventTube;
    sp<Handler> mHandler;//消息处理器
其中mEventThread主要是用来分析VSync信号的。

在SurfaceFlinger中有一个类型为MessageQueue的成员变量mEventQueue,在SurfaceFlinger的onFirstRef函数中会调用其init函数

  1. void SurfaceFlinger::onFirstRef()  
  2. {  
  3.     mEventQueue.init(this);  
  4. }  
void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);
}
在这个函数中创建了Looper和Handler对象,并且把flinger保存在mFlinger中。

  1. void MessageQueue::init(const sp<SurfaceFlinger>& flinger)  
  2. {  
  3.     mFlinger = flinger;  
  4.     mLooper = new Looper(true);  
  5.     mHandler = new Handler(*this);  
  6. }  
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}
我们来看下Handler这个类,它是MessageQueue类的一个内部类,这个类主要处理3个消息。

  1. class Handler : public MessageHandler {  
  2.     enum {  
  3.         eventMaskInvalidate     = 0x1,//invalidate消息  
  4.         eventMaskRefresh        = 0x2,//刷新消息  
  5.         eventMaskTransaction    = 0x4  
  6.     };  
  7.     MessageQueue& mQueue;  
  8.     int32_t mEventMask;  
  9. public:  
  10.     Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }  
  11.     virtual void handleMessage(const Message& message);  
  12.     void dispatchRefresh();  
  13.     void dispatchInvalidate();  
  14.     void dispatchTransaction();  
  15. };  
    class Handler : public MessageHandler {
        enum {
            eventMaskInvalidate     = 0x1,//invalidate消息
            eventMaskRefresh        = 0x2,//刷新消息
            eventMaskTransaction    = 0x4
        };
        MessageQueue& mQueue;
        int32_t mEventMask;
    public:
        Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
        virtual void handleMessage(const Message& message);
        void dispatchRefresh();
        void dispatchInvalidate();
        void dispatchTransaction();
    };


我们再来看在SurfaceFlinger主函数最后调用了下面方法。

  1. flinger->run();  
    flinger->run();

SurfaceFlinger::run代码如下

  1. void SurfaceFlinger::run() {  
  2.     do {  
  3.         waitForEvent();  
  4.     } while (true);  
  5. }  
void SurfaceFlinger::run() {
    do {
        waitForEvent();
    } while (true);
}

waitForEvent函数如下:

  1. void SurfaceFlinger::waitForEvent() {  
  2.     mEventQueue.waitMessage();  
  3. }  
void SurfaceFlinger::waitForEvent() {
    mEventQueue.waitMessage();
}

然后又调用了EventQueue的waitMessage方法,记住这里是在主线程中循环调用的。

下面我们来看下waitMessage方法,flushCommands之前在分析Binder的博客中有提到,主要是清理工作的,和Binder驱动的交互关了。而pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息。这里的消息只有自己在Handler中发的消息,还有在setEventThread中自己添加的fd。

  1. void MessageQueue::waitMessage() {  
  2.     do {  
  3.         IPCThreadState::self()->flushCommands();  
  4.         int32_t ret = mLooper->pollOnce(-1);  
  5.         switch (ret) {  
  6.             case Looper::POLL_WAKE:  
  7.             case Looper::POLL_CALLBACK:  
  8.                 continue;  
  9.             case Looper::POLL_ERROR:  
  10.                 ALOGE("Looper::POLL_ERROR");  
  11.             case Looper::POLL_TIMEOUT:  
  12.                 // timeout (should not happen)  
  13.                 continue;  
  14.             default:  
  15.                 // should not happen  
  16.                 ALOGE("Looper::pollOnce() returned unknown status %d", ret);  
  17.                 continue;  
  18.         }  
  19.     } while (true);  
  20. }  
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);
}

下面是Handler中发送消息,这个会在pollOnce中处理。

  1. void MessageQueue::Handler::dispatchRefresh() {  
  2.     if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {  
  3.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));  
  4.     }  
  5. }  
  6.   
  7. void MessageQueue::Handler::dispatchInvalidate() {  
  8.     if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {  
  9.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));  
  10.     }  
  11. }  
  12.   
  13. void MessageQueue::Handler::dispatchTransaction() {  
  14.     if ((android_atomic_or(eventMaskTransaction, &mEventMask) & eventMaskTransaction) == 0) {  
  15.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::TRANSACTION));  
  16.     }  
  17. }  
void MessageQueue::Handler::dispatchRefresh() {
    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
    }
}

void MessageQueue::Handler::dispatchInvalidate() {
    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
    }
}

void MessageQueue::Handler::dispatchTransaction() {
    if ((android_atomic_or(eventMaskTransaction, &mEventMask) & eventMaskTransaction) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::TRANSACTION));
    }
}

在SurfaceFlinger的init函数还调用了如下函数

  1. mSFEventThread = new EventThread(sfVsyncSrc);  
  2. mEventQueue.setEventThread(mSFEventThread);  
    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);

我们来看setEventThread函数会调用Looper的addFd,这个最终也会在pollOnce中执行。mEventThread是一个EventThread对象,调用createEventConnection来创建一个连接。EventThread是一个线程类用来分发VSync消息。这个我们后面讲解VSync信号的时候还会详细分析。

  1. void MessageQueue::setEventThread(const sp<EventThread>& eventThread)  
  2. {  
  3.     mEventThread = eventThread;  
  4.     mEvents = eventThread->createEventConnection();  
  5.     mEventTube = mEvents->getDataChannel();  
  6.     mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,  
  7.             MessageQueue::cb_eventReceiver, this);  
  8. }  
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();
    mEventTube = mEvents->getDataChannel();
    mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
            MessageQueue::cb_eventReceiver, this);
}


三、显示设备  DisplayDevice类

DisplayDevice是显示设备的抽象,定义了3中类型的显示设备。

1.DISPLAY_PRIMARY:主显示设备,通常是LCD屏

2.DISPLAY_EXTERNAL:扩展显示设备。通过HDMI输出的显示信号

3.DISPLAY_VIRTUAL:虚拟显示设备,通过WIFI输出信号
这3钟设备,第一种是基本配置,另外两种需要硬件支持。这里我们主要讲解第一种。


SurfaceFlinger中需要显示的图层(layer)将通过DisplayDevice对象传递到OpenGLES中进行合成,合成之后的图像再通过HWComposer对象传递到Framebuffer中显示。DisplayDevice对象中的成员变量mVisibleLayersSortedByZ保存了所有需要显示在本显示设备中显示的Layer对象,同时DisplayDevice对象也保存了和显示设备相关的显示方向、显示区域坐标等信息。

上节在SurfaceFlinger的init函数中有一段代码来创建DisplayDevice对象

  1. for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {  
  2.     DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);  
  3.     // set-up the displays that are already connected  
  4.     if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {  
  5.         // All non-virtual displays are currently considered secure.  
  6.         bool isSecure = true;  
  7.         createBuiltinDisplayLocked(type);//给显示设备分配一个token  
  8.         wp<IBinder> token = mBuiltinDisplays[i];  
  9.   
  10.         sp<IGraphicBufferProducer> producer;  
  11.         sp<IGraphicBufferConsumer> consumer;  
  12.         BufferQueue::createBufferQueue(&producer, &consumer,  
  13.                 new GraphicBufferAlloc());  
  14.   
  15.         sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,  
  16.                 consumer);  
  17.         int32_t hwcId = allocateHwcDisplayId(type);  
  18.         sp<DisplayDevice> hw = new DisplayDevice(this,  
  19.                 type, hwcId, mHwc->getFormat(hwcId), isSecure, token,  
  20.                 fbs, producer,  
  21.                 mRenderEngine->getEGLConfig());  
  22.         if (i > DisplayDevice::DISPLAY_PRIMARY) {  
  23.             // FIXME: currently we don't get blank/unblank requests  
  24.             // for displays other than the main display, so we always  
  25.             // assume a connected display is unblanked.  
  26.             ALOGD("marking display %zu as acquired/unblanked", i);  
  27.             hw->setPowerMode(HWC_POWER_MODE_NORMAL);  
  28.         }  
  29.         mDisplays.add(token, hw);//把显示设备对象保存在mDisplays列表中  
  30.     }  
  31. }  
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // set-up the displays that are already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            // All non-virtual displays are currently considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);//给显示设备分配一个token
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<IGraphicBufferProducer> producer;
            sp<IGraphicBufferConsumer> consumer;
            BufferQueue::createBufferQueue(&producer, &consumer,
                    new GraphicBufferAlloc());

            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
                    consumer);
            int32_t hwcId = allocateHwcDisplayId(type);
            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
                    fbs, producer,
                    mRenderEngine->getEGLConfig());
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                // FIXME: currently we don't get blank/unblank requests
                // for displays other than the main display, so we always
                // assume a connected display is unblanked.
                ALOGD("marking display %zu as acquired/unblanked", i);
                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
            }
            mDisplays.add(token, hw);//把显示设备对象保存在mDisplays列表中
        }
    }

所有显示设备的输出都要通过HWComposer对象完成,因此上面这段代码先调用了HWComposer的isConnected来检查显示设备是否已连接,只有和显示设备连接的DisplayDevice对象才会被创建出来。即使没有任何物理显示设备被检测到,SurfaceFlinger都需要一个DisplayDevice对象才能正常工作,因此,DISPLAY_PRIMARY类型的DisplayDevice对象总是会被创建出来。

createBuiltinDisplayLocked函数就是为显示设备对象创建一个BBinder类型的Token而已。

  1. void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {  
  2.     ALOGW_IF(mBuiltinDisplays[type],  
  3.             "Overwriting display token for display type %d", type);  
  4.     mBuiltinDisplays[type] = new BBinder();  
  5.     DisplayDeviceState info(type);  
  6.     // All non-virtual displays are currently considered secure.  
  7.     info.isSecure = true;  
  8.     mCurrentState.displays.add(mBuiltinDisplays[type], info);  
  9. }  
void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
    ALOGW_IF(mBuiltinDisplays[type],
            "Overwriting display token for display type %d", type);
    mBuiltinDisplays[type] = new BBinder();
    DisplayDeviceState info(type);
    // All non-virtual displays are currently considered secure.
    info.isSecure = true;
    mCurrentState.displays.add(mBuiltinDisplays[type], info);
}

然后会调用createBufferQueue函数创建一个producer和consumer,这个之前分析过。然后又创建了一个FramebufferSurface对象。这里我们看到在新建FramebufferSurface对象时把consumer参数传入了代表是一个消费者。而在DisplayDevice的构造函数中,会创建一个Surface对象传递给底层的OpenGL ES使用,而这个Surface是一个生产者。在OpenGl ES中合成好了图像之后会将图像数据写到Surface对象中,这将触发consumer对象的onFrameAvailable函数被调用:

这就是Surface数据好了就通知消费者来拿数据做显示用,在onFrameAvailable函数汇总,通过nextBuffer获得图像数据,然后调用HWComposer对象mHwc的fbPost函数输出。

  1. void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {  
  2.     sp<GraphicBuffer> buf;  
  3.     sp<Fence> acquireFence;  
  4.     status_t err = nextBuffer(buf, acquireFence);  
  5.     if (err != NO_ERROR) {  
  6.         ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",  
  7.                 strerror(-err), err);  
  8.         return;  
  9.     }  
  10.     err = mHwc.fbPost(mDisplayType, acquireFence, buf);  
  11.     if (err != NO_ERROR) {  
  12.         ALOGE("error posting framebuffer: %d", err);  
  13.     }  
  14. }  
void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
    sp<GraphicBuffer> buf;
    sp<Fence> acquireFence;
    status_t err = nextBuffer(buf, acquireFence);
    if (err != NO_ERROR) {
        ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
                strerror(-err), err);
        return;
    }
    err = mHwc.fbPost(mDisplayType, acquireFence, buf);
    if (err != NO_ERROR) {
        ALOGE("error posting framebuffer: %d", err);
    }
}

fbPost函数最后通过调用Gralloc模块的post函数来输出图像。

我们再来看看DisplayDevice的构造函数

  1. DisplayDevice::DisplayDevice(  
  2.         const sp<SurfaceFlinger>& flinger,  
  3.         DisplayType type,  
  4.         int32_t hwcId,  
  5.         int format,  
  6.         bool isSecure,  
  7.         const wp<IBinder>& displayToken,  
  8.         const sp<DisplaySurface>& displaySurface,  
  9.         const sp<IGraphicBufferProducer>& producer,  
  10.         EGLConfig config)  
  11.     : lastCompositionHadVisibleLayers(false),  
  12.       mFlinger(flinger),  
  13.       mType(type), mHwcDisplayId(hwcId),  
  14.       mDisplayToken(displayToken),  
  15.       mDisplaySurface(displaySurface),  
  16.       mDisplay(EGL_NO_DISPLAY),  
  17.       mSurface(EGL_NO_SURFACE),  
  18.       mDisplayWidth(), mDisplayHeight(), mFormat(),  
  19.       mFlags(),  
  20.       mPageFlipCount(),  
  21.       mIsSecure(isSecure),  
  22.       mSecureLayerVisible(false),  
  23.       mLayerStack(NO_LAYER_STACK),  
  24.       mOrientation(),  
  25.       mPowerMode(HWC_POWER_MODE_OFF),  
  26.       mActiveConfig(0)  
  27. {  
  28.     mNativeWindow = new Surface(producer, false);//创建Surface对象  
  29.     ANativeWindow* const window = mNativeWindow.get();  
  30.   
  31.     /* 
  32.      * Create our display's surface 
  33.      */  
  34.   
  35.     EGLSurface surface;  
  36.     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);  
  37.     if (config == EGL_NO_CONFIG) {  
  38.         config = RenderEngine::chooseEglConfig(display, format);  
  39.     }  
  40.     surface = eglCreateWindowSurface(display, config, window, NULL);  
  41.     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);  
  42.     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);  
  43.   
  44.     // Make sure that composition can never be stalled by a virtual display  
  45.     // consumer that isn't processing buffers fast enough. We have to do this  
  46.     // in two places:  
  47.     // * Here, in case the display is composed entirely by HWC.  
  48.     // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the  
  49.     //   window's swap interval in eglMakeCurrent, so they'll override the  
  50.     //   interval we set here.  
  51.     if (mType >= DisplayDevice::DISPLAY_VIRTUAL)//虚拟设备不支持图像合成  
  52.         window->setSwapInterval(window, 0);  
  53.   
  54.     mConfig = config;  
  55.     mDisplay = display;  
  56.     mSurface = surface;  
  57.     mFormat  = format;  
  58.     mPageFlipCount = 0;  
  59.     mViewport.makeInvalid();  
  60.     mFrame.makeInvalid();  
  61.   
  62.     // virtual displays are always considered enabled 虚拟设备屏幕认为是不关闭的  
  63.     mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?  
  64.                   HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;  
  65.   
  66.     // Name the display.  The name will be replaced shortly if the display  
  67.     // was created with createDisplay().  
  68.     switch (mType) {//显示设备名称  
  69.         case DISPLAY_PRIMARY:  
  70.             mDisplayName = "Built-in Screen";  
  71.             break;  
  72.         case DISPLAY_EXTERNAL:  
  73.             mDisplayName = "HDMI Screen";  
  74.             break;  
  75.         default:  
  76.             mDisplayName = "Virtual Screen";    // e.g. Overlay #n  
  77.             break;  
  78.     }  
  79.   
  80.     // initialize the display orientation transform.  
  81.     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);  
  82. }  
DisplayDevice::DisplayDevice(
        const sp<SurfaceFlinger>& flinger,
        DisplayType type,
        int32_t hwcId,
        int format,
        bool isSecure,
        const wp<IBinder>& displayToken,
        const sp<DisplaySurface>& displaySurface,
        const sp<IGraphicBufferProducer>& producer,
        EGLConfig config)
    : lastCompositionHadVisibleLayers(false),
      mFlinger(flinger),
      mType(type), mHwcDisplayId(hwcId),
      mDisplayToken(displayToken),
      mDisplaySurface(displaySurface),
      mDisplay(EGL_NO_DISPLAY),
      mSurface(EGL_NO_SURFACE),
      mDisplayWidth(), mDisplayHeight(), mFormat(),
      mFlags(),
      mPageFlipCount(),
      mIsSecure(isSecure),
      mSecureLayerVisible(false),
      mLayerStack(NO_LAYER_STACK),
      mOrientation(),
      mPowerMode(HWC_POWER_MODE_OFF),
      mActiveConfig(0)
{
    mNativeWindow = new Surface(producer, false);//创建Surface对象
    ANativeWindow* const window = mNativeWindow.get();

    /*
     * Create our display's surface
     */

    EGLSurface surface;
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (config == EGL_NO_CONFIG) {
        config = RenderEngine::chooseEglConfig(display, format);
    }
    surface = eglCreateWindowSurface(display, config, window, NULL);
    eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
    eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);

    // Make sure that composition can never be stalled by a virtual display
    // consumer that isn't processing buffers fast enough. We have to do this
    // in two places:
    // * Here, in case the display is composed entirely by HWC.
    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
    //   window's swap interval in eglMakeCurrent, so they'll override the
    //   interval we set here.
    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)//虚拟设备不支持图像合成
        window->setSwapInterval(window, 0);

    mConfig = config;
    mDisplay = display;
    mSurface = surface;
    mFormat  = format;
    mPageFlipCount = 0;
    mViewport.makeInvalid();
    mFrame.makeInvalid();

    // virtual displays are always considered enabled 虚拟设备屏幕认为是不关闭的
    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;

    // Name the display.  The name will be replaced shortly if the display
    // was created with createDisplay().
    switch (mType) {//显示设备名称
        case DISPLAY_PRIMARY:
            mDisplayName = "Built-in Screen";
            break;
        case DISPLAY_EXTERNAL:
            mDisplayName = "HDMI Screen";
            break;
        default:
            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
            break;
    }

    // initialize the display orientation transform.
    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}

上面构造函数主要功能是创建了一个Surface对象mNativeWindow,同时用它作为参数创建EGLSurface对象,这个EGLSurface对象是OpenGL ES中绘图需要的。

这样,在DisplayDevice中就建立了一个通向Framebuffer的通道,只要向DisplayDevice的mSurface写入数据。就会到消费者FrameBufferSurface的onFrameAvailable函数,然后到HWComposer在到Gralloc模块,最后输出到显示设备。

swapBuffers函数将内部缓冲区的图像数据刷新到显示设备的Framebuffer中,它通过调用eglSwapBuffers函数来完成缓冲区刷新工作。但是注意调用swapBuffers输出图像是在显示设备不支持硬件composer的情况下。

  1. void DisplayDevice::swapBuffers(HWComposer& hwc) const {  
  2.     // We need to call eglSwapBuffers() if:  
  3.     //  (1) we don't have a hardware composer, or  
  4.     //  (2) we did GLES composition this frame, and either  
  5.     //    (a) we have framebuffer target support (not present on legacy  
  6.     //        devices, where HWComposer::commit() handles things); or  
  7.     //    (b) this is a virtual display  
  8.     if (hwc.initCheck() != NO_ERROR ||  
  9.             (hwc.hasGlesComposition(mHwcDisplayId) &&  
  10.              (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {  
  11.         EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);  
  12.         if (!success) {  
  13.             EGLint error = eglGetError();  
  14.             if (error == EGL_CONTEXT_LOST ||  
  15.                     mType == DisplayDevice::DISPLAY_PRIMARY) {  
  16.                 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",  
  17.                         mDisplay, mSurface, error);  
  18.             } else {  
  19.                 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",  
  20.                         mDisplay, mSurface, error);  
  21.             }  
  22.         }  
  23.     }  
  24.     else if(hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL)  
  25.     {  
  26.         EGLBoolean success = eglSwapBuffersVIV(mDisplay, mSurface);  
  27.         if (!success) {  
  28.             EGLint error = eglGetError();  
  29.             ALOGE("eglSwapBuffersVIV(%p, %p) failed with 0x%08x",  
  30.                         mDisplay, mSurface, error);  
  31.         }  
  32.     }  
  33.   
  34.     status_t result = mDisplaySurface->advanceFrame();  
  35.     if (result != NO_ERROR) {  
  36.         ALOGE("[%s] failed pushing new frame to HWC: %d",  
  37.                 mDisplayName.string(), result);  
  38.     }  
  39. }  
void DisplayDevice::swapBuffers(HWComposer& hwc) const {
    // We need to call eglSwapBuffers() if:
    //  (1) we don't have a hardware composer, or
    //  (2) we did GLES composition this frame, and either
    //    (a) we have framebuffer target support (not present on legacy
    //        devices, where HWComposer::commit() handles things); or
    //    (b) this is a virtual display
    if (hwc.initCheck() != NO_ERROR ||
            (hwc.hasGlesComposition(mHwcDisplayId) &&
             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
        if (!success) {
            EGLint error = eglGetError();
            if (error == EGL_CONTEXT_LOST ||
                    mType == DisplayDevice::DISPLAY_PRIMARY) {
                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
                        mDisplay, mSurface, error);
            } else {
                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
                        mDisplay, mSurface, error);
            }
        }
    }
    else if(hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL)
    {
        EGLBoolean success = eglSwapBuffersVIV(mDisplay, mSurface);
        if (!success) {
            EGLint error = eglGetError();
            ALOGE("eglSwapBuffersVIV(%p, %p) failed with 0x%08x",
                        mDisplay, mSurface, error);
        }
    }

    status_t result = mDisplaySurface->advanceFrame();
    if (result != NO_ERROR) {
        ALOGE("[%s] failed pushing new frame to HWC: %d",
                mDisplayName.string(), result);
    }
}


四、VSync信号的分发过程

在之前的博客分析过,当VSync信号到来时会调用HWComposer类中的vsync函数

  1. void HWComposer::vsync(int disp, int64_t timestamp) {  
  2.     if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {  
  3.         {  
  4.             Mutex::Autolock _l(mLock);  
  5.   
  6.             // There have been reports of HWCs that signal several vsync events  
  7.             // with the same timestamp when turning the display off and on. This  
  8.             // is a bug in the HWC implementation, but filter the extra events  
  9.             // out here so they don't cause havoc downstream.  
  10.             if (timestamp == mLastHwVSync[disp]) {  
  11.                 ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",  
  12.                         timestamp);  
  13.                 return;  
  14.             }  
  15.   
  16.             mLastHwVSync[disp] = timestamp;  
  17.         }  
  18.   
  19.         char tag[16];  
  20.         snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);  
  21.         ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);  
  22.   
  23.         mEventHandler.onVSyncReceived(disp, timestamp);  
  24.     }  
  25. }  
void HWComposer::vsync(int disp, int64_t timestamp) {
    if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
        {
            Mutex::Autolock _l(mLock);

            // There have been reports of HWCs that signal several vsync events
            // with the same timestamp when turning the display off and on. This
            // is a bug in the HWC implementation, but filter the extra events
            // out here so they don't cause havoc downstream.
            if (timestamp == mLastHwVSync[disp]) {
                ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
                        timestamp);
                return;
            }

            mLastHwVSync[disp] = timestamp;
        }

        char tag[16];
        snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
        ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);

        mEventHandler.onVSyncReceived(disp, timestamp);
    }
}

这个函数主要是调用了mEventHandler.onVSyncReceived函数,让我们先来看下mEventHandler的构造,看HWComposer的构造函数,mEventHandler是传入的参数handler。

  1. HWComposer::HWComposer(  
  2.         const sp<SurfaceFlinger>& flinger,  
  3.         EventHandler& handler)  
  4.     : mFlinger(flinger),  
  5.       mFbDev(0), mHwc(0), mNumDisplays(1),  
  6.       mCBContext(new cb_context),  
  7.       mEventHandler(handler),  
  8.       mDebugForceFakeVSync(false)  
HWComposer::HWComposer(
        const sp<SurfaceFlinger>& flinger,
        EventHandler& handler)
    : mFlinger(flinger),
      mFbDev(0), mHwc(0), mNumDisplays(1),
      mCBContext(new cb_context),
      mEventHandler(handler),
      mDebugForceFakeVSync(false)

那么我们就要看新建HWComposer的地方了,是在SurfaceFlinger的init函数中新建的,这handler就是SurfaceFlinger对象。

  1. mHwc = new HWComposer(this,  
  2.         *static_cast<HWComposer::EventHandler *>(this));  
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));

因此上面的mEventHandler.onVSyncReceived函数,就是调用了SurfaceFlinger的onVSyncReceived函数

  1. void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {  
  2.     bool needsHwVsync = false;  
  3.   
  4.     { // Scope for the lock  
  5.         Mutex::Autolock _l(mHWVsyncLock);  
  6.         if (type == 0 && mPrimaryHWVsyncEnabled) {  
  7.             needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);  
  8.         }  
  9.     }  
  10.   
  11.     if (needsHwVsync) {  
  12.         enableHardwareVsync();  
  13.     } else {  
  14.         disableHardwareVsync(false);  
  15.     }  
  16. }  
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
    bool needsHwVsync = false;

    { // Scope for the lock
        Mutex::Autolock _l(mHWVsyncLock);
        if (type == 0 && mPrimaryHWVsyncEnabled) {
            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
        }
    }

    if (needsHwVsync) {
        enableHardwareVsync();
    } else {
        disableHardwareVsync(false);
    }
}


4.1 DispSync类

上面函数我们主要看下DispSync的addResyncSample函数,看这个函数之前先看下DispSync的构造函数,在构造函数中启动了DispSyncThread线程

  1. DispSync::DispSync() :  
  2.         mRefreshSkipCount(0),  
  3.         mThread(new DispSyncThread()) {  
  4.   
  5.     mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);  
DispSync::DispSync() :
        mRefreshSkipCount(0),
        mThread(new DispSyncThread()) {

    mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);

我们再来看addResyncSample函数,将VSync信号的时间戳保存大搜了数组mResyncSamples中。然后调用了updateModelLocked函数继续分发VSync信号。

  1. bool DispSync::addResyncSample(nsecs_t timestamp) {  
  2.     Mutex::Autolock lock(mMutex);  
  3.   
  4.     size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;  
  5.     mResyncSamples[idx] = timestamp;  
  6.   
  7.     if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {  
  8.         mNumResyncSamples++;  
  9.     } else {  
  10.         mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;  
  11.     }  
  12.   
  13.     updateModelLocked();  
  14.   
  15.     if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {  
  16.         resetErrorLocked();  
  17.     }  
  18.   
  19.     if (kIgnorePresentFences) {  
  20.         // If we don't have the sync framework we will never have  
  21.         // addPresentFence called.  This means we have no way to know whether  
  22.         // or not we're synchronized with the HW vsyncs, so we just request  
  23.         // that the HW vsync events be turned on whenever we need to generate  
  24.         // SW vsync events.  
  25.         return mThread->hasAnyEventListeners();  
  26.     }  
  27.   
  28.     return mPeriod == 0 || mError > kErrorThreshold;  
  29. }  
bool DispSync::addResyncSample(nsecs_t timestamp) {
    Mutex::Autolock lock(mMutex);

    size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
    mResyncSamples[idx] = timestamp;

    if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
        mNumResyncSamples++;
    } else {
        mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
    }

    updateModelLocked();

    if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {
        resetErrorLocked();
    }

    if (kIgnorePresentFences) {
        // If we don't have the sync framework we will never have
        // addPresentFence called.  This means we have no way to know whether
        // or not we're synchronized with the HW vsyncs, so we just request
        // that the HW vsync events be turned on whenever we need to generate
        // SW vsync events.
        return mThread->hasAnyEventListeners();
    }

    return mPeriod == 0 || mError > kErrorThreshold;
}

updateModelLocked主要显示利用数组mResyncSamples中的值计算mPeriod和mPhase这两个时间值。然后最后调用了mThread的updateModel函数。mThread是DispSyncThread类。

  1. void DispSync::updateModelLocked() {  
  2.     if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {  
  3.         ......  
  4.         //计算mPeriod和mPhase  
  5.   
  6.         mThread->updateModel(mPeriod, mPhase);  
  7.     }  
  8. }  
void DispSync::updateModelLocked() {
    if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
        ......
        //计算mPeriod和mPhase

        mThread->updateModel(mPeriod, mPhase);
    }
}

我们来看下DispSyncThread的updateModel函数,这个函数只是保存了参数,然后调用了Condition的signal唤醒线程。

  1. void updateModel(nsecs_t period, nsecs_t phase) {  
  2.     Mutex::Autolock lock(mMutex);  
  3.     mPeriod = period;  
  4.     mPhase = phase;  
  5.     mCond.signal();  
  6. }  
    void updateModel(nsecs_t period, nsecs_t phase) {
        Mutex::Autolock lock(mMutex);
        mPeriod = period;
        mPhase = phase;
        mCond.signal();
    }

我们再来看DispSyncThread的threadLoop函数,主要这个函数比较计算时间来决定是否要发送信号。如果没有信号发送就会在mCond等待,有信号发送前面会在updateModel中调用mCond的singal函数,这里线程就唤醒了。gatherCallbackInvocationsLocked函数获取本次VSync信号的回调函数列表,这些回调函数是通过DispSync类的addEventListener函数加入的。接着就调用fireCallbackInvocations来依次调用列表中所有对象的onDispSyncEvent函数。

  1. virtual bool threadLoop() {  
  2.     ......  
  3.     while (true) {  
  4.         Vector<CallbackInvocation> callbackInvocations;  
  5.   
  6.         nsecs_t targetTime = 0;  
  7.   
  8.         { // Scope for lock  
  9.             ......  
  10.   
  11.             if (now < targetTime) {  
  12.                 err = mCond.waitRelative(mMutex, targetTime - now);  
  13.                 ......  
  14.             }  
  15.   
  16.             now = systemTime(SYSTEM_TIME_MONOTONIC);  
  17.             ......  
  18.   
  19.             callbackInvocations = gatherCallbackInvocationsLocked(now);  
  20.         }  
  21.   
  22.         if (callbackInvocations.size() > 0) {  
  23.             fireCallbackInvocations(callbackInvocations);  
  24.         }  
  25.     }  
  26.   
  27.     return false;  
  28. }  
    virtual bool threadLoop() {
        ......
        while (true) {
            Vector<CallbackInvocation> callbackInvocations;

            nsecs_t targetTime = 0;

            { // Scope for lock
                ......

                if (now < targetTime) {
                    err = mCond.waitRelative(mMutex, targetTime - now);
                    ......
                }

                now = systemTime(SYSTEM_TIME_MONOTONIC);
                ......

                callbackInvocations = gatherCallbackInvocationsLocked(now);
            }

            if (callbackInvocations.size() > 0) {
                fireCallbackInvocations(callbackInvocations);
            }
        }

        return false;
    }

fireCallbackInvocations函数就是遍历回调列表调用其onDispSyncEvent函数。

  1. void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {  
  2.     for (size_t i = 0; i < callbacks.size(); i++) {  
  3.         callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);  
  4.     }  
  5. }  
    void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {
        for (size_t i = 0; i < callbacks.size(); i++) {
            callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
        }
    }


4.2 EventThread和DispSync的关系

这里我们先不往下分析DispSync遍历调用回调,我们先来看看EventThread的threadLoop函数,这个函数逻辑很简单。调用waitForEvent来获取事件,然后调用每个连接的postEvent来发送Event。

  1. bool EventThread::threadLoop() {  
  2.     DisplayEventReceiver::Event event;  
  3.     Vector< sp<EventThread::Connection> > signalConnections;  
  4.     signalConnections = waitForEvent(&event);//获取Event  
  5.   
  6.     // dispatch events to listeners...  
  7.     const size_t count = signalConnections.size();  
  8.     for (size_t i=0 ; i<count ; i++) {  
  9.         const sp<Connection>& conn(signalConnections[i]);  
  10.         // now see if we still need to report this event  
  11.         status_t err = conn->postEvent(event);//发送Event  
  12.         if (err == -EAGAIN || err == -EWOULDBLOCK) {  
  13.             // The destination doesn't accept events anymore, it's probably  
  14.             // full. For now, we just drop the events on the floor.  
  15.             // FIXME: Note that some events cannot be dropped and would have  
  16.             // to be re-sent later.  
  17.             // Right-now we don't have the ability to do this.  
  18.             ALOGW("EventThread: dropping event (%08x) for connection %p",  
  19.                     event.header.type, conn.get());  
  20.         } else if (err < 0) {  
  21.             // handle any other error on the pipe as fatal. the only  
  22.             // reasonable thing to do is to clean-up this connection.  
  23.             // The most common error we'll get here is -EPIPE.  
  24.             removeDisplayEventConnection(signalConnections[i]);  
  25.         }  
  26.     }  
  27.     return true;  
  28. }  
bool EventThread::threadLoop() {
    DisplayEventReceiver::Event event;
    Vector< sp<EventThread::Connection> > signalConnections;
    signalConnections = waitForEvent(&event);//获取Event

    // dispatch events to listeners...
    const size_t count = signalConnections.size();
    for (size_t i=0 ; i<count ; i++) {
        const sp<Connection>& conn(signalConnections[i]);
        // now see if we still need to report this event
        status_t err = conn->postEvent(event);//发送Event
        if (err == -EAGAIN || err == -EWOULDBLOCK) {
            // The destination doesn't accept events anymore, it's probably
            // full. For now, we just drop the events on the floor.
            // FIXME: Note that some events cannot be dropped and would have
            // to be re-sent later.
            // Right-now we don't have the ability to do this.
            ALOGW("EventThread: dropping event (%08x) for connection %p",
                    event.header.type, conn.get());
        } else if (err < 0) {
            // handle any other error on the pipe as fatal. the only
            // reasonable thing to do is to clean-up this connection.
            // The most common error we'll get here is -EPIPE.
            removeDisplayEventConnection(signalConnections[i]);
        }
    }
    return true;
}

我们再来看下waitForEvent函数中下面代码段,timestamp为0表示没有时间,waitForSync为true表示至少有一个客户和EventThread建立了连接。这段代码一旦有客户连接,就调用enableVSyncLocked接收DispSyncSource的VSync信号。如果在接受信号中,所有客户都断开了连接,则调用disableVSyncLocked函数停止接受DispSyncSource对象的信号。

  1. // Here we figure out if we need to enable or disable vsyncs  
  2. if (timestamp && !waitForVSync) {  
  3.     // we received a VSYNC but we have no clients  
  4.     // don't report it, and disable VSYNC events  
  5.     disableVSyncLocked();  
  6. else if (!timestamp && waitForVSync) {  
  7.     // we have at least one client, so we want vsync enabled  
  8.     // (TODO: this function is called right after we finish  
  9.     // notifying clients of a vsync, so this call will be made  
  10.     // at the vsync rate, e.g. 60fps.  If we can accurately  
  11.     // track the current state we could avoid making this call  
  12.     // so often.)  
  13.     enableVSyncLocked();  
  14. }  
        // Here we figure out if we need to enable or disable vsyncs
        if (timestamp && !waitForVSync) {
            // we received a VSYNC but we have no clients
            // don't report it, and disable VSYNC events
            disableVSyncLocked();
        } else if (!timestamp && waitForVSync) {
            // we have at least one client, so we want vsync enabled
            // (TODO: this function is called right after we finish
            // notifying clients of a vsync, so this call will be made
            // at the vsync rate, e.g. 60fps.  If we can accurately
            // track the current state we could avoid making this call
            // so often.)
            enableVSyncLocked();
        }

我们先来看下enableVSyncLocked函数

  1. void EventThread::enableVSyncLocked() {  
  2.     if (!mUseSoftwareVSync) {  
  3.         // never enable h/w VSYNC when screen is off  
  4.         if (!mVsyncEnabled) {  
  5.             mVsyncEnabled = true;  
  6.             mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));  
  7.             mVSyncSource->setVSyncEnabled(true);  
  8.         }  
  9.     }  
  10.     mDebugVsyncEnabled = true;  
  11.     sendVsyncHintOnLocked();  
  12. }  
void EventThread::enableVSyncLocked() {
    if (!mUseSoftwareVSync) {
        // never enable h/w VSYNC when screen is off
        if (!mVsyncEnabled) {
            mVsyncEnabled = true;
            mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
            mVSyncSource->setVSyncEnabled(true);
        }
    }
    mDebugVsyncEnabled = true;
    sendVsyncHintOnLocked();
}

我们先来看看mVSyncSource->setCallback函数。先要知道这个mVSyncSource是在SurfaceFlinger的init函数中。

  1. sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,  
  2.         vsyncPhaseOffsetNs, true"app");  
  3. mEventThread = new EventThread(vsyncSrc);  
  4. sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,  
  5.         sfVsyncPhaseOffsetNs, true"sf");  
  6. mSFEventThread = new EventThread(sfVsyncSrc);  
  7. mEventQueue.setEventThread(mSFEventThread);  
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc);
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, true, "sf");
    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);

看到上面这段代码,我们知道这个mVsyncSource是DispSyncSource类,我们先来看起setCallback函数,就是把callback保存起来

  1. virtual void setCallback(const sp<VSyncSource::Callback>& callback) {  
  2.     Mutex::Autolock lock(mCallbackMutex);  
  3.     mCallback = callback;  
  4. }  
    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
        Mutex::Autolock lock(mCallbackMutex);
        mCallback = callback;
    }

再来看setVSyncEnabled函数,这里参数enable是true,就是调用了DispSync的addEventListenter。这里就回到了上一小节了,这里我们就在DispSync中注册了回调了

  1. virtual void setVSyncEnabled(bool enable) {  
  2.     Mutex::Autolock lock(mVsyncMutex);  
  3.     if (enable) {  
  4.         status_t err = mDispSync->addEventListener(mPhaseOffset,  
  5.                 static_cast<DispSync::Callback*>(this));  
  6.         if (err != NO_ERROR) {  
  7.             ALOGE("error registering vsync callback: %s (%d)",  
  8.                     strerror(-err), err);  
  9.         }  
  10.         //ATRACE_INT(mVsyncOnLabel.string(), 1);  
  11.     } else {  
  12.         status_t err = mDispSync->removeEventListener(  
  13.                 static_cast<DispSync::Callback*>(this));  
  14.         if (err != NO_ERROR) {  
  15.             ALOGE("error unregistering vsync callback: %s (%d)",  
  16.                     strerror(-err), err);  
  17.         }  
  18.         //ATRACE_INT(mVsyncOnLabel.string(), 0);  
  19.     }  
  20.     mEnabled = enable;  
  21. }  
    virtual void setVSyncEnabled(bool enable) {
        Mutex::Autolock lock(mVsyncMutex);
        if (enable) {
            status_t err = mDispSync->addEventListener(mPhaseOffset,
                    static_cast<DispSync::Callback*>(this));
            if (err != NO_ERROR) {
                ALOGE("error registering vsync callback: %s (%d)",
                        strerror(-err), err);
            }
            //ATRACE_INT(mVsyncOnLabel.string(), 1);
        } else {
            status_t err = mDispSync->removeEventListener(
                    static_cast<DispSync::Callback*>(this));
            if (err != NO_ERROR) {
                ALOGE("error unregistering vsync callback: %s (%d)",
                        strerror(-err), err);
            }
            //ATRACE_INT(mVsyncOnLabel.string(), 0);
        }
        mEnabled = enable;
    }

这样回想上一节在fireCallbackInvocations中遍历所有的回调时,就调用了DispSyncSource类的onDispSyncEvent函数,而这个函数主要是调用了其成员变量mCallback的onVSyncEvent,这个mCallback就是之前在EventThread中的waitForEvent注册的,就是EventThread自己。

  1. virtual void onDispSyncEvent(nsecs_t when) {  
  2.     sp<VSyncSource::Callback> callback;  
  3.     {  
  4.         Mutex::Autolock lock(mCallbackMutex);  
  5.         callback = mCallback;  
  6.   
  7.         if (mTraceVsync) {  
  8.             mValue = (mValue + 1) % 2;  
  9.             ATRACE_INT(mVsyncEventLabel.string(), mValue);  
  10.         }  
  11.     }  
  12.   
  13.     if (callback != NULL) {  
  14.         callback->onVSyncEvent(when);  
  15.     }  
  16. }  
    virtual void onDispSyncEvent(nsecs_t when) {
        sp<VSyncSource::Callback> callback;
        {
            Mutex::Autolock lock(mCallbackMutex);
            callback = mCallback;

            if (mTraceVsync) {
                mValue = (mValue + 1) % 2;
                ATRACE_INT(mVsyncEventLabel.string(), mValue);
            }
        }

        if (callback != NULL) {
            callback->onVSyncEvent(when);
        }
    }

因此最后到了EventThread的onVsyncEvent函数,这个函数把数据放在mVSyncEvent数组第一个,然后调用了Condition的broadcast函数。

  1. void EventThread::onVSyncEvent(nsecs_t timestamp) {  
  2.     Mutex::Autolock _l(mLock);  
  3.     mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;  
  4.     mVSyncEvent[0].header.id = 0;  
  5.     mVSyncEvent[0].header.timestamp = timestamp;  
  6.     mVSyncEvent[0].vsync.count++;  
  7.     mCondition.broadcast();  
  8. }  
void EventThread::onVSyncEvent(nsecs_t timestamp) {
    Mutex::Autolock _l(mLock);
    mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
    mVSyncEvent[0].header.id = 0;
    mVSyncEvent[0].header.timestamp = timestamp;
    mVSyncEvent[0].vsync.count++;
    mCondition.broadcast();
}

最后之前在EventThread的threadLoop函数中调用waitForEvent会阻塞,当这里调用Condition的broadcast之后,waitForEvent就唤醒,并且得到了mVsynEvent中的数据。紧接着就是在EventThread中的threadLoop调用conn->postEvent来发送Event。这里是通过BitTube对象中的socket发送到MessageQueue中。这个我们在第二节中分析过了。


4.3 MessageQueue分发VSync信号

我们来回顾下,在MessageQueue中有下面这个函数。这样当EventThread通过BitTube传送数据的话,pollOnce会唤醒epoll_wait然后就到这个cb_eventReceiver这个回调函数

  1. void MessageQueue::setEventThread(const sp<EventThread>& eventThread)  
  2. {  
  3.     mEventThread = eventThread;  
  4.     mEvents = eventThread->createEventConnection();  
  5.     mEventTube = mEvents->getDataChannel();  
  6.     mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,  
  7.             MessageQueue::cb_eventReceiver, this);  
  8. }  
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();
    mEventTube = mEvents->getDataChannel();
    mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
            MessageQueue::cb_eventReceiver, this);
}

cb_eventReceiver就是调用了eventReceiver函数。

  1. int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {  
  2.     MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);  
  3.     return queue->eventReceiver(fd, events);  
  4. }  
  5.   
  6. int MessageQueue::eventReceiver(int /*fd*/int /*events*/) {  
  7.     ssize_t n;  
  8.     DisplayEventReceiver::Event buffer[8];  
  9.     while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {  
  10.         for (int i=0 ; i<n ; i++) {  
  11.             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {  
  12. #if INVALIDATE_ON_VSYNC  
  13.                 mHandler->dispatchInvalidate();  
  14. #else  
  15.                 mHandler->dispatchRefresh();  
  16. #endif  
  17.                 break;  
  18.             }  
  19.         }  
  20.     }  
  21.     return 1;  
  22. }  
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
    return queue->eventReceiver(fd, events);
}

int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
    ssize_t n;
    DisplayEventReceiver::Event buffer[8];
    while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
        for (int i=0 ; i<n ; i++) {
            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
#if INVALIDATE_ON_VSYNC
                mHandler->dispatchInvalidate();
#else
                mHandler->dispatchRefresh();
#endif
                break;
            }
        }
    }
    return 1;
}

这里我们支持VSync信号就会调用mHandler的dispatchRefresh函数。

  1. void MessageQueue::Handler::dispatchRefresh() {  
  2.     if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {  
  3.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));  
  4.     }  
  5. }  
void MessageQueue::Handler::dispatchRefresh() {
    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
    }
}

而在Hander的处理中,最终是调用了SurfaceFlinger的onMessageReceived函数

  1. case REFRESH:  
  2.     android_atomic_and(~eventMaskRefresh, &mEventMask);  
  3.     mQueue.mFlinger->onMessageReceived(message.what);  
  4.     break;  
        case REFRESH:
            android_atomic_and(~eventMaskRefresh, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;

而在SurfaceFlinger的onMessageReceived函数最终会调用了handleMessageRefresh函数。

  1. void SurfaceFlinger::onMessageReceived(int32_t what) {  
  2.     ATRACE_CALL();  
  3.     switch (what) {  
  4.         ......  
  5.         case MessageQueue::REFRESH: {  
  6.             handleMessageRefresh();  
  7.             break;  
  8.         }  
  9.     }  
  10. }  
void SurfaceFlinger::onMessageReceived(int32_t what) {
    ATRACE_CALL();
    switch (what) {
        ......
        case MessageQueue::REFRESH: {
            handleMessageRefresh();
            break;
        }
    }
}

handleMessageRefresh函数负责刷新系统的显示。这样我们就分析了从底层发送VSync信号最终到达SurfaceFlinger的handleMessageRefresh函数。


4.4 VSync信号分发总结

我们回顾下整个流程,VSync信号从底层产生后,经过几个函数,保存到了SurfaceFlinger的mPrimaryDispSync变量(DisySync类)的数组中,这样设计的目的让底层的调用尽快结束,否则会耽搁下次VSync信号的发送。然后在mPrimaryDispSync变量关联的线程开始分发数组中的VSync信号,分发的过程也调用了几个回调函数,最终结果是放在EventThread对象的数组中。EventThread是转发VSync信号的中心。不但会把VSync信号发给SurfaceFlinger,还会把信号发送到用户进程中去。EventThread的工作比较重,因此SurfaceFlinger中使用了两个EventThread对象来转发VSync信号。确保能及时转发。SurfaceFlinger中的MessageQueue收到Event后,会将Event转化成消息发送,这样最终就能在主线程调用SurfaceFlinger的函数处理VSync信号了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值