首页 > 其他分享 >Android 开机动画优化之序列帧旋转90度

Android 开机动画优化之序列帧旋转90度

时间:2023-05-24 19:00:11浏览次数:41  
标签:control 动画 matrix 序列帧 开机 90 Android dinfo

问题背景:

公司项目是个VR一体机,可以理解成眼镜,用户看的是横屏。

但是项目开始的代码基线是从手机迁移过来的,因此底层配置的是竖屏(即通过adb shell wm size输出的宽小于高),system server启动后在DisplayContent中修改了屏幕方向orientation=1。

我叙述一下实现播放开关机动画的方案

时序上是:开机动画  --》 system server修改方向  --》关机动画

对创建Layer(SurfaceControl)的参数进行修改

// 获取屏幕参数
DisplayInfo dinfo; status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo); // aosp原生 //sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
// dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);

 sp<SurfaceControl> control;
 if (mShuttingDown) {
   control = session()->createSurface(String8("BootAnimation"),    // 交换宽高,关机的时候播放横图
            dinfo.h, dinfo.w, PIXEL_FORMAT_RGB_565);
 } else {
   control = session()->createSurface(String8("BootAnimation"),    // 开机播放竖图,创建竖的Layer
            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
 }

开机动画时(orientation=0,竖屏设备),用的序列帧方向是:

因为要让用户看到正的ABC。

关机动画时(orientation=1,横屏设备),用的序列帧方向是:

此时开关机动画看起来都是正常的。

我看pico应该也是这样搞的:https://developer-cn.pico-interactive.com/document/solution/242423/

优化方案:

我为什么想优化:一是觉得上面的代码不优雅,二是,也是比较重要的一点,项目计划对接ToB业务,要很多次的替换开机动画,每次都让合作方旋转90度序列帧,我觉得太麻烦,可以用代码解决就用代码解决。

不过优化的前提是,我不想修改改变屏幕方向的时机,怕出问题,毕竟项目跑了5、6年了。

比如可以在SurfaceFlinger初始化的时候改变屏幕方向(我试过,可以实现),但我对涉及的模块、功能掌握不好,况且如果能从绘制参数上修改,改动还是最小的。

思路是从surfaceflinger、libui的单元测试代码寻找方案,最终确认可以修改 layer_state_t 这个结构的参数。

具体见代码:

// 开机、关机都这样创建 SurfaceControl
sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), dinfo.h, dinfo.w, PIXEL_FORMAT_RGB_565);

创建SurfaceControl时,DisplayInfo给的宽度、高度要做一下替换,因为你要用横图做动画。

然后对开机的SurfaceControl做变换

SurfaceComposerClient::Transaction t;
t.setLayer(control, 0x40000000)
.setMatrix(control, 0.0f, 1.0f, -1.0f, 0.0f)    // 顺时针旋转90度
.setPosition(control, dinfo.w * 1.0f, 0.0f)     // x方向做位移
// .setGeometry(control, Rect(0, 0, dinfo.h, dinfo.w), // Rect(0, 0, -dinfo.h, -dinfo.w), // NATIVE_WINDOW_TRANSFORM_ROT_90) .apply();

使用 setMatrix +  setPosition 和 setGeometry 是等效的。

我解释一下:

后面追看了一下源码:

// Layer.cpp
bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms) { ui::Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); if (!allowNonRectPreservingTransforms && !t.preserveRects()) { ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored"); return false; } mCurrentState.sequence++; mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; }
// Transform.cpp
void Transform::set(float a, float b, float c, float d) { mat33& M(mMatrix); M[0][0] = a; M[1][0] = b; M[0][1] = c; M[1][1] = d; M[0][2] = 0; M[1][2] = 0; mType = UNKNOWN_TYPE; }

后面会替换成 3*3的矩阵,可能到Engine端会用这个矩阵吧。

关于Layer这个矩阵的解读,网上资料比较少,后面可以先看看View的矩阵变换,先入门,然后看一下源码。

 

标签:control,动画,matrix,序列帧,开机,90,Android,dinfo
From: https://www.cnblogs.com/yulisuo/p/17429259.html

相关文章

  • [AndroidTips]Tablet不断重启原因分析
    现象:启动后,可以进入主界面。但是过几分钟自动重启。以后不断重复此现象。分析:1、手机如果重启,会在/data/system/dropbox留下开机信息,可以查看次类文件生成的时间标来了解手机重启的时间情况。另外,系统会自动记录最后一次开机/重启的原因到/proc/bootinfo。 2、查看bootinfo,可以......
  • Android GC
    28470dalvikvmDGC_FOR_MALLOCfreed665objects/239992bytesin71ms28470dalvikvmDGC_FOR_MALLOCfreed673objects/240288bytesin87ms21940dalvikvmDGC_EXPLICITfreed4802objects/185320bytes......
  • Android 触摸音的播放
    1.源码路径 frameworks\base\services\core\java\com\android\server\audio\AudioService.java.AudioService//==========================================================================================//SoundEffects//=====================......
  • 代码混淆及android配置
    1什么是代码混淆百度百科解释:代码混淆(Obfuscatedcode)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器。已经存在许多种功能各异的代码......
  • APP测试 - 利用ABD命令将Android手机中已安装的APP导出为APK文件
    0.场景测试过程中部分迭代的APP与研发的版本不一致,又不知道具体是哪个版本。故需要导出测试出现问题的迭代APP用于复现问题 1.导出步骤1.1找到应用的包名方案A:查看手机安装的应用$adbshellpmlistpackage方案B:利用monitor监视要打开的APP$adbshellammonitor......
  • Android 单独Process 的 Service 触发 Application的构造
    今天在使用单独Process的Service(android:process,如果没有此attr就不会)时,发现该Serivce的启动会使得AndroidManifest中包裹此Service的Application再构造一个出来,想了想也合理,因为每个Application都对应一个Process,那么对于单独Process的service来说,是一个新进程,那么是需要构造出......
  • Android handler src track
    HandlerThread是真正干活的,本身就是一个Thread:HandlerThreadextendsThread主要比普通的Thread多了一个Looper,而hanlderThread的run函数其实很简单:@Overridepublicvoidrun(){mTid=Process.myTid();Looper.prepare();这一步就生了......
  • Android开发 UsageStatsManager应用使用情况管理
    前言  UsageStatsManager是用来知晓,设备中应用的使用情况的管理。它能给我们提供应用的进入前台动作与时间戳、进入后台的动作与时间戳、上次的使用时间、使用总时长等等信息。此功能在原生的设置-应用-使用统计中有所展示。所需权限<uses-permissionandroid:name="android.......
  • Android平台GB28181设备接入模块如何实现实时视频和本地录像双码流编码
    ​技术背景我们在做Android平台GB28181设备接入模块的时候,遇到这样的场景,比如执法记录仪或智慧工地等场景下,由于GB28181设备接入模块,注册到国标平台后,平时只是心跳保持,或还有实时位置订阅,查看视频的时候,是按需看,而且有时候,网络环境并不是太好,所以,催生了这样一个诉求:部分开发者希......
  • 图解LeetCode——904. 水果成篮(难度:中等)
    一、题目你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组fruits表示,其中fruits[i]是第i棵树上的水果种类。你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:你只有两个篮子,并且每个篮子只能装单一类型的水果......