The SurfaceFlinger service starts in init.rc. The last class_start command in boot Action starts all services classified as core, including SurfaceFlinger.

system/core/rootdir/init.rc

on boot
    ......
    class_start core
......
service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote
    writepid /dev/cpuset/system-background/tasks
Copy the code

Now determine the source location of the SurfaceFlinger service. In the following Android.mk, we find that the starting point is main_surfaceflinger.cpp.

frameworks/native/services/surfaceflinger/Android.mk

############################################################### # build surfaceflinger's executable include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CPPFLAGS := -std=c++11 LOCAL_SRC_FILES := \ main_surfaceflinger.cpp LOCAL_SHARED_LIBRARIES := \ libsurfaceflinger \ libcutils \ liblog \ libbinder \ libutils \ libdl LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain LOCAL_MODULE := surfaceflinger ifdef TARGET_32_BIT_SURFACEFLINGER LOCAL_32_BIT_ONLY := true endif LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_EXECUTABLE) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #Copy the code

Focus on SurfaceFlinger instantiation, and the init() method, whose run() method was introduced in the Android Source Graphics System relayoutWindow section.

frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

using namespace android;

int main(int.char* *) {
    // Limit the number of binder threads to 4 when starting SF with your own process.
    ProcessState::self() - >setThreadPoolMaxThreadCount(4);

    // Start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool(a);// instantiate SurfaceFlinger
    sp<SurfaceFlinger> flinger = new SurfaceFlinger(a);setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);

    // Initialize before the client connects
    flinger->init(a);// Release surface Flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

    // Run in this thread
    flinger->run(a);return 0;
}
Copy the code

The SurfaceFlinger class has a set of parameters initialized in the no-argument constructor. The onFirstRef() method initializes mEventQueue (MessageQueue).

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp


SurfaceFlinger::SurfaceFlinger()
    :   BnSurfaceComposer(),
        mTransactionFlags(0),
        mTransactionPending(false),
        mAnimTransactionPending(false),
        mLayersRemoved(false),
        mRepaintEverything(0),
        mRenderEngine(NULL),
        mBootTime(systemTime()),
        mVisibleRegionsDirty(false),
        mHwWorkListDirty(false),
        mAnimCompositionPending(false),
        mDebugRegion(0),
        mDebugDDMS(0),
        mDebugDisableHWC(0),
        mDebugDisableTransformHint(0),
        mDebugInSwapBuffers(0),
        mLastSwapBufferTime(0),
        mDebugInTransaction(0),
        mLastTransactionTime(0),
        mBootFinished(false),
        mForceFullDamage(false),
        mPrimaryHWVsyncEnabled(false),
        mHWVsyncAvailable(false),
        mDaltonize(false),
        mHasColorMatrix(false),
        mHasPoweredOff(false),
        mFrameBuckets(),
        mTotalTime(0),
        mLastSwapTime(0)
{
    ALOGI("SurfaceFlinger is starting");

    // Debug things...
    char value[PROPERTY_VALUE_MAX];

    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
    mGpuToCpuSupported = !atoi(value);

    property_get("debug.sf.drop_missed_frames", value, "0");
    mDropMissedFrames = atoi(value);

    property_get("debug.sf.showupdates", value, "0");
    mDebugRegion = atoi(value);

    property_get("debug.sf.ddms", value, "0");
    mDebugDDMS = atoi(value);
    if (mDebugDDMS) {
        if (!startDdmConnection()) {
            // Failed to start DDMS debugging is not enabled
            mDebugDDMS = 0; }}ALOGI_IF(mDebugRegion, "showupdates enabled");
    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
}

void SurfaceFlinger::onFirstRef(a)
{
    mEventQueue.init(this);
}
Copy the code

MessageQueue: : init (…). Method initializes mFlinger, mLooper, and mHandler.

frameworks/native/services/surfaceflinger/MessageQueue.cpp

void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}
Copy the code

SurfaceFlinger initialization is commented in detail in the code.

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::init(a) {
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");

    Mutex::Autolock _l(mStateLock);

    // Initialize EGL for default display
    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(mEGLDisplay, NULL.NULL);

    / / start EventThread
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true."app");
    mEventThread = new EventThread(vsyncSrc);
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, true."sf");
    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);

    // Initialize the H/W Composer object. There may or may not be actual hardware Composer below.
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));

    // Get a RenderEngine for a given display/configuration (without failure)
    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());

    // Retrieves the selected/created EGL context
    mEGLContext = mRenderEngine->getEGLContext(a);LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
            "couldn't create EGLContext");

    // Initialize the non-virtual display
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // Set the monitor that is already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            // Currently, all non-virtual displays are considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<IGraphicBufferProducer> producer;
            sp<IGraphicBufferConsumer> consumer;
            / / create BufferQueue
            BufferQueue::createBufferQueue(&producer, &consumer,
                    new GraphicBufferAlloc());

            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());
            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); }}// Keep GLContext up to date so that we can create textures when we create layers (this can happen before rendering something)
    getDefaultDisplayDevice() - >makeCurrent(mEGLDisplay, mEGLContext);

    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

    // If there is no HWComposer, set a false vSYNC cycle
    if (mHwc->initCheck() != NO_ERROR) {
        mPrimaryDispSync.setPeriod(16666667);
    }

    // Initialize our drawing state
    mDrawingState = mCurrentState;

    // Set initial conditions (such as canceling the default device)
    initializeDisplays(a);// Start the animation
    startBootAnim(a); }Copy the code