您的位置:首页 > 移动开发 > 微信开发

framebuffer小程序显示3个矩形 测试

2015-11-13 10:34 549 查看
本文的copyright归yuweixian4230@163.com
所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。

作者:yuweixian4230@163.com

博客:yuweixian4230.blog.chinaunix.net   

  网址 http://www.cnblogs.com/cute/archive/2011/04/20/2022114.html 有一程序关于 framebuffer,现在我对他进行测试,然后进行分析

#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;

}

显示效果



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: