RK 11.0 多屏模式下修改鼠标进入方式

要求:主屏在左,副屏在右。这种排列情况下鼠标仅可通过主屏的最右侧移入副屏的最左侧,或从副屏的最左侧移入主屏最右侧。

1.RK默认设计
1.1 RK的代码设计是当sys.mouse.presentation=1时,鼠标在屏幕边缘的时候就会移入另一个屏幕
  • frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp
void CursorInputMapper::sync(nsecs_t when) {
	...
	if (mSource == AINPUT_SOURCE_MOUSE) {
		if (moved || scrolled || buttonsChanged) {
            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);

            if (moved) {
                mPointerController->move(deltaX, deltaY);
            }

            if (buttonsChanged) {
                mPointerController->setButtonState(currentButtonState);
            }

            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
        }
        mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
        
        char mMousePresentation[PROPERTY_VALUE_MAX] = {0};
        property_get("sys.mouse.presentation", mMousePresentation, "0");
        if (strcmp(mMousePresentation, "1") == 0) {
            displayId = mDisplayId;
            float minX, minY, maxX, maxY;
            if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
            	// 如果鼠标位置在屏幕四周边缘,进入另外的屏幕,重新赋值displayId
                if (xCursorPosition==minX||xCursorPosition==maxX||yCursorPosition==minY||yCursorPosition==maxY{
                    displayId=getPolicy()->notifyDisplayIdChanged();
                    mDisplayId=displayId;
                }
            }
         }else{
            displayId = mPointerController->getDisplayId();
         }
     } else {
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
         displayId = ADISPLAY_ID_NONE;
     }
}
1.2 鼠标进入不同屏,默认居中显示
  • frameworks/base/libs/input/PointerController.cpp
void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
	...
	// Reset cursor position to center if size or display changed.
    if (oldViewport.displayId != viewport.displayId
            || oldDisplayWidth != newDisplayWidth
            || oldDisplayHeight != newDisplayHeight) {

        float minX, minY, maxX, maxY;
        if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
            mLocked.pointerX = (minX + maxX) * 0.5f;
            mLocked.pointerY = (minY + maxY) * 0.5f;
            // Reload icon resources for density may be changed.
            loadResourcesLocked();
        } else {
            mLocked.pointerX = 0;
            mLocked.pointerY = 0;
        }

        fadeOutAndReleaseAllSpotsLocked();
    } else if (oldViewport.orientation != viewport.orientation) {
}
2.修改鼠标进入方式

hdmi接入状态

  • /frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.java
public Pair<Integer, Integer> parseState(ExtconInfo extconInfo, String status) {
	...
	 if (status.contains("HDMI")){
	 	SystemProperties.set("hdmi.plugged", status.contains("HDMI=1") ? "1":"0");
	 }
}
2.1 主屏在左,副屏在右边模式下修改鼠标进入方式
  • frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp
void CursorInputMapper::sync(nsecs_t when) {
	...
	if (mSource == AINPUT_SOURCE_MOUSE) {
        if (moved || scrolled || buttonsChanged) {
            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);

            if (moved) {
                mPointerController->move(deltaX, deltaY);
            }

            if (buttonsChanged) {
                mPointerController->setButtonState(currentButtonState);
            }

            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
        }

        mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
        char mMousePresentation[PROPERTY_VALUE_MAX] = {0};
        property_get("sys.mouse.presentation", mMousePresentation, "0");
        if (strcmp(mMousePresentation, "1") == 0) {
           //displayId = mDisplayId;
           char mHdmiPlugged[PROPERTY_VALUE_MAX] = {0};
           property_get("hdmi.plugged", mHdmiPlugged, "0");
           if (strcmp(mHdmiPlugged, "1") == 0){
               displayId = mDisplayId;
           } else {
           	   // 鼠标在副屏时,拔掉hdmi导致鼠标没有功能,强制id为主屏0
               displayId = 0;
           }  
           
           float minX, minY, maxX, maxY;
           
           if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)){
           		// 鼠标在主屏屏幕右边缘位置,重新赋值displayId,位置改变
                if (displayId == 0 && xCursorPosition==maxX) {
                    displayId=getPolicy()->notifyDisplayIdChanged();
                    mDisplayId=displayId;
                    // 设置鼠标在副屏左侧显示
                    if ((strcmp(mHdmiPlugged, "1") == 0)){
                        mPointerController->setPosition(minX+10, yCursorPosition);
                    }
                }
                
				// 鼠标在副屏屏幕左边缘位置,重新赋值displayId,位置改变((主屏id默认为0,副屏id切换后递增))
                if (displayId != 0 && xCursorPosition==minX){
                    displayId=getPolicy()->notifyDisplayIdChanged();
                    mDisplayId=displayId;
                    // 设置鼠标在主屏右侧显示
                    mPointerController->setPosition(maxX-10, yCursorPosition);
                }
           } 
      	}else{
           displayId = mPointerController->getDisplayId();
        }
    } else {
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
        displayId = ADISPLAY_ID_NONE;
    }
}
<think>好的,用户想了解RK3588芯片的显示配置方法或实现方案。我需要先理解用户的需求,可能他们在开发或使用基于RK3588的设备时遇到了显示的问题,需要具体的配置步骤或方案。 首先,我应该回顾RK3588的显示系统架构。根据引用[2]中的信息,RK3588支持KMS(Kernel Mode Setting),负责分辨率、刷新率等参数的设置以及显示缓冲区的切换和图层合成。这说明显示可能涉及到KMS的配置。此外,DRM(Direct Rendering Manager)用于渲染显示,所以DRM的相关设置也很重要。 接下来,用户可能需要知道如何配置设备树(Device Tree)来支持个显示接口,比如HDMI、eDP、MIPI-DSI等。每个接口对应的节点需要正确配置,包括时钟、电源、分辨率等参数。这里需要参考RK3588的技术文档,但用户可能没有直接访问权限,所以需要基于公开的信息给出一般步骤。 然后,显示控制部分可能涉及到Rockchip的显示子系统,如VOP(Video Output Processor),需要确保每个幕分配了不同的VOP层。引用[2]提到使用ffmpeg和rkmpp进行硬解码和DRM渲染,这可能与视频输出到幕有关,但用户的问题更偏向显示配置而非解码。 用户还可能关心软件层面的配置,比如在Linux系统中使用DRM/KMS驱动,如何设置的合成方式,比如扩展模式或镜像模式。这里可能需要修改内核参数或使用工具如modetest进行配置。 此外,引用[3]提到音频路径受系统组件影响,但用户的问题是关于显示,所以可能不需要涉及音频部分,但需要注意显示和音频在HDMI等接口上的协同工作。 用户可能需要具体的步骤,比如修改设备树、配置内核驱动、使用DRM接口等。还需要注意不同显示接口的兼容性和时钟配置,确保信号稳定。同时,硬件连接的正确性也是关键,比如各接口的电气特性是否符合要求。 最后,应该提醒用户参考官方文档和社区资源,如Rockchip的Wiki或论坛,以获取最新的配置方法和解决常见问题。可能还需要提及调试工具,如使用dmesg查看内核日志,或使用modetest测试显示输出。 总结起来,回答需要涵盖硬件接口配置、设备树修改、驱动支持、显示合成配置以及调试方法,同时引用相关的资料帮助用户进一步查找详细信息。</think>### RK3588显示配置方案 RK3588芯片通过集成种显示接口(如HDMI、eDP、MIPI-DSI)和显示控制器(VOP)支持显示,其核心配置涉及**硬件接口定义、设备树配置、显示合成策略**三个层面。以下是具体实现步骤: --- #### 一、硬件接口配置 1. **接口选择** 确认主板支持的显示接口类型(如HDMI 2.1、DP 1.4、双MIPI-DSI),需满足目标幕的分辨率与刷新率需求。例如: - HDMI输出4K@60Hz需要接口支持HDMI 2.1标准 - eDP接口常用于嵌入式显示连接 2. **电气参数校准** 根据幕规格配置接口的电压、时钟信号(如MIPI-DSI的LP/HSP时钟频率),确保信号稳定性[^2]。 --- #### 二、设备树(Device Tree)配置 在Linux内核中需定义各显示接口的节点: ```dts // 示例:HDMI和MIPI-DSI双配置 &hdmi { status = "okay"; #address-cells = <1>; #size-cells = <0>; }; &dsi0 { status = "okay"; panel@0 { compatible = "panel-rockchip,xxx"; reg = <0>; backlight = <&backlight>; }; }; // VOP分配(每个幕绑定独立的VOP层) &vop { assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; assigned-clock-parents = <&pmu PLL_HPLL>, <&pmu PLL_VPLL>; }; ``` 关键配置项: - 设置`status = "okay"`启用对应接口 - 为每个显示接口分配独立的VOP(Video Output Processor)层 - 配置时钟源(如HPLL/VPLL)以避免频率冲突 --- #### 三、显示合成与模式设置 1. **DRM/KMS驱动配置** 通过Linux DRM框架实现合成: ```bash # 内核启动参数启用DRM支持 drm_kms_helper.drm_fbdev_overalloc=2 ``` 2. **显示模式设置** 使用`modetest`工具设置扩展模式(EXTEND)或镜像模式(MIRROR): ```bash # 查询支持的显示模式 modetest -M rockchip # 设置HDMI为扩展模式 modetest -M rockchip -s <connector_id>@<mode_id> -e ``` 3. **图层合成** 通过VOP支持层叠加(如GUI层+视频层),需在应用层配置合成策略: ```c // DRM API设置图层属性 drmModeSetPlane(fd, plane_id, crtc_id, fb_id, 0, x, y, width, height); ``` --- #### 四、常见问题与调试 1. **信号稳定性问题** 若出现花/闪,检查时钟配置(如`clock-names = "pclk", "hclk"`)和电源噪声。 2. **显示模式不匹配** 使用`dmesg | grep drm`查看内核日志,确认EDID数据是否正确解析。 3. **性能优化** 启用Rockchip MPP(Media Process Platform)硬件加速,减少CPU负载[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值