一、Android系統啟動
Android設備從按下開機鍵到桌面顯示畫面,大致過程如下圖流程:

開機顯示桌面、從桌面點擊 App 圖標到 Activity顯示在屏幕上的過程又是怎樣的呢?下面介紹Android系統中的“畫家” - SurfaceFlinger.
SurfaceFlinger 啟動過程:

二、SurfaceFlinger代碼剖析[Android 8.0]
代碼路徑:/frameworks/native/services/surfaceflinger/
SurfaceFlinger二進制分成surfaceflinger可執行文件(main入口)和libsurfaceflinger.so庫文件(功能實現),由main_surfaceflinger.cpp文件編譯而成,Android.mk代碼模塊編譯配置如下:
1.【執行文件-surfaceflinger】
############################################################### # build surfaceflinger's executable include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_LDFLAGS_32 := -Wl,--version-script,art/sigchainlib/version-script32.txt -Wl,--export-dynamic LOCAL_LDFLAGS_64 := -Wl,--version-script,art/sigchainlib/version-script64.txt -Wl,--export-dynamic LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_INIT_RC := surfaceflinger.rc ifeq ($(TARGET_USES_HWC2),true) LOCAL_CFLAGS += -DUSE_HWC2 endif LOCAL_SRC_FILES := \ main_surfaceflinger.cpp LOCAL_SHARED_LIBRARIES := \ android.frameworks.displayservice@1.0 \ android.hardware.configstore@1.0 \ android.hardware.configstore-utils \ android.hardware.graphics.allocator@2.0 \ libsurfaceflinger \ libcutils \ libdisplayservicehidl \ liblog \ libbinder \ libhidlbase \ libhidltransport \ libutils \ libui \ libgui \ libdl LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain LOCAL_STATIC_LIBRARIES := libtrace_proto LOCAL_MODULE := surfaceflinger ifdef TARGET_32_BIT_SURFACEFLINGER LOCAL_32_BIT_ONLY := true endif LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_EXECUTABLE)
SurfaceFlinger可執行二進制文件surfaceflinger由main_surfaceflinger.cpp文件獨立編譯而成,主要負責搭建進程啟動環境:
int main(int, char**) { // 從8.0開始,Android提供了hidl機制,將原先直接由JNI->Native->HAL的接口調用形式,統一規范成hidl service/client交互形式。
// 該方式從一方面規范和統一了Android Framework和HAL的調用機制,但實際上,從項目維度,這種調用方式對性能上開銷,將比直接調用的方式要花費更多的時間。 startHidlServices(); signal(SIGPIPE, SIG_IGN); // 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 = new 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類正式初始化 // 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); // publish GpuService sp<GpuService> gpuservice = new GpuService(); sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false); struct sched_param param = {0}; param.sched_priority = 2; if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) { ALOGE("Couldn't set SCHED_FIFO"); } // SurfaceFlinger類進入主循環(此處注意SurfaceFlinger類未繼承Threads類,不遵循Threads類的接口執行順序) // run surface flinger in this thread flinger->run(); return 0; }
startHidlServices();內容如下
static status_t startHidlServices() { using android::frameworks::displayservice::V1_0::implementation::DisplayService; using android::frameworks::displayservice::V1_0::IDisplayService; using android::hardware::configstore::getBool; using android::hardware::configstore::getBool; using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs; hardware::configureRpcThreadpool(1 /* maxThreads */, false /* callerWillJoin */); status_t err; if (getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::startGraphicsAllocatorService>(false)) { err = startGraphicsAllocatorService(); if (err != OK) { return err; } } sp<IDisplayService> displayservice = new DisplayService(); //里面調用HIDL定義接口 Return<sp<IDisplayEventReceiver >> getEventReceiver() override; err = displayservice->registerAsService(); if (err != OK) { ALOGE("Could not register IDisplayService service."); } return err; }
HIDL接口介紹可以參考:https://source.android.google.cn/reference/hidl/
2.【動態庫-libsurfaceflinger.so】
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CLANG := true LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_SRC_FILES := \ Client.cpp \ DisplayDevice.cpp \ DispSync.cpp \ EventControlThread.cpp \ StartBootAnimThread.cpp \ EventThread.cpp \ FrameTracker.cpp \ GpuService.cpp \ Layer.cpp \ LayerDim.cpp \ LayerRejecter.cpp \ LayerVector.cpp \ MessageQueue.cpp \ MonitoredProducer.cpp \ SurfaceFlingerConsumer.cpp \ SurfaceInterceptor.cpp \ Transform.cpp \ DisplayHardware/ComposerHal.cpp \ DisplayHardware/FramebufferSurface.cpp \ DisplayHardware/HWC2.cpp \ DisplayHardware/HWComposerBufferCache.cpp \ DisplayHardware/PowerHAL.cpp \ DisplayHardware/VirtualDisplaySurface.cpp \ Effects/Daltonizer.cpp \ EventLog/EventLogTags.logtags \ EventLog/EventLog.cpp \ RenderEngine/Description.cpp \ RenderEngine/Mesh.cpp \ RenderEngine/Program.cpp \ RenderEngine/ProgramCache.cpp \ RenderEngine/GLExtensions.cpp \ RenderEngine/RenderEngine.cpp \ RenderEngine/Texture.cpp \ RenderEngine/GLES20RenderEngine.cpp \ LOCAL_MODULE := libsurfaceflinger LOCAL_C_INCLUDES := \ frameworks/native/vulkan/include \ external/vulkan-validation-layers/libs/vkjson \ system/libhwbinder/fast_msgq/include \ LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_USES_HWC2),true) LOCAL_CFLAGS += -DUSE_HWC2 LOCAL_SRC_FILES += \ SurfaceFlinger.cpp \ DisplayHardware/HWComposer.cpp else LOCAL_SRC_FILES += \ SurfaceFlinger_hwc1.cpp \ DisplayHardware/HWComposer_hwc1.cpp endif LOCAL_CFLAGS += -fvisibility=hidden -Werror=format LOCAL_STATIC_LIBRARIES := \ libhwcomposer-command-buffer \ libtrace_proto \ libvkjson \ libvr_manager \ libvrflinger LOCAL_SHARED_LIBRARIES := \ android.frameworks.vr.composer@1.0 \ android.hardware.graphics.allocator@2.0 \ android.hardware.graphics.composer@2.1 \ android.hardware.configstore@1.0 \ android.hardware.configstore-utils \ libcutils \ liblog \ libdl \ libfmq \ libhardware \ libhidlbase \ libhidltransport \ libhwbinder \ libutils \ libEGL \ libGLESv1_CM \ libGLESv2 \ libbinder \ libui \ libgui \ libpowermanager \ libvulkan \ libsync \ libprotobuf-cpp-lite \ libbase \ android.hardware.power@1.0 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \ android.hardware.graphics.allocator@2.0 \ android.hardware.graphics.composer@2.1 \ libhidlbase \ libhidltransport \ libhwbinder LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_SHARED_LIBRARY)
new SurfaceFlinger(); 會執行到:onFirstRef()
void SurfaceFlinger::onFirstRef() { mEventQueue.init(this); }
onFirstRef() 中會創建 Handler 並初始化:
//MessageQueue.cpp void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { mFlinger = flinger; mLooper = new Looper(true); mHandler = new Handler(*this); }
然后會執行到 SurfaceFlinger::init(),該方法主要功能是:
- 初始化 EGL
- 創建 HWComposer
- 初始化非虛擬顯示屏
- 啟動 EventThread 線程
- 啟動開機動畫
void SurfaceFlinger::init() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); Mutex::Autolock _l(mStateLock); // initialize EGL for the default display mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(mEGLDisplay, NULL, NULL); // start the EventThread sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); mEventThread = new EventThread(vsyncSrc, *this, false); sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); mSFEventThread = new EventThread(sfVsyncSrc, *this, true); mEventQueue.setEventThread(mSFEventThread); // set EventThread and SFEventThread to SCHED_FIFO to minimize jitter struct sched_param param = {0}; param.sched_priority = 2; if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) { ALOGE("Couldn't set SCHED_FIFO for SFEventThread"); } if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, ¶m) != 0) { ALOGE("Couldn't set SCHED_FIFO for EventThread"); } // Initialize the H/W composer object. There may or may not be an // actual hardware composer underneath. mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this)); // get a RenderEngine for the given display / config (can't fail) mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); // retrieve the EGL context that was selected/created mEGLContext = mRenderEngine->getEGLContext(); LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, "couldn't create EGLContext"); // Inform native graphics APIs that the present timestamp is NOT supported: property_set(kTimestampProperty, "0"); // initialize our non-virtual displays for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); // set-up the displays that are already connected if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { // All non-virtual displays are currently considered secure. bool isSecure = true; createBuiltinDisplayLocked(type); wp<IBinder> token = mBuiltinDisplays[i]; sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer); int32_t hwcId = allocateHwcDisplayId(type); sp<DisplayDevice> hw = new DisplayDevice(this, type, hwcId, mHwc->getFormat(hwcId), isSecure, token, fbs, producer, mRenderEngine->getEGLConfig(), false); if (i > DisplayDevice::DISPLAY_PRIMARY) { // FIXME: currently we don't get blank/unblank requests // for displays other than the main display, so we always // assume a connected display is unblanked. ALOGD("marking display %zu as acquired/unblanked", i); hw->setPowerMode(HWC_POWER_MODE_NORMAL); } mDisplays.add(token, hw); } } // make the GLContext current so that we can create textures when creating Layers // (which may happens before we render something) getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext); mEventControlThread = new EventControlThread(this); mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); // set a fake vsync period if there is no HWComposer if (mHwc->initCheck() != NO_ERROR) { mPrimaryDispSync.setPeriod(16666667); } // initialize our drawing state mDrawingState = mCurrentState; // set initial conditions (e.g. unblank default device) initializeDisplays(); mRenderEngine->primeCache(); mStartBootAnimThread = new StartBootAnimThread(); if (mStartBootAnimThread->Start() != NO_ERROR) { ALOGE("Run StartBootAnimThread failed!"); } ALOGV("Done initializing"); }
創建 HWComposer:
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false) { for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) { mLists[i] = 0; } for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) { mLastHwVSync[i] = 0; mVSyncCounts[i] = 0; } char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.no_hw_vsync", value, "0"); mDebugForceFakeVSync = atoi(value); bool needVSyncThread = true; // Note: some devices may insist that the FB HAL be opened before HWC. int fberr = loadFbHalModule(); //加載 framebuffer 的 HAL 層模塊 loadHwcModule(); //加載 HWComposer 模塊 if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // close FB HAL if we don't needed it. // FIXME: this is temporary until we're not forced to open FB HAL // before HWC. framebuffer_close(mFbDev); mFbDev = NULL; } // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory. if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) && !mFbDev) { ALOGE("ERROR: failed to open framebuffer (%s), aborting", strerror(-fberr)); abort(); } // these display IDs are always reserved for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { mAllocatedDisplayIDs.markBit(i); } if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, (hwcApiVersion(mHwc) >> 24) & 0xff, (hwcApiVersion(mHwc) >> 16) & 0xff); if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; // VSYNC 信號的回調方法 mCBContext->procs.vsync = &hook_vsync; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) mCBContext->procs.hotplug = &hook_hotplug; else mCBContext->procs.hotplug = NULL; memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); // 注冊回調函數 mHwc->registerProcs(mHwc, &mCBContext->procs); } // don't need a vsync thread if we have a hardware composer needVSyncThread = false; // always turn vsync off when we start eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // the number of displays we actually have depends on the // hw composer version if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { // 1.3 adds support for virtual displays mNumDisplays = MAX_HWC_DISPLAYS; } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // 1.1 adds support for multiple displays mNumDisplays = NUM_BUILTIN_DISPLAYS; } else { mNumDisplays = 1; } } if (mFbDev) { ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)), "should only have fbdev if no hwc or hwc is 1.0"); DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]); disp.connected = true; disp.format = mFbDev->format; DisplayConfig config = DisplayConfig(); config.width = mFbDev->width; config.height = mFbDev->height; config.xdpi = mFbDev->xdpi; config.ydpi = mFbDev->ydpi; config.refresh = nsecs_t(1e9 / mFbDev->fps); disp.configs.push_back(config); disp.currentConfig = 0; } else if (mHwc) { // here we're guaranteed to have at least HWC 1.1 for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { queryDisplayProperties(i); } } if (needVSyncThread) { // we don't have VSYNC support, we need to fake it : 不支持硬件的 VSYNC,則會創建線程來模擬定時 VSYNC 信號 mVSyncThread = new VSyncThread(*this); } }
HWComposer 代表着硬件顯示設備,注冊了 VSYNC 信號的回調。VSYNC 信號本身是由顯示驅動產生的,在不支持硬件的 VSYNC,則會創建“VSyncThread”線程來模擬定時 VSYNC 信號。當硬件產生VSYNC信號時,則會發送消息,handler 收到消息進行處理。當 SurfaceFlinger 進程收到 VSync 信號后經層層調用,最終調用到該對象的 handleMessageRefresh() 方法。
- HSYNC 信號用於告訴電子槍該掃描下一行了, 即要轉到下一行起始處了;
- VSYNC 信號告訴電子槍該顯示下一幀了, 即該轉回左上角起始處了;
// SurfaceFlinger.cpp void SurfaceFlinger::handleMessageRefresh() { ATRACE_CALL(); preComposition();//處理顯示設備與 layers 的改變,更新光標 rebuildLayerStacks();//重建所有可見 Layer 列表,根據Z軸排序 setUpHWComposer();//更新 HWComposer 圖層 doDebugFlashRegions(); doComposition();//生成 OpenGL 紋理圖像 postComposition();//將圖像傳遞到物理屏幕 }
相關問題:
① 屏幕刷新速率比系統幀速率快:
此時,在前緩沖區內容全部映射到屏幕上之后,后緩沖區尚未准備好下一幀,屏幕將無法讀取下一幀,所以只能繼續顯示當前一幀的圖形,造成一幀顯示多次,也就是卡頓。
② 系統幀速率比屏幕刷新率快
此時,屏幕未完全把前緩沖區的一幀映射到屏幕,而系統已經在后緩沖區准備好了下一幀,並要求讀取下一幀到屏幕,將會導致屏幕上半部分是上一幀的圖形,而下半部分是下一幀的圖形,造成屏幕上顯示多幀,也就是屏幕撕裂。
為了解決上述問題,Android顯示系統一般會有多級緩沖,即在屏幕刷新的同時在另外一個buffer准備下一幀數據,以此提高性能:

前緩沖區:用來顯示內容到屏幕的幀緩沖區
后緩沖區:用於后台合成下一幀圖形的幀緩沖區
垂直同步(VSync):當屏幕從緩沖區掃描完一幀到屏幕上之后,開始掃描下一幀之前,發出的一個同步信號,該信號用來切換前緩沖區和后緩沖區。
屏幕刷新率(HZ):代表屏幕在一秒內刷新屏幕的次數,Android手機一般為60HZ(也就是1秒刷新60幀,大約16.67毫秒刷新1幀)
系統幀速率(FPS):代表了系統在一秒內合成的幀數,該值的大小由系統算法和硬件決定。
3. 服務啟動配置文件:/frameworks/native/services/surfaceflinger/surfaceflinger.rc
上面發現服務配置文件也在Android.mk中被加載:LOCAL_INIT_RC := 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_display_vsync_endpoint_socket:s0
4. Surface 創建過程
Surface 創建的過程就是 Activity 顯示的過程,在 ActivityThread.handleResumeActivity() 中調用了 Activity.makeVisible()具體實現:
void makeVisible() { if (!mWindowAdded) { ViewManager wm = getWindowManager();//此處 getWindowManager 獲取的是 WindowManagerImpl 對象 wm.addView(mDecor, getWindow().getAttributes()); mWindowAdded = true; } mDecor.setVisibility(View.VISIBLE); }
WindowManagerImpl.java:
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.addView(view, params, mDisplay, mParentWindow); }
WindowManagerGlobal.java:
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { ... final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params; //創建 ViewRootImpl ViewRootImpl root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams); //設置 View root.setView(view, wparams, panelParentView); ... }
創建 ViewRootImpl:
public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks { ... final Surface mSurface = new Surface(); //創建 Surface,此時 Surface 創建完什么都沒有,詳見下面分析 ... public ViewRootImpl(Context context, Display display) { mContext = context; //獲取 IWindowSession 的代理類 mWindowSession = WindowManagerGlobal.getWindowSession(); mDisplay = display; mThread = Thread.currentThread(); //主線程 mWindow = new W(this); mChoreographer = Choreographer.getInstance(); ... } }
WindowManagerGlobal.java:
public static IWindowSession getWindowSession() { synchronized (WindowManagerGlobal.class) { if (sWindowSession == null) { try { //獲取 IMS 的代理類 InputMethodManager imm = InputMethodManager.getInstance(); //獲取 WMS 的代理類 IWindowManager windowManager = getWindowManagerService(); //經過 Binder 調用,最終調用 WMS sWindowSession = windowManager.openSession( new IWindowSessionCallback.Stub() {...}, imm.getClient(), imm.getInputContext()); } catch (RemoteException e) { ... } } return sWindowSession } }
WindowManagerService.openSession:
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { //創建 Session 對象 Session session = new Session(this, callback, client, inputContext); return session; }
再次經過 Binder 將數據寫回 app 進程,則獲取的便是 Session 的代理對象 IWindowSession。
創建完 ViewRootImpl 對象后,接下來調用該對象的 setView() 方法:
ViewRootImpl:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { requestLayout(); //詳見下面分析 ... //通過 Binder調用,進入 system 進程的 Session res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mInputChannel); ... } }
final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) { //調用 WMS.addWindow return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outContentInsets, outStableInsets, outOutsets, outInputChannel); } }
WindowManagerService.java:
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) { ... WindowToken token = mTokenMap.get(attrs.token); //創建 WindowState WindowState win = new WindowState(this, session, client, token, attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent); ... //調整 WindowManager 的 LayoutParams 參數 mPolicy.adjustWindowParamsLw(win.mAttrs); res = mPolicy.prepareAddWindowLw(win, attrs); addWindowToListInOrderLocked(win, true); // 設置 input mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle); //詳見下面分析 win.attach(); mWindowMap.put(client.asBinder(), win); if (win.canReceiveKeys()) { //當該窗口能接收按鍵事件,則更新聚焦窗口 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS, false /*updateInputWindows*/); } assignLayersLocked(displayContent.getWindowList()); ... } //WindowState.java void attach() { mSession.windowAddedLocked(); }
創建 SurfaceSession 對象,並將當前 Session 添加到 WMS.mSessions 成員變量。
Session.java:
void windowAddedLocked() { if (mSurfaceSession == null) { mSurfaceSession = new SurfaceSession(); mService.mSessions.add(this); if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { mService.dispatchNewAnimatorScaleLocked(this); } } mNumWindow++; }
SurfaceSession 的創建會調用 JNI,在 JNI 調用 nativeCreate()。
android_view_SurfaceSession.cpp:
static jlong nativeCreate(JNIEnv* env, jclass clazz) { SurfaceComposerClient* client = new SurfaceComposerClient(); client->incStrong((void*)nativeCreate); return reinterpret_cast<jlong>(client); }
創建 SurfaceComposerClient 對象, 作為跟 SurfaceFlinger 通信的代理對象。
SurfaceComposerClient::SurfaceComposerClient() { //getComposerService() 將返回 SF 的 Binder 代理端的 BpSurfaceFlinger 對象 sp<ISurfaceComposer> sm(getComposerService()); //先調用 SF 的 createConnection(),再調用_init _init(sm, sm->createConnection()); if(mClient != 0) { Mutex::Autolock _l(gLock); //gActiveConnections 是全局變量,把剛才創建的 client 保存到這個 map 中去 gActiveConnections.add(mClient->asBinder(), this); } }
SurfaceFlinger.cpp:
sp<ISurfaceFlingerClient>SurfaceFlinger::createConnection() { Mutex::Autolock _l(mStateLock); uint32_t token = mTokens.acquire(); //先創建一個Client sp<Client> client = new Client(token, this); //把這個Client對象保存到mClientsMap中,token是它的標識。 status_t err = mClientsMap.add(token, client); /* 創建一個用於 Binder 通信的 BClient,BClient 派生於 ISurfaceFlingerClient, 它的作用是接受客戶端的請求,然后把處理提交給 SF,注意,並不是提交給 Client。 Client 會創建一塊共享內存,該內存由 getControlBlockMemory 函數返回。 */ sp<BClient> bclient = new BClient(this, token,client->getControlBlockMemory()); return bclient; }
Client::Client(ClientID clientID, constsp<SurfaceFlinger>& flinger):ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) { const int pgsize = getpagesize(); //下面這個操作會使 cblksize 為頁的大小,目前是4096字節 constint cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); mCblkHeap = new MemoryHeapBase(cblksize, 0, "SurfaceFlinger Clientcontrol-block"); ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); if(ctrlblk) { new(ctrlblk) SharedClient;//原來 Surface 的 CB 對象就是在共享內存中創建的這個 SharedClient 對象 } }
SharedClient:
class SharedClient { public: SharedClient(); ~SharedClient(); status_t validate(size_t token) const; uint32_t getIdentity(size_t token) const; private: Mutexlock; Condition cv; //支持跨進程的同步對象 //NUM_LAYERS_MAX 為 31,SharedBufferStack 是什么? SharedBufferStack surfaces[ NUM_LAYERS_MAX ]; }; //SharedClient的構造函數,沒什么新意,不如Audio的CB對象復雜 SharedClient::SharedClient():lock(Mutex::SHARED), cv(Condition::SHARED) { }
一個 Client 最多支持 31 個顯示層。每一個顯示層的生產/消費步調都由會對應的 SharedBufferStack 來控制。而它內部就用了幾個成員變量來控制讀寫位置。
SharedBufferStack.h:
class SharedBufferStack{ ...... //Buffer 是按塊使用的,每個 Buffer 都有自己的編號,其實就是數組中的索引號。 volatile int32_t head; //FrontBuffer 的編號 volatile int32_t available; //空閑 Buffer 的個數 volatile int32_t queued; //臟 Buffer 的個數,臟 Buffer 表示有新數據的 Buffer volatile int32_t inUse; //SF 當前正在使用的 Buffer 的編號 volatilestatus_t status; //狀態碼 ...... }
SF 的一個 Client 分配一個跨進程共享的 SharedClient 對象。這個對象有31個 SharedBufferStack 元素,每一個 SharedBufferStack 對應於一個顯示層。
一個顯示層將創建兩個 Buffer,后續的 PageFlipping 就是基於這兩個 Buffer 展開的。
接着看 SurfaceComposerClient 中這個_init函數:
void SurfaceComposerClient::_init( const sp<ISurfaceComposer>& sm, constsp<ISurfaceFlingerClient>& conn) { mPrebuiltLayerState = 0; mTransactionOpen = 0; mStatus = NO_ERROR; mControl = 0; mClient = conn;// mClient 就是 BClient 的客戶端 mControlMemory =mClient->getControlBlock(); mSignalServer = sm;// mSignalServer 就是 BpSurfaceFlinger //mControl 就是那個創建於共享內存之中的 SharedClient mControl = static_cast<SharedClient*>(mControlMemory->getBase()); }
創建完 ViewRootImpl 對象后,接下來調用該對象的 setView() 方法。在 setView() 中調用了 requestLayout() 方法我們來看下這個方法:
public void requestLayout() { checkThread(); mLayoutRequested = true; scheduleTraversals(); } public void scheduleTraversals() { if(!mTraversalScheduled) { mTraversalScheduled = true; sendEmptyMessage(DO_TRAVERSAL); //發送 DO_TRAVERSAL 消息 } } public void handleMessage(Message msg) { switch (msg.what) { ...... case DO_TRAVERSAL: ...... performTraversals();//調用 performTraversals() ...... break; ...... } } private void performTraversals() { finalView host = mView;//還記得這mView嗎?它就是 DecorView booleaninitialized = false; booleancontentInsetsChanged = false; booleanvisibleInsetsChanged; try { relayoutResult= // 1. 關鍵函數relayoutWindow relayoutWindow(params, viewVisibility,insetsPending); } ...... draw(fullRedrawNeeded);// 2. 開始繪制 ...... } private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending)throws RemoteException { //原來是調用 IWindowSession 的 relayout(),暫且記住這個調用 int relayoutResult = sWindowSession.relayout(mWindow, params, (int) (mView.mMeasuredWidth * appScale + 0.5f), (int) (mView.mMeasuredHeight * appScale + 0.5f), viewVisibility, insetsPending, mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //mSurface 做為參數傳進去了。 } ...... } private void draw(boolean fullRedrawNeeded) { Surface surface = mSurface;//mSurface 是 ViewRoot 的成員變量 ...... Canvascanvas; try { int left = dirty.left; int top = dirty.top; int right = dirty.right; int bottom = dirty.bottom; //從 mSurface 中 lock 一塊 Canvas canvas = surface.lockCanvas(dirty); ...... mView.draw(canvas);//調用 DecorView 的 draw 函數,canvas 就是畫布 ...... //unlock 畫布,屏幕上馬上就能看到 View 的樣子了 surface.unlockCanvasAndPost(canvas); } ...... }
在 ViewRoot 構造時,會創建一個 Surface,它使用無參構造函數,代碼如下所示:
final Surface mSurface = new Surface();
此時創建完的 Surface 是空的,什么都沒有。接着繼續分析 relayoutWindow(),在 relayoutWindow() 中會調用 IWindowSession 的 relayout(),這是一個跨進程方法會調用到 WMS 中的 Session.relayout(),最后調用到 WindowManagerService.relayoutWindow()。
public int relayoutWindow(Session session,IWindow client, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, boolean insetsPending, Rect outFrame, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, SurfaceoutSurface){ ..... try { //win 就是 WinState,這里將創建一個本地的 Surface 對象 Surfacesurface = win.createSurfaceLocked(); if(surface != null) { //先創建一個本地 surface,然后在 outSurface 的對象上調用 copyFrom //將本地 Surface 的信息拷貝到 outSurface 中,為什么要這么麻煩呢? outSurface.copyFrom(surface); ...... }
WindowManagerService.java::WindowState:
Surface createSurfaceLocked() { ...... try { //mSurfaceSession 就是在 Session 上創建的 SurfaceSession 對象 //這里,以它為參數,構造一個新的 Surface 對象 mSurface = new Surface(mSession.mSurfaceSession, mSession.mPid, mAttrs.getTitle().toString(), 0, w, h, mAttrs.format, flags); } Surface.openTransaction();//打開一個事務處理 ...... Surface.closeTransaction();//關閉一個事務處理 ...... }
構造 Surface 對象:
public Surface(SurfaceSession s,//傳入一個SurfaceSession對象 int pid, String name, int display, int w, int h, int format, int flags) throws OutOfResourcesException { ...... mCanvas = new CompatibleCanvas(); //又一個 native 函數 init(s,pid,name,display,w,h,format,flags); mName = name; }
static void Surface_init(JNIEnv*env, jobject clazz, jobject session, jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags) { //從 SurfaceSession 對象中取出之前創建的那個 SurfaceComposerClient 對象 SurfaceComposerClient* client = (SurfaceComposerClient*)env->GetIntField(session, sso.client); sp<SurfaceControl> surface;//注意它的類型是 SurfaceControl if (jname == NULL) { //調用 SurfaceComposerClient 的 createSurface 函數,返回的 surface 是一個 SurfaceControl 類型 surface = client->createSurface(pid, dpy, w, h, format, flags); } else{ ...... } //把這個 surfaceControl 對象設置到 Java 層的 Surface 對象中 setSurfaceControl(env, clazz, surface); }
在 createSurface 內部會使用 Binder 通信將請求發給 SurfaceFlinger:
sp<ISurface>SurfaceFlinger::createSurface(ClientID clientId, int pid, const String8& name, ISurfaceFlingerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<LayerBaseClient> layer;//LayerBaseClient 是 Layer 家族的基類 //這里又冒出一個 LayerBaseClient 的內部類,它也叫Surface sp<LayerBaseClient::Surface> surfaceHandle; Mutex::Autolock _l(mStateLock); //根據 clientId 找到 createConnection 時加入的那個 Client 對象 sp<Client> client = mClientsMap.valueFor(clientId); ...... //注意這個 id,它的值表示 Client 創建的是第幾個顯示層 //同時也表示將使用 SharedBufferStatck 數組的第 id 個元素 int32_t id = client->generateId(pid); //一個 Client 不能創建多於 NUM_LAYERS_MAX 個的Layer if(uint32_t(id) >= NUM_LAYERS_MAX) { return surfaceHandle; } //根據 flags 參數來創建不同類型的顯示層 switch(flags & eFXSurfaceMask) { case eFXSurfaceNormal: if (UNLIKELY(flags & ePushBuffers)) { //創建 PushBuffer 類型的顯示層 layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags); } else { //創建 Normal 類型的顯示層 layer = createNormalSurfaceLocked(client, d, id, w, h, flags, format); } break; case eFXSurfaceBlur: //創建 Blur 類型的顯示層 layer = createBlurSurfaceLocked(client, d, id, w, h, flags); break; case eFXSurfaceDim: //創建 Dim 類型的顯示層 layer = createDimSurfaceLocked(client, d, id, w, h, flags); break; } if(layer != 0) { layer->setName(name); setTransactionFlags(eTransactionNeeded); //從顯示層對象中取出一個 ISurface 對象賦值給 SurfaceHandle surfaceHandle = layer->getSurface(); if(surfaceHandle != 0) { params->token = surfaceHandle->getToken(); params->identity = surfaceHandle->getIdentity(); params->width = w; params->height = h; params->format = format; } } return surfaceHandle;//ISurface 的 Bn 端就是這個對象 }
sp<LayerBaseClient>SurfaceFlinger::createNormalSurfaceLocked(const sp<Client>& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) { switch(format) { //一些圖像方面的參數設置,可以不去管它 case PIXEL_FORMAT_TRANSPARENT: case PIXEL_FORMAT_TRANSLUCENT: format = PIXEL_FORMAT_RGBA_8888; break; case PIXEL_FORMAT_OPAQUE: format = PIXEL_FORMAT_RGB_565; break; } //創建一個 Layer 類型的對象 sp<Layer> layer = new Layer(this, display,client, id); //設置 Buffer status_t err = layer->setBuffers(w, h, format, flags); if (LIKELY(err == NO_ERROR)) { //初始化這個新 layer 的一些狀態 layer->initStates(w, h, flags); //下面這個函數把這個 layer 加入到 Z 軸集合中 addLayer_l(layer); } ...... return layer; }
createNormalSurfaceLocked 函數有三個關鍵點,它們是:
- 構造一個Layer對象。
- 調用Layer對象的setBuffers函數。
- 調用SF的addLayer_l函數。
當跨進程的 createSurface() 執行完返回一個 ISurface 對象,接下來會創建 SurfaceControl 對象:
SurfaceControl::SurfaceControl( const sp<SurfaceComposerClient>& client, const sp<ISurface>& surface, const ISurfaceFlingerClient::surface_data_t& data, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) //mClient 為 SurfaceComposerClient,而 mSurface 指向跨進程 createSurface() 調用返回的 ISurface 對象 :mClient(client), mSurface(surface), mToken(data.token), mIdentity(data.identity), mWidth(data.width), mHeight(data.height), mFormat(data.format), mFlags(flags){ ...... }
SurfaceControl 類可以看作是一個 wrapper 類,它封裝了一些函數,通過這些函數可以方便地調用 mClient 或 ISurface 提供的函數。
最后會執行 copyFrom() 返回給 App 客戶端:
static void Surface_copyFrom(JNIEnv* env,jobject clazz, jobject other) { //根據JNI函數的規則,clazz 是 copyFrom 的調用對象,而 other 是 copyFrom 的參數。 //目標對象此時還沒有設置 SurfaceControl,而源對象在前面已經創建了 SurfaceControl constsp<SurfaceControl>& surface = getSurfaceControl(env, clazz); constsp<SurfaceControl>& rhs = getSurfaceControl(env, other); if (!SurfaceControl::isSameSurface(surface, rhs)) { //把源 SurfaceControl 對象設置到目標 Surface 中 setSurfaceControl(env, clazz, rhs); } }
copyFrom 期間一共有三個關鍵對象,它們分別是:
- SurfaceComposerClient
- SurfaceControl
- Surface,這個 Surface 對象屬於 Native 層,和 Java 層的 Surface 相對應
其中轉移到 ViewRoot 成員變量 mSurface 中的,就是最后這個 Surface 對象了。
在 SurfaceFlinger 進程中,Client 的一個 Layer 將使用 SharedBufferStack 數組中的一個成員,並通過 SharedBufferServer 結構來控制這個成員, SurfaceFlinger 是消費者,所以可由 SharedBufferServer 來控制數據的讀取。與之相對應,客戶端的進程也會有一個對象來使用這個 SharedBufferStack,可它是通過另外一個叫 SharedBufferClient 的結構來控制的。客戶端為 SurfaceFlinger 提供數據,所以可由 SharedBufferClient 控制數據的寫入。
Surface 顯示過程總結:

如圖所示,在 App 進程中創建 PhoneWindow 后會創建 ViewRoot。ViewRoot 的創建會創建一個 Surface,這個 Surface 其實是空的,通過與 WindowManagerService 通信 copyFrom() 一個NativeSurface。在與 SurfaceFlinger 通信時,會創建 SharedClient 一段共享內存,里面存放的是 SharedBufferStack 對應 SurfaceFlinger 中的 SurfaceLayer 每個 Layer 其實是一個 FrameBuffer,每個 FrameBuffer 中有兩個 GraphicBuffer 記作 FrontBuffer 和 BackBuffer。
在SurfaceFlinger 中 SharedBufferServer 來管理 FrameBuffer。同時在 App 端 copyFrom() 出來 NativeSurface 時會創建一個 SharedBufferClient 與 SharedClient 這塊共享內存關聯。當客戶端 addView() 或者需要更新 View 時,會通過 SharedBufferClient 寫入數據到 ShareClient 中,SurfaceFlinger 中的 SharedBufferServer 接收到通知會將 FrameBuffer 中的數據傳輸到屏幕上。
5.本地窗口(Native Window)
Native Window為OpenGL與本地窗口系統之間搭建了橋梁。整個GUI系統至少需要兩種本地窗口:
(1)面向管理者(SurfaceFlinger)
SurfaceFlinger是系統中所有UI界面的管理者,需要直接或間接的持有“本地窗口”,此本地窗口是FramebufferNativeWindow。
(2)面向應用程序
這類本地窗口是Surface。
正常情況按照SDK向導生成APK應用程序,是采用Skia等第三方圖形庫,而對於希望使用OpenGL ES來完成復雜界面渲染的應用開發者來說,Android也提供封裝的GLSurfaceView(或其他方式)來實現圖形顯示。
①FramebufferNativeWindow
EGL需要通過本地窗口來為OpenGL/OpenGL ES創建環境。由於OpenGL/ES對多平台支持,考慮到兼容性和移植性。不同平台的本地窗口EGLNativeWindowType數據類型不同。
Android平台的數據類型是ANativeWindow,像是一份“協議”,規定了一個本地窗口的形態和功能。ANativeWindow是FramebufferNativeWindow的父類。
Android中,由於多緩沖技術,EGLNativeWindowType所管理的緩沖區最少2個,最大3個。
FramebufferNativeWindow初始化需要Golloc支持,步驟如下:
-
- 加載GRALLOC_HARDWARE_MODULE_ID模塊,參見上節。
- 分別打開fb和gralloc設備,打開后的設備由全局變量fbDev和grDev管理。
- 根據設備的屬性來給FramebufferNativeWindow賦初值。
- 根據FramebufferNativeWindow的實現來填充ANativeWindow中的“協議”
- 其他一些必要的初始化
②應用程序的本地窗口 - Surface
Surface也繼承了ANativeWindow
class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
Surface是面向Android系統中所有UI應用程序的,即它承擔着應用進程中的UI顯示需求。
需要面向上層實現(主要是Java層)提供繪制圖像的畫板。SurfaceFlinger需要收集系統中所有應用程序繪制的圖像數據,然后集中顯示到物理屏幕上。Surface需要扮演相應角色,本質上還是由SurfaceFlinger服務統一管理的,涉及到很多跨進程的通信細節。
③Surface的創建
Surface將通過mGraphicBufferProducer來獲取buffer,這些緩沖區會被記錄在mSlots中數據中。mGraphicBufferProducer這一核心成員的初始化流程如下:
ViewRootImpl持有一個Java層的Surface對象(mSurface)。
ViewRootImpl向WindowManagerService發起relayout請求,此時mSurface被賦予真正的有效值,將輾轉生成的SurfaceControl通過Surface.copyFrom()函數復制到mSurface中。
由此,Surface由SurfaceControl管理,SurfaceControl由SurfaceComposerClient創建。SurfaceComposerClient獲得的匿名Binder是ISurfaceComposer,其服務端實現是SurfaceFlinger。而Surface依賴的IGraphicBufferProducer對象在Service端的實現是BufferQueue。
class SurfaceFlinger : public BinderService<SurfaceFlinger>, //在ServiceManager中注冊為SurfaceFlinger public BnSurfaceComposer,//實現的接口卻叫ISurfaceComposer
④SurfaceFlinger服務框架:
Buffer,Consumer,Producer是“生產者-消費者”模型中的3個參與對象,如何協調好它們的工作是應用程序能否正常顯示UI的關鍵。
Buffer是BufferQueue,Producer是應用程序,Consumer是SurfaceFlinger。

Surface內部提供一個BufferQueue,與上層和SurfaceFlinger形成一個生產者消費者模型,上層對應Producer,SurfaceFlinger對應Consumer。三者通過Buffer產生聯系,每個Buffer都有四種狀態:
- Free:可被上層使用;
- Dequeued:出列,正在被上層使用;
- Queued:入列,已完成上層繪制,等待SurfaceFlinger合成;
- Acquired:被獲取,SurfaceFlinger正持有該Buffer進行合成;
如此循環,形成一個Buffer被循環使用的過程(FREE-> DEQUEUED->QUEUED->ACQUIRED->FREE)。
BufferQueue中的mSlots數組用於管理期內的緩沖區,最大容器是32。數據緩沖區的空間是動態分配的,應用程序與SurfaceFlinger都是使用OpenGL ES來完成UI顯示。Layer類在SurfaceFlinger中表示“層”,通俗地講就是代表了一個“畫面”,最終物理屏幕上的顯示結果就是通過對系統中同時存在的所有“畫面”進行處理疊加而成.
