- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <linux/fb.h>
- #include <linux/kd.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <sys/time.h>
- #include <string.h>
- #include <errno.h>
- struct fb_var_screeninfo vinfo;
- struct fb_fix_screeninfo finfo;
- char *frameBuffer = 0;
- //打印fb驱动中fix结构信息,注:在fb驱动加载后,fix结构不可被修改。
- void
- printFixedInfo ()
- {
- printf ("Fixed screen info:\n"
- "\tid: %s\n"
- "\tsmem_start: 0x%lx\n"
- "\tsmem_len: %d\n"
- "\ttype: %d\n"
- "\ttype_aux: %d\n"
- "\tvisual: %d\n"
- "\txpanstep: %d\n"
- "\typanstep: %d\n"
- "\tywrapstep: %d\n"
- "\tline_length: %d\n"
- "\tmmio_start: 0x%lx\n"
- "\tmmio_len: %d\n"
- "\taccel: %d\n"
- "\n",
- finfo.id, finfo.smem_start, finfo.smem_len, finfo.type,
- finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep,
- finfo.ywrapstep, finfo.line_length, finfo.mmio_start,
- finfo.mmio_len, finfo.accel);
- }
- //打印fb驱动中var结构信息,注:fb驱动加载后,var结构可根据实际需要被重置
- void
- printVariableInfo ()
- {
- printf ("Variable screen info:\n"
- "\txres: %d\n"
- "\tyres: %d\n"
- "\txres_virtual: %d\n"
- "\tyres_virtual: %d\n"
- "\tyoffset: %d\n"
- "\txoffset: %d\n"
- "\tbits_per_pixel: %d\n"
- "\tgrayscale: %d\n"
- "\tred: offset: %2d, length: %2d, msb_right: %2d\n"
- "\tgreen: offset: %2d, length: %2d, msb_right: %2d\n"
- "\tblue: offset: %2d, length: %2d, msb_right: %2d\n"
- "\ttransp: offset: %2d, length: %2d, msb_right: %2d\n"
- "\tnonstd: %d\n"
- "\tactivate: %d\n"
- "\theight: %d\n"
- "\twidth: %d\n"
- "\taccel_flags: 0x%x\n"
- "\tpixclock: %d\n"
- "\tleft_margin: %d\n"
- "\tright_margin: %d\n"
- "\tupper_margin: %d\n"
- "\tlower_margin: %d\n"
- "\thsync_len: %d\n"
- "\tvsync_len: %d\n"
- "\tsync: %d\n"
- "\tvmode: %d\n"
- "\n",
- vinfo.xres, vinfo.yres, vinfo.xres_virtual, vinfo.yres_virtual,
- vinfo.xoffset, vinfo.yoffset, vinfo.bits_per_pixel,
- vinfo.grayscale, vinfo.red.offset, vinfo.red.length,
- vinfo.red.msb_right, vinfo.green.offset, vinfo.green.length,
- vinfo.green.msb_right, vinfo.blue.offset, vinfo.blue.length,
- vinfo.blue.msb_right, vinfo.transp.offset, vinfo.transp.length,
- vinfo.transp.msb_right, vinfo.nonstd, vinfo.activate,
- vinfo.height, vinfo.width, vinfo.accel_flags, vinfo.pixclock,
- vinfo.left_margin, vinfo.right_margin, vinfo.upper_margin,
- vinfo.lower_margin, vinfo.hsync_len, vinfo.vsync_len,
- vinfo.sync, vinfo.vmode);
- }
- //画大小为width*height的同色矩阵,8alpha+8reds+8greens+8blues
- void
- drawRect_rgb32 (int x0, int y0, int width, int height, int color)
- {
- const int bytesPerPixel = 4;
- const int stride = finfo.line_length / bytesPerPixel;
- int *dest = (int *) (frameBuffer)
- + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
- int x, y;
- for (y = 0; y < height; ++y)
- {
- for (x = 0; x < width; ++x)
- {
- dest[x] = color;
- }
- dest += stride;
- }
- }
- //画大小为width*height的同色矩阵,5reds+6greens+5blues
- void
- drawRect_rgb16 (int x0, int y0, int width, int height, int color)
- {
- const int bytesPerPixel = 2;
- const int stride = finfo.line_length / bytesPerPixel;
- const int red = (color & 0xff0000) >> (16 + 3);
- const int green = (color & 0xff00) >> (8 + 2);
- const int blue = (color & 0xff) >> 3;
- const short color16 = blue | (green << 5) | (red << (5 + 6));
- short *dest = (short *) (frameBuffer)
- + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
- int x, y;
- for (y = 0; y < height; ++y)
- {
- for (x = 0; x < width; ++x)
- {
- dest[x] = color16;
- }
- dest += stride;
- }
- }
- //画大小为width*height的同色矩阵,5reds+5greens+5blues
- void
- drawRect_rgb15 (int x0, int y0, int width, int height, int color)
- {
- const int bytesPerPixel = 2;
- const int stride = finfo.line_length / bytesPerPixel;
- const int red = (color & 0xff0000) >> (16 + 3);
- const int green = (color & 0xff00) >> (8 + 3);
- const int blue = (color & 0xff) >> 3;
- const short color15 = blue | (green << 5) | (red << (5 + 5)) | 0x8000;
- short *dest = (short *) (frameBuffer)
- + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
- int x, y;
- for (y = 0; y < height; ++y)
- {
- for (x = 0; x < width; ++x)
- {
- dest[x] = color15;
- }
- dest += stride;
- }
- }
- void
- drawRect (int x0, int y0, int width, int height, int color)
- {
- switch (vinfo.bits_per_pixel)
- {
- case 32:
- drawRect_rgb32 (x0, y0, width, height, color);
- break;
- case 16:
- drawRect_rgb16 (x0, y0, width, height, color);
- break;
- case 15:
- drawRect_rgb15 (x0, y0, width, height, color);
- break;
- default:
- printf ("Warning: drawRect() not implemented for color depth %i\n",
- vinfo.bits_per_pixel);
- break;
- }
- }
- #define PERFORMANCE_RUN_COUNT 5
- void
- performSpeedTest (void *fb, int fbSize)
- {
- int i, j, run;
- struct timeval startTime, endTime;
- unsigned long long results[PERFORMANCE_RUN_COUNT];
- unsigned long long average;
- unsigned int *testImage;
- unsigned int randData[17] = {
- 0x3A428472, 0x724B84D3, 0x26B898AB, 0x7D980E3C, 0x5345A084,
- 0x6779B66B, 0x791EE4B4, 0x6E8EE3CC, 0x63AF504A, 0x18A21B33,
- 0x0E26EB73, 0x022F708E, 0x1740F3B0, 0x7E2C699D, 0x0E8A570B,
- 0x5F2C22FB, 0x6A742130
- };
- printf ("Frame Buffer Performance test...\n");
- for (run = 0; run < PERFORMANCE_RUN_COUNT; ++run)
- {
- /* Generate test image with random(ish) data: */
- testImage = (unsigned int *) malloc (fbSize);
- j = run;
- for (i = 0; i < (int) (fbSize / sizeof (int)); ++i)
- {
- testImage[i] = randData[j];
- j++;
- if (j >= 17)
- j = 0;
- }
- gettimeofday (&startTime, NULL);
- memcpy (fb, testImage, fbSize);
- gettimeofday (&endTime, NULL);
- long secsDiff = endTime.tv_sec - startTime.tv_sec;
- results[run] =
- secsDiff * 1000000 + (endTime.tv_usec - startTime.tv_usec);
- free (testImage);
- }
- average = 0;
- for (i = 0; i < PERFORMANCE_RUN_COUNT; ++i)
- average += results[i];
- average = average / PERFORMANCE_RUN_COUNT;
- printf (" Average: %llu usecs\n", average);
- printf (" Bandwidth: %.03f MByte/Sec\n",
- (fbSize / 1048576.0) / ((double) average / 1000000.0));
- printf (" Max. FPS: %.03f fps\n\n",
- 1000000.0 / (double) average);
- /* Clear the framebuffer back to black again: */
- memset (fb, 0, fbSize);
- }
- int
- main (int argc, char **argv)
- {
- const char *devfile = "/dev/fb0";
- long int screensize = 0;
- int fbFd = 0;
- /* Open the file for reading and writing */
- fbFd = open (devfile, O_RDWR);
- if (fbFd == -1)
- {
- perror ("Error: cannot open framebuffer device");
- exit (1);
- }
- //获取finfo信息并显示
- if (ioctl (fbFd, FBIOGET_FSCREENINFO, &finfo) == -1)
- {
- perror ("Error reading fixed information");
- exit (2);
- }
- printFixedInfo ();
- //获取vinfo信息并显示
- if (ioctl (fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1)
- {
- perror ("Error reading variable information");
- exit (3);
- }
- printVariableInfo ();
- /* Figure out the size of the screen in bytes */
- screensize = finfo.smem_len;
- /* Map the device to memory */
- frameBuffer =
- (char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
- fbFd, 0);
- if (frameBuffer == MAP_FAILED)
- {
- perror ("Error: Failed to map framebuffer device to memory");
- exit (4);
- }
- //测试virt fb的性能
- performSpeedTest (frameBuffer, screensize);
- printf ("Will draw 3 rectangles on the screen,\n"
- "they should be colored red, green and blue (in that order).\n");
- drawRect (vinfo.xres / 8, vinfo.yres / 8,
- vinfo.xres / 4, vinfo.yres / 4, 0xffff0000);
- drawRect (vinfo.xres * 3 / 8, vinfo.yres * 3 / 8,
- vinfo.xres / 4, vinfo.yres / 4, 0xff00ff00);
- drawRect (vinfo.xres * 5 / 8, vinfo.yres * 5 / 8,
- vinfo.xres / 4, vinfo.yres / 4, 0xff0000ff);
- sleep (5);
- printf (" Done.\n");
- munmap (frameBuffer, screensize); //解除内存映射,与mmap对应
- close (fbFd);
- return 0;
- }
fb_tset.c
最新推荐文章于 2022-07-20 17:08:32 发布