surfaceflinger的啟動:
Android P 圖形顯示系統 https://www.jianshu.com/u/f92447ae8445
Android GUI系統之SurfaceFlinger https://blog.csdn.net/vviccc/article/details/104860616
frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
surfaceflinger屬于系統的底層支撐服務,應該在系統開機的早期就要起來,比如開機動畫的繪制就要依賴surfaceflinger,從它的rc檔案可知,這個服務的class是core,是以在解析init.rc時,通過class_startcore就啟動了所有class是core的服務。而且在surfaceflinger重新開機時,關鍵程序zygote也會重新開機。
插播截取的一段init.rc的代碼看下究竟:
system/core/rootdir/init.rc
//長按power鍵,Healthd會通過發一個property信号觸發一個full boot,也即是當屬性sys.boot_from_charger_mode滿足了值為1時就會觸發,接着會觸發late-init 這個action。
on property:sys.boot_from_charger_mode=1
class_stop charger
trigger late-init
//late-init這個action,主要是挂載檔案系統,然後觸發boot。
on late-init
trigger early-fs
trigger fs
trigger late-fs
trigger boot
//在boot事件中,基礎網絡初始話,基本的kernel參數,系統服務和背景程序的權限設定等,最後啟動class類型是core的系統服務。
on boot
hostname localhost
write /proc/sys/vm/overcommit_memory 1
chmod 0664 /sys/module/lowmemorykiller/parameters/adj
chown system system /sys/power/state
class_start core
接着分析surfaceflinger的啟動。
main_surfaceflinger.cpp
int main(int, char**)@main_surfaceflinger.cpp {
//下面這三行代碼是一個獨立的程序起來時,必須調用的,其中ps->startThreadPool()會間接調用到IPCThreadState::self()->joinThreadPool(mIsMain);最終讓這個程序進入一個binder_loop的循環。
ProcessState::self()->setThreadPoolMaxThreadCount(4);
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
//執行個體化一個surfaceflinger,就是new SurfaceFlinger();
sp<SurfaceFlinger> flinger = DisplayUtils::getInstance()→getSFInstance();
//設定程序優先級,PRIORITY_URGENT_DISPLAY這是級别還是很高的。
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
//在client發起連接配接之前執行初始化。
flinger→init();
//把surfaceflinger,GpuService注冊到ServiceManager。
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
sp<GpuService> gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
//運作surfaceflinger,等待client的請求。
flinger->run();
return 0;
}
SurfaceFlinger的構造函數中沒有做太多事情,隻是給變量賦了初始值,在它第一次被引用時會執行其onFirstRef函數。
void SurfaceFlinger::onFirstRef()@SurfaceFlinger.cpp{
//初始化事件隊列MessageQueue,
mEventQueue.init(this);
}
//這個MessageQueue.cpp是surfaceflinger自定義的,是消息循環處理機制的管理者,但是并不是系統标準的消息隊列。
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)@MessageQueue.cpp{
mFlinger = flinger;
//Looper是系統中通用的實作,system/core/libutils/looper.cpp
mLooper = new Looper(true);
//Handler也是surfaceflinger自定義的一個事件處理器,是MessageQueue.h的内部類,并不是通用的Handler。
mHandler = new Handler(*this);
}
//surfaceflinger的初始化,包括egl的運作環境的設定,跟vsync脈沖信号有關的EventThread等。這塊内容不在這裡做展開。
void SurfaceFlinger::init() @SurfaceFlinger.cpp{
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this);
mHwc = new HWComposer(this);
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
initializeDisplays();
}
接下來分析surfaceflinger的工作線程是怎麼運作起來的。
void SurfaceFlinger::run() @SurfaceFlinger.cpp{
//可以看到這裡是一個無線循環。
do {
waitForEvent();
} while (true);
}
//進一步調用MessageQueue中的waitMessage。
void SurfaceFlinger::waitForEvent() @SurfaceFlinger.cpp{
mEventQueue.waitMessage();
}
//這裡依然是死循環,永遠不會跳出,即使發生了錯誤,這也可以了解,surfaceflinger是整個GUI系統的核心,如果它退出了,基本系統也就癱了。
void MessageQueue::waitMessage() @MessageQueue.cpp{
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);
}
在上面的循環中,會通過mLooper->pollOnce(-1);不斷的讀取消息進行處理。前面說過這裡的MessageQueue并不是android系統通用的消息隊列,它是消息循環處理機制的管理者,在它的init函數中也看到,内部包含了looper和hander,Looper中的mMessageEnvelopes才是真正存儲消息的地方,而這個handle也隻是一個中介,并沒有實際去處理發給surfaceflinger的消息請求,而是進一步回調了surfaceflinger的onMessageReceived方法。
void MessageQueue::Handler::handleMessage(const Message& message) @MessageQueue.cpp{
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;
}
}
通過上面的分析,知道surfaceflinger的消息處理架構是通過MessageQueue把消息請求發送到Looper的mMessageEnvelopes隊列,然後通過mLooper->pollOnce(-1);方法依次取出事件處理,其中的handle會把INVALIDATE,REFRESH這兩類消息請求轉給surfaceflinger做實質的處理。
應用程式向surfaceflinger發送的消息請求分同步、異步兩種,異步推送就是消息發過去就直接傳回了,不需要等待執行結果。接下來主要看下同步的請求是怎麼處理的?
以前面的應用程式申請建立一個layer為例:
status_t Client::createSurface()@Client.cpp{
class MessageCreateLayer : public MessageBase {
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
}
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),…);
mFlinger->postMessageSync(msg);
}
省略了很多代碼,隻關注消息處理相關的,這裡通過postMessageSync發出一個同步消息,
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t /* flags */) @SurfaceFlinger.cpp{
status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR) {
msg->wait();
}
return res;
}
在上面的函數中,除了調用mEventQueue.postMessage把消息入隊外,還調用了msg->wait();這個wait從字面意思也能看出是讓調用者線程挂起了。
//下面的MessageQueue依然是surfaceflinger自定義的類。
MessageQueue.h
class MessageBase : public MessageHandler{
void wait() const { barrier.wait(); }
}
這裡是使用barrier來實作的同步,這個barrier隻在surfaceflinger中有使用,應該說是專門為surfaceflinger設計的,是以有必要去了解下它的實作原理:
frameworks/native/services/surfaceflinger/Barrier.h
class Barrier
{
public:
inline Barrier() : state(CLOSED) { }
inline ~Barrier() { }
//釋放等待在這個barrier上的線程。
void open() {
Mutex::Autolock _l(lock);
state = OPENED;
cv.broadcast();
}
//重新設定barrier,wait方法會被block,直到open方法被調用。
void close() {
Mutex::Autolock _l(lock);
state = CLOSED;
}
//這裡會一直等待,直到barrier的狀态是OPEN。
void wait() const {
Mutex::Autolock _l(lock);
while (state == CLOSED) {
cv.wait(lock);
}
}
private:
enum { OPENED, CLOSED };
mutable Mutex lock;
mutable Condition cv;
volatile int state;
};
可以看到barrier是基于Mutex和condition實作的一個模型。Mutex實際上是基于pthread接口的在封裝,隻要是涉及到對某個共享資源的通路,都可以認為是Mutex的問題領域;但是有時候對某一個共享資源的通路的目的,隻是想判斷它是不是滿足了某個條件,比如state==CLOSED,并且什麼時候滿足這一條件是未知的,這種情況下,如果依然用Mutex來處理,就要一直去輪詢,這顯然是太浪費cpu資源了,是以才有了condition,但是condition本身并不完整,比如它沒有指定具體的條件是什麼,是以它需要被填充了具體條件才能真正的使用,這裡的barrier就是一個填充了具體條件的condition,這裡的具體條件就是state == CLOSED或者state == OPEN。
介紹完了Barrier的實作原理,再來看下它是怎麼使用的,postMessageSync時調用了barrier.wait()把調用者線程挂起,那什麼時候把它喚醒呢?一種可能的情況就是這個消息請求被處理了,就應該把調用者喚醒,讓他繼續執行未完成的工作。
是以要從消息處理的接口入手:
前面分析過,在MessageQueue的waitMessage中,是通過mLooper->pollOnce(-1);不斷的讀取消息進行處理的。
system/core/libutils/Looper.cpp
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) @Looper.cpp{
result = pollInner(timeoutMillis);
}
//從pollInner看出,它調用了message的handle中的方法handleMessage。
int Looper::pollInner(int timeoutMillis) {
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
sp<MessageHandler> handler = messageEnvelope.handler;
handler->handleMessage(message);
}
是以要看發送的那條消息中的handler是哪裡來的?
MessageCreateLayer繼承自MessageBase(MessageQueue.cpp中),
MessageQueue.cpp
void MessageBase::handleMessage(const Message&) {
this->handler();
barrier.open();
};
由于MessageBase的handler的方法是純虛函數,是以這裡調用的handle是子類的handler的方法,也即是MessageCreateLayer中的handler方法,這個方法會調用surfaceflinger來完成請求。
然後調用了barrier.open();喚醒被等待的線程。
分析了surfaceflinger的消息處理機制,再來看應用程式端是如何跟surfaceflinger通信的。
前面在分析BufferQueue時,引用過GLTest::SetUp()中一段代碼,其中建立了SurfaceComposerClient執行個體,可以作為應用程式跟surfaceflinger通信的一個橋梁。
SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
if (sm != 0) {
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
上面的實作中,首先擷取surfaceflinger的句柄ISurfaceComposer,這個名字起的容易誤解,surfaceflinger雖然注冊在ServiceManager中的名字是“surfaceflinger”,但是其服務端實作的binder接口卻是ISurfaceComposer,可以從它的繼承關系得到驗證:
class SurfaceFlinger : public BnSurfaceComposer,private Ibinder::DeathRecipient,
private HWComposer::EventHandler{}
接着SurfaceComposerClient::onFirstRef() 分析,通過surfaceflinger的 createConnection傳回一個ISurfaceComposerClient 執行個體,ISurfaceComposerClient對應的服務端是Client,
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
@SurfaceFlinger.cpp{
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
這個Client才是surfaceflinger跟應用程式互動的紐帶,比如應用程式申請surface的請求就是經過client傳遞到surfaceFlinger,可以任務client是surfaceflinger安排在應用程式中一個代理,任何有UI界面的應用程式在surfaceflinger中都有對應的Client執行個體,但是應用程式并沒有直接使用Client,而是通過ISurfaceComposerClient,ISurfaceComposerClient是應用程式與Client之間的binder接口,是以應用程式端一個請求先是通過ISurfaceComposerClient,然後傳到Client,client收到者請求後,沒有讓surfaceflinger馬上執行,而是把讓先投遞到surfaceflinger的消息隊列,然後讓client所在的線程wait,因為surfaceflinger會處理所有應用程式的請求,不能來一個請求就就打斷surfaceflinger正在執行的操作,最後SurfaceFlinger處理完成後,傳回結果,喚醒wait的應用程式。