zoukankan      html  css  js  c++  java
  • Android 显示系统:Vsync机制

    一、Vsync简介:

      屏幕的刷新过程是每一行从左到右(行刷新,水平刷新,Horizontal Scanning),从上到下(屏幕刷新,垂直刷新,Vertical Scanning)。当整个屏幕刷新完毕,即一个垂直刷新周期完成,会有短暂的空白期,此时发出 VSync 信号。所以,VSync 中的 V 指的是垂直刷新中的垂直-Vertical。

      Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,VSync是Vertical Synchronization(垂直同步)的缩写,是一种在PC上很早就广泛使用的技术,可以简单的把它认为是一种定时中断。而在Android 4.1(JB)中已经开始引入VSync机制,用来同步渲染,让AppUI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。

    二、黄油计划:三个方法改进显示系统

     1.Vsync同步:

      

      可见vsync信号没有提醒CPU/GPU工作的情况下,第二次vsync到来需要显示内容时,CPU和GPU还没有来得及准备好下一帧的数据,所以只能接着显示上一帧的数据,产生Jank!

      CPU/GPU接收vsync信号提前准备下一帧要显示的内容,所以能够及时准备好每一帧的数据,保证画面的流程。

     2.多级缓冲:

      除了Vsync的机制,Android还使用了多级缓冲的手段以优化UI流程度,例如双缓冲(A+B),在显示buffer A的数据时,CPU/GPU就开始在buffer B中准备下一帧数据:

      

      

       但是不能保证每一帧CPU、GPU都运行状态良好,可能由于资源抢占等性能问题导致某一帧GPU掉链子,vsync信号到来时buffer B的数据还没准备好,而此时Display又在显示buffer A的数据,导致后面CPU/GPU没有新的buffer着手准备数据,空白时间无事可做,后面Jank频出:

      

       因此用三级缓冲来提高系统对性能波动的容忍度:

      

       虽然GPU在准备buffer B的数据耗时过长,第二帧Jank,但是新增1个buffer可以减少CPU和GPU在vsync同步间的空白间隙,此时CPU/GPU能够利用buffer C继续工作,所以后面就不会再产生Jank了,当然具体使用多少个buffer要根据实际硬件性能情况调整,最终目的就是解决Display的Jank产生。

     3.Vsync虚拟化(Vsync App + Vsync SurfaceFlinger):

      虽然vsync使得CPU/GPU/Display同步了,但App UI和SurfaceFlinger的工作显然是一个流水线的模型。即对于一帧内容,先等App UI画完了,SurfaceFlinger再出场对其进行合并渲染后放入framebuffer,最后整到屏幕上。而现有的VSync模型是让大家一起开始干活,这样对于同一帧内容,第一个VSync信号时App UI的数据开始准备,第二个VSync信号时SurfaceFlinger工作,第三个VSync信号时用户看到Display内容,这样就两个VSync period(每个16ms)过去了,影响用户体验。
      解决思路:SurfaceFlinger在App UI准备好数据后及时开工做合成。

      Android 4.4(KitKat)引入了VSync的虚拟化,即把硬件的VSync信号先同步到一个本地VSync模型中,再从中一分为二,引出两条VSync时间与之有固定偏移的线程。示意图如下:

      

      这样,大家工作既保持一定的节拍,又可以相互错开,一前一后保持着流水节奏。

      注意其中两个Phase offset参数(即VSYNC_EVENT_PHASE_OFFSET_NSSF_VSYNC_EVENT_PHASE_OFFSET_NS)是可调的。

      处理流程:

      

       类型DispSync表示了一个基于硬件VSync信号的同步模型,它会根据从HWComposer来的硬件VSync信号的采样来进行同步。其它两个EventThread分别用了两个不同的虚拟VSync信号源(用DispSyncSource表示,其中包含了与真实VSync信号的偏移值),这两个VSync信号源就是被虚拟出来分别用于控制App UI和SurfaceFlinger渲染。在EventThread的线程循环中,如果有需要就会向DispSync注册相应的listener。DispSyncThread就像乐队鼓手一样控制着大家的节奏。它在主循环中会先通过已经向DispSync注册的listener计算下一个要产生的虚拟VSync信号还要多久,等待相应时间后就会调用相应listener的callback函数。这样,对于那些注册了listener的监听者来说,就好像被真实的VSync信号控制着一样。至于EventControlThread是用来向真实的VSync硬件发命令。

    三、Vsync框架

     1.硬件或者软件创建vsyncThread产生vsync。
     2.DispSyncThread处理vsync,把vsync虚拟化成vsync-app和vsync-sf。
     3.vsync-app/sf按需产生(如果App和SurfaceFlinger都没有更新请求,则休眠省电):
      APP端:APP需要更新界面时发出vsync请求给EventThread(设置connection.count>=0),DispSyncThread收到vsync信号后休眠offset,然后唤醒EventThread通知APP开始渲染。
      SF端:sf请求EventThread-sf,EventThread-sf收到vsync后通知SF可以开始合成。

                                (vsync框架图)

      4.代码分析:

      4.1 创建五个线程:SurfaceFlingerThread、DispSyncThread、EventThead-App、EventThead-SF、VsyncThread,都属于SurfaceFlinger进程:

     (1)启动SurfaceFlinger主线程:android-8.0.0_r4frameworks ativeservicessurfaceflingermain_surfaceflinger.cpp

    int main(int, char**) {
        startHidlServices();
    
        signal(SIGPIPE, SIG_IGN);
        // When SF is launched in its own process, limit the number of
        // binder threads to 4.
        ProcessState::self()->setThreadPoolMaxThreadCount(4);
    
        // start the thread pool
        sp<ProcessState> ps(ProcessState::self());
        ps->startThreadPool();
    
        // instantiate surfaceflinger
        sp<SurfaceFlinger> flinger = new SurfaceFlinger(); //其中创建了 mPrimaryDispSync 成员变量
    
        setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
    
        set_sched_policy(0, SP_FOREGROUND);
    
        // Put most SurfaceFlinger threads in the system-background cpuset
        // Keeps us from unnecessarily using big cores
        // Do this after the binder thread pool init
        if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);
    
        // initialize before clients can connect
        flinger->init(); //传入mPrimaryDispSync并创建EventThread(app/sf)、HWComposer
    
        // publish surface flinger
        sp<IServiceManager> sm(defaultServiceManager());
        sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
    
        // publish GpuService
        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");
        }
    
        // run surface flinger in this thread (SF的主线程)
        flinger->run();
    
        return 0;
    }

     (2)new SurfaceFlinger() 时创建了成员变量 DispSync mPrimaryDispSync;  android-8.0.0_r4frameworks ativeservicessurfaceflingerSurfaceFlinger.h

      其中 DispSync 的构造函数会启动DispSyncThread线程:
    DispSync::DispSync(const char* name) :
            mName(name),
            mRefreshSkipCount(0),
            mThread(new DispSyncThread(name)), //创建了DispSyncThread
            mIgnorePresentFences(!SurfaceFlinger::hasSyncFramework){
    
        mPresentTimeOffset = SurfaceFlinger::dispSyncPresentTimeOffset;
        mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
        // set DispSync to SCHED_FIFO to minimize jitter
        struct sched_param param = {0};
        param.sched_priority = 2;
        if (sched_setscheduler(mThread->getTid(), SCHED_FIFO, &param) != 0) {
            ALOGE("Couldn't set SCHED_FIFO for DispSyncThread");
        }
    
    
        reset();
        beginResync();
    
        if (kTraceDetailedInfo) {
            // If we're not getting present fences then the ZeroPhaseTracer
            // would prevent HW vsync event from ever being turned off.
            // Even if we're just ignoring the fences, the zero-phase tracing is
            // not needed because any time there is an event registered we will
            // turn on the HW vsync events.
            if (!mIgnorePresentFences && kEnableZeroPhaseTracer) {
                addEventListener("ZeroPhaseTracer", 0, new ZeroPhaseTracer());
            }
        }
    }
    (3)接着分析SurfaceFlinger对象,它是一个strong point,在引用时会调用其onFirstRef()方法:
    void SurfaceFlinger::onFirstRef()
    {
      //初始化消息队列,其中创建了loop和handle mEventQueue.init(
    this); }

      flinger->run()的实现: android-8.0.0_r4frameworks ativeservicessurfaceflingerSurfaceFlinger_hwc1.cpp

    void SurfaceFlinger::run() {
        do {
            waitForEvent(); //其中就是调用mEventQueue.waitMessage()
        } while (true);
    }

      waitMessage中等待AP和EventTHread给它发数据:

    void MessageQueue::waitMessage() {
        do {
            IPCThreadState::self()->flushCommands();
            int32_t ret = mLooper->pollOnce(-1);
            switch (ret) {
                case Looper::POLL_WAKE:
                case Looper::POLL_CALLBACK:
                    continue;
                case Looper::POLL_ERROR:
                    ALOGE("Looper::POLL_ERROR");
                    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);
    }

      SurfaceFlinger初始化最重要的函数是init():

    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);
    
            // initialize EGL for the default display
            mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
            eglInitialize(mEGLDisplay, NULL, NULL);
    
            // start the EventThread (创建了两个EventThread,他们的名字和offset不同)
            sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
                    vsyncPhaseOffsetNs, true, "app");
            mEventThread = new EventThread(vsyncSrc, *this, false);
            sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
                    sfVsyncPhaseOffsetNs, true, "sf");
            mSFEventThread = new EventThread(sfVsyncSrc, *this, true);

         // 创建sf与EventThread之间的connection mEventQueue.setEventThread(mSFEventThread);
    // set EventThread and SFEventThread to SCHED_FIFO to minimize jitter 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"); } // Get a RenderEngine for the given display / config (can't fail) mRenderEngine = RenderEngine::create(mEGLDisplay, HAL_PIXEL_FORMAT_RGBA_8888); }

      其中 mEventQueue.setEventThread(mSFEventThread) 的实现:

    //sufaceflinger/MessageQueue.cpp
    void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
    {
        mEventThread = eventThread;
        //创建连接,从连接获得dataChannel,把它的Fd添加到Looper,
        //也就是把EventThread里的一个fd传给了SF线程,
        //以后EventThread与SF就可以通过这个fd通信,
        mEvents = eventTHread->createEnvetConnection();
        mEventTube = mEvents->getDataChannel();
        mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
                MessageQueue::cb_eventReceiver, this); //这个cb_eventRecevier很重要,它负责处理EventThread发过来的信号
    }  

     (4)hwcomposer的构造函数:android-8.0.0_r4frameworks ativeservicessurfaceflingerDisplayHardwareHWComposer_hwc1.cpp

    HWComposer::HWComposer(
            const sp<SurfaceFlinger>& flinger,
            EventHandler& handler)
        : mFlinger(flinger),
          mFbDev(0), mHwc(0), mNumDisplays(1),
          mCBContext(new cb_context),
          mEventHandler(handler),
          mDebugForceFakeVSync(false)
    {
        for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) {
            mLists[i] = 0;
        }
    
        for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
            mLastHwVSync[i] = 0;
            mVSyncCounts[i] = 0;
        }
    
        char value[PROPERTY_VALUE_MAX];
        property_get("debug.sf.no_hw_vsync", value, "0");
        mDebugForceFakeVSync = atoi(value);
    
        bool needVSyncThread = true;
    
        // Note: some devices may insist that the FB HAL be opened before HWC.
        int fberr = loadFbHalModule();
        loadHwcModule();
    
        if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
            // close FB HAL if we don't needed it.
            // FIXME: this is temporary until we're not forced to open FB HAL
            // before HWC.
            framebuffer_close(mFbDev);
            mFbDev = NULL;
        }
    
        // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
        if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
                && !mFbDev) {
            ALOGE("ERROR: failed to open framebuffer (%s), aborting",
                    strerror(-fberr));
            abort();
        }
    
        // these display IDs are always reserved
        for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
            mAllocatedDisplayIDs.markBit(i);
        }
    
        if (mHwc) {
            ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
                  (hwcApiVersion(mHwc) >> 24) & 0xff,
                  (hwcApiVersion(mHwc) >> 16) & 0xff);
            if (mHwc->registerProcs) {
                mCBContext->hwc = this;
                mCBContext->procs.invalidate = &hook_invalidate;
                mCBContext->procs.vsync = &hook_vsync;
                if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
                    mCBContext->procs.hotplug = &hook_hotplug;
                else
                    mCBContext->procs.hotplug = NULL;
                memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
                mHwc->registerProcs(mHwc, &mCBContext->procs);
            }
    
            // don't need a vsync thread if we have a hardware composer
            needVSyncThread = false;
            // always turn vsync off when we start
            eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
    
            // the number of displays we actually have depends on the
            // hw composer version
            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
                // 1.3 adds support for virtual displays
                mNumDisplays = MAX_HWC_DISPLAYS;
            } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
                // 1.1 adds support for multiple displays
                mNumDisplays = NUM_BUILTIN_DISPLAYS;
            } else {
                mNumDisplays = 1;
            }
        }
    
        if (mFbDev) {
            ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
                    "should only have fbdev if no hwc or hwc is 1.0");
    
            DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
            disp.connected = true;
            disp.format = mFbDev->format;
            DisplayConfig config = DisplayConfig();
            config.width = mFbDev->width;
            config.height = mFbDev->height;
            config.xdpi = mFbDev->xdpi;
            config.ydpi = mFbDev->ydpi;
            config.refresh = nsecs_t(1e9 / mFbDev->fps);
            disp.configs.push_back(config);
            disp.currentConfig = 0;
        } else if (mHwc) {
            // here we're guaranteed to have at least HWC 1.1
            for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
                queryDisplayProperties(i);
            }
        }
    
        if (needVSyncThread) {
            // we don't have VSYNC support, we need to fake it
         // 如果不支持硬件Vsync则创建软件vysnc线程,它是一个sp<>,其onFirstRef()真正创建运行这个线程
    mVSyncThread = new VSyncThread(*this); } }

      加载并准备hw composer模块。Sets mHwc

    void HWComposer::loadHwcModule()
    {
        hw_module_t const* module;
    
        if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
            ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
            return;
        }
    
        int err = hwc_open_1(module, &mHwc);
        if (err) {
            ALOGE("%s device failed to initialize (%s)",
                  HWC_HARDWARE_COMPOSER, strerror(-err));
            return;
        }
    
        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
                hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
                hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
            ALOGE("%s device version %#x unsupported, will not be used",
                  HWC_HARDWARE_COMPOSER, mHwc->common.version);
            hwc_close_1(mHwc);
            mHwc = NULL;
            return;
        }
    }

     4.2 SurfaceFLinger使用vsync过程

    (1)App发数据给sf,sf发请求给EventThread-sf:AP是Producer,它通过listener->onFrameAvailable() ->进入消费者 -> mFrameAvailableListener(就是Layer对象) -> 进入SF线程-> mFlinger->signalLayerUpdate() -> mEventQueue.invalidate();

    //surfaceflinger/MessageQueue.cpp
    void MessageQueue::invalidate() {
        //mEvents是sp<IDisplayEventConnection>
        //也就是sf线程使用connection向EventThread线程请求下一个vsync信号
        mEvents->requestNextVsync();
    }
    --->
    //surfaceFlinger/EventThread.cpp
    void EventThread::Connection::requestNextVsync() {
        mEventThread->requestrNextVsync(this);
    }
    --->
    void EventTHread::requestNextVysnc(
        const sp<EventTHread::Connection>& connection) {
        if(connection->count < 0){
            //若cnt小于0,则cnt=0,然后发出广播,来唤醒某个线程,
            //当connection的cnt >= 0怎么它需要从EventThread得到vsync
            //这个函数得代码在EventThread,但是它执行在SF线程
            //也就是说,SF线程使用EventThread的函数向EventThread发出广播来唤醒EventThread线程
            connection->count = 0;
            mCondition.boradcast();
        }    
     }

    (2)EventThread-sf发请求给DispSyncThread,EventThread里面一定有一个threadLoop: android-8.0.0_r4frameworks ativeservicessurfaceflingerEventThread.cpp

    bool EventThread::threadLoop() {
        DisplayEventReceiver::Event event;
        Vector< sp<EventThread::Connection> > signalConnections;

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

     分析waitForEvent():

    //this will return when 
    //1, a vsync event has benn recevied
    //2,there was as least one connection interested in receiving it when we started waiting
    Vector< sp<EventThread::Connection > >EventThread::waitForEvent(
        DisplayEventReceiver::Event* event)
    {
        //find out connections waitting for events
        size_t count = mDisplayEventConnections.size();
        ofr(size_t i=0; i<count; i++) {
            if(connection->count >= 0) {
                //we need vsync events because at least 
                //one connnection is waiting for it
                waitForVSync = true;
            }
            ......
            if(waitFOrVSync){
                enableVSyncLocked(); //如果上面的count >= 0,代表需要得到vsync信号,然后调用enableVSyncLocked()
            }
            
            if(waitForVSync){
                ......
            } else {
                //EventThread之后就会休眠等待vsync
                mCondition.wait(mLock);
            }
        }
    }    
    

     enableVSyncLocked中给DisplaySyncThread设置回调,在DisplaySyncThread收到vsync信号后就调用这个回调函数:

    void EventThread::enableVSyncLocked() {
        if(!mVsyncEnabled) {
            mVsyncEnabled = true;
            mVSyncSource->setCallback(static_cast<VSyncSource::Callback*)(this));
            mVSYncSource->setVSyncEnabled(true);
        }
    }

    (3)H/S vsync唤醒DispSyncThread:

    //surfaceFlinger/DIsplayHardware/HWComposer_hwc1.cpp
    bool HWComposer::VSyncThread::threadLoop() {
        clock_nanosleep();
        //休眠 完成后,调用它,发出vsync信号
        //mEventHanlder就是SurfaceFlinger,
        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
    }
    --->
    //surfaceflinger/SurafceFLinger.cpp
    void SurfaceFLinger::onVSyncReceived(type, nescs_t timestamp){
        if(type == 0 && mPrimaryHWVsyncEnabled) {
            //DispSync::addResyncSample => updateModelLocked() => 
            //mThread->updateModel => mCond.signal()来唤醒某个线程,
            //mCond.signal()在DispSync.cpp,属于DispSYncThread,
            //还是之前说的套路,swVsyncThread使用DispSync的函数唤醒DispSYncThread
            needsHwVsync = mPrimaryDIspSync.addResyncSample(timestamp);
        }
        
        if(needsHwVsync) {
            enableHardwareVsync();
        }
    }

    (4)DispSyncThread发信号给EventThread,EventThread发信号给SF线程。

    //surfaceflinger/DispSync.cpp
    class DispSyncThread : public Thread {
        virtual bool threadLoop() {
            //计算最近的eventThread的时间,EventThread是Listener,
            // =>computeListenerNextEventTimeLocked 
            targetTime = computeNextEventTimeLocked(now);
            
            //休眠
            if(now < targetTime) {
                mCond.waitRelative(mMutex, targetrTime-now);
            }
            
            //之后被vsync信号唤醒,获取callback
            callbackInvacations = gatherCallbackInvocationsLocked(now);
            
            if(callbackInvocations.size() > 0) {
                //执行callback,导致EventThread的onVsyncEvent函数被调用
                fireCallbackInvocations(callbackInvovcations);
            }
        }
    }

      如果EventThread发现Connection的cnt >= 0,就会向DispSyncThread注册回调函数,最后会通过callback构造出Listener,而且EventThread运行时间是收到vsync之后加一个offset,fireCallbackInvocations()调用EventThread类的onVSyncEvent来唤醒EventThread线程:

    //surfaceFlinger/EventThread.cpp
    void EventThread::onVSyncEvent(nsecs_t timestamp) {
        Mutex::Autolock _l(mLock);
        mVSyncEvent[0].header.id = 0;
        mVsyncEvent[0].vsync.count++;
        //发出广播,唤醒EvenThread::threadLoop()向app或sf发出信号
        mCondition.broadcast();
    }

      EventThread::threadLoop()在waitForEvent里面休眠(mCondition.wait),收到广播后被唤醒,然后调用conn->postEvent(event)向SF线程或者AP发出信号,并通过connection的fd把数据写到SF线程,同样SF线程通过fd获得数据,然后调用SF线程的处理函数。

    status_t EventThread::Connection::postEvent(
            const DisplayEventReceiver::Event& event) {
        ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
        return size < 0 ? status_t(size) : status_t(NO_ERROR);
    }

     (5)sf线程对vsync的处理:在flinger->init()创建connection时,得到了一个fd,然后会检测fd。

       flinger->init() => MessageQueue::setEventThread:

    mEventTube = mEvent->getDataChannel();
    //检测fd,从fd得到数据,会调用MessageQueue::cb_eventRecevier函数
    mLooper->addFd(mEventTube0>getFd(),....,MessageQueue::cb_eventRecevier, this);
     
    --->
    //surfaceflinger/MessageQueue.cpp int MessageQueue::cb_eventRecevier(int fd, int event, void* data) { return queue->eventRecevier(fd, events); }
    --->
    int MessageQueue::eventReceiver(int fd, int events) { mHanlder->displatchInvalidate(); } ---> void MessageQueue::Handler::displayInvaliadate() { mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE)); }
    SurfaceFlinger中接收并处理消息:
    void MessageQueue::Handler::handleMessage(const Message& message) {
        switch(message.what) {
         ...
            case INVALIDATE:
                mQueue.mFlinger->onMessageReceived(message.what);
        }
    }
    
    --->
    
    // android-8.0.0_r4frameworks
    ativeservicessurfaceflingerSurfaceFlinger_hwc1.cpp
    void SurfaceFlinger::onMessageReceived(int32_t what) {
        ATRACE_CALL();
        switch (what) {
            case MessageQueue::INVALIDATE: {
                bool refreshNeeded = handleMessageTransaction(); //处理事务(设置flag,并未实际操作各个buffer):
                                         //①在handleTransactionLocked()中遍历每个Layer,执行layer->doTransaction(0)
                                         //②处理Display事务(add/remove)
                                         //③Layer角度发生了变化
                                         //处理sf本身事务: Layer的增加或者删除
                                        
    refreshNeeded |= handleMessageInvalidate(); //处理各Layer的buffer更换,使原来的界面无效,并准备好新数据用来更新:
                                      //①accquire next buffer
                                      //②release previous buffer
                                      //③bindTextureImageLocked() ---> glEGLImageTargetTexture2DOES()
       
    refreshNeeded |= mRepaintEverything; if (refreshNeeded) { // Signal a refresh if a transaction modified the window state, // a new buffer was latched, or if HWC has requested a full // repaint signalRefresh(); //发出Refresh信号,导致下面的 handleMessageRefresh()函数被调用 } break; } case MessageQueue::REFRESH: { handleMessageRefresh();  //①计算各Layer的可视区域
                           //②合成显示:a.调用opengl把各个Layer的可视区域在一个内存上描绘出来
                           //      b.使用hw composer硬件合成
    break; } } }

     

                                (Vsync时序图)

  • 相关阅读:
    9 jmeter之检查点
    8 jmeter之集合点
    7 jmeter之参数化
    6 jmeter元件的作用域与执行顺序
    5 jmeter性能测试小小的实战
    4 jmeter badboy脚本开发技术详解
    3 jmeter的两种录制方法
    2 jmeter常用功能介绍-测试计划、线程组
    Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project
    常见异常总结
  • 原文地址:https://www.cnblogs.com/blogs-of-lxl/p/11443693.html
Copyright © 2011-2022 走看看