必讀:
Android 12(S) 圖像顯示系統 - 開篇
1 前言
SurfaceFlinger作為Android圖形顯示系統處理邏輯的核心單元,我們有必要去了解其是如何啟動,初始化及進行消息處理的。這篇文章我們就來簡單分析SurfaceFlinger這個Binder系統服務的一些基本處理邏輯。接下來分兩部分講解:
>> SurfaceFlinger啟動與初始化
>> SurfaceFlinger消息隊列處理機制
Tips:
本篇涉及的代碼位置:
/frameworks/native/services/surfaceflinger/
2 SurfaceFlinger的啟動與初始化
SurfaceFlinger是一個Binder系統服務,Android設備開機啟動時就會帶起SurfaceFlinger服務進程並完成一些初始化動作。
從Android S開始,SurfaceFlinger被編譯為一個可執行二進制檔案:surfaceflinger(放置於設備/system/bin/下)。
可執行檔surfaceflinger的makefile
如下這段代碼中,可以看到這個可執行檔與surfaceflinger.rc這個init rc檔相關聯,這樣開機啟動時,init進程就可以解析這個rc檔,帶起SurfaceFlinger服務進程
cc_binary {
name: "surfaceflinger",
defaults: ["libsurfaceflinger_binary"],
init_rc: ["surfaceflinger.rc"],
srcs: [
":surfaceflinger_binary_sources",
// Note: SurfaceFlingerFactory is not in the filegroup so that it
// can be easily replaced.
"SurfaceFlingerFactory.cpp",
],
shared_libs: [
"libSurfaceFlingerProp",
],
logtags: ["EventLog/EventLogTags.logtags"],
}
再來瞅瞅surfaceflinger.rc這個檔案的內容,主要時設置一些SurfaceFlinger服務進程啟動屬性
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
capabilities SYS_NICE
onrestart restart zygote
task_profiles HighPerformance
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
這里我們就簡簡單單理解為:設備開機啟動時,init進程解析surfaceflinger.rc,然后去執行/system/bin/surfaceflinger,從而啟動了SurfaceFlinger服務進程。
如果在設備console下執行ps,你就可以看到這個進程PID了
console:/ $ ps -A | grep surfaceflinger
system 210 1 133412 38160 0 0 S surfaceflinger
可執行檔surfaceflinger的main函數入口
在此我們僅摘錄主要的代碼並注釋如下:
* /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
...
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
...
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
...
// 創建SurfaceFlinger對象,由強指針指向。
// SurfaceFlinger繼承RefBase類,所以此處一旦new出對象賦給sp指針后,將立刻觸發SurfaceFlinger類的onFirstRef方法的調用。
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
...
// SurfaceFlinger類正式初始化
// initialize before clients can connect
flinger->init();
// SurfaceFlinger向ServiceManager注冊Binder服務,
// 這樣在其他進程中可以通過getService+SERVICE_NAME來獲取SurfaceFlinger服務,繼而可以和SurfaceFlinger類進行Binder通信。
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
...
// SurfaceFlinger類進入主循環(此處注意SurfaceFlinger類未繼承Threads類,不遵循Threads類的接口執行順序)
// run surface flinger in this thread
flinger->run();
return 0;
}
對於main函數,簡簡單單把握一下幾點就可以了:
- 創建SurfaceFlinger對象,觸發執行 SurfaceFlinger::onFirstRef()
- 調用SurfaceFlinger::init()進行初始化
- 注冊服務到ServiceManager(名字是"SurfaceFlinger")
- 調用SurfaceFlinger::run()
Tips:
在設備console上執行service list命令就可以看到注冊的服務:注冊的名稱是SurfaceFlinger, 這個服務實現的接口是android.ui.ISurfaceComposer
console:/ $ service list | grep Surface
1 SurfaceFlinger: [android.ui.ISurfaceComposer]
SurfaceFlinger類定義
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ISchedulerCallback {
請關注公眾號:Android元宇宙 繼續閱讀最新文章!