Surface Flinger Loading Display Flow of Android P Graphic Architecture

Keywords: Java Android Google

Related source code:
\frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.java
\frameworks\base\core\java\android\view\SurfaceControl.java
\frameworks\base\core/jni\android_view_SurfaceControl.cpp
frameworks\native\libs\gui\include\private\gui\ComposerService.h
\frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java
\frameworks/native/services/surfaceflinger/DisplayDevice.h
frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.h
\frameworks\native\libs\gui\ISurfaceComposerClient.cpp
\frameworks\native\libs\gui\ISurfaceComposer.cpp
hardware\libhardware\include\hardware\hwcomposer_defs.h
\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
\frameworks\native\services\surfaceflinger\DisplayHardware\HWC2.cpp
\vendor\nxp-opensource\imx\display\hwcomposer_v20\hwcomposer.cpp
\hardware\interfaces\graphics\composer\2.1\utils\passthrough\include\composer-passthrough\2.1\HwcHal.h

Official information:
https://source.android.com/devices/graphics
https://source.android.google.cn/devices/graphics?hl=zh_cn
https://source.android.google.cn/devices/graphics

Google Graphics Architecture:

1,LocalDisplayAdapter.java

The main function of LocalDisplay Adapter is to initialize the display screen, get the display from Surface Flinger, and send it to Display Manager Service to initialize the display screen.
Among them, getBuiltInDisplay is ultimately a call to getBuiltInDisplay in Surface Flinger, a display adapter managed by Surface Flinger.

Source path: frameworks base services core java com android server display LocalDisplayAdapter. Java

private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
        SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
        SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
        SurfaceControl.BUILT_IN_DISPLAY_ID_THIRD,	//add by sunxiaolin 20190906
};

@Override
public void registerLocked() {
    super.registerLocked();
    mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());
    for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
        tryConnectDisplayLocked(builtInDisplayId);
    }
}
//Get display information from Surface Flinger and add displays through Display Manager Service
private void tryConnectDisplayLocked(int builtInDisplayId) {
	//Finally, call getBuiltInDisplay in Surface Flinger to get the display that you can use.
    IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
    if (displayToken != null) {
		//Omit part of the code
		//...
		//
		sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
	}
}

2,ISurfaceComposer.cpp

The getBuiltInDisplay in LocalDisplayAdapter finally calls getBuiltInDisplay() in Surface Flinger, but let's follow the process of JNI invocation in detail:
getBuiltInDisplay() in SurfaceControl calls JNI's nativeGetBuiltInDisplay, which is defined as follows:
\frameworks\base\core\java\android\view\SurfaceControl.java

private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
public static IBinder getBuiltInDisplay(int builtInDisplayId) {
    return nativeGetBuiltInDisplay(builtInDisplayId);
}

The getBuiltInDisplay in Surface ComposerClient is called in android_view_SurfaceControl.
\frameworks\base\core/jni\android_view_SurfaceControl.cpp

static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
    sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
    return javaObjectForIBinder(env, token);
}

The Surface ComposerClient call is getBuiltInDisplay in ISurface Composer, implemented as follows:
\frameworks\native\libs\gui\SurfaceComposerClient.cpp

sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
    return ComposerService::getComposerService()->getBuiltInDisplay(id);
}

The definition of getComposerService() in ComposerService is that the interface in ISurfaceComposer is called:
frameworks\native\libs\gui\include\private\gui\ComposerService.h

// Get a connection to the Composer Service.  This will block until
// a connection is established.
static sp<ISurfaceComposer> getComposerService();

\frameworks\native\libs\gui\ISurfaceComposer.cpp

virtual sp<IBinder> getBuiltInDisplay(int32_t id)
{
    Parcel data, reply;
    data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
    data.writeInt32(id);
    remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply);
    return reply.readStrongBinder();
}
status_t BnSurfaceComposer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
       case GET_BUILT_IN_DISPLAY: {
	        CHECK_INTERFACE(ISurfaceComposer, data, reply);
	        int32_t id = data.readInt32();
	        //Call getBuiltInDisplay in Surface Flinger
	        sp<IBinder> display(getBuiltInDisplay(id));
	        reply->writeStrongBinder(display);
	        return NO_ERROR;
     }
   }
}

3,SurfaceFlinger.java

Source path: frameworks native services surfaceflinger SurfaceFlinger. CPP
// Return to tryConnectDisplayLocked in LocalDisplayAdapter.java to complete the function of screen connection

sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
        return nullptr;
    }
    ALOGI("sunxiaolin,getDefaultDisplay: id=%d", id);
    return mBuiltinDisplays[id];
}

Question: Where does the display information in Surface Flinger come from?
As you can see in getBuiltInDisplay(), display information exists in mBuiltinDisplays, which is defined as follows:

sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];

The initialization of mBuiltin Displays is done in the process Display Hot plug Events Locked.
In fact, the underlying driver code sends Hotplug messages to Surface Flinger, tells Surface Flinger how many screens and related information are available, and initializes them.

void SurfaceFlinger::processDisplayHotplugEventsLocked() {
    for (const auto& event : mPendingHotplugEvents) {
    	//Judging displayType
        auto displayType = determineDisplayType(event.display, event.connection);
        if (displayType == DisplayDevice::DISPLAY_ID_INVALID) {
            ALOGW("Unable to determine the display type for display %" PRIu64, event.display);
            continue;
        }

		//Omit part of the code
		//...
		
		//Call onHotplug to get
        getBE().mHwc->onHotplug(event.display, displayType, event.connection);

		ALOGI("sunxiaolin processDisplayHotplugEventsLocked displayType=%d",displayType);

        if (event.connection == HWC2::Connection::Connected) {
            if (!mBuiltinDisplays[displayType].get()) {
                ALOGV("sunxiaolin,Creating built in display %d", displayType);
                mBuiltinDisplays[displayType] = new BBinder();
                // All non-virtual displays are currently considered secure.
                DisplayDeviceState info(displayType, true);
                if( displayType == DisplayDevice::DISPLAY_THIRD ){
					info.displayName = "THIRD Screen";
				}else{
					 info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?
                        "Built-in Screen" : "External Screen";
				}
                mCurrentState.displays.add(mBuiltinDisplays[displayType], info);
                mInterceptor->saveDisplayCreation(info);
            }
        } else {
            ALOGV("Removing built in display %d", displayType);

            ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]);
            if (idx >= 0) {
                const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
                mInterceptor->saveDisplayDeletion(info.displayId);
                mCurrentState.displays.removeItemsAt(idx);
            }
            mBuiltinDisplays[displayType].clear();
        }

        processDisplayChangesLocked();
    }

    mPendingHotplugEvents.clear();
}

Surface Flinger receives the HAL layer Hotplug message flow as follows:
The HAL layer is called into HWC2.cpp, and the code is as follows:
\frameworks\native\services\surfaceflinger\DisplayHardware\HWC2.cpp

Return<void> onHotplug(Hwc2::Display display,
                       IComposerCallback::Connection conn) override
{
    HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
    mCallback->onHotplugReceived(mSequenceId, display, connection);
    return Void();
}

mCallback was registered at the time of init() in Surface Flinger:

getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);

So onHotplugReceived calls onHotplugReceived in Surface Flinger and finally processes DisplayHotplugEvents Locked to initialize mBuiltinDisplays.

Log, printed in the mode, can analyze the whole display ing loading process

1970-01-01 08:00:14.457 2506-2506/? I/HWC2: sunxiaolin,registerCallback,Hwc2
1970-01-01 08:00:14.461 2592-2667/? I/display: sunxiaolin,DisplayManager
1970-01-01 08:00:14.574 2592-2684/? I/display: sunxiaolin,threadLoop
1970-01-01 08:00:14.574 2592-2667/? I/hwcomposer: sunxiaolin,hwc2_register_callback HWC_DISPLAY_PRIMARY
1970-01-01 08:00:14.574 2592-2667/? I/hwcomposer: sunxiaolin,onHotplug disp=0,connected=1
1970-01-01 08:00:14.574 2506-2506/? I/HWC2: sunxiaolin,onHotplug,Hwc2
1970-01-01 08:00:14.575 2506-2506/? I/SurfaceFlinger: sunxiaolin determineDisplayType
1970-01-01 08:00:14.575 2506-2506/? I/SurfaceFlinger: sunxiaolin determineDisplayType primaryDisplayId2
1970-01-01 08:00:14.575 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2
1970-01-01 08:00:14.575 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2,displayId=0
1970-01-01 08:00:14.575 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2,displayType=1
1970-01-01 08:00:14.575 2506-2506/? I/SurfaceFlinger: sunxiaolin processDisplayHotplugEventsLocked displayType=0
1970-01-01 08:00:14.575 2506-2506/? V/SurfaceFlinger: sunxiaolin,Creating built in display 0
1970-01-01 08:00:14.575 2506-2506/? I/SurfaceFlinger: sunxiaolin processDisplayChangesLocked find displays that were added state.type(hwcId)=0
1970-01-01 08:00:15.048 2691-2696/? I/SurfaceFlinger: sunxiaolin,ISurfaceComposer,getDefaultDisplay: id=0
1970-01-01 08:00:15.048 2506-2629/? I/SurfaceFlinger: sunxiaolin,getDefaultDisplay: id=0
1970-01-01 08:00:15.241 2592-2592/? I/hwcomposer: sunxiaolin,hwc2_present_display HWC_DISPLAY_EXTERNAL
1970-01-01 08:00:15.241 2592-2592/? I/hwcomposer: sunxiaolin,onHotplug disp=1,connected=1
1970-01-01 08:00:15.241 2506-2506/? I/HWC2: sunxiaolin,onHotplug,Hwc2
1970-01-01 08:00:15.241 2506-2506/? I/SurfaceFlinger: sunxiaolin determineDisplayType
1970-01-01 08:00:15.241 2506-2506/? I/SurfaceFlinger: sunxiaolin determineDisplayType externalDisplayId2
1970-01-01 08:00:15.241 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2
1970-01-01 08:00:15.241 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2,displayId=1
1970-01-01 08:00:15.242 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2,displayType=1
1970-01-01 08:00:15.242 2506-2506/? I/SurfaceFlinger: sunxiaolin processDisplayHotplugEventsLocked displayType=1
1970-01-01 08:00:15.242 2506-2506/? V/SurfaceFlinger: sunxiaolin,Creating built in display 1
1970-01-01 08:00:15.242 2506-2506/? I/SurfaceFlinger: sunxiaolin processDisplayChangesLocked find displays that were added state.type(hwcId)=1
1970-01-01 08:00:15.253 2592-2592/? I/hwcomposer: sunxiaolin,hwc2_present_display HWC_DISPLAY_EXTERNAL + 1
1970-01-01 08:00:15.253 2592-2592/? I/hwcomposer: sunxiaolin,onHotplug disp=2,connected=1
1970-01-01 08:00:15.253 2506-2506/? I/HWC2: sunxiaolin,onHotplug,Hwc2
1970-01-01 08:00:15.253 2506-2506/? I/SurfaceFlinger: sunxiaolin determineDisplayType
1970-01-01 08:00:15.253 2506-2506/? I/SurfaceFlinger: sunxiaolin determineDisplayType thirdDisplayId2
1970-01-01 08:00:15.253 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2
1970-01-01 08:00:15.253 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2,displayId=2
1970-01-01 08:00:15.254 2506-2506/? I/HWC2: sunxiaolin, Device::onHotplug,Hwc2,displayType=1
1970-01-01 08:00:15.254 2506-2506/? I/SurfaceFlinger: sunxiaolin processDisplayHotplugEventsLocked displayType=2
1970-01-01 08:00:15.254 2506-2506/? V/SurfaceFlinger: sunxiaolin,Creating built in display 2
1970-01-01 08:00:15.254 2506-2506/? I/SurfaceFlinger: sunxiaolin processDisplayChangesLocked find displays that were added state.type(hwcId)=2
1970-01-01 08:00:15.290 2506-2522/? I/HWC2: sunxiaolin,onVsync,Hwc2

Posted by penguin_powered on Mon, 09 Sep 2019 02:54:49 -0700