Android UI架构(四)--SurfaceFlinger的初始化.md

参考:

  1. Vsync虚拟化

  2. Android SurfaceFlinger SW Vsync模型

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

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

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


一、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.rc
ifeq ($(TARGET_USES_HWC2),true)
    LOCAL_CFLAGS += -DUSE_HWC2
endif
LOCAL_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<ISurfaceFlingerConfigs,
            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);

    // VrFlinger仅支持DayDream设备
    useVrFlinger = getBool< ISurfaceFlingerConfigs,
            &ISurfaceFlingerConfigs::useVrFlinger>(false);

    maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,
            &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);

    hasWideColorDisplay =
            getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(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<SurfaceFlinger> mFlinger;
    sp<Looper> mLooper;
    sp<EventThread> mEventThread;
    sp<IDisplayEventConnection> mEvents;
    gui::BitTube mEventTube; // BitTube对象,用于Socket监听VSYNC信号
    sp<Handler> 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<SurfaceFlinger>& flinger);
    void setEventThread(const sp<EventThread>& events);
    void waitMessage();
    status_t postMessage(const sp<MessageBase>& 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<SurfaceFlinger>& 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<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
                vsyncPhaseOffsetNs, true, "app");
        mEventThread = new EventThread(vsyncSrc, *this, false);
        // 启动SF EventThread,该线程用于SurfaceFlinger接收vsync信号用于渲染
        sp<VSyncSource> 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, &param) != 0) {
            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
        }
        if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, &param) != 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<HWComposer::EventHandler*>(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>& 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>& 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<EventThread> const mEventThread;
        gui::BitTube mChannel; // 用于Vsync信号传输的BitTube
    };
public:
    EventThread(const sp<VSyncSource>& src, SurfaceFlinger& flinger, bool interceptVSyncs);

    sp<Connection> createEventConnection() const;
    status_t registerDisplayEventConnection(const sp<Connection>& connection);
    void setVsyncRate(uint32_t count, const sp<Connection>& connection);
    void requestNextVsync(const sp<Connection>& 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<EventThread::Connection> > 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>& connection);

    void enableVSyncLocked();
    void disableVSyncLocked();
    void sendVsyncHintOnLocked();

    // constants
    sp<VSyncSource> mVSyncSource;
    PowerHAL mPowerHAL;
    SurfaceFlinger& mFlinger;
    mutable Mutex mLock;
    mutable Condition mCondition;

    // protected by mLock
    SortedVector< wp<Connection> > 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<VSyncSource>& 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<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; // 指定事件类型
        mVSyncEvent[i].header.id = 0;
        mVSyncEvent[i].header.timestamp = 0;
        mVSyncEvent[i].vsync.count =  0;
    }
    struct sigevent se;
    se.sigev_notify = SIGEV_THREAD;
    se.sigev_value.sival_ptr = this;
    se.sigev_notify_function = vsyncOffCallback;
    se.sigev_notify_attributes = NULL;
    // 设置定时器,以系统开机时间为准
    // CLOCK_MONOTONIC : 单调递增时间
    timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
}

1.4.1.3 MessageQueue:setEventThread(sf)

void MessageQueue::setEventThread(const sp<EventThread>& 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<EventThread> mEventThread;
    sp<EventThread> mSFEventThread;

所以看EventThread:onFirstRef


void EventThread::onFirstRef() {
    // 这里运行该线程,设置调度策略
    run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}

bool EventThread::threadLoop() {
    DisplayEventReceiver::Event event;
    Vector< sp<EventThread::Connection> > signalConnections;
    // 2.1 等待Vsync事件,其实也将本线程注册进监听了DispSync
    signalConnections = waitForEvent(&event);
    // 分发事件给监听者
    const size_t count = signalConnections.size();
    for (size_t i=0 ; i<count ; i++) {
        const sp<Connection>& 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信号。

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<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
        mLastHwVSync[i] = 0;
        mVSyncCounts[i] = 0;
    }
    // 加载HWC模块,即处理对应的so文件
    loadHwcModule(useVrComposer);
}
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<void(std::shared_ptr, nsecs_t)> 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<SurfaceFlinger>& flinger);
    virtual ~EventControlThread() {}
    void setVsyncEnabled(bool enabled);
    virtual bool threadLoop();
private:
    sp<SurfaceFlinger> mFlinger;
    bool mVsyncEnabled;
    Mutex mMutex;
    Condition mCond;
};

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

1.4.3.1 EventControlThread(const sp&)

EventControlThread::EventControlThread(const sp<SurfaceFlinger>& 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<IBinder>, 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<MessageQueue *>(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 ; i<n ; i++) {
            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                // 1.5.4 分发给handler处理
                mHandler->dispatchInvalidate();
                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<int>(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.cpp
void MessageQueue::invalidate() {
    // 1.5.6.2 这里的 mEvents 是EventThread.Connection
    mEvents->requestNextVsync();
}
#### 1.5.6.2 EventThread::Connection::requestNextVsync()
void EventThread::Connection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
}

void EventThread::requestNextVsync(
        const sp<EventThread::Connection>& 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()

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.cpp
void 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>& 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<IDisplayEventConnection> mEventConnection;
    std::unique_ptr<gui::BitTube> mDataChannel;
};

2.1 EventThread:waitForEvent

Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
        DisplayEventReceiver::Event* event)
{
    Mutex::Autolock _l(mLock);
    Vector< sp<EventThread::Connection> > 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<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
            timestamp = mVSyncEvent[i].header.timestamp;
            if (timestamp) {
                // 存在VSync事件,分发
                if (mInterceptVSyncs) {
                    mFlinger.mInterceptor.saveVSyncEvent(timestamp);
                }
                *event = mVSyncEvent[i];
                mVSyncEvent[i].header.timestamp = 0;
                vsyncCount = mVSyncEvent[i].vsync.count;
                break;
            }
        }
        // 时间戳为0,处理非VSync事件--Hotplug
        if (!timestamp) {
            eventPending = !mPendingEvents.isEmpty();
            if (eventPending) {
                *event = mPendingEvents[0];
                mPendingEvents.removeAt(0);
            }
        }

        // find out connections waiting for events
        size_t count = mDisplayEventConnections.size();
        for (size_t i=0 ; i<count ; i++) {
            sp<Connection> 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<HWC2::Display>& 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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值