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