Android GUI 系列之Surfaceflinger

文章目录

  • Android GUI 系列之Surfaceflinger
    • 前言
    • 1. Surfaceflinger是什么?
    • 2. Surfaceflinger
      • 2.1 特点一
      • 2.2 特点二
      • 2.3 特点三
      • 2.4 特点四
      • 2.5 特点五
    • 3. 小结
    • 4. Surfaceflinger初始化
      • 4.1 初始化涉及文件
      • 4.2 Android.bp浏览
      • 4.3 Surfaceflinger.rc
      • 4.4 main_surfaceflinger.cpp
      • 4.5 Surfaceflinger实例化
        • 4.5.1 DispSync初始化
        • 4.5.2 图元队列调度
      • 4.6 Surfaceflinger初始化
        • 4.6.1 EventThread|DispSyncSource的初始化
        • 4.6.2 EventThread实例化
        • 4.6.3 Surfaceflinger的EventThread初始化
        • 4.6.4 监听
        • 4.6.5 BitTube
        • 4.6.6 事件监听过程
        • 4.6.7 RenderEngine初始化
        • 4.6.8 HWComposer初始化
          • 4.6.8.1 HWComposer初始化
          • 4.6.8.2 HWComposer监听
        • 4.6.9 mEventControlThread的初始化
        • 4.6.10 初始化屏幕数据
      • 4.7 Surfaceflinger的run
      • 4.8 Surfaceflinger初始化显示屏模块
      • HWComposer 主动处理onHotplug
      • processDisplayChangesLocked 尝试为屏幕分配图元Surface
      • setupNewDisplayDeviceInternal
      • onInitializeDisplays
    • 4.9 总结

前言

很早开始就有想写写博客的想法,毕竟好记心不如烂笔头,这段时间公司业务要求,对音视频、渲染等要有深度理解,突然之间发现自己脑袋是空空的,没办法就只有系统性的回炉一遍,同时也做好存档,以便于后期的复习、升华做铺垫!好了废话不多说了。我们首先从界面绘制渲染开始,竟然是绘制那么针对我们Android系统而言我们是怎么把视图呈现给用户的呢?带着这个疑惑,我们就从surfaceflinger开始一一解析。


1. Surfaceflinger是什么?

通过查阅源码发现surfaceflinger几乎贯通了Android所有领域的知识,从硬件抽象层到framework层,CPU响应处理到OpenGL等等硬件绘制,复杂~。。。所以本文不针对细则逻辑做描述,我们从架构解析开始,来了解它的设计思想。
surfaceflinger是整个Android系统渲染的核心进程,所有的应用的渲染逻辑最后都会来到surfaceflinger进行处理,最有在把处理后的图像数据交给CPU/GPU绘制在屏幕上。


2. Surfaceflinger

在学习之前给出其总结的五个特点。以便后面的细则理解和设计结构的理解。

2.1 特点一

surfaceflinger在Android系统中并不是担当渲染角色,而是一个工具(“传输机器”),把每个应用传输过来的图元数据处理后交给CPU||GPU做绘制处理。

2.2 特点二

由于针对每个应用而言都是以Surface做为一个图元为传输单位,向surfaceflinger传输图元数据。如下图:

2.3 特点三

通过阅读发现Surfaceflinger设计核心思想就是以生产者和消费者的模式,会把每一个应用的Surface图元保存到SufaceflingerQueue队列中,Surfaceflinger作为消费者会根据一定的逻辑规则把生产者放入Surface一一处理。如下图:

2.4 特点四

由于应用进程和Surfaceflinger是两个独立的进程,那么图元数据是怎么实现传输的呢?这里就需要跨进程通信,这里就会连锁反应想到socket和binder但是由于socket需要拷贝两次在效率上不可取,binder又有大小限制好像是1M不到还要包括其它的通信也不可取,所以为了解决这个问题,Android系统使用了共享内存(匿名共享内存ion),匿名共享内存也只需要拷贝一次的进程通信方式,听大神说比较接近Linux共享内存。具体实现方式后期在学习~如下图:

2.5 特点五

Surfaceflinger底层有一个时间钟在不断循环,从硬件中发出或者从软件模拟发出记时唤起,每个一段时间(16ms)都会获取Surfaceflinger中的图元队列通过CPU/GPU绘制到屏幕上。这个特点有点绕,因为此特点应用有办法通知Surfaceflinger渲染模式,Surfaceflinger绘制屏幕有自身回调自身特点等。如下图:

PS:对于相位和Vsync(垂直信号)的介绍我们会在后续同步。

3. 小结

上述五点就是Surfaceflinger的设计核心特点,按照这五个特点阅读可以降低其复杂性。那么Surfaceflinger和skia有什么关系呢?和顶层View的绘制又有什么关系呢?

我们通过层级区分如下:

  1. framework面向应用开发者的View是便于开发的控件,里面提供了当前控制的属性以及功能。
  2. Skia是Android对于屏幕的画笔,经过View的onDraw方法回调,把需要绘制的东西通过Skia绘制成像素图元保存起来。
  3. Surfaceflinger是最后接收Skia的绘制结果,最后同步到屏幕上。

所以,Skia是Android渲染的核心,最终Skia和系统结合起来才是一个完整的渲染体系。如下图:


4. Surfaceflinger初始化

针对初始化我们通过代码结合形式来分析代码来至版本9.0。在阅读源码做下铺垫,首先我们先弄清楚EGL/OPENGL ES,Displayhardware,Gralloc,FramcbuffernativeWindow等等之间的关系。如下图:

  • Android HAL层提供了Gralloc,包括fb和gralloc两个设备。前者负责打开内核中的framebuffer、初始化配置,提供Post,setSwapInsterval等操作接口;后者者管理针缓冲区的分配和释放。这就意味着上层元素只能通过Gralloc来访问帧缓冲区,从而保证系统对framebuffer的有序使用和统一管理。
  • 另外HAL层的另一个重要模块Conposer它是为厂商自制UI合成提供接口,它的直接使用者是surfaceflinger中的HWConposer,同时还负责VSync信号的产生和控制。VSync是一种同步机制,可以是硬件产生,也可以通过软件来模拟Thread。
  • 由于OpenGL ES是一个通用的函数库,在不同的平台系统上需要被本地化及就是把它具体的平台窗口系统联系起来。FramebufferNativeWindow主要就是负责OpenGL ES在Android平台上本地化的中介之一。还有一个本地窗口Surface。为OpenGL ES配置本地窗口的是EGL。
  • OpenGL ES 只是一个接口协议,具体实现既可以采用软件,也可以依托于硬件。那么OpenGLES 动态运行时是如何取舍的?这个就是EGL的作用之一,它回去读取egl.cfg这个配置文件,然后根据设定动态加赞libagl||libhgl。
  • surfaceflinger中持有一个数组mDisplays来描述系统中支持的显示设备及Display,它是由surfaceflinger在readyToRun中判断并赋值,并且在DisplayDevice在初始化时还将调用eglgetDisplay,eglcreateWindowSurface等,并利用EGL来完成OpenGLES的环境搭建。。。

4.1 初始化涉及文件

  • /frameworks/native/services/surfaceflinger/Android.bp
  • /frameworks/native/services/surfaceflinger/surfaceflinger.rc
  • /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
  • /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
  • /frameworks/native/services/surfaceflinger/DispSync.cpp
  • /frameworks/native/services/surfaceflinger/MessageQueue.cpp
  • /frameworks/native/services/surfaceflinger/EventThread.cpp
  • /frameworks/native/services/surfaceflinger/MessageQueue.cpp
  • /frameworks/native/libs/gui/BitTube.cpp
  • /frameworks/native/services/surfaceflinger/EventThread.cpp
  • /frameworks/native/libs/gui/DisplayEventReceiver.cpp
  • /frameworks/native/services/surfaceflinger/MessageQueue.cpp
  • /frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
  • /frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
  • /frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
  • /frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.cpp
  • /frameworks/native/services/surfaceflinger/EventControlThread.cpp
  • /frameworks/native/services/surfaceflinger/MessageQueue.cpp

4.2 Android.bp浏览

需要明白Surfaceflinger的启动需要先了解其涉及的模块,bp文件路径: /frameworks/native/services/surfaceflinger/Android.bp
对应代码如下:

cc_defaults {name: "libsurfaceflinger_defaults",defaults: ["surfaceflinger_defaults"],cflags: ["-DGL_GLEXT_PROTOTYPES","-DEGL_EGLEXT_PROTOTYPES",],shared_libs: ["android.frameworks.vr.composer@1.0","android.hardware.configstore-utils","android.hardware.configstore@1.0","android.hardware.configstore@1.1","android.hardware.graphics.allocator@2.0","android.hardware.graphics.composer@2.1","android.hardware.graphics.composer@2.2","android.hardware.power@1.0","libbase","libbinder","libbufferhubqueue","libcutils","libdl","libEGL","libfmq","libGLESv1_CM","libGLESv2","libgui","libhardware","libhidlbase","libhidltransport","libhwbinder","liblayers_proto","liblog","libpdx_default_transport","libprotobuf-cpp-lite","libsync","libtimestats_proto","libui","libutils","libvulkan",],static_libs: ["libserviceutils","libtrace_proto","libvkjson","libvr_manager","libvrflinger",],header_libs: ["android.hardware.graphics.composer@2.1-command-buffer","android.hardware.graphics.composer@2.2-command-buffer",],export_static_lib_headers: ["libserviceutils",],export_shared_lib_headers: ["android.hardware.graphics.allocator@2.0","android.hardware.graphics.composer@2.1","android.hardware.graphics.composer@2.2","libhidlbase","libhidltransport","libhwbinder",],
}
cc_library_headers {...
}filegroup {name: "libsurfaceflinger_sources",srcs: [...],
}
cc_library_shared {name: "libsurfaceflinger",defaults: ["libsurfaceflinger_defaults"],...
}
cc_binary {name: "surfaceflinger",defaults: ["surfaceflinger_defaults"],init_rc: ["surfaceflinger.rc"],srcs: ["main_surfaceflinger.cpp"],...
}
...

Surfaceflinger中涉及的几个核心:

  • android.hardware.graphics.allocator@2.0 (图元生成器抽象硬件层的实现)
  • android.hardware.graphics.composer@2.x(hwc图层合成抽象硬件层实现)
  • binder,OpenGL es,hwbinder(抽象硬件层的binder)等等
  • 设定了SurfaceFlinger的在Android启动初期需要加载的init.rc文件:surfaceflinger.rc
  • SurfaceFlinger的主函数入口main_surfaceflinger.cpp

PS:针对硬件抽象层不好理解,我们先把这个疑问预留这里,后期在学习总结。

4.3 Surfaceflinger.rc

文件路径: /frameworks/native/services/surfaceflinger/surfaceflinger.rc
对应代码如下:

service surfaceflinger /system/bin/surfaceflingerclass core animationuser systemgroup graphics drmrpc readproconrestart restart zygotewritepid /dev/stune/foreground/taskssocket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_disp

上面代码在启动surfaceflinger服务、系统之外,同步还启动了三个socket-跨进程通信的。具体作用不是当前重点后续在做研究。

4.4 main_surfaceflinger.cpp

Surfaceflinger启动入口其文件路径:
/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {//忽略了SIGPIPE信号,因为在SurfaceFlinger的Client-Server模型中,或者说IPC机制中,很可能会触发SIGPIPE信号,而这个信号的默认动作是终止进程//当客户端/服务端的socket关闭时,防止进程退出signal(SIGPIPE, SIG_IGN);hardware::configureRpcThreadpool(1 /* maxThreads */,false /* callerWillJoin */);startGraphicsAllocatorService();//初始化Hal层的图元生成器服务//设定surfaceflinger进程的binder线程池个数上限为4,并启动binder线程池;ProcessState::self()->setThreadPoolMaxThreadCount(4);//开启线程//大多数程序都是需要IPC的,这里也需要,但是使用Binder机制是很繁琐的,所以Android为程序进程使用Binder机制封装了两个实现类:ProcessState、IPCThreadState//其中ProcessState负责打开Binder驱动,进行mmap等准备工作;IPCThreadState负责具体线程跟Binder驱动进行命令交互。sp<ProcessState> ps(ProcessState::self());ps->startThreadPool();// 实例化sp<SurfaceFlinger> flinger = new SurfaceFlinger();//设置surfaceflinger进程为高优先级以及前台调度策略;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 initif (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);// 执行surfaceflinger初始化方法flinger->init();//将surfaceflinger添加到ServiceManager//sp是strongponiter强指针(sp对象的析构函数调用RefBase的decStrong来减少强弱引用指针计数)sp<IServiceManager> sm(defaultServiceManager());sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);// 注册GPUsp<GpuService> gpuservice = new GpuService();sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);startDisplayService(); // 启动图形处理相关服务struct sched_param param = {0};param.sched_priority = 2;if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {ALOGE("Couldn't set SCHED_FIFO");}// 运行当前线程flinger->run();return 0;
}

在上面方法中我们抽离几个核心方法解读:

  • startGraphicsAllocatorService初始化hal层的图元生成器
  • 初始化ProcessState,把该进程映射到Binder驱动程序
  • Surfaceflinger实例化
  • set_sched_policy设置前台进程
  • Surfaceflinger初始化
  • 由于Surfaceflinger本质是Binder服务,所以需要添加到ServiceManager进程中
  • 初始化GpuService,添加到ServiveManager进程中
  • 启动图形处理相关服务DisplayService
  • sched_setscheduler把进程调度模式设置为实时进程的FIFO
  • 调用Surfaceflinger的run方法

PS:由于Surfaceflinger不像应用进程一样是前台应用,它是运行云后台的为了保证它不被干掉,为了CPU不断的优先把资源传递给Surfaceflinger,为了让得到的渲染机会在16ms完成。
这里有一个FIFO就是实时调度策略,细则感兴趣的桐学可以学习下linux的进程调度。
Surfaceflinger被设置为SP_FOREGROUND,设置为前台进程,加入到前台进程数组中。接着SCHED_FIFO优先级策略。这样就能保证Surfaceflinger是在较高优先级下运行,同时保证只要每一次遍历进程调度类的时候,必定会先让渡给Surfaceflinger,接着让调渡给Ap应用。

4.5 Surfaceflinger实例化

创建SurfaceFlinger对象,在其构造函数中,主要是一些成员变量的初始化工作核心是提供的surfaceflinger的binder能力,提供layer创建等能力,系统提供的监听Binder进程死亡的事件回调,HWComper提供的监听显示器变化事件回调以及Hwcomposer中的Vsync信号。
代码路径:/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag): BnSurfaceComposer(),mTransactionFlags(0),mTransactionPending(false),mAnimTransactionPending(false),mLayersRemoved(false),mLayersAdded(false),mRepaintEverything(0),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),mPrimaryDispSync("PrimaryDispSync"),mPrimaryHWVsyncEnabled(false),mHWVsyncAvailable(false),mHasPoweredOff(false),mNumLayers(0),mVrFlingerRequestsDisplay(false),mMainThreadId(std::this_thread::get_id()),mCreateBufferQueue(&BufferQueue::createBufferQueue),mCreateNativeWindowSurface(&impl::NativeWindowSurface::create) {}
  • BnSurfaceComposer,IBinder::DeathRecipient,HWComposer::EventHandler SurfaceFlinger的父类
  • mPrimaryDispSync 主要的信号同步处理器
  • BufferQueue 图元消费队列
SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {ALOGI("SurfaceFlinger is starting");vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);hasSyncFramework = getBool< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::hasSyncFramework>(true);dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);// Vr flinger is only enabled on Daydream ready devices.useVrFlinger = getBool< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::useVrFlinger>(false);maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,&ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);hasWideColorDisplay =getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);V1_1::DisplayOrientation primaryDisplayOrientation =getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(V1_1::DisplayOrientation::ORIENTATION_0);switch (primaryDisplayOrientation) {case V1_1::DisplayOrientation::ORIENTATION_90:mPrimaryDisplayOrientation = DisplayState::eOrientation90;break;case V1_1::DisplayOrientation::ORIENTATION_180:mPrimaryDisplayOrientation = DisplayState::eOrientation180;break;case V1_1::DisplayOrientation::ORIENTATION_270:mPrimaryDisplayOrientation = DisplayState::eOrientation270;break;default:mPrimaryDisplayOrientation = DisplayState::eOrientationDefault;break;}ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation);mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);// 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 enabledmDebugDDMS = 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");const size_t defaultListSize = MAX_LAYERS;auto listSize = property_get_int32("debug.sf.max_igbp_list_size", int32_t(defaultListSize));mMaxGraphicBufferProducerListSize = (listSize > 0) ? size_t(listSize) : defaultListSize;property_get("debug.sf.early_phase_offset_ns", value, "0");const int earlyWakeupOffsetOffsetNs = atoi(value);ALOGI_IF(earlyWakeupOffsetOffsetNs != 0, "Enabling separate early offset");mVsyncModulator.setPhaseOffsets(sfVsyncPhaseOffsetNs - earlyWakeupOffsetOffsetNs,sfVsyncPhaseOffsetNs);//我们应该读取'persist.sys.sf '。color_saturation‘这//但是由于/data可能被加密,我们需要等到vold之后//读取属性属性是//在启动动画之后读取if (useTrebleTestingOverride()) {//如果没有覆盖SurfaceFlinger就不能连接到HIDL//舱单上没有列出的服务。被认为是//从set服务名派生设置,但是它//如果使用的名称不是'default',则是易碎的//用于以后的生产目的。setenv("TREBLE_TESTING_OVERRIDE", "true", true);}
}

Surfaceflinger实例化实现如下特点:

  • 初始化了vsyncPhaseOffsetNs,sfVsyncPhaseOffsetNs两个相位差,分别是指app的以及sf的相位差。关于相位差后面在学习
  • 设置Surfaceflinger的渲染方向,是哪一个角度
  • mPrimaryDispSync 主显示屏信号同步器初始化
  • 根据Android的全局配置,判断是否需要打开三重缓冲,HWC合成机制

4.5.1 DispSync初始化

void DispSync::init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset) {mIgnorePresentFences = !hasSyncFramework;mPresentTimeOffset = dispSyncPresentTimeOffset;mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);// set DispSync to SCHED_FIFO to minimize jitterstruct 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) {//如果我们没有得到现在的栅栏,那么零相位示踪剂//将阻止HW垂直同步事件被关闭。//即使我们只是忽略了栅栏,零相位跟踪也是//不需要,因为任何时候有一个事件注册我们将//打开HW垂直同步事件。if (!mIgnorePresentFences && kEnableZeroPhaseTracer) {mZeroPhaseTracer = std::make_unique<ZeroPhaseTracer>();addEventListener("ZeroPhaseTracer", 0, mZeroPhaseTracer.get());}}
}

在这个过程中初始化了DispSyncThread这个线程并且运行起来,并且初始化一些简单的数据。同时设置这个线程调度的优先类为FIFO。相位计算?

4.5.2 图元队列调度

因为这里的SurfaceFlinger对象是一个StrongPointer强指针,所以首先会走到RefBase的onFirstRef方法。故

 void SurfaceFlinger::onFirstRef()
{mEventQueue->init(this);
}

查看surfaceFlinger.h,发现mEventQueue是MessqgeQueue创建的对象。

 // these are thread safemutable std::unique_ptr<MessageQueue> mEventQueue{std::make_unique<impl::MessageQueue>()};

文件路劲/frameworks/native/services/surfaceflinger/MessageQueue.cpp
所以初始化会创建消息队列需要的Handler、Looper。

  void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {mFlinger = flinger;mLooper = new Looper(true);mHandler = new Handler(*this);
}

此处MessageQueue不是常见的消息队列,在SurfaceFlinger目录单独编写,mEventQueue更像是消息循环机制的管理者,其中包含了一个looper,在looper中的mMessageEnvelopes这个容器才是真正存储消息的地方。
waitMessage主要通过调用mLooper的pollOnce方法来监听消息

 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 happenALOGE("Looper::pollOnce() returned unknown status %d", ret);continue;}} while (true);
}

handler也不是常见的那个Handler,而是Messagequeue中自定义的一个事件处理器,是专门为Surfaceflinger设计的,handler收到消息,进一步回调Surfaceflinger中的onMessageReceived。

 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);mQueue.mFlinger->onMessageReceived(message.what);break;}
}

上面代码注册了两种不同的图元刷新监听,一个是invalidate局部刷新,一个是refresh重新刷新。最后都会回调到Surfaceflinger的onMessageReceived中。换句话说,每当我们需要图元刷新的时候,就会通过mEventQueue的post方法,把数据异步加载到Handler中进行刷新。

4.6 Surfaceflinger初始化

void SurfaceFlinger::init() {ALOGI(  "SurfaceFlinger's main thread ready to run. ""Initializing graphics H/W...");ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs);Mutex::Autolock _l(mStateLock);// start the EventThread当应用和sf的vsync偏移量一致时,则只创建一个EventThread线程// std::make_unique比较新,它是在c++14里加入标准库的。//template<typename T, typename... Ts>//std::unique_ptr<T> make_unique(Ts&&... params)//{//return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));//}//make_unique只是把参数完美转发给,要创建对象的构造函数,再从new出来的原生指针,构造std::unique_ptr。//这种形式的函数,不支持数组和自定义删除器。//make_unique函数:把任意集合的参数,完美转发给动态分配对象的构造函数,//然后返回一个指向那对象的智能指针。mEventThreadSource =std::make_unique<DispSyncSource>(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs,true, "app");mEventThread = std::make_unique<impl::EventThread>(mEventThreadSource.get(),[this]() { resyncWithRateLimit(); },impl::EventThread::InterceptVSyncsCallback(),"appEventThread");mSfEventThreadSource =std::make_unique<DispSyncSource>(&mPrimaryDispSync,SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");mSFEventThread =std::make_unique<impl::EventThread>(mSfEventThreadSource.get(),[this]() { resyncWithRateLimit(); },[this](nsecs_t timestamp) {mInterceptor->saveVSyncEvent(timestamp);},"sfEventThread");//设置EventThreadmEventQueue->setEventThread(mSFEventThread.get());mVsyncModulator.setEventThread(mSFEventThread.get());//获取RenderEngine引擎,渲染引擎,通过工厂模式实现对于不同版本的OpenGL分装. 详细实现下面接下来再进行分析getBE().mRenderEngine =RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,hasWideColorDisplay? RE::RenderEngine::WIDE_COLOR_SUPPORT: 0);LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,"Starting with vr flinger active is not currently supported.");getBE().mHwc.reset(//初始化硬件composer对象, hwcomposer实例化,主要是监听显示器硬件变化, hard抽象层。new HWComposer(std::make_unique<Hwc2::impl::Composer>(getBE().mHwcServiceName)));//监听getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);//处理任何初始热插拔和结果显示更改。//该方法第一次进来无效,这是SF重启发现有屏幕插进来,一般不会走进来processDisplayHotplugEventsLocked();LOG_ALWAYS_FATAL_IF(!getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY),"Registered composer callback but didn't create the default primary display");//将默认的显示GLContext设置为当前,这样我们就可以创建纹理//当我们创建图层时(可能会在渲染之前发生)//第一次进来还没有链接进来的Display的Binder对象,跳过getDefaultDisplayDeviceLocked()->makeCurrent();//打开vr功能相关模块if (useVrFlinger) {auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {//这个回调函数被vr flinger分派线程调用。我们//需要调用signalTransaction(),它需要持有//当我们不在主线程时mStateLock。收购// mStateLock从vr flinger分派线程可能触发一个//surface flinger中的死锁(见b/66916578),因此发布一个消息//改为在主线程上处理。sp<LambdaMessage> message = new LambdaMessage([=]() {ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);mVrFlingerRequestsDisplay = requestDisplay;signalTransaction();});postMessageAsync(message);};mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(),getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),vrFlingerRequestDisplayCallback);if (!mVrFlinger) {ALOGE("Failed to start vrflinger");}}mEventControlThread = std::make_unique<impl::EventControlThread>([this](bool enabled) { setVsyncEnabled(HWC_DISPLAY_PRIMARY, enabled); });// //初始化绘图状态mDrawingState = mCurrentState;//初始化显示设备,以Event事件形式发送initializeDisplays();getBE().mRenderEngine->primeCache();//通知本地图形api是否支持当前的时间戳:if (getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable)) {mStartPropertySetThread = new StartPropertySetThread(false);} else {mStartPropertySetThread = new StartPropertySetThread(true);}if (mStartPropertySetThread->Start() != NO_ERROR) {ALOGE("Run StartPropertySetThread failed!");}mLegacySrgbSaturationMatrix = getBE().mHwc->getDataspaceSaturationMatrix(HWC_DISPLAY_PRIMARY,Dataspace::SRGB_LINEAR);ALOGV("Done initializing");
}

在init过程中初始化不少重要的对象:

  • DispSyncSource 的初始化
  • EventThread 的初始化
  • EventQueue 监听初始化
  • RenderEngine渲染引擎的初始化
  • 初始化HWComposer监听显示器硬件变化
  • EventControlThread初始化
  • 初始化和链接DisplayService

4.6.1 EventThread|DispSyncSource的初始化

文件路径:/frameworks/native/services/surfaceflinger/EventThread.cpp

mEventThreadSource =std::make_unique<DispSyncSource>(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs,true, "app");
mEventThread = std::make_unique<impl::EventThread>(mEventThreadSource.get(),[this]() { resyncWithRateLimit(); },impl::EventThread::InterceptVSyncsCallback(),"appEventThread");

能看到实际上mEventThread本质上就是一个DisSyncSource对象,我们看看他的构造函数:

class DispSyncSource final : 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(),mVsyncMutex(),mPhaseOffset(phaseOffset),mEnabled(false) {}~DispSyncSource() override = default;...

在这个中设置两个关键参数,一个是上面初始化好的DispSync显示同步信号,一个是app的DispSyncSource(相位差)

4.6.2 EventThread实例化

其逻辑流程大概如下:

把app的DispSyncSource作为参数,进行实例化

EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName): mVSyncSource(src),mResyncWithRateLimitCallback(resyncWithRateLimitCallback),mInterceptVSyncsCallback(interceptVSyncsCallback) {for (auto& event : mVSyncEvent) {event.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;event.header.id = 0;event.header.timestamp = 0;event.vsync.count = 0;}mThread = std::thread(&EventThread::threadMain, this);pthread_setname_np(mThread.native_handle(), threadName);pid_t tid = pthread_gettid_np(mThread.native_handle());// Use SCHED_FIFO to minimize jitterconstexpr int EVENT_THREAD_PRIORITY = 2;struct sched_param param = {0};param.sched_priority = EVENT_THREAD_PRIORITY;if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, &param) != 0) {ALOGE("Couldn't set SCHED_FIFO for EventThread");}set_sched_policy(tid, SP_FOREGROUND);
}

能够看到在这个过程中做的事情和DispSync的方法很相似。首先实例化一个内部线程,并且设置这个线程的启动后的方法,以及设置该线程为FIFO策略并且设置为前台线程,使用更高的优先级。

void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {std::unique_lock<std::mutex> lock(mMutex);while (mKeepRunning) {DisplayEventReceiver::Event event;Vector<sp<EventThread::Connection> > signalConnections;signalConnections = waitForEventLocked(&lock, &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 eventstatus_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.removeDisplayEventConnectionLocked(signalConnections[i]);}}}
}

能看到在这个过程中,会通过waitForEventLocked阻塞等待外部链接进来的EventThread的Connection,链接进来。一般是应用程序注册了Choreographer之后,就会注册DisplayEventReceiver,此时会对应DisplayEventReceiverDispatch一个Looper的callback,同时会通过Binder把当前为当前对象注册一个Connect给Surfaceflinger进程的EventThread。当唤醒之后,经过检测将会调用postEvent把同步信号同步给Ap应用。

在waitForEventLocked等待循环的过程中,每一次同步信号的发出都会调用构造函数进来的回调interceptVSyncsCallback,也就是:

resyncWithRateLimit();

同时会根据条件判断,当前是否打开同步信号。

4.6.3 Surfaceflinger的EventThread初始化

 mSfEventThreadSource =std::make_unique<DispSyncSource>(&mPrimaryDispSync,SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");mSFEventThread =std::make_unique<impl::EventThread>(mSfEventThreadSource.get(),[this]() { resyncWithRateLimit(); },[this](nsecs_t timestamp) {mInterceptor->saveVSyncEvent(timestamp);},"sfEventThread");//设置EventThreadmEventQueue->setEventThread(mSFEventThread.get());mVsyncModulator.setEventThread(mSFEventThread.get());

Surfaceflinger的EventThread监听的是本进程的,其先去看看mEventQueue这个Surfaceflinger中的MessageQueue的setEventThread方法

void MessageQueue::setEventThread(android::EventThread* eventThread) {if (mEventThread == eventThread) {return;}if (mEventTube.getFd() >= 0) {mLooper->removeFd(mEventTube.getFd());}mEventThread = eventThread;mEvents = eventThread->createEventConnection();mEvents->stealReceiveChannel(&mEventTube);mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,this);
}

在这个过程中能看到和Ap应用极其相似的逻辑。首先通过eventThread的createEventConnection创建一个Connection,EventThread可以从waitForEventLocked能够监听到这个链接。

sp<BnDisplayEventConnection> EventThread::createEventConnection() const {return new Connection(const_cast<EventThread*>(this));
}
EventThread::Connection::Connection(EventThread* eventThread): count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}EventThread::Connection::~Connection() {//这里什么都不做——清理将自动发生//当主线程唤醒时}void EventThread::Connection::onFirstRef() {//注意:mEventThread对我们没有强引用mEventThread->registerDisplayEventConnection(this);
}

初始化了一个BitTube对象,以及把当前的Connection注册到EventThread中,让waitForEvent可以监听到新的监听进来了。

4.6.4 监听

status_t EventThread::registerDisplayEventConnection(const sp<EventThread::Connection>& connection) {std::lock_guard<std::mutex> lock(mMutex);mDisplayEventConnections.add(connection);mCondition.notify_all();return NO_ERROR;
}

4.6.5 BitTube

封装过的socketpair。是一个全双工的通道,可以从1号写入,0号读取。也可以从0号写入,1号读取。在BitTube中设定了0是接受,1是写入其实就和管道一样的。
文件路径:/frameworks/native/libs/gui/BitTube.cpp

static const size_t DEFAULT_SOCKET_BUFFER_SIZE = 4 * 1024;BitTube::BitTube(size_t bufsize) {init(bufsize, bufsize);
}BitTube::BitTube(DefaultSizeType) : BitTube(DEFAULT_SOCKET_BUFFER_SIZE) {}BitTube::BitTube(const Parcel& data) {readFromParcel(&data);
}void BitTube::init(size_t rcvbuf, size_t sndbuf) {int sockets[2];if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {size_t size = DEFAULT_SOCKET_BUFFER_SIZE;setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));// since we don't use the "return channel", we keep it small...setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));fcntl(sockets[0], F_SETFL, O_NONBLOCK);fcntl(sockets[1], F_SETFL, O_NONBLOCK);mReceiveFd.reset(sockets[0]);mSendFd.reset(sockets[1]);} else {mReceiveFd.reset();ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));}
}

4.6.6 事件监听过程

接着调用EventThread::Connection的stealReceiveChannel

status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {//重置这个位管的接收文件描述符为receiveFdoutChannel->setReceiveFd(mChannel.moveReceiveFd());return NO_ERROR;
}

当waitForEvent接触等待后,将会调用Connection的postEvent方法:
文件路径:/frameworks/native/services/surfaceflinger/EventThread.cpp

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);
}

文件路径:/frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,Event const* events, size_t count)
{return gui::BitTube::sendObjects(dataChannel, events, count);
}

这样就完成了从发送端到接收端的过程监听,当有数据唤醒时候就会进入到MessageQueue的回调中。
文件路径:/frameworks/native/services/surfaceflinger/MessageQueue.cpp

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);return queue->eventReceiver(fd, events);
}int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {ssize_t n;DisplayEventReceiver::Event buffer[8];while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {for (int i = 0; i < n; i++) {if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {mHandler->dispatchInvalidate();break;}}}return 1;
}

此时MessageQueue就会调用Handler中的dispatchInvalidate,也就调用到了Surfaceflinger的onMessageReceived回调。

4.6.7 RenderEngine初始化

//获取RenderEngine引擎,渲染引擎,通过工厂模式实现对于不同版本的OpenGL分装. 详细实现下面接下来再进行分析
getBE().mRenderEngine =RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,hasWideColorDisplay?RE::RenderEngine::WIDE_COLOR_SUPPORT:0);

getBE其实是SurfaceflingerBE,它控制所有硬件接口,理解为Surfaceflinger缩影。Surfaceflinger是对整个系统的视图刷新控制。

std::unique_ptr<RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featureFlags) {//初始化EGL,作为默认的显示EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);if (!eglInitialize(display, nullptr, nullptr)) {LOG_ALWAYS_FATAL("failed to initialize EGL");}//初始化EGL的版本GLExtensions& extensions = GLExtensions::getInstance();extensions.initWithEGLStrings(eglQueryStringImplementationANDROID(display, EGL_VERSION),eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS));// The code assumes that ES2 or later is available if this extension is// supported.//选择处理EGL的配置EGLConfig config = EGL_NO_CONFIG;if (!extensions.hasNoConfigContext()) {config = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);}//初始化EGL上下文EGLint renderableType = 0;if (config == EGL_NO_CONFIG) {renderableType = EGL_OPENGL_ES2_BIT;} else if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");}//设置GL版本号EGLint contextClientVersion = 0;if (renderableType & EGL_OPENGL_ES2_BIT) {contextClientVersion = 2;} else if (renderableType & EGL_OPENGL_ES_BIT) {contextClientVersion = 1;} else {LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs");}//获取属性std::vector<EGLint> contextAttributes;contextAttributes.reserve(6);contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);contextAttributes.push_back(contextClientVersion);bool useContextPriority = overrideUseContextPriorityFromConfig(extensions.hasContextPriority());if (useContextPriority) {contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);}contextAttributes.push_back(EGL_NONE);//初始化EGL上下文EGLContext ctxt = eglCreateContext(display, config, nullptr, contextAttributes.data());// if can't create a GL context, we can only abort.LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");// now figure out what version of GL did we actually get// NOTE: a dummy surface is not needed if KHR_create_context is supportedEGLConfig dummyConfig = config;if (dummyConfig == EGL_NO_CONFIG) {dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);}EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};//创建一个dump的SurfaceEGLSurface dummy = eglCreatePbufferSurface(display, dummyConfig, attribs);LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");//把EGLDisplay和dump链接起来EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));GlesVersion version = parseGlesVersion(extensions.getVersion());// initialize the renderer while GL is currentstd::unique_ptr<RenderEngine> engine;switch (version) {case GLES_VERSION_1_0:case GLES_VERSION_1_1:LOG_ALWAYS_FATAL("SurfaceFlinger requires OpenGL ES 2.0 minimum to run.");break;case GLES_VERSION_2_0:case GLES_VERSION_3_0:engine = std::make_unique<GLES20RenderEngine>(featureFlags);break;}//设置EGLDisplayengine->setEGLHandles(display, config, ctxt);ALOGI("OpenGL ES informations:");ALOGI("vendor    : %s", extensions.getVendor());ALOGI("renderer  : %s", extensions.getRenderer());ALOGI("version   : %s", extensions.getVersion());ALOGI("extensions: %s", extensions.getExtensions());ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());//把EGLDisplay设置为当前OpenGL es的环境eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);eglDestroySurface(display, dummy);return engine;
}
  • 初始化EGLDisplay ,获得当前系统默认的显示屏对象
  • 初始化EGL的版本
  • chooseEglConfig选择处理EGL的配置。通过eglGetConfigs查找可返回的EGL配置的数目,接着调用eglChooseConfig从所有配置项中得到最为推荐的配置数组,最后通过遍历查询,把系统中符合当前配置项中所有的配置都添加进来
  • eglCreateContext 初始化EGL上下文
  • 设置GL版本号
  • eglCreatePbufferSurface创建一个dump的Surface,开辟一段可以缓存帧数据的空间,并用eglMakeCurrent把EGLDisplay和dump链接起来,其目的就是为了检查OpenGL es是否有问题。
  • setEGLHandles 设置EGLDisplay,上下文和配置为全局配置
  • eglMakeCurrent 把EGLDisplay设置为当前OpenGL es的环境,销毁dump这个Surface

4.6.8 HWComposer初始化

它联通的硬件抽象层Conposer,他是被HWComposer直接使用的,HWComposer除了直接管理Composer以外还负责VSync信号的生成和控制。

    getBE().mHwc.reset(//初始化硬件composer对象, hwcomposer实例化,主要是监听显示器硬件变化, hard抽象层。new HWComposer(std::make_unique<Hwc2::impl::Composer>(getBE().mHwcServiceName)));

能看到HWComposer中传入一个Hwc2::impl::Composer对象,先看看这个对象:文件路径:/frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp

Composer::Composer(const std::string& serviceName): mWriter(kWriterInitialSize),mIsUsingVrComposer(serviceName == std::string("vr"))
{mComposer = V2_1::IComposer::getService(serviceName);if (mComposer == nullptr) {LOG_ALWAYS_FATAL("failed to get hwcomposer service");}mComposer->createClient([&](const auto& tmpError, const auto& tmpClient){if (tmpError == Error::NONE) {mClient = tmpClient;}});if (mClient == nullptr) {LOG_ALWAYS_FATAL("failed to create composer client");}// 2.2 support is optionalsp<IComposer> composer_2_2 = IComposer::castFrom(mComposer);if (composer_2_2 != nullptr) {mClient_2_2 = IComposerClient::castFrom(mClient);LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr, "IComposer 2.2 did not return IComposerClient 2.2");}if (mIsUsingVrComposer) {sp<IVrComposerClient> vrClient = IVrComposerClient::castFrom(mClient);if (vrClient == nullptr) {LOG_ALWAYS_FATAL("failed to create vr composer client");}}
}

能看到Composer对象中又会持有一个mComposer对象。这个对象可以暂且理解类似为Binder,从抽象层(hal)服务端传送过来的IComposer接口对象。之后所有要和硬件层进行交互,只需要操作这个IComposer对象即可。接着调用IComposer的createClient创建开一个Client对象。如果里面有2.2版本的IComposer对象则会把2.1版本的IComposer转化过去,这样软件层Composer就和硬件抽象层的Composer对应起来,等待HWComposer的操作。

4.6.8.1 HWComposer初始化
HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer): mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}

初始化一个HWC2::Device对象,hal层的对应的对象。

4.6.8.2 HWComposer监听
   //监听getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);

注册SF的监听到HWC中。
文件路径:/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp

void HWComposer::registerCallback(HWC2::ComposerCallback* callback,int32_t sequenceId) {mHwcDevice->registerCallback(callback, sequenceId);
}

继续,文件路径:/frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.cpp

void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {if (mRegisteredCallback) {ALOGW("Callback already registered. Ignored extra registration ""attempt.");return;}mRegisteredCallback = true;sp<ComposerCallbackBridge> callbackBridge(new ComposerCallbackBridge(callback, sequenceId));mComposer->registerCallback(callbackBridge);
}

能看到HWC会借助一callbackBridge对象把对象注册到hal层中进行监听…本身回调无法传入Binder,这里是进入hal层,转而使用一个包裹的可以传入底层协议的hal对象进行回调。

class ComposerCallbackBridge : public Hwc2::IComposerCallback {public:ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId): mCallback(callback), mSequenceId(sequenceId) {}Return<void> onHotplug(Hwc2::Display display,IComposerCallback::Connection conn) override{HWC2::Connection connection = static_cast<HWC2::Connection>(conn);mCallback->onHotplugReceived(mSequenceId, display, connection);return Void();}Return<void> onRefresh(Hwc2::Display display) override{mCallback->onRefreshReceived(mSequenceId, display);return Void();}Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override{mCallback->onVsyncReceived(mSequenceId, display, timestamp);return Void();}private:ComposerCallback* mCallback;int32_t mSequenceId;
};

能看到很简单的思路,每当hal层发生回调的时候,如刷新请求等时候,就会调用callback对应的onRefreshReceived,onVsyncReceived,onHotplugReceived三个方法,此时SF就通过了ComposerBridge联通了hal层,这样就能做到从hal通知到软件层。

4.6.9 mEventControlThread的初始化

文件路径:/frameworks/native/services/surfaceflinger/EventControlThread.cpp

EventControlThread::EventControlThread(EventControlThread::SetVSyncEnabledFunction function): mSetVSyncEnabled(function) {pthread_setname_np(mThread.native_handle(), "EventControlThread");pid_t tid = pthread_gettid_np(mThread.native_handle());setpriority(PRIO_PROCESS, tid, ANDROID_PRIORITY_URGENT_DISPLAY);set_sched_policy(tid, SP_FOREGROUND);
}EventControlThread::~EventControlThread() {{std::lock_guard<std::mutex> lock(mMutex);mKeepRunning = false;mCondition.notify_all();}mThread.join();
}void EventControlThread::setVsyncEnabled(bool enabled) {std::lock_guard<std::mutex> lock(mMutex);mVsyncEnabled = enabled;mCondition.notify_all();
}// Unfortunately std::unique_lock gives warnings with -Wthread-safety
void EventControlThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {auto keepRunning = true;auto currentVsyncEnabled = false;while (keepRunning) {mSetVSyncEnabled(currentVsyncEnabled);std::unique_lock<std::mutex> lock(mMutex);mCondition.wait(lock, [this, currentVsyncEnabled, keepRunning]() NO_THREAD_SAFETY_ANALYSIS {return currentVsyncEnabled != mVsyncEnabled || keepRunning != mKeepRunning;});currentVsyncEnabled = mVsyncEnabled;keepRunning = mKeepRunning;}
}} // namespace impl
} // namespace android

能看到EventControlThread其实就是对整个HWC的EventThread的控制。
因为mSetVSyncEnabled其实对应的是:

 mEventControlThread = std::make_unique<impl::EventControlThread>([this](bool enabled) { setVsyncEnabled(HWC_DISPLAY_PRIMARY, enabled); });

它只对HWC负责…

4.6.10 初始化屏幕数据

void SurfaceFlinger::initializeDisplays() {class MessageScreenInitialized : public MessageBase {SurfaceFlinger* flinger;public:explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }virtual bool handler() {flinger->onInitializeDisplays();return true;}};sp<MessageBase> msg = new MessageScreenInitialized(this);postMessageAsync(msg);  // we may be called from main thread, use async message
}
status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,nsecs_t reltime, uint32_t /* flags */) {return mEventQueue->postMessage(msg, reltime);
}

mEventQueue->postMessage可以看到在这里借助Surfaceflinger的异步机制调用到下一次Looper回来之后才会调用,mEventQueue中的Looper仅仅只是初始化,还没循环阻塞起来进行监听,需要等到mEventQueue进行了Looper。
因此这个时候不会立即进入Handler中进行回调。而是会继续下一个步骤。

4.7 Surfaceflinger的run

此时Surfaceflinger的init方法已经结束了。当经过startDisplayService的注册hal层的DisplayService方法之后,接着在main_surfaceflinger中会继续走surfaceFlinger的run方法。

void SurfaceFlinger::run() {do {waitForEvent();} while (true);
}
void SurfaceFlinger::waitForEvent() {mEventQueue->waitMessage();
}
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 happenALOGE("Looper::pollOnce() returned unknown status %d", ret);continue;}} while (true);
}

进入这个死循环之后,会处理一下Binder过来的消息,接着通过epoll等待有人唤醒epoll。

为什么在init的时候就提前把mEventQueue的消息循环起来,为了让注册到硬件层中ComposerCallback进行回调。等到回调之后再执行刚刚因为run起来而执行的异步消息。

4.8 Surfaceflinger初始化显示屏模块

屏幕驱动一定是最早启动的那几个常用服务,因此当Surfaceflinger启动之后,在底层一定会准备好一个通知,Surfaceflinger注册了监听一定会回调,ComposerCallbackBridge中回调,实际上对应的是Surfaceflinger屏幕热插拔回调:onHotplugReceived。

void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t display,HWC2::Connection connection) {ALOGV("onHotplugReceived(%d, %" PRIu64 ", %s)", sequenceId, display,connection == HWC2::Connection::Connected ? "connected" : "disconnected");//忽略没有正确sequenceId的事件。if (sequenceId != getBE().mComposerSequenceId) {//获取硬件对应的序列号return;}//只有当我们不在主线程时才会锁定。这个函数通常是//在hwbinder线程上调用,但是在主显示上调用//拥有状态锁的主线程已经被持有,所以不要尝试这样做//在这里获取。ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);mPendingHotplugEvents.emplace_back(HotplugEvent{display, connection});if (std::this_thread::get_id() == mMainThreadId) {//如果在主线程上,则立即处理所有挂起的热插拔事件。processDisplayHotplugEventsLocked();}setTransactionFlags(eDisplayTransactionNeeded);
}

HWC2::Connection 代表当前的链接状态,而hwc2_display_t则是来自hal层的结构体代表屏幕,此时构建一个新的结构体压入mPendingHotplugEvents 集合中,等待Surfaceflinger消化这个集合中的数据。

这里可能出现两个不同的线程一个是来自hwBinder(实际也是一个Binder驱动,只是专门负责和硬件交流罢了),一个可能是来自自己线程。我们就默认是当前线程即可,就会执行processDisplayHotplugEventsLocked。

void SurfaceFlinger::processDisplayHotplugEventsLocked() {for (const auto& event : mPendingHotplugEvents) {auto displayType = determineDisplayType(event.display, event.connection);if (displayType == DisplayDevice::DISPLAY_ID_INVALID) {ALOGW("Unable to determine the display type for display %" PRIu64, event.display);continue;}if (getBE().mHwc->isUsingVrComposer() && displayType == DisplayDevice::DISPLAY_EXTERNAL) {ALOGE("External displays are not supported by the vr hardware composer.");continue;}getBE().mHwc->onHotplug(event.display, displayType, event.connection);if (event.connection == HWC2::Connection::Connected) {if (!mBuiltinDisplays[displayType].get()) {ALOGV("Creating built in display %d", displayType);mBuiltinDisplays[displayType] = new BBinder();// All non-virtual displays are currently considered secure.DisplayDeviceState info(displayType, true);info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?"Built-in Screen" : "External Screen";mCurrentState.displays.add(mBuiltinDisplays[displayType], info);mInterceptor->saveDisplayCreation(info);}} else {ALOGV("Removing built in display %d", displayType);ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]);if (idx >= 0) {const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));mInterceptor->saveDisplayDeletion(info.displayId);mCurrentState.displays.removeItemsAt(idx);}mBuiltinDisplays[displayType].clear();}processDisplayChangesLocked();}mPendingHotplugEvents.clear();
}
  • 此时会调用mHwc->onHotplug主动通知HWComposer
  • 如果此时显示屏是告诉Surfaceflinger是插入了一个屏幕,则需要屏幕id作为index,为mBuiltinDisplays赋值一个BBinder,等待DisplayerManagerService的调用。并且保存当前的状态。把当前屏幕加入到mCurrentState的display
  • 如果此时屏幕关闭或者拔出,则销毁当前mBuiltinDisplays对应index中屏幕的信息以及信息
  • processDisplayChangesLocked 处理屏幕状态发生变化后的处理
  • mBuiltinDisplays本质上就是一个大小为2数组,但是设定两个不同的类型:
    DISPLAY_PRIMARY 数值为0 是指主屏幕
    DISPLAY_EXTERNAL 数值为1 指额外屏幕

HWComposer 主动处理onHotplug

void HWComposer::onHotplug(hwc2_display_t displayId, int32_t displayType,HWC2::Connection connection) {if (displayType >= HWC_NUM_PHYSICAL_DISPLAY_TYPES) {ALOGE("Invalid display type of %d", displayType);return;}ALOGV("hotplug: %" PRIu64 ", %s %s", displayId,displayType == DisplayDevice::DISPLAY_PRIMARY ? "primary" : "external",to_string(connection).c_str());mHwcDevice->onHotplug(displayId, connection);// Disconnect is handled through HWComposer::disconnectDisplay via// SurfaceFlinger's onHotplugReceived callback handlingif (connection == HWC2::Connection::Connected) {mDisplayData[displayType].hwcDisplay = mHwcDevice->getDisplayById(displayId);mHwcDisplaySlots[displayId] = displayType;}
}

会把链接上的屏幕保存到mDisplayData和mHwcDisplaySlots两个数组中。不过核心还是把事情委托下层的mHwcDevice的事情。

processDisplayChangesLocked 尝试为屏幕分配图元Surface

void SurfaceFlinger::processDisplayChangesLocked() {//这里我们利用Vector的copy-on-write语义来//通过跳过整个事务来提高性能//知道列表是相同的const KeyedVector<wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);const KeyedVector<wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);if (!curr.isIdenticalTo(draw)) {mVisibleRegionsDirty = true;const size_t cc = curr.size();size_t dc = draw.size();//查找被删除的显示//(即:处于绘图状态但不处于当前状态)//也处理改变的显示//显示在两个列表中for (size_t i = 0; i < dc;) {const ssize_t j = curr.indexOfKey(draw.keyAt(i));if (j < 0) {//处于绘制状态但不处于当前状态//在主显示器上调用makeCurrent(),因此我们可以//确保没有与此显示相关的东西// 是电流。const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());if (defaultDisplay != nullptr) defaultDisplay->makeCurrent();sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));if (hw != nullptr) hw->disconnect(getHwComposer());if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)mEventThread->onHotplugReceived(draw[i].type, false);mDisplays.removeItem(draw.keyAt(i));} else {//这个显示在两个列表中。看看有没有什么变化。const DisplayDeviceState& state(curr[j]);const wp<IBinder>& display(curr.keyAt(j));const sp<IBinder> state_binder = IInterface::asBinder(state.surface);const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);if (state_binder != draw_binder) {//改变表面就像破坏和//重新创建DisplayDevice,所以我们只是删除它//从绘图状态,以便它被重新添加// 在下面。sp<DisplayDevice> hw(getDisplayDeviceLocked(display));if (hw != nullptr) hw->disconnect(getHwComposer());mDisplays.removeItem(display);mDrawingState.displays.removeItemsAt(i);dc--;// at this point we must loop to the next itemcontinue;}const sp<DisplayDevice> disp(getDisplayDeviceLocked(display));if (disp != nullptr) {if (state.layerStack != draw[i].layerStack) {disp->setLayerStack(state.layerStack);}if ((state.orientation != draw[i].orientation) ||(state.viewport != draw[i].viewport) || (state.frame != draw[i].frame)) {disp->setProjection(state.orientation, state.viewport, state.frame);}if (state.width != draw[i].width || state.height != draw[i].height) {disp->setDisplaySize(state.width, state.height);}}}++i;}//查找添加的显示//(即:在当前状态而不是在绘图状态)for (size_t i = 0; i < cc; i++) {if (draw.indexOfKey(curr.keyAt(i)) < 0) {const DisplayDeviceState& state(curr[i]);sp<DisplaySurface> dispSurface;sp<IGraphicBufferProducer> producer;sp<IGraphicBufferProducer> bqProducer;sp<IGraphicBufferConsumer> bqConsumer;mCreateBufferQueue(&bqProducer, &bqConsumer, false);int32_t hwcId = -1;if (state.isVirtualDisplay()) {// Virtual displays without a surface are dormant:// they have external state (layer stack, projection,// etc.) but no internal state (i.e. a DisplayDevice).if (state.surface != nullptr) {// Allow VR composer to use virtual displays.if (mUseHwcVirtualDisplays || getBE().mHwc->isUsingVrComposer()) {int width = 0;int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width);ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status);int height = 0;status = state.surface->query(NATIVE_WINDOW_HEIGHT, &height);ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status);int intFormat = 0;status = state.surface->query(NATIVE_WINDOW_FORMAT, &intFormat);ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status);auto format = static_cast<ui::PixelFormat>(intFormat);getBE().mHwc->allocateVirtualDisplay(width, height, &format, &hwcId);}// TODO: Plumb requested format back up to consumersp<VirtualDisplaySurface> vds =new VirtualDisplaySurface(*getBE().mHwc, hwcId, state.surface,bqProducer, bqConsumer,state.displayName);dispSurface = vds;producer = vds;}} else {ALOGE_IF(state.surface != nullptr,"adding a supported display, but rendering ""surface is provided (%p), ignoring it",state.surface.get());hwcId = state.type;dispSurface = new FramebufferSurface(*getBE().mHwc, hwcId, bqConsumer);producer = bqProducer;}const wp<IBinder>& display(curr.keyAt(i));if (dispSurface != nullptr) {mDisplays.add(display,setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,producer));if (!state.isVirtualDisplay()) {mEventThread->onHotplugReceived(state.type, true);}}}}}mDrawingState.displays = mCurrentState.displays;
}

能看到在Surfaceflinger中有两个显示屏的State。一个是mCurrentState当前持有所有的显示屏数据的mCurrentState,换句话说Surfaceflinger当前的状态。另一个是mDrawingState,也就是Surfaceflinger需要绘制的状态。

Surfaceflinger每一次绘制只会绘制在mDrawingState中的屏幕和图元,而不是mCurrentState。但是每一次执行该方法的时候会为mDrawingState中的display设置为mCurrentState的display。

因此第一次回调的时候,一定不会在mDrawingState找到mCurrentState中的显示屏数据。先调用getDisplayDeviceLocked尝试设置默认屏幕也就是主屏幕为当前要绘制的屏幕。关闭其他屏幕。但是此时主屏幕都还没有初始化好,这段逻辑也就没用。

把display对应的BBinder和通过setupNewDisplayDeviceInternal生产的DisplayService设置到mDisplays这个map缓存中。

如果,如果不是虚拟屏幕,此时将会进行调用EventThread的onHotplugReceived。这里不要弄混淆ComposerCallback一样的HotPlugin回调。这个是EventThread是发送vysnc,用于唤醒waitForEvent的阻塞:

void EventThread::onHotplugReceived(int type, bool connected) {ALOGE_IF(type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,"received hotplug event for an invalid display (id=%d)", type);std::lock_guard<std::mutex> lock(mMutex);if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {DisplayEventReceiver::Event event;event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;event.header.id = type;event.header.timestamp = systemTime();event.hotplug.connected = connected;mPendingEvents.add(event);mCondition.notify_all();}
}

能看到此时会唤起阻塞住线程mCondition

setupNewDisplayDeviceInternal

sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {bool hasWideColorGamut = false;std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes;if (hasWideColorDisplay) {std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);for (ColorMode colorMode : modes) {switch (colorMode) {case ColorMode::DISPLAY_P3:case ColorMode::ADOBE_RGB:case ColorMode::DCI_P3:hasWideColorGamut = true;break;default:break;}std::vector<RenderIntent> renderIntents = getHwComposer().getRenderIntents(hwcId,colorMode);hwcColorModes.emplace(colorMode, renderIntents);}}HdrCapabilities hdrCapabilities;getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities);auto nativeWindowSurface = mCreateNativeWindowSurface(producer);auto nativeWindow = nativeWindowSurface->getNativeWindow();/** Create our display's surface*/std::unique_ptr<RE::Surface> renderSurface = getRenderEngine().createSurface();renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY);renderSurface->setAsync(state.type >= DisplayDevice::DISPLAY_VIRTUAL);renderSurface->setNativeWindow(nativeWindow.get());const int displayWidth = renderSurface->queryWidth();const int displayHeight = renderSurface->queryHeight();// Make sure that composition can never be stalled by a virtual display// consumer that isn't processing buffers fast enough. We have to do this// in two places:// * Here, in case the display is composed entirely by HWC.// * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the//   window's swap interval in eglMakeCurrent, so they'll override the//   interval we set here.if (state.type >= DisplayDevice::DISPLAY_VIRTUAL) {nativeWindow->setSwapInterval(nativeWindow.get(), 0);}// virtual displays are always considered enabledauto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL: HWC_POWER_MODE_OFF;sp<DisplayDevice> hw =new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,dispSurface, std::move(renderSurface), displayWidth, displayHeight,hasWideColorGamut, hdrCapabilities,getHwComposer().getSupportedPerFrameMetadata(hwcId),hwcColorModes, initialPowerMode);if (maxFrameBufferAcquiredBuffers >= 3) {nativeWindowSurface->preallocateBuffers();}ColorMode defaultColorMode = ColorMode::NATIVE;Dataspace defaultDataSpace = Dataspace::UNKNOWN;if (hasWideColorGamut) {defaultColorMode = ColorMode::SRGB;defaultDataSpace = Dataspace::SRGB;}setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,RenderIntent::COLORIMETRIC);if (state.type < DisplayDevice::DISPLAY_VIRTUAL) {hw->setActiveConfig(getHwComposer().getActiveConfigIndex(state.type));}hw->setLayerStack(state.layerStack);hw->setProjection(state.orientation, state.viewport, state.frame);hw->setDisplayName(state.displayName);return hw;
}

这里面的核心结构有两个,一个是通过图元生产者构建一个nativeWindow,同时让RenderEngine渲染引擎生成一个RE::Surface对象,并从RE::Surface获取宽高信息,layer栈,并全部收集到DisplayDevice。mDisplays 通过displayID找到DisplayDevice,DisplayDevice能找到对应的nativeWindow,最后能找到E::Surface。

onInitializeDisplays

void SurfaceFlinger::onInitializeDisplays() {// reset screen orientation and use primary layer stackVector<ComposerState> state;Vector<DisplayState> displays;DisplayState d;d.what = DisplayState::eDisplayProjectionChanged |DisplayState::eLayerStackChanged;d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];d.layerStack = 0;d.orientation = DisplayState::eOrientationDefault;d.frame.makeInvalid();d.viewport.makeInvalid();d.width = 0;d.height = 0;displays.add(d);setTransactionState(state, displays, 0);setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL,/*stateLockHeld*/ false);const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);const nsecs_t period = activeConfig->getVsyncPeriod();mAnimFrameTracker.setDisplayRefreshPeriod(period);// Use phase of 0 since phase is not known.// Use latency of 0, which will snap to the ideal latency.setCompositorTimingSnapped(0, period, 0);
}

在这里能看到其实就是收集主屏幕相关的信息,通过setTransactionState设置和调整mCurrentState中的display中属性的状态。

4.9 总结

本文讲解了hal层之上的SurfaceFlinger的初始化,让我们对SurfaceFlinger有一个整体概括性的印象。

  • PrimaryDispSync EventThread MessageQueue组成了Vysnc同步信号的发放逻辑
  • Surfaceflinger有一个SurfaceflingerBE作为面向硬件设备操作的对象。里面包含两个及其重要的角色HWComposer,以及RenderEngine。HWComposer里面包裹这和hal通信的媒介HWC::Device,同时HWComposer会把Surfaceflinger注册到hal层,等待硬件的回调。RenderEngine则是为渲染图元做出了画面承载体的准备,和准备了OpenGL es相关的环境

    关于OpenGL ES讲解请查阅

Android GUI 系列之Surfaceflinger相关推荐

  1. Android GUI系统之SurfaceFlinger(01)显示系统框架

    该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录 本章关键点总结 & 说明: 本章节思维导图如上.主要讲述了显示系统的基础,了解FrameBuffer ...

  2. android Gui系统之SurfaceFlinger(1)---SurfaceFlinger概论

    GUI 是任何系统都很重要的一块. android GUI大体分为4大块. 1)SurfaceFlinger 2)WMS 3)View机制 4)InputMethod 这块内容非常之多,但是理解后,可 ...

  3. c语言调用android surface,Android GUI SurfaceFlinger

    本文涉及的源代码基于 Android-7.1.1r. 一.Android GUI 框架 SurfaceFlinger 是 Android GUI 的核心,但是从 OpenGL_ES 的角度来看,它也只 ...

  4. 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)

    Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...

  5. 一篇文章看明白 Android 图形系统 Surface 与 SurfaceFlinger 之间的关系

    Android - SurfaceFlinger 图形系统 相关系列 一篇文章看明白 Android 系统启动时都干了什么 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制 一篇文 ...

  6. Android GUI系统框架介绍

    这个又是内部技术分享时准备的PPT,Android GUI框架是一个非常庞大的系统,也是Android最重要的系统之一,其决定了一个Android界面究竟如何显示出来,显示效果/效率怎样,也一直是An ...

  7. Android学习系列(10)--App列表之拖拽ListView(上)

    研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨.       鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...

  8. Android 面试系列 Dn.1---- Service?

    Yo....Yo..Yo... 各位学zha老爷们好,我是靠颜值混日子的榴莲欧巴,欢迎学zha老爷们按时来阅读今天的 Android面试系列.如果您是一个年龄小于24岁妹纸,一定要关注微信公众号&qu ...

  9. Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析...

    在前面一篇文章中,我们分析了Android应用程序与SurfaceFlinger服务的连接过程.Android应用程序成功连接上SurfaceFlinger服务之后,还需要一块匿名共享内存来和Surf ...

最新文章

  1. genesis cam 最新版_触屏精灵下载_触屏精灵最新版下载[其他行业]
  2. 小作文十大必背范文:五星级真题
  3. zookeeper源码分析之一服务端启动过程
  4. IJCAI 2021 | 中科院计算所:自监督增强的知识蒸馏方法
  5. SQL Server 自增字段重置
  6. 你知道吗?Python原来可以做这些
  7. 未来两年九大信息安全威胁
  8. python不是5的倍数_查找所有低于1000的数字之和,这是Python中3或5的倍数
  9. 药品召回管理办法(征求意见稿)(转)
  10. 伽码值(灰度系数)相关
  11. pat 秋 Professional Ability Test
  12. 短信验证注册,一个完整而优雅的JAVA后端实现
  13. Android实现有声计算器代码,android studio实现简单的计算器(无bug)
  14. SIP与P2P的技术携手创造奇迹?
  15. 徒手格斗技巧 源自特种部队 防身必备
  16. MYSQL数据库表A数据同步到表B
  17. 梦想世界3手游服务器维护,《梦想世界3》手游全新内容“沧海秘宝”正式上线 同名新服同期开启...
  18. 新浪微博中链接不能直接打开的最新解决方案
  19. “智能体”就绪 政企打开智能升级通路
  20. 卡b卡社区在线下单系统无加密全套源码

热门文章

  1. Scrapy安装在win7-32
  2. 电影《饥饿站台》所告诉我的
  3. 安卓开发,拼接屏幕、大屏幕、户外广告无人值守循环播放视频,图片。开机自动播放,断电后自动播放,重起后自动播放功能
  4. linux中添加一个用户名和密码,uClinux中添加Telnetd登陆时的用户名和密码
  5. 苹果显示4g却上不了网_电脑上不了网怎么办?试试这个方法!有奇效
  6. Matlab回归分析
  7. 华科计算机科学学院夏令营,2018年华中科技大学全校各学院保研夏令营信息统计...
  8. 【Chrome插件开发】ReRes和request-interceptor源码赏析+复现+插件开发完整解决方案
  9. 弱矩阵、强矩阵、和平衡矩阵组织结构的区别
  10. LeetCode | Climbing Stairs