迅为RK3588开发板Android多屏显示之多屏同显和多屏异显

    迅为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 的多显示器支持需要设备支持<feature name="android.software.activities_on_secondary_displays" />。

同时 application 或者 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 源码,然后烧写镜像。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/909406.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

登录功能设计(php+mysql)

一 登录功能 1. 创建一个登录页面&#xff08;login.php&#xff09;&#xff0c;包含一个表单&#xff0c;用户输入用户名和密码。 2. 在表单的提交事件中&#xff0c;使用PHP代码处理用户输入的用户名和密码。 3. 首先&#xff0c;连接MySQL数据库。然后&a…

vue--vueCLI

何为CLI ■ CLI是Command-Line Interface,俗称脚手架. ■ 使用Vue.js开发大型应用时&#xff0c;我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。&#xff08;vue 脚手架的作用&#xff09;&#xff0c; 而通过vue-cli即可&#xff1a;vue-cli 可以…

软件测试工程师面试整理 —— 编程与自动化!

在软件测试领域&#xff0c;编程与自动化是提升测试效率、覆盖率和可靠性的关键因素。掌握编程技术和自动化测试框架&#xff0c;能够帮助测试人员有效地执行大量重复性测试任务&#xff0c;并迅速反馈软件的质量状况。以下是编程与自动化在测试中的主要应用及相关技术介绍&…

宝顶白芽,慢生活的味觉盛宴

在快节奏的生活中&#xff0c;人们愈发向往那种悠然自得、返璞归真的生活方式。白茶&#xff0c;以其独特的韵味和清雅的风格&#xff0c;成为了现代人追求心灵宁静与生活品质的象征。而在众多白茶之中&#xff0c;竹叶青茶业出品的宝顶白芽以其甘甜醇爽的特质&#xff0c;成为…

安卓APP渗透安全测试

1.移动安全测试点分析 1.1主要测试 客户端 数据传输 服务端 l反编译 l二次打包 l组件安全 lWebview漏洞 l数据安全 l界面劫持 l数据备份风险 lDebug调试风险 l安全策略 l数据窃听 l中间人攻击 l信息泄露 l任意修改数据包 lSQL注入 l上传漏洞 l暴力破解 l逻辑漏洞 lXSS…

CentOS 7 安装 ntp,自动校准系统时间

1、安装 ntp yum install ntp 安装好后&#xff0c;ntp 会自动注册成为服务&#xff0c;服务名称为 ntpd 2、查看当前 ntpd 服务的状态 systemctl status ntpd 3、启动 ntpd 服务、查看 ntpd 服务的状态 systemctl start ntpdsystemctl status ntpd 4、设置 ntpd 服务开机启…

ESP-HaloPanel:用 ESP32-C2 打造超低成本智能家居面板

项目简介 在生活品质日益提升的今天&#xff0c;智能家居系统已经走进了千家万户&#xff0c;并逐渐成为现代生活的一部份。与此同时&#xff0c;一款设计精致、体积轻盈、操作简便的全屋智能家居控制面板&#xff0c;已经成为众多家庭的新宠。这种高效、直观的智能化的解决方…

如何用ChatGPT结合Python处理遥感数据

在科技飞速发展的时代&#xff0c;遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究&#xff0c;空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而&#xff0c;对于许多专业人士而言&#xff0c;如何高效地处…

TCP Analysis Flags 之 TCP Keep-Alive

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

使用buildx构建多架构平台镜像

1. 查看buildx插件信息 比较新的docker-ce版本默认已经集成了buildx插件 [rootdocker ~]# docker buildx version github.com/docker/buildx v0.11.2 9872040 [rootdocker ~]#2. 增加多平台镜像构建支持 通过tonistiigi/binfmt:latest初始化一个基于容器的构建环境&#xff…

【Linux】编辑器vim 与 编译器gcc/g++

目录 一、编辑器vim&#xff1a; 1、对vim初步理解&#xff1a; 2、vim的模式&#xff1a; 3、进入与退出&#xff1a; 4、vim命令模式下的指令集&#xff1a; 移动光标&#xff1a; 删除&#xff1a; cv&#xff1a; 撤销&#xff1a; 其他&#xff1a; 5、vim底行模…

面试总结!

OSI七层模型&#xff1a; 什么是OSI七层模型&#xff1f; 我们需要了解互联网的本质是一系列的网络协议&#xff0c;这个协议就叫做OSI协议&#xff08;开放系统互联(Open System Interconnection&#xff09;&#xff09;&#xff0c;它是由ISO&#xff08;国际标准化组织&…

人工智能技术:未来生活的“魔法师”

想象一下&#xff0c;未来的某一天&#xff0c;你醒来时&#xff0c;智能助手已经为你准备好了早餐&#xff0c;你的智能家居系统根据你的心情和日程安排调整了室内的光线和音乐&#xff0c;而你的自动驾驶汽车已经在门口等你。这不是科幻小说&#xff0c;这是人工智能技术为我…

Multi Agents协作机制设计及实践

01 多智能体协作机制的背景概述 在前述博客中&#xff0c;我们利用LangChain、AutoGen等开发框架构建了一个数据多智能体的平台&#xff0c;并使用了LangChain的Multi-Agents框架。然而&#xff0c;在实施过程中&#xff0c;我们发现现有的框架存在一些局限性&#xff0c;这些…

100、Python并发编程:保护临界资源的最简单方式,加锁

引言 前面的文章中已经提到了并发编程中能够带来性能提升的同时&#xff0c;也带来了一些问题&#xff0c;比如对共享资源/临界资源的竞争&#xff0c;可能会导致状态的不一致。最终的结果是虽然性能提升了&#xff0c;但是结果却是错误的…… 所以&#xff0c;并发编程中一个…

PHP电商供应链ERP管理系统小程序源码

&#x1f680;电商供应链大揭秘&#xff01;ERP管理系统如何重塑你的商业版图✨ &#x1f50d; 什么是电商供应链ERP管理系统&#xff1f; 电商供应链ERP管理系统是一款基于FastAdminThinkPHP开发的系统。该系统可满足电商企业管理自身进销存&#xff0c;帮助中小型电商企业管…

python: Parent-child form operations using ttkbootstrap

# encoding: utf-8 # 版權所有 2024 ©塗聚文有限公司 # 許可資訊查看&#xff1a;言語成了邀功的功臣&#xff0c;還需要行爲每日來值班嗎&#xff1f; # 描述&#xff1a; 主、子表單 窗體傳值 Parent-child form operations # Author : geovindu,Geovin Du 塗聚文. …

跳表原理笔记

课程地址 跳表是一种基于随机化的有序数据结构&#xff0c;它提出是为了赋予有序单链表以 O(logn) 的快速查找和插入的能力 创建 首先在头部创建一个 sentinel 节点&#xff0c;然后在 L1 层采用“抛硬币”的方式来决定 L0 层的指针是否增长到 L1 层 例如上图中&#xff0c;L…

医院信息化与智能化系统(17)

医院信息化与智能化系统(17) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…

selenium操作已开启的浏览器,方便调试

一、谷歌浏览器配置&#xff1a; 在所安装的谷歌下面&#xff0c;执行下面命令&#xff0c;打开谷歌浏览器&#xff0c;用来selenium的操作&#xff1a; 注意事项&#xff1a;端口需要不被占用&#xff0c;--user-data-dir"D:\workspace\chrome-data"这个路径需要有…