参考:

  1. Vsync虚拟化

  2. Android SurfaceFlinger SW Vsync模型

  3. Android SurfaceFlinger服务的消息队列创建过程分析

  4. Android6.0 显示系统(六) 图像的输出过程

  5. Android图形显示系统(一)

文章目录

  • 一、SurfaceFlinger的启动
    • 1.1 surfaceflinger.rc
    • 1.2 main_surfaceflinger.cpp:main()
    • 1.3 实例化SurfaceFlinger
      • 1.3.1 SurfaceFlinger:onFirstRef()
      • 1.3.2 MessageQueue:init()
    • 1.4 SurfaceFlinger:init()
      • 1.4.1 EventThread
        • 1.4.1.1 DispSyncSource
        • 1.4.1.2 new EventThread()
        • 1.4.1.3 MessageQueue:setEventThread(sf)
        • 1.4.1.4 EventThread.run()
        • 1.4.2.1 HWComposer.setEventHandler(EventHandler*)
        • 1.4.2.2 HWC2:registerVsyncCallback(VsyncCallback)
      • 1.4.3 启动EventControlThread
        • 1.4.3.1 EventControlThread(const sp&)
        • 1.4.3.2 EventControlThread.run()
      • 1.4.4 mDrawingState = mCurrentState;
    • 1.5 SurfaceFlinger:run()
      • 1.5.1 MessageQueue.waitMessage()
      • 1.5.2 MessageQueue.cb_eventReceiver()
      • 1.5.3 MessageQueue:eventReceiver
      • 1.5.4 MessageQueue.handler:dispatchInvalidate()
      • 1.5.5 MessageQueue.handler:handleMessage
      • 1.5.6 SurfaceFlinger:onMessageReceived()
        • 1.5.6.1 SurfaceFlinger:signalLayerUpdate
      • 1.5.8 SurfaceFlinger:handleMessageInvalidate()
      • 1.5.9 SurfaceFlinger:signalRefresh()
        • 1.5.9.1 SurfaceFlinger:handleMessageRefresh()
  • 二、VSync信号的启动与处理
    • 2.1 DisplayEventReceiver
    • 2.1 EventThread:waitForEvent

一、SurfaceFlinger的启动

要理解SurfaceFlinger的工作机制,必须要理解SF所有线程的工作内容。从SF的启动流程入手分析整个SF的工作机制~ PS. 这篇笔记写的时间较早,基于Andorid 8.0(O). 不过大致流程没有变化,凑合看。

1.1 surfaceflinger.rc

Android7.0以后的版本对init.rc脚本进行了重构,将各种服务进行归类拆分,而其中的SurfaceFlinger服务作为独立进程由surfaceflinger.rc脚本启动。

service surfaceflinger /system/bin/surfaceflinger    class core animation    user system    group graphics drmrpc readproc    onrestart restart zygote    writepid /dev/stune/foreground/tasks    socket pdx/system/vr/display/client    stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

这里的 /system/bin/surfaceflinger 可以从Android.mk文件中看到具体启动的代码:

LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"LOCAL_INIT_RC := surfaceflinger.rcifeq ($(TARGET_USES_HWC2),true)    LOCAL_CFLAGS += -DUSE_HWC2endifLOCAL_SRC_FILES := \    main_surfaceflinger.cpp    ......LOCAL_MODULE := surfaceflinger

重点来了:main_surfaceflinger.cpp

1.2 main_surfaceflinger.cpp:main()

int main(int, char**) {    // 从8.0开始,Android提供了hidl机制,将原先直接由    // JNI->Native->HAL的接口调用形式,统一规范成hidl service/client    // 交互形式。该方式从一方面规范和统一了Android Framework和HAL    // 的调用机制,这个是Android O的Treble计划核心,mark一下,有空研究    startHidlServices();        // 忽略SIGPIPE信息,IPC机制中如果客户端关闭了,可能会产生SIGPIPE信号    // 该信号是进程终止信号,SF进程不应该响应这个信号    signal(SIGPIPE, SIG_IGN);    // 设置进程最大线程数为4(主线程不计入),线程过多会影响性能    ProcessState::self()->setThreadPoolMaxThreadCount(4);    // 开启线程池    sp<ProcessState> ps(ProcessState::self());    ps->startThreadPool();    // 1.3 实例化SurfaceFlinger,注意这里的flinger是一个强引用指针    sp<SurfaceFlinger> flinger = new SurfaceFlinger();    // 设置SF进程的优先级为高优先级(PRIORITY_URGENT_DISPLAY = -8)    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);    // 设置为前台调度策略    set_sched_policy(0, SP_FOREGROUND);    // 将SF的大多数线程优先级设为SP_SYSTEM    if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);    // 1.4 初始化SurfaceFlinger    flinger->init();    // 将SF服务添加至ServiceManager中    sp<IServiceManager> sm(defaultServiceManager());    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);    // 添加GpuService至ServiceManager    sp<GpuService> gpuservice = new GpuService();    sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);    struct sched_param param = {0};    param.sched_priority = 2;    if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {        ALOGE("Couldn't set SCHED_FIFO");    }    // 1.5 SF运行在当前线程中    flinger->run();    return 0;}

1.3 实例化SurfaceFlinger

先看一下SurfaceFlinger的定义:

class SurfaceFlinger : public BnSurfaceComposer,    private IBinder::DeathRecipient,    private HWComposer::EventHandler{        ......}

可以看到SF是继承了BnSurfaceComposer、DeathRecipient和 HWComposer::EventHandler的。

  1. BnSurfaceComposer继承了BnInterface,提供onTranscat(SF实现)接口供客户端调用

  2. DeathRecipient是Android的Binder机制提供的死亡监听

  3. HWComposer::EventHandler,这个用来处理来自硬件或软件产生的Vsync信号,包括其他各种消息

SurfaceFlinger::SurfaceFlinger()    :  BnSurfaceComposer(),        mTransactionFlags(0),        mTransactionPending(false),        mAnimTransactionPending(false),        mLayersRemoved(false),        mLayersAdded(false),        mRepaintEverything(0),        mHwc(nullptr), // mHwc = nullptr        mRealHwc(nullptr), // mRealHwc = nullptr        mVrHwc(nullptr),        mRenderEngine(nullptr),         mBootTime(systemTime()),        mBuiltinDisplays(),        mVisibleRegionsDirty(false),        mGeometryInvalid(false),        mAnimCompositionPending(false),        mDebugRegion(0),        mDebugDDMS(0),        mDebugDisableHWC(0),        mDebugDisableTransformHint(0),        mDebugInSwapBuffers(0),        mLastSwapBufferTime(0),        mDebugInTransaction(0),        mLastTransactionTime(0),        mBootFinished(false),        mForceFullDamage(false),        mInterceptor(this),        mPrimaryDispSync("PrimaryDispSync"),        mPrimaryHWVsyncEnabled(false), //mPrimaryHWVsyncEnabled = false        mHWVsyncAvailable(false),        mHasColorMatrix(false),        mHasPoweredOff(false),        mFrameBuckets(),        mTotalTime(0),        mLastSwapTime(0),        mNumLayers(0),        mVrFlingerRequestsDisplay(false){    ALOGI("SurfaceFlinger is starting");    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);    sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);    hasSyncFramework = getBool< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::hasSyncFramework>(true);    useContextPriority = getBool< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::useContextPriority>(false);    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);    maxVirtualDisplaySize = getUInt64(0);    // VrFlinger仅支持DayDream设备    useVrFlinger = getBool< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::useVrFlinger>(false);    maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,            &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);    hasWideColorDisplay =            getBool(false);    // debugging stuff...    char value[PROPERTY_VALUE_MAX];    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");    mGpuToCpuSupported = !atoi(value);    property_get("debug.sf.showupdates", value, "0");    mDebugRegion = atoi(value);    property_get("debug.sf.ddms", value, "0");    mDebugDDMS = atoi(value);    if (mDebugDDMS) {        if (!startDdmConnection()) {            // start failed, and DDMS debugging not enabled            mDebugDDMS = 0;        }    }    ALOGI_IF(mDebugRegion, "showupdates enabled");    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");    property_get("debug.sf.disable_backpressure", value, "0");    mPropagateBackpressure = !atoi(value);    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");    property_get("debug.sf.enable_hwc_vds", value, "0");    mUseHwcVirtualDisplays = atoi(value);    ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");    property_get("ro.sf.disable_triple_buffer", value, "1");    mLayerTripleBufferingDisabled = atoi(value);    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");}

实例化过程中中会启动DDMS调试工具,这里重点注意:mHwc,mRealHwc均为nullptr;且mPrimaryHWVsyncEnabled=false。

1.3.1 SurfaceFlinger:onFirstRef()

智能指针第一被引用时会调用该方法。

void SurfaceFlinger::onFirstRef(){   // 1.3.2 初始化Looper和Handler    mEventQueue.init(this);}

先看下mEventQueue究竟是什么:

class SurfaceFlinger : public BnSurfaceComposer,    private IBinder::DeathRecipient,    private HWComposer::EventHandler{        ......    private:        // 线程安全        mutable MessageQueue mEventQueue;}

MessageQueue的定义:

class MessageQueue {    class Handler : public MessageHandler {        enum {            eventMaskInvalidate    = 0x1, // Invalidate消息            eventMaskRefresh        = 0x2, // Refresh消息            eventMaskTransaction    = 0x4 // Transaction消息        };        MessageQueue& mQueue;        int32_t mEventMask;    public:        explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }        virtual void handleMessage(const Message& message);        void dispatchRefresh();        void dispatchInvalidate();    };    friend class Handler;    sp mFlinger;    sp mLooper;    sp mEventThread;    sp mEvents;    gui::BitTube mEventTube; // BitTube对象,用于Socket监听VSYNC信号    sp mHandler;    static int cb_eventReceiver(int fd, int events, void* data);    int eventReceiver(int fd, int events);public:    enum {        INVALIDATE  = 0,        REFRESH    = 1,    };    MessageQueue();    ~MessageQueue();    void init(const sp& flinger);    void setEventThread(const sp& events);    void waitMessage();    status_t postMessage(const sp& message, nsecs_t reltime=0);    //  下一次接收到 VSYNC 时发送INVALIDATE 消息    void invalidate();    // 下一次接收到 VSYNC 时发送 REFRESH 消息     void refresh();};

1.3.2 MessageQueue:init()

这里的MessageQueue是native层实现的,位于:frameworks/native/services/surfaceflinger/MessageQueue.cpp

void MessageQueue::init(const sp& flinger){    mFlinger = flinger;    mLooper = new Looper(true); //绑定到SF主线程    mHandler = new Handler(*this);}

1.4 SurfaceFlinger:init()

这个方法比较长,主要做了如下工作:

  1. 为OpenGL渲染准备环境;

  2. 启动App EventThread和SF EventThread;

  3. 初始化HWComposer;

  4. 启动EventControlThread;

  5. 初始化图层状态,显示状态,最后启动开机动画线程!

重点关注2,3,4步骤。

void SurfaceFlinger::init() {    ALOGI(  "SurfaceFlinger's main thread ready to run. "            "Initializing graphics H/W...");    ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs);    { // Autolock scope        Mutex::Autolock _l(mStateLock);        // 初始化EGL作为默认显示,为OpenGL渲染准备环境        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);        eglInitialize(mEGLDisplay, NULL, NULL);        // 1.4.1 启动App EventThread,该线程用于接收vsync信号并且上报给App进程,App开始画图        sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync,                vsyncPhaseOffsetNs, true, "app");        mEventThread = new EventThread(vsyncSrc, *this, false);                // 启动SF EventThread,该线程用于SurfaceFlinger接收vsync信号用于渲染        sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,                sfVsyncPhaseOffsetNs, true, "sf");        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);        // 1.4.1.3 创建BitTube并监听其文件描述符        mEventQueue.setEventThread(mSFEventThread);        // 设置App EventThread和SF EventThread线程的调度策略为SCHED_FIFO(实时调度策略,先到先服务)        // 这样可以优化阻塞,更流畅        struct sched_param param = {0};        param.sched_priority = 2;        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");        }        if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {            ALOGE("Couldn't set SCHED_FIFO for EventThread");        }        // 创建渲染引擎,主要是选择EGL配置,选择OpenGL版本,创建OpenGL上下文        // 后续有时间跟进瞅一下        mRenderEngine = RenderEngine::create(mEGLDisplay,                HAL_PIXEL_FORMAT_RGBA_8888);    }    // 暂时不支持vr flinger    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,        "Starting with vr flinger active is not currently supported.");        // 1.4.2 初始化Hwc,这里的参数控制vr Composer    mRealHwc = new HWComposer(false);     mHwc = mRealHwc;    // 1.4.2.1 由SF主线程处理event    mHwc->setEventHandler(static_cast(this));     Mutex::Autolock _l(mStateLock);    // 通知本地图形API是否支持当前时间戳    if (getHwComposer().hasCapability(            HWC2::Capability::PresentFenceIsNotReliable)) {        property_set(kTimestampProperty, "0");    } else {        property_set(kTimestampProperty, "1");    }    if (useVrFlinger) { // 不考虑Vr Flinger         auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {            ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);            mVrFlingerRequestsDisplay = requestDisplay;            signalTransaction();        };        mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),                                            vrFlingerRequestDisplayCallback);        if (!mVrFlinger) {            ALOGE("Failed to start vrflinger");        }    }    // 获取EGL上下文    mEGLContext = mRenderEngine->getEGLContext();    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,            "couldn't create EGLContext");    // 设置当前GL上下文以便创建图层时创建纹理    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);    // 1.4.3 启动EventControlThread,VSync信号闸刀控制线程    mEventControlThread = new EventControlThread(this);    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);    // 1.4.4 初始化绘图状态    // mDrawingState : 上一次绘图图层状态    // mCurrentState : 当前图层状态    mDrawingState = mCurrentState;    // 初始化显示状态    initializeDisplays();    // 内存缓存增强    mRenderEngine->primeCache();    // 启动开机动画线程!    mStartBootAnimThread = new StartBootAnimThread();    if (mStartBootAnimThread->Start() != NO_ERROR) {        ALOGE("Run StartBootAnimThread failed!");    }    ALOGV("Done initializing");}

1.4.1 EventThread

App EventThread和SF EventThread的区别除了名称,只在于相移phase offset。

名称|作用|相移

—|---|—

app|用于接收vsync信号并且上报给App进程,App开始画图|VSYNC_EVENT_PHASE_OFFSET_NS

sf|用于SurfaceFlinger接收vsync信号用于渲染|SF_VSYNC_EVENT_PHASE_OFFSET_NS

这两个值都可配,这两个一般用来调节performance. 具体可在 BoardConfig.mk里配置。

这里要解释下相移的作用。Android 4.1(Jelly Bean)引入了Vsync(Vertical Syncronization)用于渲染同步,使得App UI和SurfaceFlinger可以按硬件产生的VSync节奏来进行工作。

但新的问题产生了,App UI和SurfaceFlinger的工作都是流水线模型,对应一帧内容,AppUI先绘制完毕后由SurfaceFlinger合成渲染放入FrameBuffer,最终显示到屏幕上。这样从AppUI接收到Vsync信号到最终显示过去了2个Vsync周期(2 * 16.6ms),严重影响体验。针对这个问题Android4.4引入了虚拟Vsync,也就是将硬件产生的Vsync信号同步到本地Vsync模型后一分为二,引出两个Vsync线程,如下图:

为了好理解,做个假设:产生Vsync信号,先通知AppUI绘制,一段时间后通知SurfaceFlinger合成。如果AppUI绘制速度够快,SurfaceFlinger就可以不用等待而直接渲染合成图像了。

理解这个,app和sf EventThread我们就看其中一个的初始化即可。

先瞅瞅DispSyncSource,该类继承了VSyncSource,实现了其虚函数,主要功能恰如其名:设置相移、Vsync开关和提供接收Vsync事件的回调。

1.4.1.1 DispSyncSource

// 定义在SurfaceFlinger.cpp中class DispSyncSource : public VSyncSource, private DispSync::Callback {public:    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,        const char* name) :            mName(name),            mValue(0),            mTraceVsync(traceVsync),            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),            mVsyncEventLabel(String8::format("VSYNC-%s", name)),            mDispSync(dispSync),            mCallbackMutex(),            mCallback(),            mVsyncMutex(),            mPhaseOffset(phaseOffset),            mEnabled(false) {}  // 默认mEnable为false        ......};// 定义在EventThread.h文件中 class VSyncSource : public virtual RefBase {public:    class Callback: public virtual RefBase {    public:        virtual ~Callback() {}        virtual void onVSyncEvent(nsecs_t when) = 0;    };    virtual ~VSyncSource() {}    virtual void setVSyncEnabled(bool enable) = 0;    virtual void setCallback(const sp& callback) = 0;    virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;};

1.4.1.2 new EventThread()

照惯例,初始化之前看看EventThread的定义:

class EventThread : public Thread, private VSyncSource::Callback {    class Connection : public BnDisplayEventConnection {    public:        explicit Connection(const sp& eventThread);        status_t postEvent(const DisplayEventReceiver::Event& event);        // count >= 1 : 连续vsync事件,count为vsync频次        // count == 0 : 一次vsync事件        // count ==-1 : one-shot event that fired this round / disabled        int32_t count;    private:        virtual ~Connection();        virtual void onFirstRef();         status_t stealReceiveChannel(gui::BitTube* outChannel) override; // 设置BitTube通道        status_t setVsyncRate(uint32_t count) override; // 设置Vsync频率        void requestNextVsync() override;    // 异步请求Vsync        sp const mEventThread;        gui::BitTube mChannel; // 用于Vsync信号传输的BitTube    };public:    EventThread(const sp& src, SurfaceFlinger& flinger, bool interceptVSyncs);    sp createEventConnection() const;    status_t registerDisplayEventConnection(const sp& connection);    void setVsyncRate(uint32_t count, const sp& connection);    void requestNextVsync(const sp& connection);    // called before the screen is turned off from main thread    void onScreenReleased();    // called after the screen is turned on from main thread    void onScreenAcquired();    // called when receiving a hotplug event    void onHotplugReceived(int type, bool connected);    Vector< sp > waitForEvent(            DisplayEventReceiver::Event* event);    void dump(String8& result) const;    void sendVsyncHintOff();    void setPhaseOffset(nsecs_t phaseOffset);private:    virtual bool        threadLoop();    virtual void        onFirstRef();    virtual void onVSyncEvent(nsecs_t timestamp);    void removeDisplayEventConnection(const wp& connection);    void enableVSyncLocked();    void disableVSyncLocked();    void sendVsyncHintOnLocked();    // constants    sp mVSyncSource;    PowerHAL mPowerHAL;    SurfaceFlinger& mFlinger;    mutable Mutex mLock;    mutable Condition mCondition;    // protected by mLock    SortedVector< wp > mDisplayEventConnections;    Vector< DisplayEventReceiver::Event > mPendingEvents;    DisplayEventReceiver::Event mVSyncEvent[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];    bool mUseSoftwareVSync;    bool mVsyncEnabled;    // for debugging    bool mDebugVsyncEnabled;    bool mVsyncHintSent;    const bool mInterceptVSyncs;    timer_t mTimerId;};

不难发现,EventThread除了继承Thread,同时还是VSyncSource的内部类Callback的子类。并且还有一个继承了BnDisplayEventConnection的内部类Connection。

这个Connection的作用是作为服务端分发Vsync信号给app或者sf进程,后面详细介绍。

// 初始化EventThread::EventThread(const sp& src, SurfaceFlinger& flinger, bool interceptVSyncs)    : mVSyncSource(src), // Vsync事件源:1、app;2、sf      mFlinger(flinger),      mUseSoftwareVSync(false),      mVsyncEnabled(false),      mDebugVsyncEnabled(false),      mVsyncHintSent(false),      mInterceptVSyncs(interceptVSyncs) {    // DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES默认为2,也就是默认最多支持双屏显示    // 初始化 mVSyncEvent     for (int32_t i=0 ; i

1.4.1.3 MessageQueue:setEventThread(sf)

void MessageQueue::setEventThread(const sp& eventThread){    mEventThread = eventThread;    // 创建BitTube连接    mEvents = eventThread->createEventConnection();    // 获取BitTube文件描述符         mEvents->stealReceiveChannel(&mEventTube);    // SF主线程监听该文件描述符,重点注意这里传入    // 的回调函数:cb_eventReceiver,后续会遇到的    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,            MessageQueue::cb_eventReceiver, this);}    

1.4.1.4 EventThread.run()

上面的初始化过程很完美,但总感觉少了什么。EventThread线程是什么时候run的呢?仔细看SurfaceFlinger.h中关于EventThread的定义。

    // SurfaceFlinger.h:两个强引用类型    sp mEventThread;    sp mSFEventThread;

所以看EventThread:onFirstRef

void EventThread::onFirstRef() {    // 这里运行该线程,设置调度策略    run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);}bool EventThread::threadLoop() {    DisplayEventReceiver::Event event;    Vector< sp > signalConnections;    // 2.1 等待Vsync事件,其实也将本线程注册进监听了DispSync    signalConnections = waitForEvent(&event);    // 分发事件给监听者    const size_t count = signalConnections.size();    for (size_t i=0 ; i& conn(signalConnections[i]);        // 上报该事件        status_t err = conn->postEvent(event);        if (err == -EAGAIN || err == -EWOULDBLOCK) {            // 目标不接收事件,可能队列已满,现在直接丢弃            ALOGW("EventThread: dropping event (%08x) for connection %p",                    event.header.type, conn.get());        } else if (err < 0) {            // 处理pipe错误            removeDisplayEventConnection(signalConnections[i]);        }    }    return true;}
#### 1.4.1.5 EventThread.Connection:postEvent() ```c++ status_t EventThread::Connection::postEvent(
    const DisplayEventReceiver::Event& event) {// 通过BitTube发送Vsync事件。这里Send的事件,会被SurfaceFlinger主线程// 响应,也就是MessageQueue.hanlder,1.4.1.3:MessageQueue:setEventThread(sf)ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);return size < 0 ? status_t(size) : status_t(NO_ERROR);

}

### 1.4.2 初始化HWComposer回到1.4 SurfaceFlinger.init()方法,初始化的HWComposer是负责接收并转发来自硬件的VSync信号。```c++HWComposer::HWComposer(bool useVrComposer)    : mHwcDevice(),      mDisplayData(2),      mFreeDisplaySlots(),      mHwcDisplaySlots(),      mCBContext(),      mEventHandler(nullptr),      mVSyncCounts(),      mRemainingHwcVirtualDisplays(0){   // HWC_NUM_PHYSICAL_DISPLAY_TYPES = 2    for (size_t i=0 ; i

1.4.2.1 HWComposer.setEventHandler(EventHandler*)

设置HWC的EventHandler,这里传入的handler就是继承了EventHandler的SurfaceFlinger本身。

void HWComposer::setEventHandler(EventHandler* handler){    if (handler == nullptr) {        ALOGE("setEventHandler: Rejected attempt to clear handler");        return;    }    bool wasNull = (mEventHandler == nullptr);    mEventHandler = handler;    // 第一次设置EventHandler时进入    if (wasNull) {        // 注册热插拔回调        auto hotplugHook = std::bind(&HWComposer::hotplug, this,                std::placeholders::_1, std::placeholders::_2);        mHwcDevice->registerHotplugCallback(hotplugHook);        // 注册刷新回调        auto invalidateHook = std::bind(&HWComposer::invalidate, this,                std::placeholders::_1);        mHwcDevice->registerRefreshCallback(invalidateHook);        // 1.4.2.2 注册Vsync回调,注意这里传入的参数 &HWComposer::vsync        auto vsyncHook = std::bind(&HWComposer::vsync, this,                std::placeholders::_1, std::placeholders::_2);        mHwcDevice->registerVsyncCallback(vsyncHook);    }}

1.4.2.2 HWC2:registerVsyncCallback(VsyncCallback)

这里为display注册监听了vsync,这里稍稍注意下传入的参数类型:

VsyncCallback : typedef std::function VsyncCallback;

这是个函数指针,c++11引入的标准,暂时只要明确这是一个回调。

void Device::registerVsyncCallback(VsyncCallback vsync){    mVsync = vsync;    for (auto& pending : mPendingVsyncs) {        auto& display = pending.first;        auto timestamp = pending.second;        mVsync(std::move(display), timestamp); // 传入display    }}

这里已经准备好接收Vsync信号了,但接下来我们继续分析SurfaceFlinger的启动。

1.4.3 启动EventControlThread

Andorid5.0以后,专门启用一个线程控制Vsync信号,这个线程就是EventControlThread,先看下定义:

class EventControlThread: public Thread {public:    explicit EventControlThread(const sp& flinger);    virtual ~EventControlThread() {}    void setVsyncEnabled(bool enabled);    virtual bool threadLoop();private:    sp mFlinger;    bool mVsyncEnabled;    Mutex mMutex;    Condition mCond;};

定义很简单,继承了Thread类,持有一个SurfaceFlinger的强引用。

1.4.3.1 EventControlThread(const sp&)

EventControlThread::EventControlThread(const sp& flinger):        mFlinger(flinger),        mVsyncEnabled(false) { // 默认禁止Vsync信号,当然了,原因SF现在还没准备好嘛}

1.4.3.2 EventControlThread.run()

android native中的Thread.run就是不断运行threadLoop()。

这里通过Condition来控制SurfaceFlinger是否接收Vsync信号。

bool EventControlThread::threadLoop() {    Mutex::Autolock lock(mMutex); //持锁    bool vsyncEnabled = mVsyncEnabled;#ifdef USE_HWC2    mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);#else    mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,            mVsyncEnabled);#endif    while (true) {        // mCond阻塞,通过信号量控制        status_t err = mCond.wait(mMutex);        if (err != NO_ERROR) {            ALOGE("error waiting for new events: %s (%d)",                strerror(-err), err);            return false;        }        // 解除阻塞后,如果开关状态发生变化,调用mFlinger->eventControl        // 之后保存当前开关状态        if (vsyncEnabled != mVsyncEnabled) {#ifdef USE_HWC2            mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);#else            mFlinger->eventControl(HWC_DISPLAY_PRIMARY,                    SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);#endif            vsyncEnabled = mVsyncEnabled;        }    }    return false;}

看完这个函数自然有两个疑问,谁控制mCond?SF->eventControl的作用?先不着急,回到SurfaceFlinger.init()继续分析SF的启动流程。

1.4.4 mDrawingState = mCurrentState;

需要看这个State的定义–在SurfaceFlinger.h文件中;State是个私有内部类,主要功能是按照Z轴顺序储存了一组layer。

private:    class State {    public:        explicit State(LayerVector::StateSet set) : stateSet(set) {}        State& operator=(const State& other) {            // We explicitly don't copy stateSet so that, e.g., mDrawingState            // always uses the Drawing StateSet.            layersSortedByZ = other.layersSortedByZ;            displays = other.displays;            return *this;        }        const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;        LayerVector layersSortedByZ;        DefaultKeyedVector< wp, DisplayDeviceState> displays;        void traverseInZOrder(const LayerVector::Visitor& visitor) const;        void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;    };    // 必须被mStateLock锁保护    State mCurrentState{LayerVector::StateSet::Current};    // 只能被SF主线程访问,不需要同步    State mDrawingState{LayerVector::StateSet::Drawing};

1.5 SurfaceFlinger:run()

在初始化所有资源和状态后,SF开始处理。

void SurfaceFlinger::run() {    do {        // 死循环一直执行。        waitForEvent();    } while (true);}void SurfaceFlinger::waitForEvent() {    // 1.5.1 上面分析得知,mEventQueue是MessageQueue类型    mEventQueue.waitMessage();}

1.5.1 MessageQueue.waitMessage()

void MessageQueue::waitMessage() {    do {        IPCThreadState::self()->flushCommands();        // 1.5.2 重点在这里,Looper接收消息给主线程的handler处理        //([1.3.2]MessageQueue.init & [1.4.1.3]MessageQueue:setEventThread)。        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");                continue;            case Looper::POLL_TIMEOUT:                // timeout (should not happen)                continue;            default:                // should not happen                ALOGE("Looper::pollOnce() returned unknown status %d", ret);                continue;        }    } while (true); // 双重死循环??}

1.5.2 MessageQueue.cb_eventReceiver()

从1.4.1.3MessageQueue:setEventThread 可知对应Fd有事件,会调用这个回调函数。

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {    MessageQueue* queue = reinterpret_cast(data);    //1.5.3    return queue->eventReceiver(fd, events);}

1.5.3 MessageQueue:eventReceiver

int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {    ssize_t n;    DisplayEventReceiver::Event buffer[8];    // 从BitTube读取事件    while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {        for (int i=0 ; idispatchInvalidate();                break;            }        }    }    return 1;}

1.5.4 MessageQueue.handler:dispatchInvalidate()

void MessageQueue::Handler::dispatchInvalidate() {    // 给mEventMask标上eventMaskInvalidate标识,表明SurfaceFlinger正在处理Invalidate事件    // 这也说明了如果SF正在处理消息时,会忽略重复的消息    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {        // 通过Looper发送INVALIDATE消息        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));    }}

这里就有个问题,为什么通过BitTube读取的事件不直接处理,反而要多此一举重新进入消息队列处理呢?:

1.5.5 MessageQueue.handler:handleMessage

void MessageQueue::Handler::handleMessage(const Message& message) {    switch (message.what) {        case INVALIDATE:            // 移除标识,表明可以接收处理下一次事件            android_atomic_and(~eventMaskInvalidate, &mEventMask);            // 1.5.6 转交给SF处理咯            mQueue.mFlinger->onMessageReceived(message.what);            break;        case REFRESH:            android_atomic_and(~eventMaskRefresh, &mEventMask);            mQueue.mFlinger->onMessageReceived(message.what);            break;    }}

1.5.6 SurfaceFlinger:onMessageReceived()

void SurfaceFlinger::onMessageReceived(int32_t what) {    ATRACE_CALL();    switch (what) {        case MessageQueue::INVALIDATE: {            // 这个frameMissed 暂时还没看出是什么意思,涉及到Fence机制            // 先从字面意思理解,这里判断是否跳过该帧            bool frameMissed = !mHadClientComposition &&                    mPreviousPresentFence != Fence::NO_FENCE &&                    (mPreviousPresentFence->getSignalTime() ==                            Fence::SIGNAL_TIME_PENDING);            ATRACE_INT("FrameMissed", static_cast(frameMissed));            if (mPropagateBackpressure && frameMissed) {                ALOGD("Backpressure trigger, skipping transaction & refresh!");                // 1.5.6.1 请求Vsync信号                // Backpressure被触发,frameMissed = true,跳过此次的Transaction和refresh                signalLayerUpdate();                break;            }            // 目前忽略VrFlinger            updateVrFlinger();  // 1.5.7 处理Transaction消息,每个layer处理(doTransaction)            bool refreshNeeded = handleMessageTransaction();            // 1.5.8 处理Invalidate消息,重绘            refreshNeeded |= handleMessageInvalidate();            refreshNeeded |= mRepaintEverything;            if (refreshNeeded) {                // 1.5.9 如果事务修改了窗口状态,锁定了新的缓冲区,                // 或者HWC请求完全重新绘制,则发出刷新信号                signalRefresh();            }            break;        }        case MessageQueue::REFRESH: {            // 1.5.9.1 刷新            handleMessageRefresh();            break;        }    }}

1.5.6.1 SurfaceFlinger:signalLayerUpdate

这个方法最终是通过SurfaceFlinger请求Vsync信号,为什么绕个圈子请求?注意 mCondition.broadcast

void SurfaceFlinger::signalLayerUpdate() {    // 通过MessageQueue使EventThread请求下一次Vsync信号    mEventQueue.invalidate();}// MessageQueue.cppvoid MessageQueue::invalidate() {    // 1.5.6.2 这里的 mEvents 是EventThread.Connection    mEvents->requestNextVsync();}
#### 1.5.6.2 EventThread::Connection::requestNextVsync() ```c++

void EventThread::Connection::requestNextVsync() {

mEventThread->requestNextVsync(this);

}

void EventThread::requestNextVsync(

    const sp& connection) {Mutex::Autolock _l(mLock);// SF向硬件请求Vsync,两次请求间隔必须大于500ns,否则忽略mFlinger.resyncWithRateLimit();if (connection->count < 0) {    connection->count = 0;    // 通知有Vsync信号来了,1.4.1.4:EventThread:threadLoop()中    // waitForEvent 终于等到事件了。    mCondition.broadcast();}

}

### 1.5.7 SurfaceFlinger:handleMessageTransaction()```c++void SurfaceFlinger::handleTransaction(uint32_t transactionFlags){    ATRACE_CALL();    // 拷贝mDrawingState副本,避免死锁    State drawingState(mDrawingState);    Mutex::Autolock _l(mStateLock);    const nsecs_t now = systemTime();    mDebugInTransaction = now;    // 标记Transaction    transactionFlags = getTransactionFlags(eTransactionMask);    // 这部分代码过长,稍后分析。主要功能是调用每个 Layer    // 的 doTransaction,处理系统在两次刷新期间的各种变化    handleTransactionLocked(transactionFlags);    mLastTransactionTime = systemTime() - now;    mDebugInTransaction = 0;    invalidateHwcGeometry();}

1.5.8 SurfaceFlinger:handleMessageInvalidate()

bool SurfaceFlinger::handleMessageInvalidate() {    ATRACE_CALL();    // 重绘,更新每个layer状态,后续分析    return handlePageFlip();}

1.5.9 SurfaceFlinger:signalRefresh()

这里的流程是通过MessageQueue将Refresh消息添加至消息队列后,回到SurfaceFlinger处理。

MessageQueue.handler收到REFRESH消息,转交给SurfaceFlinger:onMessageReceived处理。

void SurfaceFlinger::signalRefresh() {    mEventQueue.refresh();}// MessageQueue.cppvoid MessageQueue::refresh() {    mHandler->dispatchRefresh();}void MessageQueue::Handler::dispatchRefresh() {    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));    }}void MessageQueue::Handler::handleMessage(const Message& message) {    switch (message.what) {        case INVALIDATE:            android_atomic_and(~eventMaskInvalidate, &mEventMask);            mQueue.mFlinger->onMessageReceived(message.what);            break;        case REFRESH:            android_atomic_and(~eventMaskRefresh, &mEventMask);            // 1.5.6 回到SF处理该消息            mQueue.mFlinger->onMessageReceived(message.what);            break;    }}

1.5.9.1 SurfaceFlinger:handleMessageRefresh()

处理刷新,SF的消息处理流程复杂。这刷新操作后续分析。

void SurfaceFlinger::handleMessageRefresh() {    ATRACE_CALL();    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);    preComposition(refreshStartTime);    rebuildLayerStacks();    setUpHWComposer();    doDebugFlashRegions();    doComposition();    postComposition(refreshStartTime);    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);    mHadClientComposition = false;    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {        const sp& displayDevice = mDisplays[displayId];        mHadClientComposition = mHadClientComposition ||                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());    }    mLayersWithQueuedFrames.clear();}

好了,SF启动流程分析完了。

二、VSync信号的启动与处理

SF启动完成了,万事俱备就等着硬件设备的Vsync信号了~等一下,Vsync信号是怎么传递给SF的呢?
1.4.1.4 EventThread.run()中等待Vsync信号,我们从这里开始分析,在分析之前先看一下DisplayEventReceiver这个类。

2.1 DisplayEventReceiver

这个类其实就是传输VSync信号,也包括Hotplug事件。先看定义:

class DisplayEventReceiver {public:    enum {        DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'), // vsyn        DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'), // plug    };    struct Event {        struct Header {            uint32_t type; // 事件类型:1、vsyn;2、plug            uint32_t id; // 0:vsyn plug:plug            nsecs_t timestamp __attribute__((aligned(8))); // 时间戳        };        struct VSync {            uint32_t count;        };        struct Hotplug {            bool connected;        };        Header header;         union {            VSync vsync;            Hotplug hotplug;        };    };public:    // DisplayEventReceiver创建并注册了SF的一个事件连接,默认禁止VSync    // 通过调用setVSyncRate、requestNextVsync开始接受。其他事件则即刻分发    DisplayEventReceiver(            ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);    ~DisplayEventReceiver();    status_t initCheck() const;    // 获取用于接收事件的文件描述符,该描述符由本类持有,不得关闭    int getFd() const;    // 从队列中读取事件并返回事件个数如果返回NOT_ENOUGH_DATA    // 表示这个对象永远无效,不能继续调用本方法    ssize_t getEvents(Event* events, size_t count);    static ssize_t getEvents(gui::BitTube* dataChannel, Event* events, size_t count);    // 向队列中写入事件并返回写入的数量    static ssize_t sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count);    // 设置VSync分发频率,每次VSync事件返回1,其他事件返回2,没有事件返回0。    status_t setVsyncRate(uint32_t count);    // 请求下一次Vsync    status_t requestNextVsync();private:    sp mEventConnection;    std::unique_ptr mDataChannel;};

2.1 EventThread:waitForEvent

Vector< sp > EventThread::waitForEvent(        DisplayEventReceiver::Event* event){    Mutex::Autolock _l(mLock);    Vector< sp > signalConnections;    do {        bool eventPending = false;        bool waitForVSync = false;        size_t vsyncCount = 0;        nsecs_t timestamp = 0;        // 从mVSyncEvent数组中读取timestamp        // 其实只有mVSyncEvent[0]中存入了Vsync事件信息        for (int32_t i=0 ; i connection(mDisplayEventConnections[i].promote());            if (connection != NULL) {                bool added = false;                if (connection->count >= 0) {                    // we need vsync events because at least                    // one connection is waiting for it                    waitForVSync = true;                    if (timestamp) {                        // we consume the event only if it's time                        // (ie: we received a vsync event)                        if (connection->count == 0) {                            // fired this time around                            connection->count = -1;                            signalConnections.add(connection);                            added = true;                        } else if (connection->count == 1 ||                                (vsyncCount % connection->count) == 0) {                            // continuous event, and time to report it                            signalConnections.add(connection);                            added = true;                        }                    }                }                if (eventPending && !timestamp && !added) {                    // we don't have a vsync event to process                    // (timestamp==0), but we have some pending                    // messages.                    signalConnections.add(connection);                }            } else {                // we couldn't promote this reference, the connection has                // died, so clean-up!                mDisplayEventConnections.removeAt(i);                --i; --count;            }        }        // 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();        }        // note: !timestamp implies signalConnections.isEmpty(), because we        // don't populate signalConnections if there's no vsync pending        if (!timestamp && !eventPending) {            // wait for something to happen            if (waitForVSync) {                // This is where we spend most of our time, waiting                // for vsync events and new client registrations.                //                // If the screen is off, we can't use h/w vsync, so we                // use a 16ms timeout instead.  It doesn't need to be                // precise, we just need to keep feeding our clients.                //                // We don't want to stall if there's a driver bug, so we                // use a (long) timeout when waiting for h/w vsync, and                // generate fake events when necessary.                bool softwareSync = mUseSoftwareVSync;                nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);                if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {                    if (!softwareSync) {                        ALOGW("Timed out waiting for hw vsync; faking it");                    }                    // FIXME: how do we decide which display id the fake                    // vsync came from ?                    mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;                    mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;                    mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);                    mVSyncEvent[0].vsync.count++;                }            } else {                // Nobody is interested in vsync, so we just want to sleep.                // h/w vsync should be disabled, so this will wait until we                // get a new connection, or an existing connection becomes                // interested in receiving vsync again.                mCondition.wait(mLock);            }        }    } while (signalConnections.isEmpty());    // here we're guaranteed to have a timestamp and some connections to signal    // (The connections might have dropped out of mDisplayEventConnections    // while we were asleep, but we'll still have strong references to them.)    return signalConnections;}

这里是初动力,来自硬件的vsync信号:

void HWComposer::vsync(const std::shared_ptr& display,        int64_t timestamp) {    auto displayType = HWC2::DisplayType::Invalid;    auto error = display->getType(&displayType);    if (error != HWC2::Error::None) {        ALOGE("vsync: Failed to determine type of display %" PRIu64,                display->getId());        return;    }    if (displayType == HWC2::DisplayType::Virtual) {        ALOGE("Virtual display %" PRIu64 " passed to vsync callback",                display->getId());        return;    }    if (mHwcDisplaySlots.count(display->getId()) == 0) {        ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",                display->getId());        return;    }    int32_t disp = mHwcDisplaySlots[display->getId()];    {        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);    // 收到Vsync,发送给mEventHandler,也就是SurfaceFlinger    mEventHandler->onVSyncReceived(this, disp, timestamp);}

Vsync信号不仅仅只有来自HWC的硬件Vsync,也有使用软件模拟的Vsync,甚至大多数情况下app收到的vsync信号都是来自软件模拟的。更多请关注DispSync探秘。

更多相关文章

  1. Android-防止事件导致的oncreate的多次调用
  2. 基于TCP和多线程实现无线鼠标键盘-Socket(2)
  3. cocos2dx android平台事件系统解析
  4. android中在子线程中更新UI的几种方法
  5. android利用handler线程间的通信
  6. 关于Android在非UI线程更新UI的问题。
  7. android 线程通信Handler Bundle

随机推荐

  1. android书
  2. Android(安卓)View转换成图片保存
  3. Android之Button练习
  4. Android(安卓)“No Class Deff. Find Err
  5. Android弹出软键盘工具类
  6. android eclipse 项目相互引用设置
  7. Android五子连珠
  8. android java 3des加密 ECB/CBC
  9. Android(安卓)封装http请求的工具类
  10. Android(安卓)线程同步 ConditionVariabl