Android 显示系统:SurfaceFlinger完全解读

Posted blogs-of-lxl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 显示系统:SurfaceFlinger完全解读相关的知识,希望对你有一定的参考价值。

一、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 surfaceflingers 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, &param) != 0) 
        ALOGE("Couldn‘t set SCHED_FIFO for SFEventThread");
    
    if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, &param) != 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();//将图像传递到物理屏幕

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完全解读的主要内容,如果未能解决你的问题,请参考以下文章

android系统 主要有哪几部分?

Android 系统概览

怎样下载原生android系统

android瀑布流怎么显示

Android系统如何升级?

android瀑布流怎么显示