参考:

  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. cocos2dx android平台事件系统解析
  2. 基于TCP和多线程实现无线鼠标键盘-Socket(2)
  3. Android中有关Handler的使用(三)
  4. Android(安卓)Studio中与网站通信
  5. Android异步加载图片,并缓存到SD卡
  6. Android-防止事件导致的oncreate的多次调用
  7. 【Android】报错:Can't create handler inside thread that has n
  8. Android输入法之输入系统
  9. android中在子线程中更新UI的几种方法

随机推荐

  1. ScaleImageView图片缩放查看器
  2. Android之旅 -- ARouter 使用介绍(一)
  3. android数据保存
  4. 在android中使用Realm数据库
  5. Android,一个函数实现指南针
  6. android classes.dex 反编译
  7. Android(安卓)Studio下,如何解决:java-An
  8. Android(安卓)带checkbox的listView 实现
  9. 手机扫描二维码下载APP,根据操作系统不同
  10. Android(安卓)imageView 自定义单个或多