当前位置: 代码网 > it编程>App开发>Android > Android10处理Android字样开机动画翻转一次的问题

Android10处理Android字样开机动画翻转一次的问题

2024年08月02日 Android 我要评论
An10 处理Android字样开机动画播放时翻转问题


一、背景说明

  • 系统版本:android 10(q)
  • 厂商:高通
  • 问题描述:系统开机出现android资源动画时翻转一次,先倒屏再正屏
    android

二、分析及解决

1、检查persist.panel.orientation

从现象来看是android动画播放时屏幕方向发生了改变,于是检查屏幕方向关联属性persist.panel.orientation

$getprop persist.panel.orientation
90   //我的设备90°为正屏,270°为倒屏

再检查system.prop

$cat system/build.prop
...
persist.panel.orientation=90
...

说明方向属性没毛病

2、代码分析

android字样图片资源位于:
frameworks\base\core\res\assets\images\android-logo-mask.png
frameworks\base\core\res\assets\images\android-logo-shine.png
frameworks\base\core\res\assets\images\clock_font.png
android字样开机动画显示代码实现位于:
frameworks\base\cmds\bootanimation\bootanimation.cpp

bool bootanimation::threadloop()
{
    bool r;
    // we have no bootanimation file, so we use the stock android logo
    // animation.
    if (mzipfilename.isempty()) {
        r = android();    //android字样动画
    } else {
        r = movie();    //zip开机帧动画
    }
    ...
}
...
bool bootanimation::android()
{
    slogd("%sanimationshowntiming start time: %" prid64 "ms", mshuttingdown ? "shutdown" : "boot",
            elapsedrealtime());
    inittexture(&mandroid[0], massets, "images/android-logo-mask.png");
    inittexture(&mandroid[1], massets, "images/android-logo-shine.png");

    mcallbacks->init({});

    // clear screen  清除屏幕
    glshademodel(gl_flat);
    gldisable(gl_dither);
    gldisable(gl_scissor_test);
    glclearcolor(0,0,0,1);
    glclear(gl_color_buffer_bit);
    eglswapbuffers(mdisplay, msurface);

    glenable(gl_texture_2d);
    gltexenvx(gl_texture_env, gl_texture_env_mode, gl_replace);

    const glint xc = (mwidth  - mandroid[0].w) / 2;
    const glint yc = (mheight - mandroid[0].h) / 2;
    const rect updaterect(xc, yc, xc + mandroid[0].w, yc + mandroid[0].h);

    glscissor(updaterect.left, mheight - updaterect.bottom, updaterect.width(),
            updaterect.height());

    // blend state
    glblendfunc(gl_src_alpha, gl_one_minus_src_alpha);
    gltexenvx(gl_texture_env, gl_texture_env_mode, gl_replace);

    const nsecs_t starttime = systemtime();
    do {
        nsecs_t now = systemtime();
        double time = now - starttime;
        float t = 4.0f * float(time / us2ns(16667)) / mandroid[1].w;
        glint offset = (1 - (t - floorf(t))) * mandroid[1].w;
        glint x = xc - offset;

        gldisable(gl_scissor_test);
        glclear(gl_color_buffer_bit);

        glenable(gl_scissor_test);
        gldisable(gl_blend);
        glbindtexture(gl_texture_2d, mandroid[1].name);
        gldrawtexioes(x,                 yc, 0, mandroid[1].w, mandroid[1].h);
        gldrawtexioes(x + mandroid[1].w, yc, 0, mandroid[1].w, mandroid[1].h);

        glenable(gl_blend);
        glbindtexture(gl_texture_2d, mandroid[0].name);
        gldrawtexioes(xc, yc, 0, mandroid[0].w, mandroid[0].h);

        eglboolean res = eglswapbuffers(mdisplay, msurface);
        if (res == egl_false)
            break;

        // 12fps: don't animate too fast to preserve cpu
        const nsecs_t sleeptime = 83333 - ns2us(systemtime() - now);
        if (sleeptime > 0)
            usleep(sleeptime);

        checkexit();
    } while (!exitpending());

    gldeletetextures(1, &mandroid[0].name);
    gldeletetextures(1, &mandroid[1].name);
    return false;
}

分析android播放实现未找到与屏幕方向旋转相关的代码,于是搜索persist.panel.orientation

status_t bootanimation::readytorun() {
    //add by xxf
    char value[property_value_max];
    property_get("persist.panel.orientation", value,"0");  //从属性persist.panel.orientation获取屏幕方向
    int orient= atoi(value) / 90;
    if(orient== 1 || orient == 3) {
        is_land = true;//横屏显示,正屏或倒屏
    }
    //add by xxf
    massets.adddefaultassets();

    mdisplaytoken = surfacecomposerclient::getinternaldisplaytoken();
    if (mdisplaytoken == nullptr)
        return -1;

    displayinfo dinfo;
    status_t status = surfacecomposerclient::getdisplayinfo(mdisplaytoken, &dinfo);
    if (status)
        return -1;

    //add by xxf
    // create the native surface
    sp<surfacecontrol> control;
    if(is_land){
         control= session()->createsurface(string8("bootanimation"),
            dinfo.h, dinfo.w, pixel_format_rgb_565);
    }else{
         control = session()->createsurface(string8("bootanimation"),
            dinfo.w, dinfo.h, pixel_format_rgb_565);
    }
    surfacecomposerclient::transaction t;
    if(is_land){
        t.setdisplayprojection(mdisplaytoken, displaystate::eorientation270, rect(dinfo.h, dinfo.w), rect(dinfo.h, dinfo.w));  //设置显示参数
        t.apply();
    }
    //add by xxf
 ...
}

从这里可以看出,屏幕方向强行设置为了270°,故倒屏了,再后续流程中拿到了正确的orientation故又正屏了,改动如下:

if(is_land){
        //modify start by mart!nhu to correct oriention in bootanimation
        //t.setdisplayprojection(mdisplaytoken, displaystate::eorientation270, rect(dinfo.h, dinfo.w), rect(dinfo.h, dinfo.w));
        t.setdisplayprojection(mdisplaytoken, orient == displaystate::eorientation90 ? displaystate::eorientation90 : displaystate::eorientation270, rect(dinfo.h, dinfo.w), rect(dinfo.h, dinfo.w));
        //modify end by mart!nhu to correct oriention in bootanimation
        t.apply();
    }

3、措施验证

编译bootanimation模块

mmm frameworks/base/cmds/bootanimation/

将生成的libbootanimation.so替换至平台中,并重启

adb root;adb remount;adb push \\wsl$\ubuntu-18.04\home\mart!nhu\aosp_an10\out\target\product\xxx\obj\shared_libraries\libbootanimation_intermediates\libbootanimation.so system/lib64/libbootanimation.so;adb shell sync;adb reboot

验证ok,设置270° 验证同样显示正常

开机android动画,zip帧动画,视频具体播放实现待有空了再梳理下,敬请期待~

总结

通过问题现象首先排除系统属性是否异常,确认无误后检查代码实现流程,关注屏幕方向的关键参数设置,中间可埋log定位。最终导入措施,替换so文件验证有效。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com