迅为RK3588开发板是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP,内置NPU,支持INT4/INT8/INT16/FP16混合运算能力,支持安卓12和、Debian11、Build root、Ubuntu20和22版本登系统。了解更多信息可点击迅为官网
【实验平台】:迅为RK3588开发板
【内容来源】《【北京迅为】itop-3588开发板多屏显示手册v1.0》
RK3588最多可以支持7个屏幕显示,这主要取决于RK3588芯片内置了VOP控制器,
支持四路视频同显或异显,可有效提高行业定制的拓展性。本章节我们将介绍在RK3588的Android12系统上实现多屏显示。
1.1 Android 多屏同显
iTOP-RK3588开发板支持以下屏幕
迅为MIPI 7寸屏幕
标准HDMI屏幕(通过HDMI线连接)
迅为 LVDS 7 寸屏幕
迅为 LVDS 10.1 寸 1024*600 屏幕
迅为 LVDS 10.1 寸 1280*800 屏幕
迅为 LVDS 10.1 寸 1280*800 新屏幕
然后修改Android12源码kernel-5.10/arch/arm64/boot/dts/rockchip/topeet_screen_lcds.dts中
的设备树文件,如下图所示。LVDS屏幕是MIPI通过转接板连接显示的,RK3588不支持LVDS显示接口。
注:
其中#define LCD_TYPE_LVDS_10_1_1280X800_GT911和#define
LCD_TYPE_LVDS_10_1_1280X800_GT9271不同之处在于屏幕背板,可通过如下进行区分:
#define LCD_TYPE_LVDS_10_1_1280X800_GT911
#define LCD_TYPE_LVDS_10_1_1280X800_GT9271
我们可以根据自己的需求来修改topeet_screen_choose.dtsi文件。总之,修改
topeet_screen_choose.dtsi的规律是:打开所连接的屏幕对应的宏定义,rk3588有三个显示通道vp0 vp1 vp2 vp3,所打开的宏定义对应的vp通道不能重复。默认打开对应的宏定义为多屏同显。
RK3588 VP和各显示接口的连接关系如下图所示。
1.2 Android 多屏异显
如果要支持多屏异显,首先要调试好双屏或多屏都可以正常显示,并且分别挂载在不同的vp上,可以参考上一个小节根据自己的需求打开topeet_screen_choose.dtsi设备树中的宏定义。
默认开启后,多屏显示的是同一个画面(如果要支持双屏或者多屏异显,需要应用支持异显, 才会显示不同的内容)。查看当前的屏幕显示状态输入以下命令
cat /sys/kernel/debug/dri/0/summary
如果双屏或者多屏的显示器分辨率比例不同,比如说主屏是16:9,副屏是4:3,那么副 屏显示的画面会拉伸或者缩小,原因是副屏的画面是主屏映射过去的,所以副屏上显示的是 主屏的分辨率。如果同样的屏幕情况下,应用支持异显,那么副屏会显示实际正常的分辨率。
所以如果要支持双屏或者多屏同显并要求显示正常,双屏或者多屏的屏幕的分辨率比要一致。
1.2.1 指定主副屏
多屏异显的实际应用中,需要指定哪个是主屏,哪个是副屏。修改Android12源码目录下3588-android12/device/rockchip/rk3588/rk3588_s/rk3588_s.mk文件,添加如下内容:
如果要指定MIPI屏幕为主屏,HDMI屏幕为副屏,如下设置:
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=HDMI-A
如果要指定MIPI屏幕为主屏,EDP屏幕为副屏,如下设置:
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=eDP
如果需要定义多个主副屏时,需要用逗号隔开,比如指定MIPI eDP为主屏,HDMI-A为副屏,
设置如下:
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI,eDP
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=HDMI-A
1.2.2 异显方案介绍
目前有两种异显方案分别是Android Presentation和Andorid Activity指定屏幕启动。
Android Presentation,需要APP应用开发中调用相应接口使指定的view (Presentation view是一个特殊的dialog类型view)在副屏中显示。
Android Activity指定屏幕启动,APP在启动activity时可以使用display id参数在对应的屏幕上直接显示。
两者主要区别在:
1前者的acitivity需要独立开发,把需要显示的内容投到副屏,后者可以不需要源码,调用命令行或者系统接口把第三方app的acitivity投送到副屏;
2 .前者只有一个activity在顶层,通过特殊的dialog将指定内容显示在副屏,后者是两个activity分别显示在主副屏。
接下来我们详细讲述这俩种方法。
1.2.3 Android Presentation
本小节讲解Android Presentation异显方案,瑞芯微和迅为提供了使用Android Presentation编写好的APP例程,接下来进行测试。
1.2.3.1 ApiDemos APP
在Android12源码中瑞芯微已经提供了使用Presentation接口的测试APP,在源码development/samples/ApiDemos目录下,需要使用mm命令编译APP。迅为提供了编译好的 测试APP在网盘资料“iTOP-RK3588开发板/02_【iTOP-RK3588开发板】/12_多屏显示配套 资料/Android/ApiDemosAPK”目录下。
此APP源码在Android源码3588-android12/development/samples/ApiDemos目录下,进入 此目录,输入“mm”命令进行编译,如下图所示:
然后使用adb命令安装APP,依次点击App->Activity->Presentation选项,即可进入Presentation调用界面。如下图所示:
在该界面需点击如下副屏的checkbox选项,即可在副屏显示相应图片。副屏HDMi屏幕显示图片,
1.2.3.2 Presentation sampleAPP
此APP在网盘资料“iTOP-RK3588开发板/02_【iTOP-RK3588开发板】/12_多屏显示配 套资料/Android/Presentation sample”目录下,下载此APP工程,然后用Androidstudio打开, 并编译apk。编译成功之后,安装APP,APP安装成功之后如下图所示:
打开APP如下图所示:
点击“显示副屏”按钮,会在副屏显示,如下图所示:
APP重要知识点讲解:
随着用户的需求增多,特别是对于一些Android平板电脑以及其他的一些Android智能设备可能有多个屏幕,用户不仅想要在主屏幕上显示内容,同样在第二屏幕上也要显示想要的内容,这样可以达到更好的体验效果。Google也是不负众望在Android4.2版本以后提供了Presentation类,可以轻松实现在两块屏幕上同时显示不同的内容。Presentation是一个特殊的dialog,它的目的是显示内容到第二屏幕。在Presentation创建的时候关联一个目标设备,确
定Presentation要显示在那个设备上,根据这个设备的信息来配置Presentation的context和resources信息。目前系统提供了两种方式来与目标显示屏进行绑定。
1通过MediaRouter接口获取并绑定:
选择显示presentation的设备最简单的方法就是使用Media Router,media router服务持续追踪在系统中哪个音频、视频线路是可用的,当routes被选择或者不被选择,或者更好的显示presentation display的线路发生改变后media router就会发送消息。所以一些应用程序可以自动监视这些消息来在首选设备上显示或取消presentation。
首选显示presentation的设备是Media Router进行推荐的,如果应用想要显示内容在第二 屏幕上就该使用该设备。下面将给出如何使用media router在主屏的设备创建和显示
presentation。
MediaRouter mediaRouter =(MediaRouter)
context.getSystemService(Context.MEDIA_ROUTER_SERVICE); MediaRouter.RouteInfo route =
mediaRouter.getSelectedRoute();
if(route !=null){
Display presentationDisplay = route.getPresentationDisplay();
if(presentationDisplay !=null){
Presentation presentation =newMyPresentation(context, presentationDisplay);
presentation.show();
}
}
根据上面代码可以看出通过系统服务Media Router来选择一个合适的route,从route中来获取首选的display,如果display不为空就会创建该presentation,创建完成后调用presentation的show方法将该presentation显示出来。
2通过DisplayManager接口获取并绑定
另外一个获取首选display的方法是直接使用display Manager来获取。display manager服务提供方法枚举和描述系统中所有的设备,包括可以显示presentation的设备。display manager持续追踪系统中所有的设备,然而,并不是所有的设备都适合显示presentation,例如,如果 一个Activity试图在主屏幕上显示一个presentation,它可能会掩盖自己的内容,这就像在Activity上打开一个dialog一样。
DisplayManager displayManager =(DisplayManager)
context.getSystemService(Context.DISPLAY_SERVICE); Display[] presentationDisplays
=displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if(presentationDisplays.length >0){
// If there is more than one suitable presentation display, then we could consider
// giving the user a choice. For this example, we simply choose the first display
// which is the one the system recommends as the preferred presentation display.
Display display = presentationDisplays[1]; // displays[1]是副屏
Presentation presentation =new MyPresentation(context, presentationDisplay);
presentation.show();
}
根据上面代码可以看出通过系统服务Display Manager来获取所有适合显示presentation的display列表,如果获取到了多个适合display对象,我们选择副屏的display。最后显示presentation。
1.2.4 Android Activity 指定屏幕启动
本小节讲解Android Activity指定屏幕启动异显方案,瑞芯微提供了使用Android Activity指定屏幕启动编写好的APP例程,接下来进行测试。
1.2.4.1 dualscreendemo APP
RK DualScreen主要区别与android presentation,在于它实现了应用的派发,允许厂商快速根据现有的app功能,进行模块的集成,减少开发周期和研发成本。示例代码为DualScreenDemo.zip工程,在网盘资料“iTOP-RK3588开发板/02_【iTOP-RK3588开发板】/12_多屏显示配套资料/Android/DualScreenDemo”目录下下载。
使用Androidstudio打开此工程代码,编译安装APP,安装完成后如下所示:
打开此APP,如下所示,有三个按钮。
第三个按钮使用了Android Activity指定屏幕启动,关键代码如下所示,第一个和第二个按钮使用了Presentation。
private void showSecondByActivity(Context context){
ActivityOptions options = ActivityOptions.makeBasic();
MediaRouter mediaRouter = (MediaRouter)
context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route =
mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
if (route != null) {
Display presentationDisplay = route.getPresentationDisplay();
options.setLaunchDisplayId(presentationDisplay.getDisplayId());
Intent intent = new Intent("android.intent.action.MUSIC_PLAYER");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, options.toBundle());
}
}
在startActivity接口参数中设置指定屏幕的display id,Activity将在指定屏幕上直接启动显示。
Activity的多显示器支持需要设备支持。
同时application或者activity需要支持分屏属性即或者标签下设 置新的属性android:resizeableActivity="true",这个属性在你target到Android N后android:resizeableActivity的默认值就是true。
ActivityOptions提供两个新函数以支持多个显示器,分别是setLaunchDisplayId()和getLaunchDisplayId()。
setLaunchDisplayId()指定Activity在启动后应显示在哪个显示器上。
getLaunchDisplayId()返回操作组件的当前启动显示器。
在上述代码中使用MediaRouter接口获取副屏的display id,同理也可以使用
DisplayManager接口获取响应的display id。
1.2.5 支持输入法在副屏显示
修改Android12源码下的device/rockchip/common/display_settings.xml文件,如下所示:
将设置相应屏幕shouldShowIme为true,如上配置支持输入法在local:1的副屏上显示。
1.2.6 副屏 DPI 设置
修改Android12源码下的device/rockchip/common/display_settings.xml文件,
修改forcedDensity的值可以修改副屏的屏幕密度。
1.2.7 主屏幕可以触摸,副屏不触摸
如果想要实现主屏可以触摸,副屏不用触摸的功能。有两种解决方式:第一种是在App应用代码中实现。第二种需要修改framework层的源码。
第一种方式:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
第二种方式:
修改Android12源码frameworks/native/services/inputflinger/reader/EventHub.cpp文件,屏蔽掉device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;属性,
1.2.8 多屏异触
多屏异触需要指定主副屏。这里使用修改Android源码的方式实现绑定副屏触摸芯片。这样设置以后,系统开机会自动将ft5x06触摸绑定到副屏上面去。修改文件:
frameworks/native/services/inputflinger/reader/EventHub.cpp,添加如下加红的代码。通过修改EventHub.cpp文件,在isExternalDeviceLocked函数中判断设备名称为指定的副屏设备(比如副屏的设备名称是generic ft5x06 (79)),则返回true。
bool EventHub::isExternalDeviceLocked(Device* device) {
const char *I2C_DEVICE_NAME = "generic ft5x06 (79)";
ALOGE("input deviceis '%s' ",device->identifier.name.c_str());
if (strcmp(device->identifier.name.c_str(), I2C_DEVICE_NAME) == 0) {
return true;
}
if (device->configuration) {
bool value;
if (device->configuration->tryGetProperty(String8("device.internal"), value)) {
return !value;
}
}
return device->identifier.bus == BUS_USB || device->identifier.bus ==
BUS_BLUETOOTH;
}
这里的I2C_DEVICE_NAME需要根据实际情况添加,用户可根据ALOGE打印信息在logcat中寻找识别到的芯片实际的名字。下面是添加了ALOGE打印信息后在logcat中得到的设备名字的截图:
上图中的goodix-ts和generic ft5x06 (79)即为这里使用的触摸IC芯片的名字,将这个复制 到代码中即可。修改完毕,重新编译Android镜像,用户测试的时候可以直接使用ApiDemo APP进行测试。
1.2.9 鼠标异屏切换
在多屏异显情况下,修改以下代码使鼠标箭头可以移动到需要的副屏上去进行操作。
我们需要修改Android12源码中
frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp文件
搜索"sys.mouse.presentation",然后将下面的代码中0改为1。
char mMousePresentation[PROPERTY_VALUE_MAX] = {1};
property_get("sys.mouse.presentation", mMousePresentation, "1");
if (strcmp(mMousePresentation, "1") == 0) {
displayId = mDisplayId;
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
if(xCursorPosition==minX||xCursorPosition==maxX||yCursorPosition==minY||yCursorPosition==
maxY){
displayId=getPolicy()->notifyDisplayIdChanged();
mDisplayId=displayId;
}
}
}else{
displayId = mPointerController->getDisplayId();
}
然后重新编译Android源码,然后烧写镜像。
-
Android
+关注
关注
12文章
3917浏览量
127031 -
RK3588
+关注
关注
6文章
303浏览量
4140 -
迅为电子
+关注
关注
0文章
23浏览量
22
发布评论请先 登录
相关推荐
评论