首页 > 移动平台 > 详细

Android 显示系统:SurfaceFlinger完全解读

时间:2019-07-30 21:36:53      阅读:461      评论:0      收藏:0      [点我收藏+]

一、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完全解读

原文:https://www.cnblogs.com/blogs-of-lxl/p/11272756.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!