Android P图形架构之三屏异显实现

相关源码:
\frameworks\base\core\java\android\view\SurfaceControl.java
\frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.java
\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
frameworks\native\services\surfaceflinger\DisplayHardware\HWComposer.h
\hardware\libhardware\include\hardware\hwcomposer_defs.h
\vendor\nxp-opensource\imx\display\hwcomposer_v20\hwcomposer.cpp
\vendor\nxp-opensource\imx\display\display\DisplayManager.cpp

我们都知道安卓支持多屏异显。但是android 9.0系统中,默认只加载了两个物理屏和一个虚拟屏。

具体资料可以参考谷歌官方资料:
https://developer.android.com/guide/topics/ui/multi-window
https://developer.android.com/about/versions/oreo/android-8.0

参考文章:
《Android P实现双屏异显》
《Android P图形架构之SurfaceFlinger加载显示屏流程》

android 9.0显示屏的定义:

  • display 0 主屏
  • display 1 副屏(辅助屏)
  • display 2 虚拟屏(显示display 1上)

增加第三块屏后的定义:

  • display 0 主屏
  • display 1 副屏(辅助屏)
  • display 2 扩展屏(第三块屏)
  • display 3 虚拟屏(显示display 1或者display 2上)

Framework层

1、SurfaceControl中,增加第三块屏的定义:
\frameworks\base\core\java\android\view\SurfaceControl.java

/**
 * Built-in physical display id: Main display.
 * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
 */
public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;

/**
* Built-in physical display id: Attached HDMI display.
* Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
*/
public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;

//add by sunxiaolin 20190906
public static final int BUILT_IN_DISPLAY_ID_THIRD = 2;

2、LocalDisplayAdapter中,增加第三块屏的逻辑处理:
\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);
    }
}

3、SurfaceFlinger中,增加第三块屏的逻辑处理:
\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

DisplayDevice::DisplayType SurfaceFlinger::determineDisplayType(hwc2_display_t display,
                                                                HWC2::Connection connection) const {
    // Figure out whether the event is for the primary display or an
    // external display by matching the Hwc display id against one for a
    // connected display. If we did not find a match, we then check what
    // displays are not already connected to determine the type. If we don't
    // have a connected primary display, we assume the new display is meant to
    // be the primary display, and then if we don't have an external display,
    // we assume it is that.
    ALOGI("sunxiaolin determineDisplayType");
    const auto primaryDisplayId = getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_PRIMARY);
    const auto externalDisplayId = getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_EXTERNAL);
    const auto thirdDisplayId = getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_THIRD);
    if (primaryDisplayId && primaryDisplayId == display) {
		ALOGI("sunxiaolin determineDisplayType primaryDisplayId");
        return DisplayDevice::DISPLAY_PRIMARY;
    } else if (externalDisplayId && externalDisplayId == display) {
		ALOGI("sunxiaolin determineDisplayType externalDisplayId");
        return  DisplayDevice::DISPLAY_EXTERNAL;
    } else if (thirdDisplayId && thirdDisplayId == display) {
		ALOGI("sunxiaolin determineDisplayType thirdDisplayId");
        return  DisplayDevice::DISPLAY_THIRD;
    } else if (connection == HWC2::Connection::Connected && !primaryDisplayId) {
		ALOGI("sunxiaolin determineDisplayType primaryDisplayId2");
        return DisplayDevice::DISPLAY_PRIMARY;
    } else if (connection == HWC2::Connection::Connected && !externalDisplayId) {
		ALOGI("sunxiaolin determineDisplayType externalDisplayId2");
        return DisplayDevice::DISPLAY_EXTERNAL;
    } else if (connection == HWC2::Connection::Connected && !thirdDisplayId) {
		ALOGI("sunxiaolin determineDisplayType thirdDisplayId2");
        return DisplayDevice::DISPLAY_THIRD;
    }

    return DisplayDevice::DISPLAY_ID_INVALID;
}

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

        if (getBE().mHwc->isUsingVrComposer() && displayType == DisplayDevice::DISPLAY_EXTERNAL) {
            ALOGE("External displays are not supported by the vr hardware composer.");
            continue;
        }

        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();
}

4、修改虚拟屏的判断,增加一块屏将2改成3,即display 3是虚拟屏

 static const int32_t VIRTUAL_DISPLAY_ID_BASE = 3;

HAL层

HAL层中,也需要修改显示屏的定义,即display 0,1,2修改成display 0,1,2,3:
源码:hardware\libhardware\include\hardware\hwcomposer_defs.h

/* Display types and associated mask bits. */
enum {
    HWC_DISPLAY_PRIMARY     = 0,
    HWC_DISPLAY_EXTERNAL    = 1,    // HDMI, DP, etc.
    
    //add by sunxiaolin 20190906
    HWC_DISPLAY_THIRD       = 2,	// the third display 
    HWC_DISPLAY_VIRTUAL     = 3,
	//modiy start by sunxiaolin 20190906
    HWC_NUM_PHYSICAL_DISPLAY_TYPES = 3, // value 2 --> 3
    HWC_NUM_DISPLAY_TYPES          = 4,	// value 3 --> 4
    //modiy end by sunxiaolin 20190906
};

驱动层

最终是驱动层将屏的相关信息,通过HAL层,发送给SurfaceFlinger中。

display中获取显示屏的处理:
\vendor\nxp-opensource\imx\display\hwcomposer_v20\hwcomposer.cpp

//主屏的初始化,回调给SurfaceFlinger
static int hwc2_register_callback(hwc2_device_t* device, int32_t descriptor,
                                  hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer)
{
    if (!device) {
        ALOGE("%s invalid device", __func__);
        return HWC2_ERROR_BAD_PARAMETER;
    }

    struct hwc2_context_t *ctx = (struct hwc2_context_t*)device;
    switch (descriptor) {
        case HWC2_CALLBACK_HOTPLUG:
            ctx->mHotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
            ctx->mHotplugData = callbackData;
            break;
        case HWC2_CALLBACK_REFRESH:
            ctx->mRefresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
            ctx->mRefreshData = callbackData;
            break;
        case HWC2_CALLBACK_VSYNC:
            ctx->mVsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
            ctx->mVsyncData = callbackData;
            break;
    }

    DisplayManager::getInstance()->setCallback(ctx->mListener);
    if (descriptor == HWC2_CALLBACK_HOTPLUG && pointer != NULL) {
		ALOGI("sunxiaolin,hwc2_register_callback HWC_DISPLAY_PRIMARY");
        ctx->mListener->onHotplug(HWC_DISPLAY_PRIMARY, true);
    }

    return HWC2_ERROR_NONE;
}

//副屏的初始化,回调给SurfaceFlinger
static int hwc2_present_display(hwc2_device_t* device, hwc2_display_t display,
                                int32_t* outPresentFence)
{
    if (!device) {
        ALOGE("%s invalid device", __func__);
        return HWC2_ERROR_BAD_PARAMETER;
    }

    Display* pDisplay = NULL;
    DisplayManager* displayManager = DisplayManager::getInstance();
    pDisplay = displayManager->getDisplay(display);
    if (pDisplay == NULL) {
        ALOGE("%s invalid display id:%" PRId64, __func__, display);
        return HWC2_ERROR_BAD_DISPLAY;
    }

    pDisplay->composeLayers();
    pDisplay->updateScreen();
    if (outPresentFence != NULL) {
        pDisplay->getPresentFence(outPresentFence);
    }

    struct hwc2_context_t *ctx = (struct hwc2_context_t*)device;
    if (ctx->checkHDMI && ctx->mHotplug != NULL && ctx->mVsync != NULL) {
        ctx->checkHDMI = false;
        Display* fb = displayManager->getPhysicalDisplay(HWC_DISPLAY_EXTERNAL);
        ALOGI("sunxiaolin,hwc2_present_display HWC_DISPLAY_EXTERNAL");
        ctx->mListener->onHotplug(HWC_DISPLAY_EXTERNAL, fb->connected());
        
        //增加第三块屏(扩展平),回调给SurfaceFlinger
        ctx->checkHDMI = false;
        Display* fb2 = displayManager->getPhysicalDisplay(HWC_DISPLAY_THIRD);
        ALOGI("sunxiaolin,hwc2_present_display HWC_DISPLAY_THIRD");
        ctx->mListener->onHotplug(HWC_DISPLAY_THIRD, fb2->connected());
    }

    return HWC2_ERROR_NONE;
}

//回调给HAL层,在给到SurfaceFlinger.so
void DisplayListener::onHotplug(int disp, bool connected)
{
	ALOGI("sunxiaolin,onHotplug disp=%d,connected=%d",disp,connected);
    if (mCtx == NULL || mCtx->mHotplug == NULL) {
        return;
    }

    hwc2_connection_t connection = connected ? HWC2_CONNECTION_CONNECTED
                                             : HWC2_CONNECTION_DISCONNECTED;
    mCtx->mHotplug(mCtx->mHotplugData, disp, connection);
}

重点:
Display* fb = displayManager->getPhysicalDisplay(HWC_DISPLAY_EXTERNAL);
Display* fb2 = displayManager->getPhysicalDisplay(HWC_DISPLAY_THIRD);

DisplayManager中管理者显示屏,前提是kernel里已经加载了第三块显示屏驱动:
\vendor\nxp-opensource\imx\display\display\DisplayManager.cpp

#define MAX_PHYSICAL_DISPLAY 10
#define MAX_VIRTUAL_DISPLAY  16

Display* DisplayManager::getPhysicalDisplay(int id)
{
    Mutex::Autolock _l(mLock);
    if (id < 0 || id >= MAX_PHYSICAL_DISPLAY) {
        ALOGE("%s invalid id %d", __func__, __LINE__);
        return NULL;
    }

	ALOGI("%s %d sunxiaolin id=%d", __func__, __LINE__,id);

    if (mDrmMode) {
        return mKmsDisplays[id];
    }
    return mFbDisplays[id];
}

你可能感兴趣的:(android,p,display架构)