直接操作android的/dev/graphics/fb0

  看到网友们写了自己的一些对/dev/graphics/fb0操作的例子,自己也跟着模仿了下,效果如下:

  这是在android电视上的效果,代码如下:

  1 #include <stdlib.h>
  2 #include <unistd.h>
  3 #include <stdio.h>
  4 #include <fcntl.h>
  5 #include <linux/fb.h>
  6 #include <linux/kd.h>
  7 #include <sys/mman.h>
  8 #include <sys/ioctl.h>
  9 #include <sys/time.h>
 10 #include <string.h>
 11 #include <errno.h>
 12 
 13 #define FRAMEBUFFER "/dev/graphics/fb0"
 14 
 15 struct fb_var_screeninfo vinfo;
 16 struct fb_fix_screeninfo finfo;
 17 char *frameBuffer = 0;  
 18 
 19 //打印fb驱动中fix结构信息
 20 void printFixedInfo()
 21 {
 22     printf("Fixed screen info:\n"
 23             "\t id: %s\n"
 24             "\t smem_start: 0x%lx\n"
 25             "\t smem_len: %d\n"
 26             "\t type: %d\n"
 27             "\t type_aux: %d\n"
 28             "\t visual: %d\n"
 29             "\t xpanstep: %d\n"
 30             "\t ypanstep: %d\n"
 31             "\t ywrapstep: %d\n"
 32             "\t line_length: %d\n"   //
 33             "\t mmio_start: 0x%lx\n"
 34             "\t mmio_len: %d\n"
 35             "\t accel: %d\n"
 36             "\n", finfo.id, finfo.smem_start, finfo.smem_len, finfo.type,
 37             finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep,
 38             finfo.ywrapstep, finfo.line_length, finfo.mmio_start,
 39             finfo.mmio_len, finfo.accel);
 40 }
 41 
 42 //打印fb驱动中var结构信息
 43 void printVariableInfo()
 44 {
 45     printf("Variable screen info:\n"
 46             "\t xres: %d\n"
 47             "\t yres: %d\n"
 48             "\t xres_virtual: %d\n"
 49             "\t yres_virtual: %d\n"
 50             "\t xoffset: %d\n"
 51             "\t yoffset: %d\n"            
 52             "\t bits_per_pixel: %d\n"   //每一个像素点 占用内存空间32 为4个字节
 53             "\t grayscale: %d\n"
 54             "\t red: offset: %d - length : %d  -  msb_right : %d\n"
 55             "\t green: offset: %d - length : %d  -  msb_right : %d\n"
 56             "\t blue: offset: %d - length : %d  -  msb_right : %d\n"
 57             "\t transp: offset: %d - length : %d  -  msb_right : %d\n"
 58             "\t nonstd: %d\n"
 59             "\t activate: %d\n"
 60             "\t height: %d\n"
 61             "\t width: %d\n"
 62             "\t accel_flags: 0x%x\n"
 63             "\t pixclock: %d\n"
 64             "\t left_margin: %d\n"
 65             "\t right_margin: %d\n"
 66             "\t upper_margin: %d\n"   //
 67             "\t lower_margin: %d\n"  ///帧切换:从绘图到同步之间的延迟
 68             "\t hsync_len: %d\n"
 69             "\t vsync_len: %d\n"
 70             "\t sync: %d\n"
 71             "\t vmode: %d\n"
 72             "\n", 
 73             vinfo.xres, vinfo.yres, vinfo.xres_virtual,
 74             vinfo.yres_virtual, vinfo.xoffset, vinfo.yoffset,
 75             vinfo.bits_per_pixel, vinfo.grayscale, 
 76             vinfo.red.offset, vinfo.red.length, vinfo.red.msb_right, 
 77             vinfo.green.offset, vinfo.green.length, vinfo.green.msb_right, 
 78             vinfo.blue.offset, vinfo.blue.length, vinfo.blue.msb_right, 
 79             vinfo.transp.offset, vinfo.transp.length, vinfo.transp.msb_right,
 80             vinfo.nonstd, vinfo.activate, vinfo.height, vinfo.width, vinfo.accel_flags,
 81             vinfo.pixclock, vinfo.left_margin, vinfo.right_margin,
 82             vinfo.upper_margin, vinfo.lower_margin, vinfo.hsync_len,
 83             vinfo.vsync_len, vinfo.sync, vinfo.vmode);
 84 }
 85 //图片//画大小为width*height的同色矩阵,8alpha+8reds+8greens+8blues
 86 void drawRect_rgb32(int x0, int y0, int width, int height, int color)
 87 {
 88     const int bytesPerPixel = 4;  //每一个像素点 占用内存空间
 89     // stride表示一行有多少个像素
 90     const int stride = finfo.line_length / bytesPerPixel;  //finfo.line_length 以字节数表示,就是屏幕的宽度
 91 
 92     int *dest = (int *) (frameBuffer) + (x0 + vinfo.xoffset) + (y0 + vinfo.yoffset) * stride ;
 93 
 94     int x, y;
 95     for (y = 0; y < height; ++y)
 96     {
 97         for (x = 0; x < width; ++x)
 98         {
 99             dest[x] = color;
100         }
101         dest += stride;
102     }
103 }
104 
105 void draw(int x0, int y0, int width, int height, int color)
106 {
107     const int bytesPerPixel = 4;  //每一个像素点 占用内存空间
108     // stride表示一行有多少个像素
109     const int stride = finfo.line_length / bytesPerPixel;  //finfo.line_length 以字节数表示,就是屏幕的宽度
110 
111     int *dest = (int *) (frameBuffer) + (x0 + vinfo.xoffset) + (y0 + vinfo.yoffset) * stride ;
112 
113     int i = 0;
114     int x, y;
115      for (y = 0; y < height; ++y)
116     {
117         for (x = 0; x < width; ++x)
118         {
119             i++;
120             dest[x] = img[i];
121             if(i == 4229358)
122                 i =  0;
123         }
124         dest += stride;
125     }
126 }
127 
128 
129 //画大小为width*height的同色矩阵,5reds+6greens+5blues
130 void drawRect_rgb16(int x0, int y0, int width, int height, int color)
131 {
132     const int bytesPerPixel = 2;
133     const int stride = finfo.line_length / bytesPerPixel;
134     const int red = (color & 0xff0000) >> (16 + 3);
135     const int green = (color & 0xff00) >> (8 + 2);
136     const int blue = (color & 0xff) >> 3;
137     const short color16 = blue | (green << 5) | (red << (5 + 6));
138 
139     short *dest = (short *) (frameBuffer) + (y0 + vinfo.yoffset) * stride
140             + (x0 + vinfo.xoffset);
141 
142     int x, y;
143     for (y = 0; y < height; ++y)
144     {
145         for (x = 0; x < width; ++x)
146         {
147             dest[x] = color16;
148         }
149         dest += stride;
150     }
151 }
152 
153 //画大小为width*height的同色矩阵,5reds+5greens+5blues
154 void drawRect_rgb15(int x0, int y0, int width, int height, int color)
155 {
156     const int bytesPerPixel = 2;
157     const int stride = finfo.line_length / bytesPerPixel;
158     const int red = (color & 0xff0000) >> (16 + 3);
159     const int green = (color & 0xff00) >> (8 + 3);
160     const int blue = (color & 0xff) >> 3;
161     const short color15 = blue | (green << 5) | (red << (5 + 5)) | 0x8000;
162 
163     short *dest = (short *) (frameBuffer) + (y0 + vinfo.yoffset) * stride
164             + (x0 + vinfo.xoffset);
165 
166     int x, y;
167     for (y = 0; y < height; ++y)
168     {
169         for (x = 0; x < width; ++x)
170         {
171             dest[x] = color15;
172         }
173         dest += stride;
174     }
175 }
176 
177 void drawRect(int x0, int y0, int width, int height, int color)
178 {
179     switch (vinfo.bits_per_pixel)
180     {
181     case 32:
182         drawRect_rgb32(x0, y0, width, height, color);
183         break;
184     case 16:
185         drawRect_rgb16(x0, y0, width, height, color);
186         break;
187     case 15:
188         drawRect_rgb15(x0, y0, width, height, color);
189         break;
190     default:
191         printf("Warning: drawRect() not implemented for color depth %i\n",
192                 vinfo.bits_per_pixel);
193         break;
194     }
195 }
196 
197 
198 int main(int argc, char **argv)
199 {
200     const char *devfile = FRAMEBUFFER;
201     long int screensize = 0;
202     int fbFd = 0;
203 
204     fbFd = open(devfile, O_RDWR);
205     if (fbFd == -1)
206     {
207         perror("Error: cannot open framebuffer device");
208         exit(1);
209     }
210 
211     //获取finfo信息并显示
212     if (ioctl(fbFd, FBIOGET_FSCREENINFO, &finfo) == -1)
213     {
214         perror("Error reading fixed information");
215         exit(2);
216     }
217     printFixedInfo();
218     //获取vinfo信息并显示
219     if (ioctl(fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1)
220     {
221         perror("Error reading variable information");
222         exit(3);
223     }
224     printVariableInfo();
225 
226     screensize = finfo.smem_len; ///dev/graphics/fb0 的大小,也就是内存大小
227 
228     frameBuffer = (char *) mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbFd, 0);
229     if (frameBuffer == MAP_FAILED )
230     {
231         perror("Error: Failed to map framebuffer device to memory");
232         exit(4);
233     }
234 
235     memset(frameBuffer, 0, screensize);
236 
237     printf("Will draw 3 rectangles on the screen,\n");
238     //void drawRect_rgb32(int x0, int y0, int width, int height, int color)
239     
240     //drawRect(vinfo.xres / 8    , vinfo.yres / 8    , vinfo.xres / 4, vinfo.yres / 4, 0xffff0000);
241     //drawRect(vinfo.xres * 3 / 8, vinfo.yres * 3 / 8, vinfo.xres / 4, vinfo.yres / 4, 0xff00ff00);
242     //drawRect(vinfo.xres * 5 / 8, vinfo.yres * 5 / 8, vinfo.xres / 4, vinfo.yres / 4, 0xff0000ff)
243     while(1)
244     {
245         //注意,起始坐标x,y的值只能是小于 vinfo.xres ,vinfo.yres ,宽度和高度不能超过 vinfo.xres,vinfo.yres,减去起始坐标x,y的差,否则会出错。
246         //draw(vinfo.xres*3/4,vinfo.yres*3/4, vinfo.xres*1/4,vinfo.yres*1/4 , 0xff);
247         //sleep(3);
248         
249         drawRect(0 ,0  , vinfo.xres ,vinfo.yres , 0xff00ff00); //绿色
250         sleep(1);
251         drawRect(vinfo.xres*1/4 ,vinfo.yres*1/4  , vinfo.xres*3/4 ,vinfo.yres*3/4 , 0xff000000); //黑色
252         sleep(1); 
253         drawRect(vinfo.xres/2   ,vinfo.yres/2    , vinfo.xres/2   ,vinfo.yres/2   , 0xff0000ff); //红色
254         sleep(5);
255     }
256     
257     printf(" Done.\n");
258 
259     munmap(frameBuffer, screensize);    //解除内存映射,与mmap对应
260     close(fbFd);
261     return 0;
262 }

由于上传有些问题,所以最后一个图片的部分没有上传,不过不影响其他效果。

代码中有几个自定义判断的swich函数,其中我的机器识别的是32真彩的所以只调用了 drawRect_rgb32(x0, y0, width, height, color);这个函数。

图像显示其实是直接对frameBuffer这个映射的内存进行操作,这个frameBuffer这个指针对应的映射地址其实就是显存,每一个一像素就是4个字节,可以从代码中看到。有什么不对的地方欢迎指出来,希望对你有所帮助。

posted @ 2016-07-07 17:28  winfu  阅读(4822)  评论(4编辑  收藏  举报