一、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(),该方法主要功能是:
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() 方法。
// SurfaceFlinger.cpp void SurfaceFlinger::handleMessageRefresh() { ATRACE_CALL(); preComposition();//处理显示设备与 layers 的改变,更新光标 rebuildLayerStacks();//重建所有可见 Layer 列表,根据Z轴排序 setUpHWComposer();//更新 HWComposer 图层 doDebugFlashRegions(); doComposition();//生成 OpenGL 纹理图像 postComposition();//将图像传递到物理屏幕 }
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); ... }
1
2
3
4
5
6
7
8
9
10
11
12
13
创建 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();
...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
WindowManagerService.openSession:
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {
//创建 Session 对象
Session session = new Session(this, callback, client, inputContext);
return session;
}
1
2
3
4
5
再次经过 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);
...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
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);
}
}
1
2
3
4
5
6
7
8
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();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
创建 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++;
}
1
2
3
4
5
6
7
8
9
10
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);
}
1
2
3
4
5
创建 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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
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 对象
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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) {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
一个 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; //状态码
......
}
1
2
3
4
5
6
7
8
9
10
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());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
创建完 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);
}
......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
在 ViewRoot 构造时,会创建一个 Surface,它使用无参构造函数,代码如下所示:
final Surface mSurface = new Surface();
1
此时创建完的 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);
......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();//关闭一个事务处理
......
}
1
2
3
4
5
6
7
8
9
10
11
12
构造 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;
}
1
2
3
4
5
6
7
8
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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在 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 端就是这个对象
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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){
......
}
1
2
3
4
5
6
7
8
9
10
11
12
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);
}
}
1
2
3
4
5
6
7
8
9
10
copyFrom 期间一共有三个关键对象,它们分别是:
SurfaceComposerClient
SurfaceControl
Surface,这个 Surface 对象属于 Native 层,和 Java 层的 Surface 相对应
其中转移到 ViewRoot 成员变量 mSurface 中的,就是最后这个 Surface 对象了。
在 SurfaceFlinger 进程中,Client 的一个 Layer 将使用 SharedBufferStack 数组中的一个成员,并通过 SharedBufferServer 结构来控制这个成员,我们知道 SurfaceFlinger 是消费者,所以可由 SharedBufferServer 来控制数据的读取。
与之相对应,客户端的进程也会有一个对象来使用这个 SharedBufferStack,可它是通过另外一个叫 SharedBufferClient 的结构来控制的。客户端为 SurfaceFlinger 提供数据,所以可由 SharedBufferClient 控制数据的写入。
Android 显示系统:SurfaceFlinger完全解读
原文:https://www.cnblogs.com/blogs-of-lxl/p/11272756.html