Android graphics(三) surfaceflinger

程序员 2024-9-20 07:16:06 135 0 来自 中国
一、媒介

本文紧张内容  
1、surfaceflinger初始化流程;
2、surfaceflinger消息机制;
3、surfaceflinger绘制流程;
4、VSync分发流程
surfaceFlinger由init历程启动,独立历程运行,它接受来自多个泉源的数据缓冲区,对它们举行合成,然后发送到体现装备。
简述体现过程  
1>、一个页面,一样平常分为三个window,状态栏、app和导航栏,每个window看作要体现的一层,windowManager体现时,哀求surfaceflinger为每个window创建衣蛾surface(layer)来绘制体现
每一个体现layer层,我们看作一个bufferqueue缓存队列。surfaceflinger合成bufferqueue,合成后送到Hardware Composer体现。
2>、体现按照肯定革新率更新画面,手机平板通常为60fps(16.6ms体现一次),一次革新由vsync信号发起,surfaceflinger吸收到信号后构造这一次革新体现。
3>、当 VSYNC 信号到达时,SurfaceFlinger 会遍历它的层列表,以探求新的缓冲区。如果找到新的缓冲区,它会获取该缓冲区;
否则,它会继续使用从前获取的缓冲区。SurfaceFlinger 必须始终体现内容,因此它会保存一个缓冲区。如果在某个层上没有提交缓冲区,则该层会被忽略。
备注:本文只列出关键代码,关键流程。
二、surfaceflinger启动流程

2.1、main入口

surfaceflinger.rc由init.rc启动,main_surfaceflinger.cpp main函数为启动入口   int main(int, char**) {    startGraphicsAllocatorService();    // instantiate surfaceflinger    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();    // initialize before clients can connect    flinger->init();    // publish surface flinger    sp<IServiceManager> sm(defaultServiceManager());    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,                   IServiceManager:UMP_FLAG_PRIORITY_CRITICAL | IServiceManager:UMP_FLAG_PROTO);    flinger->run();}提炼此中紧张三件变乱,紧张还是一个surfaceFlinger的创建
1、createSurfaceFlinger并init(陪同onFirstRef)
2、addService到上层
3、进入消息循环
2.2、surfaceflinger构造

class SurfaceFlinger : public BnSurfaceComposer,                       public PriorityDumper,                       private IBinder:eathRecipient,                       private HWC2::ComposerCallback,                       private ISchedulerCallback {SurfaceComposer继续自BnSurfaceComposer,即为实现了ISurfaceComposer接口的Bn服务端;
Dump信息PriorityDumper;
殒命关照DeathRecipient,当Binder服务端步调挂掉后,可以关照给绑定的Binder客户端步调;
实现了HWC2的ComposerCallback回调,监听Composer HAL的一些变乱,比如Hotplug, Vsync ...
2.3、消息队列SurfaceFlinger:nFirstRef

这里引出surfaceflinger重点之一surfaceflinger的消息队列。后面单独讲
SurfaceFlinger继续RefBase类,以是此处一旦new出对象赋给sp指针后,将立刻触发SurfaceFlinger类的onFirstRef方法的调用。
void SurfaceFlinger:nFirstRef() {    mEventQueue->init(this);}2.4、SurfaceFlinger::init

// Do not call property_set on main thread which will be blocked by init// Use StartPropertySetThread instead.void SurfaceFlinger::init() {    // Get a RenderEngine    mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(            renderengine::RenderEngineCreationArgs::Builder()                    .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))                    .setImageCacheSize(maxFrameBufferAcquiredBuffers)                    .setUseColorManagerment(useColorManagement)                    .setEnableProtectedContext(enable_protected_contents(false))                    .setPrecacheToneMapperShaderOnly(false)                    .setSupportsBackgroundBlur(mSupportsBlur)                    .setContextPriority(                            useContextPriority                                    ? renderengine::RenderEngine::ContextPriority::REALTIME                                    : renderengine::RenderEngine::ContextPriority::MEDIUM)                    .build()));    // 创建HWComposer,通过mCompositionEngine->setHwComposer设置对象属性,并注册回调    mCompositionEngine->setTimeStats(mTimeStats);    mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));    mCompositionEngine->getHwComposer().setCallback(this);    ClientCache::getInstance().setRenderEngine(&getRenderEngine());    // 任何初始热插拔和体现更改的结果    processDisplayHotplugEventsLocked();    const auto display = getDefaultDisplayDeviceLocked();    LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");    const auto displayId = display->getPhysicalId();    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),                        "Internal display is disconnected.");    // 初始化display    initializeDisplays();    // 开启一个设置属性的线程    if (mStartPropertySetThread->Start() != NO_ERROR) {        ALOGE("Run StartPropertySetThread failed!");    }}init方法紧张做了这么几件变乱:
1、创建一个RenderEngine
2、创建HWComposer,通过mCompositionEngine->setHwComposer设置对象属性,并注册回调
3、处理处罚Display体现屏幕的热插拔
4、初始化体现装备
5、开启设置属性线程
2.5、SurfaceFlinger::run

main函数中末了一步,run开启无穷循环等待消息
void SurfaceFlinger::run() {    while (true) {        mEventQueue->waitMessage();    }}2.5小结

上面五个小点总结了surfaceflinger的初始化过程。团体来说初始化更多还是对象的创建,要更加深入的明白surfaceflinger,
我们还应该分析一些紧张流程出来明白。如许才有助于明白surfaceflinger在绘制过程中如何承上启下
三、Surfaceflinger消息队列

在surafceflinger的构造函数中初始化
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)      : ...        mEventQueue(mFactory.createMessageQueue()),        //framework/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h     //frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cppstd::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() {    return std::make_unique<android::impl::MessageQueue>();}//framework/native/services/surfaceflinger/Scheduler/MessageQueue.hclass MessageQueue {public:    enum {        INVALIDATE = 0,        REFRESH = 1,    };    virtual ~MessageQueue() = default;    virtual void init(const sp<SurfaceFlinger>& flinger) = 0;    virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,                           std::chrono::nanoseconds workDuration) = 0;    virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;    virtual void setInjector(sp<EventThreadConnection>) = 0;    virtual void waitMessage() = 0;    virtual void postMessage(sp<MessageHandler>&&) = 0;    virtual void invalidate() = 0;    virtual void refresh() = 0;    virtual std:ptional<std::chrono::steady_clock::time_point> nextExpectedInvalidate() = 0;};如上代码,surfaceflinger消息队列中,紧张的两个变乱,INVALIDATEREFRESH
// framework/native/services/surfaceflinger/Scheduler/MessageQueue.cppvoid MessageQueue::Handler::dispatchRefresh() {    if ((mEventMask.fetch_or(eventMaskRefresh) & eventMaskRefresh) == 0) {        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));    }}void MessageQueue::Handler::dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp) {    if ((mEventMask.fetch_or(eventMaskInvalidate) & eventMaskInvalidate) == 0) {        mVsyncId = vsyncId;        mExpectedVSyncTime = expectedVSyncTimestamp;        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));    }}void MessageQueue::Handler::handleMessage(const Message& message) {    switch (message.what) {        case INVALIDATE:            mEventMask.fetch_and(~eventMaskInvalidate);            mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);            break;        case REFRESH:            mEventMask.fetch_and(~eventMaskRefresh);            mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);            break;    }}消息队列又处理处罚回surfaceflinger中的onMessageReceived方法
//SurfaceFlinger.cppvoid SurfaceFlinger:nMessageReceived(int32_t what, nsecs_t expectedVSyncTime) {    ATRACE_CALL();    switch (what) {        case MessageQueue::INVALIDATE: {            onMessageInvalidate(expectedVSyncTime);            break;        }        case MessageQueue::REFRESH: {            onMessageRefresh();            break;        }    }}这里摘录一个bufferqueue的acquireBuffer方法时的堆栈
vsync革新信号过来onMessageReceived收到消息后,bufferqueue开始处理处罚图像队列
04-19 19:33:38.926   666   666 E acquireBuffer: #00 pc 0004d34f  /system/lib/libgui.so (android::BufferQueueConsumer::acquireBuffer(android::BufferItem*, long long, unsigned long long)+74)04-19 19:33:38.926   666   666 E acquireBuffer: #01 pc 000645cf  /system/lib/libgui.so (android::ConsumerBase::acquireBufferLocked(android::BufferItem*, long long, unsigned long long)+62)04-19 19:33:38.926   666   666 E acquireBuffer: #02 pc 0007a7a1  /system/lib/libsurfaceflinger.so (android::FramebufferSurface::advanceFrame(bool)+112)04-19 19:33:38.926   666   666 E acquireBuffer: #03 pc 000edf1f  /system/lib/libsurfaceflinger.so (android::compositionengine::impl::RenderSurface::queueBuffer(android::base::unique_fd_impl<android::base:efaultCloser>, bool)+358)04-19 19:33:38.926   666   666 E acquireBuffer: #04 pc 000e46e7  /system/lib/libsurfaceflinger.so (android::compositionengine::impl::Output::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+454)04-19 19:33:38.926   666   666 E acquireBuffer: #05 pc 000de3e5  /system/lib/libsurfaceflinger.so (android::compositionengine::impl:isplay::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+72)04-19 19:33:38.926   666   666 E acquireBuffer: #06 pc 000e3011  /system/lib/libsurfaceflinger.so (android::compositionengine::impl::Output::present(android::compositionengine::CompositionRefreshArgs const&)+92)04-19 19:33:38.926   666   666 E acquireBuffer: #07 pc 000dcfa1  /system/lib/libsurfaceflinger.so (android::compositionengine::impl::CompositionEngine::present(android::compositionengine::CompositionRefreshArgs&)+144)04-19 19:33:38.926   666   666 E acquireBuffer: #08 pc 000baf81  /system/lib/libsurfaceflinger.so (android::SurfaceFlinger:nMessageRefresh()+1280)04-19 19:33:38.926   666   666 E acquireBuffer: #09 pc 000b8b1d  /system/lib/libsurfaceflinger.so (android::SurfaceFlinger:nMessageReceived(int, long long)+52)四、surfaceflinger绘制流程

4.1、wms和surfaceflinger创建surface流程

4.1.1、wms和surfaceflinger创建毗连

要体现的页面通过window告诉surfaceflinger创建surface来绘图,这个surface就是一个layer(layer的核心就是buffer queue);
surfaceflinger创建的bufferqueue不会转达到app,而是通过内存共享直接供app绘制。bufferqueue都不会转达;
那么这一节内容我们来讲讲这个流程
//WMSpublic int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {    win.attach(); // WindowState}// WindowState.attchvoid attach() {    mSession.windowAddedLocked();}void windowAddedLocked(String packageName) {    if (mSurfaceSession == null) {        mSurfaceSession = new SurfaceSession();    }}// SurfaceSession.javaprivate long mNativeClient; // SurfaceComposerClient*/** Create a new connection with the surface flinger. */public SurfaceSession() {    mNativeClient = nativeCreate();}// frameworks/base/core/jni/android_view_SurfaceSession.cppstatic jlong nativeCreate(JNIEnv* env, jclass clazz) {    SurfaceComposerClient* client = new SurfaceComposerClient();    client->incStrong((void*)nativeCreate);    return reinterpret_cast<jlong>(client);}void SurfaceComposerClient:nFirstRef() {    sp<ISurfaceComposerClient> conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : sf->createConnection();    if (conn != 0) {        mClient = conn;    }    // ...}sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {    return initClient(new Client(this)); // initClient方法只是调用initCheck查抄了一下}上面截取了一段流程代码:
1>、从我们熟知的addwindow开始,WindowSate体现一个window;
2>、mSurfaceSession体现一个跟surfaceflinger的毗连,此中SurfaceComposerClient就是体现毗连的指针;
3>、末了创建的Client实现ISurfaceComposerClient的aidl,它可以创建Surface,并且维护一个应用步调的全部Layer;
4.1.2、Surface创建对应Layer

// ViewRootImpl.javapublic final Surface mSurface = new Surface();一个ViewRootImpl对应一个Surface(上层surface),而Surface 在 SurfaceFlinger 中对应的实体是 Layer 对象。  1>、一个Vsync信号(vysnc发起页面革新流程)实验ViewRootImpl.performTraversals    private void performTraversals() {    relayoutWindow(params, viewVisibility, insetsPending)    // measure, layout, draw}private int relayoutWindow(...) throws RemoteException {    // 末了一个参数 mSurface 就是之前创建的 Surface 对象    mWindowSession.relayout(mWindow, ..., mSurface);}// WMSpublic int relayoutWindow(Session session, ..., Surface outSurface) {    result = createSurfaceControl(outSurface, result, win, winAnimator);}private int createSurfaceControl(Surface outSurface, int result, WindowState win, WindowStateAnimator winAnimator) {    WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);    if (surfaceController != null) {        surfaceController.getSurface(outSurface);    } else {        outSurface.release();    }    return result;}上面这一段紧张是为了阐明relayoutWindow会createSurfaceControl
2>、surface的layer创建由SurfaceControl来举行
private SurfaceControl(...) {    // 返回 native SurfaceControl 指针    mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, windowType, ownerUid);}// frameworks/base/core/jni/android_view_SurfaceControl.cppstatic jlong nativeCreate(...) {    // client 即wms和surfaceflinger创建毗连时的SurfaceComposerClient指针      sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));    client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);}// framework/native/libs/gui/SurfaceComposerClient.cppstatus_t SurfaceComposerClient::createSurfaceChecked(..., sp<SurfaceControl>* outSurface, ...) {    err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),                                     &handle, &gbp, &id, &transformHint);}//framework/native/services/surfaceflinger/Client.cppstatus_t Client::createSurface(...) {    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,                                 parentHandle, outLayerId, nullptr, outTransformHint);}这里来来回回末了还是SurfaceComposerClient指针构造了createSurface,即创建了surface对应的layer
4.1.3、上层surface和Layer对应起来

createSurfaceControl创建了layer,接着立马getSurface创建对应关系
由于上层创建的surface还是一个空的对象,copyFrom即是就是添补了surface的内容
接上面4.1.2中createSurfaceControl方法中的surfaceController.getSurface(outSurface)
// outSurface是上层ViewRootImpl创建的surfacevoid getSurface(Surface outSurface) {    outSurface.copyFrom(mSurfaceControl);}// Surface.javapublic void copyFrom(SurfaceControl other) {    long surfaceControlPtr = other.mNativeObject;    // mNativeObject是4.2.2 小结 SurfaceControl创建时返回的指针    long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);    synchronized (mLock) {        if (mNativeObject != 0) {            nativeRelease(mNativeObject);        }        // 把指针赋值给mNativeObject        setNativeObjectLocked(newNativeObject);    }}private void setNativeObjectLocked(long ptr) {    if (mNativeObject != ptr) {        mNativeObject = ptr;        if (mHwuiContext != null) {            mHwuiContext.updateSurface();        }    }}// frameworks/base/core/jni/android_view_Surface.cppstatic jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {    // java指针和底层指针的转换    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));    sp<Surface> surface(ctrl->getSurface());    if (surface != NULL) {        surface->incStrong(&sRefBaseOwner);    }    return reinterpret_cast<jlong>(surface.get());}sp<Surface> SurfaceControl::getSurface() const{    Mutex::Autolock _l(mLock);    if (mSurfaceData == 0) {        return generateSurfaceLocked();    }    return mSurfaceData;}sp<Surface> SurfaceControl::generateSurfaceLocked() const{    // mGraphicBufferProducer 是上面创建的 gbp 对象    // 这里new surface实际是底层的surface    mSurfaceData = new Surface(mGraphicBufferProducer, false);    return mSurfaceData;}1、nativeGetFromSurfaceControl 返回native Suface的指针,指针的值赋给SurfaceControl.mNativeObject
2、上层surface调用copyFrom添补内容时,实际就是拿到了SurfaceControl了,也拥有了底层的surface指针,子集关系。
4.2、Vysnc流程

4.2.1 几点概念

1、VSYNC 信号可同步体现流水线。体现流水线由应用渲染、SurfaceFlinger 合成以及用于在屏幕上体现图像的硬件肴杂渲染器 (HWC) 构成。
2、VSYNC 可同步应用叫醒以开始渲染的时间、SurfaceFlinger 叫醒以合成屏幕的时间以及屏幕革新周期。这种同步可以消除卡顿,并提升图形的视觉体现。
3、vysnc的引入,可以及时的告知cpu/gpu停息别的变乱,及时处理处罚体现的这一帧。从而淘汰卡顿发生。
4、三级缓存:vsync+三级缓存,当第n+1处理处罚不外来的时间,由于有三次缓存数据,纵然n+1卡顿,或者n+1和n+2卡顿,只要没有连着卡三次,都有缓存可以拿,UI上就不会造成卡顿。
4.2.2 DispSync

DispSync 维护屏幕基于硬件的周期性 VSYNC 变乱的模子


我们一共有三个信号,HW_VYNC_0 是硬件产生的同步信号
DispSync则负责产生由Choreographer 和 SurfaceFlinger 使用的 VSYNC 和 SF_VSYNC 信号,不管是否吸收到HW_VYSNC_0都会产生,HW_VYSNC_0只是起到参考作用
4.2.3 Vync的偏移


HW_VSYNC_0 - 屏幕开始体现下一帧。
VSYNC - 应用读取输入内容并天生下一帧。
SF_VSYNC - SurfaceFlinger 开始为下一帧举行合成
VSYNC_EVENT_PHASE_OFFSET_NS 和 SF_VSYNC_EVENT_PHASE_OFFSET_NS 对应phase-app和phase-sf,默认都为0
偏移量的参加是为了淘汰耽误,我们以正常情况来讲,一帧16.6ms就能渲染完成。App可以在phase-sf - phase-app时间内完成绘制,SurfaceFlinger可以在VSync周期 - phase-sf时间内完成合成,那么在下一个VSync信号时就可以上屏,即帧耽误为16ms。如许抱负情况下,耽误就被控制成了一帧。
如果app绘制超时,sf就会在下一帧绘制,增长了一帧的周期。以是一样平常情况下,体系都会将phase-sf - phase-app设置为VSync周期。如许不管出现怎样的耽误征象,sf的耽误周期都是控制为一帧一帧的增长。
4.2.4 Vync代码流程

简述整个过程:
1、整个Vsync流程是从HWC监听硬件产生的Vsync开始,由DispSync维护VSYNC模子,Vsync信号是不绝存在的。
2、app哀求vsync
一个页面并不是无时无刻都在革新,当触摸view发生厘革,哀求核心,开始动画或者startActivity等等时,ViewRootImpl会调用scheduleTraversals流程,这个流程会让app吸收下一个Vsync信号。
就是不管哪个方式革新view都是scheduleTraversals来触发
   scheduleTraversals -> mChoreographer.postCallback() -> doScheduleVsync -> scheduleVsyncLocked -> nativeScheduleVsync -> requestNextVsync()3、app吸收vsync
收到信号后会控制view通过performTraversals方法绘制三大流程
   onVsync -> doFrame -> TraversalRunnable -> doTraversal() -> performTraversals()4.2.4.1 Vsync初始化

分几个部门:
1、initScheduler 初始化vysnc机制
2、createVsyncSchedule:VSyncTracker、VSyncDispatch、VsyncController
initScheduler部门
//frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.hstruct ComposerCallback {    // 热插拔变乱    virtual void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) = 0;     // refresh 革新变乱    virtual void onComposerHalRefresh(hal::HWDisplayId) = 0;     // VSYNC信号变乱    virtual void onComposerHalVsync(hal::HWDisplayId, int64_t timestamp,                                     std:ptional<hal::VsyncPeriodNanos>) = 0;};//frameworks/native/services/surfaceflinger/SurfaceFlinger.cppvoid SurfaceFlinger::init() {    mCompositionEngine->setTimeStats(mTimeStats);    mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));    // init方法注册回调开始,注册回调会立马触发onComposerHalHotplug方法    mCompositionEngine->getHwComposer().setCallback(this); }//frameworks/native/services/surfaceflinger/SurfaceFlinger.cppvoid SurfaceFlinger:nComposerHalHotplug(hal::HWDisplayId hwcDisplayId,                                          hal::Connection connection) {    if (std::this_thread::get_id() == mMainThreadId) {        // Process all pending hot plug events immediately if we are on the main thread.        processDisplayHotplugEventsLocked(); // 主线程中去处理处罚 hot plug evnets    }}//frameworks/native/services/surfaceflinger/SurfaceFlinger.cppvoid SurfaceFlinger::processDisplayHotplugEventsLocked() {        if (event.connection == hal::Connection::CONNECTED) {                if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {                    initScheduler(state); // 初始化Scheduler                }}上面这部门代码initScheduler流程,是Vsync初始开始的地方,代码是从surfaceflinger::init开始,给HWC setCallback,直接回调hotplag热插拔,开始Scheduler的初始化
接下来就是initScheduler详细内容:
void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {    if (mScheduler) {        // In practice it's not allowed to hotplug in/out the primary display once it's been        // connected during startup, but some tests do it, so just warn and return.        ALOGW("Can't re-init scheduler");        return;    }    const auto displayId = displayState.physical->id;    scheduler::RefreshRateConfigs::Config config =            {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),             .frameRateMultipleThreshold =                     base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)};    // 设置信息,革新率革新周期Period    mRefreshRateConfigs =            std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,                                                            displayState.physical->activeMode                                                                    ->getId(),                                                            config);    const auto currRefreshRate = displayState.physical->activeMode->getFps();    // fps信息    mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,                                                                      hal:owerMode::OFF);    // 不同分辨率下的VSYNC设置信息    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);    mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());    // 创建Scheduler对象    mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);    const auto configs = mVsyncConfiguration->getCurrentConfigs();    const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();    //创建一个名字为app的connection     mAppConnectionHandle =            mScheduler->createConnection("app", mFrameTimeline->getTokenManager(),                                         /*workDuration=*/configs.late.appWorkDuration,                                         /*readyDuration=*/configs.late.sfWorkDuration,                                         impl::EventThread::InterceptVSyncsCallback());    //创建一个名字为appsf的connection                                        mSfConnectionHandle =            mScheduler->createConnection("appSf", mFrameTimeline->getTokenManager(),                                         /*workDuration=*/std::chrono::nanoseconds(vsyncPeriod),                                         /*readyDuration=*/configs.late.sfWorkDuration,                                         [this](nsecs_t timestamp) {                                             mInterceptor->saveVSyncEvent(timestamp);                                         });    //initVsync紧张作用是绑定一个回调函数 MessageQueue::vsyncCallback 到VSyncDispatch上,回调名字"sf"    mEventQueue->initVsync(mScheduler->getVsyncDispatch(), *mFrameTimeline->getTokenManager(),                           configs.late.sfWorkDuration);    mRegionSamplingThread =            new RegionSamplingThread(*this, RegionSamplingThread::EnvironmentTimingTunables());    mFpsReporter = new FpsReporter(*mFrameTimeline, *this);    mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, displayId,                                            displayState.physical->activeMode->getId(),                                            vsyncPeriod);    static auto ignorePresentFences =            base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false);    mScheduler->setIgnorePresentFences(            ignorePresentFences ||            getHwComposer().hasCapability(hal::Capability:RESENT_FENCE_IS_NOT_RELIABLE));}简述流程:
1、HwComposer注册回调会立马触发onComposerHalHotplug方法,热插拔立马initScheduler
2、设置fps、革新周期、Vsync信息、app/sf偏移量、创建Scheduler、sf/appSf/app 三个callback
createVsyncSchedule
struct VsyncSchedule {        std::unique_ptr<scheduler::VsyncController> controller;        std::unique_ptr<scheduler::VSyncTracker> tracker;        std::unique_ptr<scheduler::VSyncDispatch> dispatch;    };Scheduler::VsyncSchedule Scheduler::createVsyncSchedule(bool supportKernelTimer) {    auto clock = std::make_unique<scheduler::SystemClock>();    auto tracker = createVSyncTracker();    auto dispatch = createVSyncDispatch(*tracker);    // TODO(b/144707443): Tune constants.    constexpr size_t pendingFenceLimit = 20;    auto controller =            std::make_unique<scheduler::VSyncReactor>(std::move(clock), *tracker, pendingFenceLimit,                                                      supportKernelTimer);    return {std::move(controller), std::move(tracker), std::move(dispatch)};}创建VSyncTracker、VSyncDispatch、VsyncController封装到VsyncSchedule并返回
名称作用VSyncTracker根据硬件的Vysnc、汗青数据创建一个Vsync模子,推测Vsync信号VSyncDispatch分发Vsync回调VsyncController共同tracker采样Connectionapp,appSf,sf三个监听vysnc初始化部门紧张先容创建了哪些东西,vysnc运行机制的干系主角根本都列出来了。接下来我们先讲App哀求Vsync和app吸收Vsync。然后解说Vsync的运作。
4.2.4.2、App哀求Vsync

前面有简单提到app怎么开始哀求vsync:
   scheduleTraversals -> mChoreographer.postCallback() -> doScheduleVsync -> scheduleVsyncLocked -> nativeScheduleVsync -> requestNextVsync()本文先容的重点是surfaceflinger,以是我们来详细看下哀求这个过程,surfaceflinger做了什么,java层也比力简单,跟着上面的流程去追一下就好。
DisplayEventReceiver.javapublic void scheduleVsync() {        ...        nativeScheduleVsync(mReceiverPtr);    }///android_view_DisplayEventReceiver.cppstatic void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {    sp<NativeDisplayEventReceiver> receiver =            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);    status_t status = receiver->scheduleVsync();    ...}//DisplayEventDispatcher.cppstatus_t DisplayEventDispatcher::scheduleVsync() {    ...    status_t status = mReceiver.requestNextVsync();    ...      return OK;}//DisplayEventReceiver.cppstatus_t DisplayEventReceiver::requestNextVsync() {    if (mEventConnection != nullptr) {        mEventConnection->requestNextVsync();        return NO_ERROR;    }    return NO_INIT;}///EventThread.cpp void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {    if (connection->resyncCallback) {        connection->resyncCallback();    }    std::lock_guard<std::mutex> lock(mMutex);    if (connection->vsyncRequest == VSyncRequest::None) {        connection->vsyncRequest = VSyncRequest::Single;        mCondition.notify_all();    } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {        connection->vsyncRequest = VSyncRequest::Single;    }}App哀求sync的流程,紧张还是一个间接调用。在mCondition.notify_all叫醒锁后,继续后边的流程
4.2.4.3、App吸收Vsync

//EventThread.cpp void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {    DisplayEventConsumers consumers;    //1、如果队列不为空取一次vsync的event变乱出来    if (!mPendingEvents.empty()) {            event = mPendingEvents.front();            mPendingEvents.pop_front();    ...    //2、先取出一个connection ,然后用shouldConsumeEvent判定是否发送到connection    //这里无穷循环,会取出全部需要分发消息的connection    auto it = mDisplayEventConnections.begin();    while (it != mDisplayEventConnections.end()) {        if (const auto connection = it->promote()) {            vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;            if (event && shouldConsumeEvent(*event, connection)) {                consumers.push_back(connection);            }        } else {            it = mDisplayEventConnections.erase(it);        }    }    ...    //3、前面两个都满足了consumers就不为空,就开始分发    if (!consumers.empty()) {        dispatchEvent(*event, consumers);        consumers.clear();    }    ...    //4、上述两个条件没有满足,会走到这里wait,直到有哀求来notify叫醒,也就是上面的notify_all    if (mState == State::Idle) {        mCondition.wait(lock);    }1、如许EventThread就起到了一个有哀求才会vsync的监测作用。
2、留意consumers是全部需要分发dispatchEvent的connection合集
3、继续dispatchEvent流程
//EventThread.cppvoid EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,                                const DisplayEventConsumers& consumers) {    for (const auto& consumer : consumers) {        switch (consumer->postEvent(copy)) {status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {    constexpr auto toStatus = [](ssize_t size) {        ...        auto size = DisplayEventReceiver::sendEvents(&mChannel, mPendingEvents.data(),                                                     mPendingEvents.size());                                                     //DisplayEventReceiver.cpp ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,        Event const* events, size_t count){    return gui::BitTube::sendObjects(dataChannel, events, count);}//BitTube.cpp ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {    const char* vaddr = reinterpret_cast<const char*>(events);    ssize_t size = tube->write(vaddr, count * objSize);}ssize_t BitTube::write(void const* vaddr, size_t size) {    ssize_t err, len;    do {        len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);        // cannot return less than size, since we're using SOCK_SEQPACKET        err = len < 0 ? errno : 0;    } while (err == EINTR);    return err == 0 ? len : -err;}int BitTube::getFd() const {    return mReceiveFd;}这里稍作表明:
1、dispatchEvent流程一层一层调用会通过BitTube来转达信息
2、BitTube用Linux/Unix中的socketpair举行跨历程数据转达,
3、成员变量mReceiveFd,看起来是一个吸收端,实际上这个fd也可以用来发送,同样mSendFd也可以用来吸收,只是BitTube是按照单向方式使用它的:一端写入数据,另一端读出数据
4、这里我们可以简单明白为mSendFd用来发送,mReceiveFd对端用来吸收。
//DisplayEventDispatcher.cppstatus_t DisplayEventDispatcher::initialize() {    ...    int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);}int DisplayEventDispatcher::handleEvent(int, int events, void*) {    ...    // Drain all pending events, keep the last vsync.    nsecs_t vsyncTimestamp;    PhysicalDisplayId vsyncDisplayId;    uint32_t vsyncCount;    VsyncEventData vsyncEventData;    //processPendingEvents取出一个有用的sync event    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {        mWaitingForVsync = false;        //分发        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);}        void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,                                               uint32_t count, VsyncEventData vsyncEventData) {    JNIEnv* env = AndroidRuntime::getJNIEnv();    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));    if (receiverObj.get()) {        ALOGV("receiver %p ~ Invoking vsync handler.", this);        // 调用到java层dispatchVsync方法        env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,                            timestamp, displayId.value, count, vsyncEventData.id,                            vsyncEventData.deadlineTimestamp, vsyncEventData.frameInterval);        ALOGV("receiver %p ~ Returned from vsync handler.", this);    }    mMessageQueue->raiseAndClearException(env, "dispatchVsync");}//DisplayEventReceiver.java@SuppressWarnings("unused")private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,        long frameTimelineVsyncId, long frameDeadline, long frameInterval) {    onVsync(timestampNanos, physicalDisplayId, frame,            new VsyncEventData(frameTimelineVsyncId, frameDeadline, frameInterval));}public void onVsync(long timestampNanos, long physicalDisplayId, int frame,                VsyncEventData vsyncEventData) {    ...    mTimestampNanos = timestampNanos;    mFrame = frame;    mLastVsyncEventData = vsyncEventData;    Message msg = Message.obtain(mHandler, this);    msg.setAsynchronous(true);    mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);     private final class FrameHandler extends Handler {    public FrameHandler(Looper looper) {        super(looper);    }    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            case MSG_DO_FRAME:                doFrame(System.nanoTime(), 0, new DisplayEventReceiver.VsyncEventData());                break;            case MSG_DO_SCHEDULE_VSYNC:                doScheduleVsync();                break;            case MSG_DO_SCHEDULE_CALLBACK:                doScheduleCallback(msg.arg1);                break;        }    }}吸收流程
1、有vysnc哀求,有需要发送的connection,下一次vysnc event开始dispatchevent
2、dispatchevent间接由DisplayEventDispatcher来负责分发
3、分发时,间接调用java层dispatchVsync,由上层控制绘制view
4.2.4.4、surfaceflinger吸收Vsync

1、有了上面app收发,根本就明白vsync是怎么被分发出去了。
2、在initScheduler流程时,实际我们创建了三个监听app、appSf、sf,app就是app的收发,appSf这个监听紧张为surfaceflinger的工作线程服务,sf则用来关照surfaceflinger合成体现流程
3、接着surfaceflinger::initScheduler
mEventQueue->initVsync(mScheduler->getVsyncDispatch(), *mFrameTimeline->getTokenManager(),                           configs.late.sfWorkDuration);///MessageQueue.cppvoid MessageQueue::setInjector(sp<EventThreadConnection> connection) {    ...        mLooper->addFd(                tube.getFd(), 0, Looper::EVENT_INPUT,                [](int, int, void* data) {                    reinterpret_cast<MessageQueue*>(data)->injectorCallback();                    return 1; // Keep registration.                },                this);    }    void MessageQueue::Handler::handleMessage(const Message& message) {    switch (message.what) {        case INVALIDATE:            mEventMask.fetch_and(~eventMaskInvalidate);            mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);            break;        case REFRESH:            mEventMask.fetch_and(~eventMaskRefresh);            mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);            break;    }}//SurfaceFlinger.cppvoid SurfaceFlinger:nMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) {    switch (what) {        case MessageQueue::INVALIDATE: {            onMessageInvalidate(vsyncId, expectedVSyncTime);            break;        }        case MessageQueue::REFRESH: {            onMessageRefresh();            break;        }    }}网上许多文章都是从SurfaceFlinger::onMessageReceived
surfaceflinger绘制流程小结
本节紧张讲两个部门
第一部门:app的layer如何和surfaceflinger毗连起来
第二部门:vsync分发流程
Vsync流程
1、代码流程从如何从HWC吸收Vsync信号开始
2、initScheduler初始化部门、app哀求Vsync、app吸收Vsync、surfaceflinger吸收Vysnc  四个部门流程团结
3、EventThread监听Vsync、connection创建毗连、Choreographer衔接app和surfaceflinger、Dispatcher分发vsync
4、这里挑选的都是vsync比力主线的几个流程,理清他们,明白vsync分发应该没题目。
5、尚有一个从hwc转达vsync到eventthread这个流程有爱好的可以本身去阅读一下源码
整条线:
app startactivity时创建surface和底层layer的毗连,app开始绘制时哀求下一个vysnc信号,vsync信号分发回app,app开始把视图绘制到layer,末了送显
五、写在末了

本文紧张讲了文章开头提到的,surfaceflinger的初始化,底层handler消息机制,surfaceflinger的绘制流程(surface和layer毗连&vsync分发)。盼望通过本篇文章,能对surfaceflinger总体有个清楚的认知。
read the fucking source code!
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2025-4-19 19:34, Processed in 0.133570 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表