本文的copyright归yuweixian4230@163.com 所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:yuweixian4230@163.com
博客:yuweixian4230.blog.chinaunix.net 网址 http://www.cnblogs.com/cute/archive/2011/04/20/2022114.html 有一程序关于 framebuffer,现在我对他进行测试,然后进行分析
代码附件:
xx.rar 现在 将 程序贴出来
- #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;
-
}
显示效果
阅读(1419) | 评论(0) | 转发(0) |