Android P图形架构之SurfaceFlinger加载显示屏流程

相关源码:
\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

官方资料:
https://source.android.com/devices/graphics
https://source.android.google.cn/devices/graphics?hl=zh_cn
https://source.android.google.cn/devices/graphics

谷歌官网图形架构:
Surface 如何被渲染

1、LocalDisplayAdapter.java

LocalDisplayAdapter的主要作用是初始化显示屏,从SurfaceFlinger中获取到屏的显示,并发送给DisplayManagerService进行显示屏的初始化。
其中,getBuiltInDisplay最终是调用SurfaceFlinger中的getBuiltInDisplay,由SurfaceFlinger管理的显示适配器。

源码路径:\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);
    }
}
从SurfaceFlinger中获取显示屏信息,并通过DisplayManagerService,add displays
private void tryConnectDisplayLocked(int builtInDisplayId) {
	//最终调用到SurfaceFlinger中getBuiltInDisplay,获取到可以使用的显示屏display
    IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
    if (displayToken != null) {
		//省略一部分代码
		//...
		//
		sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
	}
}

2、ISurfaceComposer.cpp

LocalDisplayAdapter中的getBuiltInDisplay,最终是调用SurfaceFlinger中的getBuiltInDisplay(),但是我们还是详细跟一下JNI调用的流程:
SurfaceControl中的getBuiltInDisplay()调用了JNI的nativeGetBuiltInDisplay,定义如下:
\frameworks\base\core\java\android\view\SurfaceControl.java

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

android_view_SurfaceControl中调用的是SurfaceComposerClient中的getBuiltInDisplay,
\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);
}

SurfaceComposerClient调用是ISurfaceComposer中的getBuiltInDisplay,实现如下:
\frameworks\native\libs\gui\SurfaceComposerClient.cpp

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

ComposerService中关于getComposerService()的定义,得知调用的是ISurfaceComposer中的接口:
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();
	        //调用到SurfaceFlinger中的getBuiltInDisplay
	        sp<IBinder> display(getBuiltInDisplay(id));
	        reply->writeStrongBinder(display);
	        return NO_ERROR;
     }
   }
}

3、SurfaceFlinger.java

源码路径:\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
//返回给LocalDisplayAdapter.java中的tryConnectDisplayLocked,以便完成显示屏连接的功能

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];
}

问题点:SurfaceFlinger中的显示屏信息又是从何而来呢?
getBuiltInDisplay()中可以看到,显示屏信息是存在mBuiltinDisplays中的,mBuiltinDisplays定义如下:

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

而mBuiltinDisplays的初始化又是在processDisplayHotplugEventsLocked中进行完成。
事实上,底层驱动层代码将发送Hotplug的消息给到SurfaceFlinger,告知SurfaceFlinger有几块显示屏和相关信息,并进行初始化处理。

void SurfaceFlinger::processDisplayHotplugEventsLocked() {
    for (const auto& event : mPendingHotplugEvents) {
    	//判断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;
        }

		//省略一部分代码
		//...
		
		//调用onHotplug,获取到
        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();
}

SurfaceFlinger接收到HAL层Hotplug消息流程如下:
HAL层调用到HWC2.cpp中,代码如下:
\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是在SurfaceFlinger中init()的时候注册的:

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

所以onHotplugReceived调用到SurfaceFlinger中的onHotplugReceived,并最终processDisplayHotplugEventsLocked,对mBuiltinDisplays进行了初始化。

调式中打印的Log,可以分析整个display加载的流程

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值