相关源码:
\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 20190906public static final int BUILT_IN_DISPLAY_ID_THIRD = 2;2、LocalDisplayAdapter中,增加第三块屏的逻辑处理:\frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.javaprivate 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};@Overridepublic 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

//主屏的初始化,回调给SurfaceFlingerstatic 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;}//副屏的初始化,回调给SurfaceFlingerstatic 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.sovoid 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  16Display* 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];}

更多相关文章

  1. Android中为窗口定义主题
  2. Android中Activity的4种加载模式
  3. Android 解决自定义 CheckBox 样式时的背景显示异常问题
  4. android 自定义组件 :对VelocityTracker的研究
  5. Android webkit image的加载过程解析(二)
  6. Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
  7. 自定义tabhost实现
  8. Android高手进阶教程(三)之----Android 中自定义View的应用

随机推荐

  1. Android中的FlexboxLayout
  2. Android中MenuInflater实例
  3. android app 不会被low memory killer回
  4. 在配置最新Androi adt20.0.0 遇到的一些
  5. CSS3实现android(安卓)Logo图标效果
  6. Qt 实现android camera摄像头的preview和
  7. android检测网络是否正常
  8. android UI设计属性中英对照表(未修订)
  9. Android(安卓)Settings中的默认设置
  10. Android(安卓)源码分析鼠标事件传递