Android回爐系列之Surfaceflinger
文章目錄
- Android回爐系列之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.7 RenderEngine初始化
- 4.8 HWComposer初始化
- 4.8.1 HWComposer初始化
- 4.8.2 HWComposer監聽
- 4.8 Surfaceflinger的run
前言
很早開始就有想寫寫博客的想法,畢竟好記心不如爛筆頭,這段時間公司業務要求,對音視頻、渲染等要有深度理解,突然之間發現自己腦袋是空空的,沒辦法就只有系統性的回爐一遍,同時也做好存檔,以便于后期的復習、升華做鋪墊!好了廢話不多說了,我們首先從界面繪制渲染開始,竟然是繪制那么針對我們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的繪制又有什么關系呢?
我們通過層級區分如下:
- framework面向應用開發者的View是便于開發的控制元件,里面提供了當前控制的屬性以及功能,
- Skia是Android對于螢屏的畫筆,經過View的onDraw方法回呼,把需要繪制的東西通過Skia繪制成像素圖元保存起來,
- 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/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_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 init
if (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);
// 注冊GPU
sp<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, ¶m) != 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 enabled
mDebugDDMS = 0;
}
}
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
property_get("debug.sf.disable_backpressure", value, "0");
mPropagateBackpressure = !atoi(value);
ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
property_get("debug.sf.enable_hwc_vds", value, "0");
mUseHwcVirtualDisplays = atoi(value);
ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
property_get("ro.sf.disable_triple_buffer", value, "1");
mLayerTripleBufferingDisabled = atoi(value);
ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
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 jitter
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(mThread->getTid(), SCHED_FIFO, ¶m) != 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 safe
mutable 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 happen
ALOGE("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");
//設定EventThread
mEventQueue->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 jitter
constexpr int EVENT_THREAD_PRIORITY = 2;
struct sched_param param = {0};
param.sched_priority = EVENT_THREAD_PRIORITY;
if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, ¶m) != 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 event
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.
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");
//設定EventThread
mEventQueue->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) {
//重置這個位管的接收檔案描述符為receiveFd
outChannel->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.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 supported
EGLConfig 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的Surface
EGLSurface 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 current
std::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;
}
//設定EGLDisplay
engine->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.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 optional
sp<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.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.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層中進行監聽…
4.8 Surfaceflinger的run
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/243334.html
標籤:其他
上一篇:appium啟動后報錯
