android返回后屏幕旋转了,Android recovery 模式下屏幕显示旋转

Android recovery 模式下屏幕显示旋转

大家在网上搜索 Android屏幕旋转,成千上万的文章,但是没有几个是写recovery 模式的。难道你们只旋转正常模式下的屏幕方向,不管recovery模式,那升级的画面岂不是有问题。

很对人使用的是MTK平台,对与MTK平台,MTK已经帮你做好了,你只用修改一下配置就行了。

MTK平台我们可以在bootable/recovery/minui/mt_graphic_rotate.cpp 清晰的看到下面的代码:

#ifndef MTK_LCM_PHYSICAL_ROTATION

#define MTK_LCM_PHYSICAL_ROTATION "undefined"

#endif

static int rotate_config(GRSurface *gr_draw)

{

if (rotate_index<0)

{

if (gr_draw->pixel_bytes != 4) rotate_index=0; // support 4 bytes pixel only

else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) rotate_index=1;

else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3)) rotate_index=2;

else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) rotate_index=3;

else rotate_index=0;

printf("[graphics] rotate_config %d %s\n", rotate_index, MTK_LCM_PHYSICAL_ROTATION);

}

return rotate_index;

}

已经很清楚了,只需要修改 MTK_LCM_PHYSICAL_ROTATION 这个宏就可以了。这是MTK已经改造过的recovery 。

那么其他一些平台 并没有想MTK平台这样,帮你改造好了。比如RK平台,我在RK的代码里只发现了,一个旋转180度的配置,那我要旋转270度怎么办。那就需要自己去看代码了。

recovery 模式 是直接操作 dev目录下的 fb ,如果对这种操作不熟悉的同学需要去补课,不然可能会看不懂我接下来说的。

在 bootable/recovery/minui/graphics_fbdev.c 我们可以看到下面的代码。

static gr_surface fbdev_init(minui_backend* backend) {

int fd;

void *bits;

int tmp = 0;

struct fb_fix_screeninfo fi;

fd = open("/dev/graphics/fb0", O_RDWR);

if (fd < 0) {

perror("cannot open fb0");

return NULL;

}

if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {

perror("failed to get fb0 info");

close(fd);

return NULL;

}

if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {

perror("failed to get fb0 info");

close(fd);

return NULL;

}

//这里是我添加的,调换 高度 和 宽度

#ifdef RotateScreen_270

tmp = vi.xres;

vi.xres = vi.yres;

vi.yres = tmp;

#endif

vi.red.offset = 0;

vi.red.length = 8;

vi.green.offset = 8;

vi.green.length = 8;

vi.blue.offset = 16;

vi.blue.length = 8;

vi.transp.offset = 24;

vi.transp.length = 8;

vi.bits_per_pixel = 32;

vi.nonstd = 2;

bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if (bits == MAP_FAILED) {

perror("failed to mmap framebuffer");

close(fd);

return NULL;

}

memset(bits, 0, fi.smem_len);

gr_framebuffer[0].width = vi.xres;

gr_framebuffer[0].height = vi.yres;

gr_framebuffer[0].row_bytes = vi.xres * 4;

gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;

gr_framebuffer[0].data = bits;

memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes);

}

我们看到了 “/dev/graphics/fb0”,相信很多人知道这是什么,这是video buffer,那么所有的 width、height、pixel_bytes、这些信息都来自与内核。而且用到了mmap,我们关心的屏幕相关信息都在这里。我们关心 gr_framebuffer[0].data = bits;,不了解 mmap的同学,请查看其他资料。这个文件里的很多方法,例如 fbdev_init(),fbdev_flip(),返回值都是gr_framebuffer, 其他文件都是调用这两个个方法,获取 gr_framebuffer,然后在上面作画。

那么我的方法就很简单了,我再构造一个 GRSurface,然后设置参数,在fbdev_init(),fbdev_flip(),方法里返回我自己增加的 这个GRSurface。

那么 就会在 我 增加的 这个 GRSurface 上面作画,

然后在 fbdev_flip 中 做画面的旋转,为什么要旋转呢,比如我的屏幕内核里面读出来的是 1024x768,我在fbdev_init,中调换了高和宽,fbdev_init(),fbdev_flip(),返回的 GRSurface 都是 768x1024的,其他文件也会认为屏幕就是768x1024的,所以生成的画面都是在768x1024的 GRSurface 中(也就是我新增的 GRSurface),但是这个buf是不可以直接传入内核的,为什么你们仔细想想,内核是1024x768的,这点并没有改变,所以我们要把这个画面转成内核可以使用的。

void rk_rotate_surface_90(GRSurface* surface,GRSurface* src) {

GGLuint width = surface->width;

GGLuint height = surface->height;

int byt = 4; // 4 byte for ARGB_8888 (2 byte for RGB_565)

int length = width * height;

GGLubyte* des_data = malloc(sizeof(GGLubyte)*length*byt);

memcpy(des_data,src->data,src->height * src->row_bytes);

memset(surface->data, 0, sizeof(GGLubyte)*length*byt);

int i = 0;

int j = 0;

for(i = 0;i < width;i++){

for(j = 0;j < height;j++) {

surface->data[((width-1-i)*height +j)*byt] = des_data[(j*width + i)*byt];

surface->data[((width-1-i)*height +j)*byt+1] = des_data[(j*width + i)*byt+1];

surface->data[((width-1-i)*height +j)*byt+2] = des_data[(j*width + i)*byt+2];

surface->data[((width-1-i)*height +j)*byt+3] = des_data[(j*width + i)*byt+3];

}

}

free(des_data);

}

static gr_surface fbdev_flip(minui_backend* backend __unused) {

#ifdef RotateScreen_270

rk_rotate_surface_270(gr_draw,subx_draw);

#endif

}

static void set_displayed_framebuffer(unsigned n)

{

int tmp;

if (n > 1 || !double_buffered) return;

vi.yres_virtual = gr_framebuffer[0].height * 2;

vi.yoffset = n * gr_framebuffer[0].height;

vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;

#ifdef RotateScreen_270

tmp = vi.xres;

vi.xres = vi.yres;

vi.yres = tmp;

vi.yres_virtual = gr_framebuffer[0].width * 2;

vi.yoffset = n * gr_framebuffer[0].width;

#endif

if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {

perror("active fb swap failed");

}

if (ioctl(fb_fd,RK_FBIOSET_CONFIG_DONE, NULL) < 0) {

perror("set config done failed");

}

displayed_buffer = n;

#ifdef RotateScreen_270

tmp = vi.xres;

vi.xres = vi.yres;

vi.yres = tmp;

#endif

}

最后和内核交互的时候需要 修正 参数,交互完成后再修改成我们需要的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值