Android 7.1 竖屏转横屏全过程实现-基于高通平台

原帖出处:

背景:

调试使用一款800x1280分辨率的屏,客户希望横屏使用(1280x800),且没有旋转过程,看起来就是横屏显示一样。修改主要涉及几个方面,第一是LK阶段的图片,第二是开机动画的显示(/system/bin/bootanimation),第三是最终进入系统后的显示,且所有的显示过程无缝连接。

涉及的库文件:

/system/lib64/libsurfaceflinger.so

/system/framework/services.jar

/system/framework/framework-res.apk

/system/bin/bootanimation

Android显示子系统大致流程:

主要分为两个部分,LK部分和kernel独立。主要讲kernel部分。

显示驱动加载—>创建/dev/graphic/fb0à启动servicesurfaceflinger /system/bin/surfaceflinger

à启动servicebootanim /system/bin/bootanimation—>启动zygote和system-server进入Java

service zygote /system/bin/app_process64-Xzygote /system/bin --zygote --start-system-server进入Android系统—>启动各种servicemanager –>启动activity managerà启动luncher—>等待用户启动app。

涉及的文件路径:

开机动画的路径:vendor\qcom\proprietary\qrdplus\Extension\apps\BootAnimation\

更换开机动画:

C:\Users\binq>adb push X:\shaomingliang\android7.1\LA.UM.5.6\vendor\qcom\proprie

tary\qrdplus\Extension\apps\BootAnimation\bootanimation.zip /system/media/

surfaceflinger文件:

frameworks\native\services\surfaceflinger\DisplayDevice.cpp

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

加载开机动画的代码:

frameworks\base\cmds\bootanimation\bootanimation_main.cpp

frameworks\base\cmds\bootanimation\BootAnimation.cpp

JAVA层代码:

frameworks/base/core/res/res/values/config.xml

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

kernel部分代码:

kernel/msm-3.18/arch/arm/boot/dts/qcom/dsi-panel-nt35521s-kd101n66-40ni-k2-800p-video.dtsi(屏的配置文件)

device/qcom/msm8937_64/system.prop 添加属性

1、 修改LK阶段图片

高通使用splash.img存储LK的开机动画,在device/qcom/common/display/logo/logo.png

添加对应分辨率的图片,重新打包编译splash.img下载进去即可。

2、 修改kernel中屏的相关配置,

使屏旋转180度,这样在后面Android部分只需要旋转90度即可,不需要旋转270.旋转270有可能会遇到Android设置界面设置字体闪屏的问题。

在配置文件中添加:

qcom,mdss-dsi-panel-orientation = "180";

3、 开机动画横屏,

修改/system/bin/bootanimation(C++)

在frameworks\base\cmds\bootanimation\BootAnimation.cpp中添加:

@@ -286,7+286,22 @@ status_t BootAnimation::readyToRun() {

status_t status =SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);

if (status)

return -1;

+ //ALOGE("eliot BootAnimation::readyToRun111111\n");

+

+ char value[PROPERTY_VALUE_MAX];

+ property_get("persist.panel.orientation", value,"0");

+ int orient= atoi(value) / 90;

+

+ if(orient== 1 || orient == 3) {

+ inttemp = dinfo.h;

+ dinfo.h= dinfo.w;

+ dinfo.w= temp;

+ }

+ RectdestRect(dinfo.w, dinfo.h);

+ mSession->setDisplayProjection(dtoken, orient, destRect, destRect);

+

+ //ALOGE("eliot BootAnimation::readyToRun22222222\n");

// create the native surface

sp<SurfaceControl> control =session()->createSurface(String8("BootAnimation"),

dinfo.w, dinfo.h,PIXEL_FORMAT_RGB_565);

在device/qcom/msm8937_64/system.prop添加:

persist.panel.orientation=90 #bootanimation daemon会读取这个字符串进行旋转操作。

qemu.hw.mainkeys=0 #这个是虚拟按键

4、 JAVA层修改默认方向

frameworks/base/core/res/res/values/config.xml

修改:

---a/frameworks/base/core/res/res/values/config.xml

+++b/frameworks/base/core/res/res/values/config.xml

@@ -619,7 +619,7 @@

settings are omitted from the system UI. In certain situations we may

still use the accelerometer to determine the orientation, such as when

docked if the dock is configured to enable the accelerometer. -->

- <bool name="config_supportAutoRotation">true</bool>

+ <boolname="config_supportAutoRotation">false</bool>

<!-- If true, the screen can be rotated via the accelerometer in all4

rotations as the default behavior. -->

@@ -674,7 +674,7 @@

<!-- The number of degrees to rotate the display when the keyboard isopen.

A value of -1 means no change in orientation by default. -->

- <integername="config_lidOpenRotation">-1</integer>

+ <integername="config_lidOpenRotation">90</integer>

<!-- Indicate whether the lid state impacts the accessibility of

the physical keyboard. 0 means itdoesn't, 1 means it is accessible

修改

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

+++b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

@@ -6924,7 +6924,7 @@ public classPhoneWindowManager implements WindowManagerPolicy{

if (preferredRotation >=0) {

returnpreferredRotation;

}

- return Surface.ROTATION_0;

+ return Surface.ROTATION_90;

}

}

}

修改

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

---a/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

+++b/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

@@ -553,7 +553,7 @@ public classWindowManagerService extends IWindowManager.Stub

/** All DisplayContents in the world, kept here */

SparseArray<DisplayContent> mDisplayContents = newSparseArray<>(2);

- int mRotation = 0;

+ int mRotation = 1;

int mLastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

boolean mAltOrientation = false;

@@ -3857,7 +3857,7 @@ public classWindowManagerService extends IWindowManager.Stub

long ident = Binder.clearCallingIdentity();

try {

int req = getOrientationLocked();

+ req =ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; //add

if (req != mLastOrientation) {

mLastOrientation = req;

//send a message to Policyindicating orientation change to take

参考网站: http://blog.youkuaiyun.com/q1183345443/article/details/53068526
<think>首先,用户的问题是:“我想了解高通平台实现图片旋的技术方法或代码实现 请问高通平台 实现 图片旋 方法”。用户要求在高通平台实现图片旋的技术方法或代码实现。 从系统级指令中,我有几个关键点: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 参考的站内引用: - 引用[1]:关于高通平台Android 7.1系统显示旋180度,涉及mPanelInverseMounted和isPanelInverseMounted定义问题。 - 引用[2]:高通Android 7.1修改logo,横屏全过程实现,涉及LK阶段图片、开机动画和系统显示。 - 引用[3]:高通平台Camera开发,涉及模块选型和硬件准备。 - 引用[4]:高通平台LCD驱动框架,涉及帧缓冲(framebuffer)设备驱动。 用户的问题集中在图片旋,所以我需要从这些引用中提取相关信息。引用[2]最相关,因为它讨论了横屏的修改,包括图片旋。 关键点从引用[2]: - 修改涉及LK阶段的图片(开机图片)。 - 开机动画(/system/bin/bootanimation)。 - 系统显示(进入系统后的显示)。 - 目标是所有显示过程无缝连接,看起来像横屏显示。 引用[4]提到帧缓冲(framebuffer)设备驱动,这是显示驱动的基础。LCD驱动属于帧缓冲设备驱动,用户空间应用程序可以通过/dev/fb*设备操作显示缓冲区。 所以,实现图片旋可能涉及: 1. **硬件层**:通过显示控制器或GPU旋图像。 2. **驱动层**:修改LCD驱动或帧缓冲驱动来处理旋。 3. **应用层**:在Android系统中设置旋属性。 在Android系统中,幕旋通常通过设置display属性实现,如persist.sys.rotation或类似。 用户提到“图片旋”,可能包括静态图片(如开机图片)和动态内容(如UI)。在高通平台上,这通常涉及高通显示硬件和驱动。 步骤: 1. **理解旋机制**:在显示管道中,图像数据可以被旋高通平台可能有硬件支持旋,如MDP(Mobile Display Processor)。 2. **修改驱动**:在LCD驱动中设置旋参数。引用[4]提到帧缓冲设备,用户空间可以写入颜色值,驱动负责显示。 3. **Android系统设置**:在Android中,可以通过属性或配置文件设置幕方向。 从引用[2],具体修改: - LK阶段:修改开机图片的旋- 开机动画:修改bootanimation程序。 - 系统显示:修改Android的display配置。 代码实现方面: - **LK阶段**:LK是Little Kernel,高通启动过程的一部分。修改LK中的显示初始化代码来设置旋- **Bootanimation**:修改/system/bin/bootanimation的源代码或配置来旋动画。 - **Android系统**:修改frameworks/base或device-specific代码来设置默认方向。 可能的代码位置: - 驱动:/kernel/drivers/video/msm/mdss/mdss_fb.c 或类似文件。 - Android:/system/core/init/init.rc 或设备特定的init文件设置属性。 - 在BoardConfig.mk或类似文件中设置旋。 通用方法: 1. **硬件旋**:使用显示控制器的旋功能。例如,在MDSS驱动中设置旋角度。 2. **软件旋**:在应用层或中间层旋图像数据,但这可能性能较低。 为了回答用户,我应该: - 结构清晰:分步骤解释。 - 真实可靠:基于引用和通用知识。 - 使用中文。 - 生成相关问题。 - 添加引用标识。 大纲回答: 1. **引言**:解释高通平台图片旋的常见方法。 2. **技术方法**: - LK阶段旋 - Bootanimation旋 - Android系统旋 3. **代码实现示例**:提供伪代码或关键代码片段。 4. **相关问题生成**:在末尾。 引用标识:当引用参考内容时,在末尾添加[^1]、[^2]等。 例如,引用[2]提到“修改主要涉及几个方面”,所以我可以引用它。 最终回答结构: - 开头简述。 - 分点详细方法。 - 代码块(如果适用)。 - 相关问题。</think>### 高通平台实现图片旋的技术方法及代码实现高通平台实现图片旋(如横屏180度旋)通常涉及显示管道(display pipeline)的硬件和软件协同工作。主要方法包括:利用显示控制器(如MDP或DPU)的硬件旋功能、修改帧缓冲(framebuffer)驱动、调整Android系统配置。以下内容基于参考引用和通用高通平台开发实践,分步骤解释技术方法并提供关键代码示例。实现时需注意目标Android版本(如Android 7.1或更高),并确保所有修改无缝衔接显示过程[^2]。 --- #### 1. **技术方法概述** 图片旋高通平台分为三个层级: - **硬件层**:通过显示控制器(如高通MDP)支持0°、90°、180°或270°旋,减少CPU负载。 - **驱动层**:修改LCD驱动或帧缓冲设备驱动(framebuffer),设置旋参数。 - **应用层**:在Android系统中配置显示属性(如persist.sys.rotation),影响开机图片、动画和UI。 关键目标是确保旋过程无缝,避免闪烁或延迟[^2][^4]。 --- #### 2. **详细实现步骤及代码示例** ##### (1) **LK阶段(Little Kernel,开机前阶段)旋** LK是高通平台的引导加载程序,负责显示初始开机图片(如logo)。旋需修改LK代码,设置显示控制器的旋寄存器。 - **技术方法**: - 在LK的显示初始化代码中,添加旋角度配置。 - 使用高通提供的寄存器接口(如MDP或DPU控制器)设置旋- 确保图片数据在帧缓冲中预旋- **代码实现示例**(基于C语言,常见路径:`bootable/bootloader/lk/app/aboot/display.c`): ```c // 设置显示旋角度(例如90度旋) void display_set_rotation(uint32_t rotation_angle) { // 获取显示控制器基地址(MDP或DPU) uint32_t *mdp_base = (uint32_t *)MDP_BASE_ADDR; // 设置旋寄存器:MDP_ROTATION_CFG寄存器 // 旋角度:0x0(0°),0x1(90°),0x2(180°),0x3(270°) uint32_t rot_cfg = rotation_angle & 0x3; writel(rot_cfg, mdp_base + MDP_ROTATION_OFFSET); // 更新帧缓冲:确保图像数据对齐旋 struct fb_var_screeninfo var; fb_get_var(&var); var.rotate = rotation_angle; // 设置旋属性 fb_set_var(&var); } // 在LK初始化中调用 void display_init() { // ...其他初始化代码 display_set_rotation(90); // 设置为90度旋 } ``` **说明**:修改后需重新编译LK镜像。如果旋无效,检查硬件是否支持该角度(引用中客户遇到向问题,可能因寄存器配置错误)[^1][^2]。 ##### (2) **Bootanimation阶段(开机动画)旋** Bootanimation是Android开机动画进程(`/system/bin/bootanimation`),旋需修改其源代码或配置。 - **技术方法**: - 在`bootanimation`代码中,添加旋逻辑(如使用OpenGL ES或SurfaceFlinger旋)。 - 或通过Android属性动态设置旋- **代码实现示例**(基于C++,常见路径:`frameworks/base/cmds/bootanimation/BootAnimation.cpp`): ```cpp // 在渲染循环中添加旋处理 void BootAnimation::onDraw(const sp<Surface>& surface) { // 获取SurfaceFlinger服务 sp<SurfaceComposerClient> client = new SurfaceComposerClient(); sp<SurfaceControl> surfaceControl = client->createSurface( String8("BootAnimation"), displayWidth, displayHeight, PIXEL_FORMAT_RGB_565); // 设置旋:使用SurfaceFlinger的变换矩阵 SurfaceComposerClient::Transaction t; t.setMatrix(surfaceControl, 0, 1, -1, 0); // 90度旋矩阵 t.apply(); // 渲染图像 ANativeWindow_Buffer buffer; surface->lock(&buffer, NULL); // ...绘制图像到buffer surface->unlockAndPost(); } // 或在启动时设置系统属性 system("setprop persist.sys.rotation 90"); // 设置全局旋属性 ``` **说明**:修改后需重新编译bootanimation并替换到`/system/bin/`。确保权限正确(`chmod 755`)[^2]。 ##### (3) **Android系统阶段(进入系统后)旋** 进入Android后,旋由SurfaceFlinger和显示服务管理。修改系统属性或设备配置文件。 - **技术方法**: - 设置`persist.sys.rotation`属性定义默认方向。 - 修改`SurfaceFlinger`或`DisplayManagerService`处理旋- 在设备树(device tree)或BoardConfig中定义旋- **代码实现示例**(修改Android系统配置): - **步骤1:修改`init.rc`设置属性**(路径:`system/core/rootdir/init.rc`): ```bash # 添加开机时设置旋属性 on boot setprop persist.sys.rotation 90 # 90度旋 ``` - **步骤2:调整显示服务**(路径:`frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java`): ```java // 在系统启动时强制旋 public void onStart() { // ...其他代码 Settings.Global.putInt(getContext().getContentResolver(), "user_rotation", Surface.ROTATION_90); // 设置用户旋角度 } ``` - **步骤3:驱动层支持**(基于帧缓冲设备,引用[^4]): 在LCD驱动中设置旋参数(路径:`kernel/drivers/video/fbdev/msm/mdss_fb.c`): ```c static int mdss_fb_set_rotation(struct fb_info *info, int rotation) { struct msm_fb_data *fb_data = info->par; // 设置硬件旋 mdss_mdp_set_rotation(fb_data->mfd, rotation); return 0; } ``` --- #### 3. **注意事项** - **硬件支持**:确认高通SoC(如Snapdragon系列)支持硬件旋(引用[^4]中的帧缓冲机制)。若不支持,需软件回退(性能较低)。 - **无缝连接**:确保LK、bootanimation和Android阶段旋角度一致(如均设为90°),避免显示跳变[^2]。 - **调试技巧**:使用`dmesg`检查驱动日志,或通过`getprop persist.sys.rotation`验证属性设置。 - **版本兼容**:Android 7.1及以上需适配新API(如SurfaceControl),旧版本可能直接修改`build.prop`。 通过以上方法,可在高通平台实现高效图片旋。若需完整代码,建议参考高通官方文档或特定设备树(device tree)配置[^1][^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值