|
【技术分享】Lubuntu分辨率自适应
发表于 2016-6-17 17:17:48
浏览:42918
|
回复:13
打印
只看该作者
[复制链接]
楼主
本帖最后由 hongyin 于 2016-6-17 17:20 编辑
好久没发帖了,近期工作太忙,所以自适应(基于VGA)的整理迟迟没有更新,今天先来无事,所以把之前的研究成果拿出来供大家参考,如有问题,可以发我邮箱(iamphy@qq.com)进行交流,废话少说,谈正事。
首先,请先下载附件,该文件并非压缩包,下载后直接将后缀名改成.c即可,并将该文件cp到相应目录:kernel/drivers/video/rockchip/lcdc下,该文件修复了1440x900和1366x768两种分辨率的异常(兼容性有待考证),还有就是RGB颜色问题;准备工作做好之后,自行编译内核进行烧写;
然后,下面的代码便是自动适配分辨率的,这是一个单独的程序,需要各位网友自行cp进行编译,编译完成之后,只需要将执行路径添加到/etc/rc.local文件即可;若网友发现有问题,请邮件相互交流。
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <linux/fb.h>
- #define NUM_BUFFERS 2
- #define RK_FBIOSET_CLEAR_FB 0x4633
- #if 0
- #define DEBUG_P(format, ...) printf(format, ##__VA_ARGS__)
- #else
- #define DEBUG_P(format, ...)
- #endif
- int main(int argc, char *argv[])
- {
- FILE *fp = fopen("/sys/class/graphics/fb0/screen_info", "r");
- if(fp == NULL)
- {
- perror("fopen err:");
- return -1;
- }
- int xres = 0;
- int yres = 0;
- char line1[64] = {0};
- char line2[64] = {0};
- fgets(line1, sizeof(line1), fp);
- fgets(line2, sizeof(line2), fp);
- sscanf(line1, "xres:%d\n", &xres);
- sscanf(line2, "yres:%d\n", &yres);
- fclose(fp);
- DEBUG_P("read x:%d, y:%d\n", xres, yres);
- int fd = open("/dev/fb0", O_RDWR, 0);
- if (fd < 0)
- {
- fprintf(stderr, "No fb devices found!\n");
- return -errno;
- }
- struct fb_fix_screeninfo finfo;
- if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
- {
- close(fd);
- return -errno;
- }
- struct fb_var_screeninfo info;
- if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
- {
- close(fd);
- return -errno;
- }
- info.reserved[0] = 0;
- info.reserved[1] = 0;
- info.reserved[2] = 0;
- info.xoffset = 0;
- info.yoffset = 0;
- info.width = xres;
- info.height = yres;
- info.xres = xres;
- info.yres = yres;
- info.xres_virtual = info.xres;
- info.yres_virtual = info.yres * NUM_BUFFERS;
- info.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
- info.bits_per_pixel = 32;
- info.red.offset = 16;
- info.red.length = 8;
- info.green.offset = 8;
- info.green.length = 8;
- info.blue.offset = 0;
- info.blue.length = 8;
- info.transp.offset = 0;
- info.transp.length = 0;
- info.grayscale &= 0xff;
- info.grayscale |= (info.xres<<8) + (info.yres<<20);
- info.nonstd &= 0xffffff00;
- info.nonstd |= 2;//HAL_PIXEL_FORMAT_RGBX_8888;
- ioctl(fd, RK_FBIOSET_CLEAR_FB, NULL);
- if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
- {
- perror("FBIOPUT_VSCREENINFO failed");
- close(fd);
- return -errno;
- }
- if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
- {
- fprintf(stderr, "FBIOGET_VSCREENINFO failed.\n");
- close(fd);
- return -errno;
- }
- int refreshRate = 0;
- if ( info.pixclock > 0 )
- {
- refreshRate = 1000000000000000LLU / ((uint64_t)
- (info.upper_margin + info.lower_margin + info.yres + info.hsync_len ) *
- (info.left_margin + info.right_margin + info.xres + info.vsync_len ) *
- info.pixclock);
- if (refreshRate == 0)
- {
- refreshRate = 60*1000; // 60 Hz
- }
- }
- if ((int)(info.width) <= 0 || (int)(info.height) <= 0)
- {
- // the driver doesn't return that information
- // default to 160 dpi
- info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
- info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
- }
- float xdpi = (info.xres * 25.4f) / info.width;
- float ydpi = (info.yres * 25.4f) / info.height;
- float fps = refreshRate / 1000.0f;
- DEBUG_P("using (fd=%d)\n"
- "id = %s\n"
- "xres = %d px\n"
- "yres = %d px\n"
- "xres_virtual = %d px\n"
- "yres_virtual = %d px\n"
- "bpp = %d\n"
- "r = %2u:%u\n"
- "g = %2u:%u\n"
- "b = %2u:%u\n"
- "format = %d\n",
- fd,
- finfo.id,
- info.xres,
- info.yres,
- info.xres_virtual,
- info.yres_virtual,
- info.bits_per_pixel,
- info.red.offset, info.red.length,
- info.green.offset, info.green.length,
- info.blue.offset, info.blue.length,
- info.nonstd);
- DEBUG_P("width = %d mm (%f dpi)\n"
- "height = %d mm (%f dpi)\n"
- "refresh rate = %.2f Hz\n",
- info.width, xdpi,
- info.height, ydpi,
- fps);
- int videodata[2];
- videodata[1] = videodata[0] = finfo.smem_start;
- ioctl(fd, 0x5002, videodata);
- close(fd);
- return 0;
- }
复制代码
|
|