MTK 开机第二张 logo 显示流程汇总

前言

代码流程汇总

流程

【第一张 logo 显示在 lk 启动流程中介绍】

【第二张 logo 初始化显示位置】:
Z:\work\E260L_CMCC_0919_eng\device\mediatek\mt6755\init.mt6755.rc
    # Update the second boot logo
    service bootlogoupdater /vendor/bin/boot_logo_updater
        class core
        oneshot
    
    /////////////////////////////////////////////////////////////////////////////
    // vendor\mediatek\proprietary\external\boot_logo_updater\boot_logo_updater.c
    main(void)
        // 获得启动模式,即启动的原因,并设置相应的属性节点值
        int ret = update_boot_reason();
                    fd = open(BOOT_MODE_PATH, O_RDWR);                          // /sys/class/BOOT/BOOT/boot/boot_mode
                    s = read(fd, (void *)&boot_mode, sizeof(boot_mode));
                    property_get(BOOT_PACKAGE_SYS_PROPERTY, propVal, "0");      // sys.boot.reason"
                    property_set(BOOT_REASON_SYS_PROPERTY, propVal);            // persist.sys.bootpackage
        
        // 设置背光亮度
        set_int_value(LCD_BACKLIGHT_PATH, 120);                                 // /sys/class/leds/lcd-backlight/brightness
                    write_to_file(path, buf, strlen(buf));    
                            int fd = open(path, O_RDWR);
                            int count = write(fd, buf, size);
                            close(fd);
        
        // 都不在文件中了:查看 Android.mk 
        // LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libshowlogo/
        // 最终此文件中找到了对应的函数实现,代码路径为:
        //      vendor\mediatek\proprietary\external\libshowlogo
        set_draw_mode(DRAW_ANIM_MODE_FB);
                    //Charging_animation.cpp
                    set_draw_mode(int draw_mode)
                        // 设置显示模式全局变量,有两种显示模式
                        // #define DRAW_ANIM_MODE_FB       1
                        // #define DRAW_ANIM_MODE_SURFACE  0
                        draw_anim_mode = draw_mode;
        
        // 获得对应平台的 fstab 文件,获得 logo.img 挂载位置,然后读取 logo 
        // 然后初始化显示设备,有两种显示方式:
        //      1. 直接在 fb 内核中显示
        //      2. 在 surface 中显示 
        anim_init();
                    //Charging_animation.cpp            
                    anim_init()
                        // 获得对应平台的 fstab 文件,然后获得其挂载分区 /logo 
                        // 读取对应的 logo 镜像文件
                        anim_logo_init();
                                int ret = property_get("ro.hardware", propbuf, "");
                                snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
                                fstab = fs_mgr_read_fstab(fstab_filename);
                                rec = fs_mgr_get_entry_for_mount_point(fstab, LOGO_MNT_POINT);
                                fd = open(rec->blk_device, O_RDONLY);
                                logo_addr = (unsigned int*)malloc(LOGO_BUFFER_SIZE);
                                // (1) skip the image header
                                len = read(fd, logo_addr, 512);
                                // get the image
                                len = read(fd, logo_addr, LOGO_BUFFER_SIZE - 512);
                                close(fd);
    
                        // 1. 在 fb 中显示 logo                
                        if (draw_anim_mode == (DRAW_ANIM_MODE_FB)) {
                            anim_fb_init();
                                    // 打开 fb0, 
                                    fb_fd = open(FB_NODE_PATH, O_RDWR);
                                    
                                    // 获得屏相关的信息参数
                                    ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);
                                    ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);
                                    
                                    // 将显示屏映射到进程的地址空间中
                                    fb_size  = finfo.line_length * vinfo.yres;
                                    dec_logo_addr = (unsigned int*) malloc(fb_size);
                                    lk_fb_addr =(unsigned int*)mmap(0, fb_size*3, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
                                    charging_fb_addr = (unsigned int*)((unsigned int)lk_fb_addr + fb_size);
                                    kernel_fb_addr = (unsigned int*)((unsigned int)charging_fb_addr + fb_size);
                                    fb_addr = lk_fb_addr;
                                    
                                    // 设置本地的屏的相关参数
                                    phical_screen.bits_per_pixel = vinfo.bits_per_pixel;
                                    phical_screen.fill_dst_bits = vinfo.bits_per_pixel;
                                    phical_screen.red_offset = vinfo.red.offset;
                                    phical_screen.blue_offset = vinfo.blue.offset;
                                    phical_screen.width = vinfo.xres;
                                    phical_screen.height = vinfo.yres;
                                    phical_screen.allignWidth = finfo.line_length/(vinfo.bits_per_pixel/8);
                                    phical_screen.needAllign = 1;
                                    phical_screen.need180Adjust = 1;
                                    phical_screen.fb_size = fb_size;
                                    
                                    // 设置旋转参数
                                    if(0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3))
                                        。。。
                                        phical_screen.rotation = 270;
                                    
                        // 2. 在 surface 中显示 logo 初始化
                        } else {
                            anim_surface_init();
                                    surfaceControl = client->createSurface(String8("charging-surface"), dinfo_width,  dinfo_height, PIXEL_FORMAT_BGRA_8888);
                                    SurfaceComposerClient::openGlobalTransaction();
                                    surfaceControl->setLayer(2000000);
                                    SurfaceComposerClient::closeGlobalTransaction();
                                    
                                    // data structure to access surface content
                                    surface = surfaceControl->getSurface();
                                    phical_screen.width = dinfo.w;
                                    phical_screen.height = dinfo.h;
                                    
                                    // for we adjust the roration avove, so no need to consider rotation
                                    phical_screen.rotation = 0;
                                    phical_screen.need180Adjust = 0;
                                                                    
                                    ANativeWindow* window = surface.get();
                                    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_CPU);
                                    err = window->dequeueBuffer(window, &buf, &fenceFd);
                                    sp<Fence> mFence(new Fence(fenceFd));
                                    mFence->wait(Fence::TIMEOUT_NEVER);
                                    gb = new GraphicBuffer(buf, false);
                                    phical_screen.needAllign = 1;
                                    phical_screen.allignWidth = gb->getStride();
                                    window->cancelBuffer(window, buf, fenceFd);
                                    // use PIXEL_FORMAT_RGBA_8888 for surface flinger
                                    phical_screen.bits_per_pixel = 32;
                                    phical_screen.fill_dst_bits = 32;
                                    fb_size  = dinfo.w * dinfo.h* 4;
                                    dec_logo_addr = malloc(fb_size);
                                    phical_screen.fb_size = fb_size;
                                                                
                        }
                    
        // 显示 logo, 其实就是
        //      1. 从 logo.img 中读出对应的 logo 
        //      2. 将 logo 填充到显示缓冲区中即可
        show_kernel_logo();
                anim_show_logo(kernel_logo_position);       // 此参数为 kernel logo 在 logo.img 中的 index  ,static int kernel_logo_position = KERNEL_LOGO_INDEX ;
                        if (draw_anim_mode == (DRAW_ANIM_MODE_FB)) {
                            anim_set_buffer_address(index);
                            fill_animation_logo(index, fb_addr, dec_logo_addr, logo_addr,phical_screen);        // 显示图片
                            anim_fb_disp_update();
                         } else {
                            ARect tmpRect;
                            tmpRect.left = 0;
                            tmpRect.top = 0;
                            tmpRect.right = phical_screen.width;
                            tmpRect.bottom = phical_screen.height;

                            status_t  lockResult = surface->lock(&outBuffer, &tmpRect);

                            SLOGD("[libshowlogo: %s %d]outBuffer.bits = %d\n",__FUNCTION__,__LINE__, (int)outBuffer.bits);
                            SLOGD("[libshowlogo: %s %d]surface->lock return =  0x%08x,  %d\n",__FUNCTION__,__LINE__,lockResult,lockResult);
                            if (0 == lockResult)
                            {
                                fill_animation_logo(index, (void *)outBuffer.bits, dec_logo_addr, logo_addr,phical_screen);// 显示图片
                                surface->unlockAndPost();
                            }
                         }
        // 相关资源的释放        
        anim_deinit();   
                anim_logo_deinit();
                        free_fstab();
                        free(logo_addr);
                        logo_addr = NULL;
                        free(dec_logo_addr);
                if (draw_anim_mode == (DRAW_ANIM_MODE_FB)) {
                    anim_fb_deinit();
                        munmap(lk_fb_addr, fb_size*3);
                        close(fb_fd);
                } else {
                    anim_surface_deinit();
                            surface = surfaceControl->getSurface();
                            ANativeWindow* window = surface.get();
                            native_window_api_disconnect(window,NATIVE_WINDOW_API_CPU);
                            surfaceControl->clear();
                            client->dispose();
                }

猜你喜欢

转载自blog.csdn.net/wangjun7121/article/details/88141248
MTK
今日推荐