动态修改屏分辨率
发布日期:2021-06-29 14:50:57 浏览次数:3 分类:技术文章

本文共 11283 字,大约阅读时间需要 37 分钟。

现成的 ADB 命令为:

wm size 1920x1280 ----> 这个 ADB 修改分辨率
wm density 240 ----> 这个 修改dpi

dpi 计算公式: ( √(x^2 + y^2) ) / 屏幕尺寸

其实 wm 调用的就 是 上层 WindowsManger.java 的方法,最终调用到 Framework 下的 WindowsManagerServices.java 代码。

如果上层想对 分辨率修改,可以重写 WindowsManagerServices.java 下的set 分辨率的方法。
这种方法也是最稳妥的办法。

wm 执行log 如下:

px30_evb:/ # wm size 640x480 logcat 如下:10-12 08:05:46.995  1727  1727 D AndroidRuntime: Calling main entry com.android.commands.wm.Wm10-12 08:05:47.001   396   408 I WindowManager: Using new display size: 640x480

如果在驱动中写死的话,一般不建议这样修改,容易出问题:

高通平台:

--- a/kernel/msm-3.18/drivers/video/msm/mdss/mdss_fb.c+++ b/kernel/msm-3.18/drivers/video/msm/mdss/mdss_fb.c@@ -2501,8 +2501,8 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)        else                fix->line_length = var->xres * bpp; -       var->xres_virtual = var->xres;-       var->yres_virtual = panel_info->yres * mfd->fb_page;+       var->xres_virtual = 1920;	//var->xres;+       var->yres_virtual = 1080 * mfd->fb_page;        var->bits_per_pixel = bpp * 8;  /* FrameBuffer color depth */         /*@@ -3410,8 +3410,8 @@ void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, {        u32 frame_rate; -       var->xres = mdss_fb_get_panel_xres(pinfo);-       var->yres = pinfo->yres;+       var->xres = 1920;		//mdss_fb_get_panel_xres(pinfo);+       var->yres = 1080;		//pinfo->yres;        var->lower_margin = pinfo->lcdc.v_front_porch -                pinfo->prg_fet;        var->upper_margin = pinfo->lcdc.v_back_porch +

rockchip 平台

参考:

@ kernel\drivers\video\fbdev\core\modedb.c/** * fb_videomode_to_var - convert fb_videomode to fb_var_screeninfo * @var: pointer to struct fb_var_screeninfo * @mode: pointer to struct fb_videomode */void fb_videomode_to_var(struct fb_var_screeninfo *var,			 const struct fb_videomode *mode){
var->xres = mode->xres; var->yres = mode->yres; var->xres_virtual = mode->xres; var->yres_virtual = mode->yres; var->xoffset = 0; var->yoffset = 0; var->pixclock = mode->pixclock; var->left_margin = mode->left_margin; var->right_margin = mode->right_margin; var->upper_margin = mode->upper_margin; var->lower_margin = mode->lower_margin; var->hsync_len = mode->hsync_len; var->vsync_len = mode->vsync_len; var->sync = mode->sync; var->vmode = mode->vmode & FB_VMODE_MASK;}
@ kernel\drivers\video\rockchip\rk_fb.cint rk_fb_register(struct rk_lcdc_driver *dev_drv,		   struct rk_lcdc_win *win, int id){
struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev); struct fb_info *fbi; struct rk_fb_par *fb_par = NULL; int i = 0, ret = 0, index = 0; unsigned long flags; char time_line_name[16]; int mirror = 0; if (rk_fb->num_lcdc == RK30_MAX_LCDC_SUPPORT) return -ENXIO; for (i = 0; i < RK30_MAX_LCDC_SUPPORT; i++) {
if (!rk_fb->lcdc_dev_drv[i]) {
rk_fb->lcdc_dev_drv[i] = dev_drv; rk_fb->lcdc_dev_drv[i]->id = id; rk_fb->num_lcdc++; break; } } index = i; init_lcdc_device_driver(rk_fb, win, index); dev_drv->fb_index_base = rk_fb->num_fb; for (i = 0; i < dev_drv->lcdc_win_num; i++) {
fbi = framebuffer_alloc(0, &fb_pdev->dev); if (!fbi) {
dev_err(&fb_pdev->dev, "fb framebuffer_alloc fail!"); return -ENOMEM; } fb_par = devm_kzalloc(&fb_pdev->dev, sizeof(struct rk_fb_par), GFP_KERNEL); if (!fb_par) {
dev_err(&fb_pdev->dev, "malloc fb_par for fb%d fail!", rk_fb->num_fb); return -ENOMEM; } fb_par->id = rk_fb->num_fb; fb_par->lcdc_drv = dev_drv; fbi->par = (void *)fb_par; fbi->var = def_var; fbi->fix = def_fix; sprintf(fbi->fix.id, "fb%d", rk_fb->num_fb); fb_videomode_to_var(&fbi->var, &dev_drv->cur_screen->mode); if (dev_drv->dsp_mode == ONE_VOP_DUAL_MIPI_VER_SCAN) {
fbi->var.xres /= 2; fbi->var.yres *= 2; fbi->var.xres_virtual /= 2; fbi->var.yres_virtual *= 2; } fbi->var.width = dev_drv->cur_screen->width; fbi->var.height = dev_drv->cur_screen->height; fbi->var.grayscale |= ((fbi->var.xres & 0xfff) << 8) + (fbi->var.yres << 20); fbi->var.reserved[0] |= (fbi->var.xres >> 12);#if defined(CONFIG_LOGO_LINUX_BMP) fbi->var.bits_per_pixel = 32;#else fbi->var.bits_per_pixel = 16;#endif fbi->fix.line_length = (fbi->var.xres_virtual) * (fbi->var.bits_per_pixel >> 3); if (dev_drv->iommu_enabled) fb_ops.fb_mmap = rk_fb_mmap; fbi->fbops = &fb_ops; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->pseudo_palette = dev_drv->win[i]->pseudo_pal; ret = register_framebuffer(fbi); if (ret < 0) {
dev_err(&fb_pdev->dev, "%s fb%d register_framebuffer fail!\n", __func__, rk_fb->num_fb); return ret; } rkfb_create_sysfs(fbi); rk_fb->fb[rk_fb->num_fb] = fbi; dev_info(fbi->dev, "rockchip framebuffer registerd:%s\n", fbi->fix.id); rk_fb->num_fb++; if (i == 0) {
init_waitqueue_head(&dev_drv->vsync_info.wait); init_waitqueue_head(&dev_drv->update_regs_wait); ret = device_create_file(fbi->dev, &dev_attr_vsync); if (ret) dev_err(fbi->dev, "failed to create vsync file\n"); dev_drv->vsync_info.thread = kthread_run(rk_fb_wait_for_vsync_thread, dev_drv, "fb-vsync"); if (dev_drv->vsync_info.thread == ERR_PTR(-ENOMEM)) {
dev_err(fbi->dev, "failed to run vsync thread\n"); dev_drv->vsync_info.thread = NULL; } dev_drv->vsync_info.active = 1; mutex_init(&dev_drv->output_lock); INIT_LIST_HEAD(&dev_drv->update_regs_list); INIT_LIST_HEAD(&dev_drv->saved_list); mutex_init(&dev_drv->update_regs_list_lock); init_kthread_worker(&dev_drv->update_regs_worker); dev_drv->update_regs_thread = kthread_run(kthread_worker_fn, &dev_drv->update_regs_worker, "rk-fb"); if (IS_ERR(dev_drv->update_regs_thread)) {
int err = PTR_ERR(dev_drv->update_regs_thread); dev_drv->update_regs_thread = NULL; pr_info("failed to run update_regs thread\n"); return err; } init_kthread_work(&dev_drv->update_regs_work, rk_fb_update_regs_handler); snprintf(time_line_name, sizeof(time_line_name), "vop%d-timeline", id); dev_drv->timeline = sw_sync_timeline_create(time_line_name); dev_drv->timeline_max = 1; } } /* show logo for primary display device */#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) if (dev_drv->prop == PRMRY) {
u16 xact, yact; int format; u32 dsp_addr; struct fb_info *main_fbi = rk_fb->fb[0]; main_fbi->fbops->fb_open(main_fbi, 1); main_fbi->var.pixclock = dev_drv->pixclock; if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev) rockchip_iovmm_set_fault_handler(dev_drv->dev, rk_fb_sysmmu_fault_handler); } rk_fb_alloc_buffer(main_fbi); /* only alloc memory for main fb */ dev_drv->uboot_logo = support_uboot_display(); if (dev_drv->uboot_logo && uboot_logo_offset && uboot_logo_base) {
int width, height, bits, xvir; phys_addr_t start = uboot_logo_base + uboot_logo_offset; unsigned int size = uboot_logo_size - uboot_logo_offset; unsigned int nr_pages; int ymirror = 0; struct page **pages; char *vaddr; int logo_len, i = 0; if (dev_drv->ops->get_dspbuf_info) dev_drv->ops->get_dspbuf_info(dev_drv, &xact, &yact, &format, &dsp_addr, &ymirror); logo_len = rk_fb_pixel_width(format) * xact * yact >> 3; nr_pages = size >> PAGE_SHIFT; pages = kzalloc(sizeof(struct page) * nr_pages, GFP_KERNEL); if (!pages) return -ENOMEM; while (i < nr_pages) {
pages[i] = phys_to_page(start); start += PAGE_SIZE; i++; } vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); if (!vaddr) {
pr_err("failed to vmap phy addr 0x%lx\n", (long)(uboot_logo_base + uboot_logo_offset)); kfree(pages); return -1; } if (bmpdecoder(vaddr, main_fbi->screen_base, &width, &height, &bits)) {
kfree(pages); vunmap(vaddr); return 0; } kfree(pages); vunmap(vaddr); if (width != xact || height != yact) {
pr_err("can't support uboot kernel logo use different size [%dx%d] != [%dx%d]\n", xact, yact, width, height); return 0; } xvir = ALIGN(width * bits, 1 << 5) >> 5; ymirror = 0; local_irq_save(flags); if (dev_drv->ops->wait_frame_start) dev_drv->ops->wait_frame_start(dev_drv, 0); mirror = ymirror || dev_drv->cur_screen->y_mirror; if (dev_drv->ops->post_dspbuf) {
dev_drv->ops->post_dspbuf(dev_drv, main_fbi->fix.smem_start + (mirror ? logo_len : 0), rk_fb_data_fmt(0, bits), width, height, xvir, ymirror); } if (dev_drv->iommu_enabled) {
rk_fb_poll_wait_frame_complete(); if (dev_drv->ops->mmu_en) dev_drv->ops->mmu_en(dev_drv); freed_index = 0; } local_irq_restore(flags); return 0; } else if (dev_drv->uboot_logo && uboot_logo_base) {
u32 start = uboot_logo_base; int logo_len, i = 0; int y_mirror = 0; unsigned int nr_pages; struct page **pages; char *vaddr; int align = 0, xvir; dev_drv->ops->get_dspbuf_info(dev_drv, &xact, &yact, &format, &start, &y_mirror); logo_len = rk_fb_pixel_width(format) * xact * yact >> 3; if (logo_len > uboot_logo_size || logo_len > main_fbi->fix.smem_len) {
pr_err("logo size > uboot reserve buffer size\n"); return -1; } if (y_mirror) start -= logo_len; align = start % PAGE_SIZE; start -= align; nr_pages = PAGE_ALIGN(logo_len + align) >> PAGE_SHIFT; pages = kzalloc(sizeof(struct page) * nr_pages, GFP_KERNEL); if (!pages) return -ENOMEM; while (i < nr_pages) {
pages[i] = phys_to_page(start); start += PAGE_SIZE; i++; } vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); if (!vaddr) {
pr_err("failed to vmap phy addr 0x%x\n", start); kfree(pages); return -1; } memcpy(main_fbi->screen_base, vaddr + align, logo_len); kfree(pages); vunmap(vaddr); xvir = ALIGN(xact * rk_fb_pixel_width(format), 1 << 5) >> 5; local_irq_save(flags); if (dev_drv->ops->wait_frame_start) dev_drv->ops->wait_frame_start(dev_drv, 0); mirror = y_mirror || dev_drv->cur_screen->y_mirror; dev_drv->ops->post_dspbuf(dev_drv, main_fbi->fix.smem_start + (mirror ? logo_len : 0), format, xact, yact, xvir, y_mirror); if (dev_drv->iommu_enabled) {
rk_fb_poll_wait_frame_complete(); if (dev_drv->ops->mmu_en) dev_drv->ops->mmu_en(dev_drv); freed_index = 0; } local_irq_restore(flags); return 0; } else {
if (dev_drv->iommu_enabled) {
if (dev_drv->ops->mmu_en) dev_drv->ops->mmu_en(dev_drv); freed_index = 0; } }#if defined(CONFIG_LOGO) main_fbi->fbops->fb_set_par(main_fbi);#if defined(CONFIG_LOGO_LINUX_BMP) if (fb_prewine_bmp_logo(main_fbi, FB_ROTATE_UR)) {
fb_set_cmap(&main_fbi->cmap, main_fbi); fb_show_bmp_logo(main_fbi, FB_ROTATE_UR); }#else if (fb_prepare_logo(main_fbi, FB_ROTATE_UR)) {
fb_set_cmap(&main_fbi->cmap, main_fbi); fb_show_logo(main_fbi, FB_ROTATE_UR); }#endif main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi);#endif } else {
struct fb_info *extend_fbi = rk_fb->fb[dev_drv->fb_index_base]; extend_fbi->var.pixclock = rk_fb->fb[0]->var.pixclock; if (rk_fb->disp_mode == DUAL_LCD) {
extend_fbi->fbops->fb_open(extend_fbi, 1); if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev) rockchip_iovmm_set_fault_handler(dev_drv->dev, rk_fb_sysmmu_fault_handler); } rk_fb_alloc_buffer(extend_fbi); } }#endif return 0;}

转载地址:https://ciellee.blog.csdn.net/article/details/102583694 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:理解 Audio 音频系统三 之 [2] AudioFlinger --- AudioThread
下一篇:C++ 实现Buffer 动态分配管理,FIFO模式存取数据

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月08日 18时17分30秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章