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
}
最后和內核交互的時候需要 修正 參數,交互完成后再修改成我們需要的參數。
總結
以上是生活随笔為你收集整理的android返回后屏幕旋转了,Android recovery 模式下屏幕显示旋转的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为p50预计售价鸿蒙是什么,华为P50
- 下一篇: 孑孓怎么读?