开启framebuff以后,测试framebuff。
下边frambuffer.cpp程序修改自。在此对 “曾有你的森林” 表示感谢。
将发rambuff和skia结和起来。framebuff负责显示,skia负责绘图,这样就搭建起来一个简单的GUI系统。
smem_start: 0xd0000000 表示frambuffer的起始地址。
smem_len: 3145728 表示frambuffer的大小。
line_length: 4096 表示一行的大小。
xres_virtual: 1024 表示分辨率
yres_virtual: 768 表示分辨率
bits_per_pixel: 32 一个像素的大小
3145728 = 1024*768*32/8
smem_len = xres_virtual*yres_virtual*bits_per_pixel/8
root@ubuntu10:/work/skia-read-only/wanghuan# ./test-skia
Fixed screen info:
id: VESA VGA
smem_start: 0xd0000000
smem_len: 3145728
type: 0
type_aux: 0
visual: 2
xpanstep: 0
ypanstep: 0
ywrapstep: 0
line_length: 4096
mmio_start: 0x0
mmio_len: 0
accel: 0
Variable screen info:
xres: 1024
yres: 768
xres_virtual: 1024
yres_virtual: 768
yoffset: 0
xoffset: 0
bits_per_pixel: 32
grayscale: 0
red: offset: 16, length: 8, msb_right: 0
green: offset: 8, length: 8, msb_right: 0
blue: offset: 0, length: 8, msb_right: 0
transp: offset: 24, length: 8, msb_right: 0
nonstd: 0
activate: 0
height: -1
width: -1
accel_flags: 0x0
pixclock: 12714
left_margin: 128
right_margin: 32
upper_margin: 16
lower_margin: 4
hsync_len: 128
vsync_len: 4
sync: 0
vmode: 0
Frame Buffer Performance test...
Average: 12642 usecs
Bandwidth: 237.304 MByte/Sec
Max. FPS: 79.101 fps
root@ubuntu10:/work/skia-read-only/wanghuan# cat Makefile -n
1 # Build the unix test app
2 C_INCLUDES := -I../include/core \
3 -I../include/config \
4 -I../include/effects \
5 -I../include/images \
6 -I../include/utils \
7 -I../include/views \
8 -I../include/xml \
9 -I../include/gpu \
10 -I../gpu/include \
11 -I../include/utils/unix \
12 -I../samplecode
13
14 VPATH = libs:../src/ports:../samplecode:../src/core:../src/utils/unix
15
16 #generate debugging info
17 CFLAGS = -g
18
19 SRC_LIST := framebuff.cpp
20
21 test-skia: $(SRC_LIST) ../out/libskia.a -lpthread -lz -lfreetype -lpng -ljpeg
22 g++ $(C_INCLUDES) $(CFLAGS) $^ -o $@
23
24 clean:
25 #rm -rf ../out # Copied from ../Makefile
26 #rm -rf out
root@ubuntu10:/work/skia-read-only/wanghuan# cat framebuff.cpp -n
1 /*
2 * =====================================================================================
3 * Filename: framebuff.c
4 * Description:
5 *
6 * Version: 1.0
7 * Created: 2011年04月09日 12时38分23秒
8 * Revision: none
9 * Compiler: gcc
10 *
11 * Author: wanghuan (),
12 * Company:
13 * =====================================================================================
14 */
15
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #include
26 #include
27
28 #include "SkBitmap.h"
29 #include "SkDevice.h"
30 #include "SkPaint.h"
31 #include "SkRect.h"
32 #include "SkStream.h"
33 #include "SkTemplates.h"
34 #include "SkMatrix.h"
35 #include "SkImageEncoder.h"
36 #include "SkImageDecoder.h"
37
38 struct fb_var_screeninfo vinfo;
39 struct fb_fix_screeninfo finfo;
40 char *frameBuffer = 0;
41 #define SKIA_SCALE 0 /* 是否支持图片压缩*/
42
43 //打印fb驱动中fix结构信息,注:在fb驱动加载后,fix结构不可被修改。
44 void
45 printFixedInfo ()
46 {
47 printf ("Fixed screen info:\n"
48 "\tid: %s\n"
49 "\tsmem_start: 0x%lx\n"
50 "\tsmem_len: %d\n"
51 "\ttype: %d\n"
52 "\ttype_aux: %d\n"
53 "\tvisual: %d\n"
54 "\txpanstep: %d\n"
55 "\typanstep: %d\n"
56 "\tywrapstep: %d\n"
57 "\tline_length: %d\n"
58 "\tmmio_start: 0x%lx\n"
59 "\tmmio_len: %d\n"
60 "\taccel: %d\n"
61 "\n",
62 finfo.id, finfo.smem_start, finfo.smem_len, finfo.type,
63 finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep,
64 finfo.ywrapstep, finfo.line_length, finfo.mmio_start,
65 finfo.mmio_len, finfo.accel);
66 }
67
68 //打印fb驱动中var结构信息,注:fb驱动加载后,var结构可根据实际需要被重置
69 void
70 printVariableInfo ()
71 {
72 printf ("Variable screen info:\n"
73 "\txres: %d\n"
74 "\tyres: %d\n"
75 "\txres_virtual: %d\n"
76 "\tyres_virtual: %d\n"
77 "\tyoffset: %d\n"
78 "\txoffset: %d\n"
79 "\tbits_per_pixel: %d\n"
80 "\tgrayscale: %d\n"
81 "\tred: offset: %2d, length: %2d, msb_right: %2d\n"
82 "\tgreen: offset: %2d, length: %2d, msb_right: %2d\n"
83 "\tblue: offset: %2d, length: %2d, msb_right: %2d\n"
84 "\ttransp: offset: %2d, length: %2d, msb_right: %2d\n"
85 "\tnonstd: %d\n"
86 "\tactivate: %d\n"
87 "\theight: %d\n"
88 "\twidth: %d\n"
89 "\taccel_flags: 0x%x\n"
90 "\tpixclock: %d\n"
91 "\tleft_margin: %d\n"
92 "\tright_margin: %d\n"
93 "\tupper_margin: %d\n"
94 "\tlower_margin: %d\n"
95 "\thsync_len: %d\n"
96 "\tvsync_len: %d\n"
97 "\tsync: %d\n"
98 "\tvmode: %d\n"
99 "\n",
100 vinfo.xres, vinfo.yres, vinfo.xres_virtual, vinfo.yres_virtual,
101 vinfo.xoffset, vinfo.yoffset, vinfo.bits_per_pixel,
102 vinfo.grayscale, vinfo.red.offset, vinfo.red.length,
103 vinfo.red.msb_right, vinfo.green.offset, vinfo.green.length,
104 vinfo.green.msb_right, vinfo.blue.offset, vinfo.blue.length,
105 vinfo.blue.msb_right, vinfo.transp.offset, vinfo.transp.length,
106 vinfo.transp.msb_right, vinfo.nonstd, vinfo.activate,
107 vinfo.height, vinfo.width, vinfo.accel_flags, vinfo.pixclock,
108 vinfo.left_margin, vinfo.right_margin, vinfo.upper_margin,
109 vinfo.lower_margin, vinfo.hsync_len, vinfo.vsync_len,
110 vinfo.sync, vinfo.vmode);
111 }
112
113 //画大小为width*height的同色矩阵,8alpha+8reds+8greens+8blues
114 void
115 drawRect_rgb32 (int x0, int y0, int width, int height, int color)
116 {
117 const int bytesPerPixel = 4;
118 const int stride = finfo.line_length / bytesPerPixel;
119
120 int *dest = (int *) (frameBuffer)
121 + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
122
123 int x, y;
124 for (y = 0; y < height; ++y)
125 {
126 for (x = 0; x < width; ++x)
127 {
128 dest[x] = color;
129 }
130 dest += stride;
131 }
132 }
133
134 //画大小为width*height的同色矩阵,5reds+6greens+5blues
135 void
136 drawRect_rgb16 (int x0, int y0, int width, int height, int color)
137 {
138 const int bytesPerPixel = 2;
139 const int stride = finfo.line_length / bytesPerPixel;
140 const int red = (color & 0xff0000) >> (16 + 3);
141 const int green = (color & 0xff00) >> (8 + 2);
142 const int blue = (color & 0xff) >> 3;
143 const short color16 = blue | (green << 5) | (red << (5 + 6));
144
145 short *dest = (short *) (frameBuffer)
146 + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
147
148 int x, y;
149 for (y = 0; y < height; ++y)
150 {
151 for (x = 0; x < width; ++x)
152 {
153 dest[x] = color16;
154 }
155 dest += stride;
156 }
157 }
158
159 //画大小为width*height的同色矩阵,5reds+5greens+5blues
160 void
161 drawRect_rgb15 (int x0, int y0, int width, int height, int color)
162 {
163 const int bytesPerPixel = 2;
164 const int stride = finfo.line_length / bytesPerPixel;
165 const int red = (color & 0xff0000) >> (16 + 3);
166 const int green = (color & 0xff00) >> (8 + 3);
167 const int blue = (color & 0xff) >> 3;
168 const short color15 = blue | (green << 5) | (red << (5 + 5)) | 0x8000;
169
170 short *dest = (short *) (frameBuffer)
171 + (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
172
173 int x, y;
174 for (y = 0; y < height; ++y)
175 {
176 for (x = 0; x < width; ++x)
177 {
178 dest[x] = color15;
179 }
180 dest += stride;
181 }
182 }
183
184 void
185 drawRect (int x0, int y0, int width, int height, int color)
186 {
187 switch (vinfo.bits_per_pixel)
188 {
189 case 32:
190 drawRect_rgb32 (x0, y0, width, height, color);
191 break;
192 case 16:
193 drawRect_rgb16 (x0, y0, width, height, color);
194 break;
195 case 15:
196 drawRect_rgb15 (x0, y0, width, height, color);
197 break;
198 default:
199 printf ("Warning: drawRect() not implemented for color depth %i\n",
200 vinfo.bits_per_pixel);
201 break;
202 }
203 }
204
205 #define PERFORMANCE_RUN_COUNT 5
206 void
207 performSpeedTest (void *fb, int fbSize)
208 {
209 int i, j, run;
210 struct timeval startTime, endTime;
211 unsigned long long results[PERFORMANCE_RUN_COUNT];
212 unsigned long long average;
213 unsigned int *testImage;
214
215 unsigned int randData[17] = {
216 0x3A428472, 0x724B84D3, 0x26B898AB, 0x7D980E3C, 0x5345A084,
217 0x6779B66B, 0x791EE4B4, 0x6E8EE3CC, 0x63AF504A, 0x18A21B33,
218 0x0E26EB73, 0x022F708E, 0x1740F3B0, 0x7E2C699D, 0x0E8A570B,
219 0x5F2C22FB, 0x6A742130
220 };
221
222 printf ("Frame Buffer Performance test...\n");
223 for (run = 0; run < PERFORMANCE_RUN_COUNT; ++run)
224 {
225 /* Generate test image with random(ish) data: */
226 testImage = (unsigned int *) malloc (fbSize);
227 j = run;
228 for (i = 0; i < (int) (fbSize / sizeof (int)); ++i)
229 {
230 testImage[i] = randData[j];
231 j++;
232 if (j >= 17)
233 j = 0;
234 }
235
236 gettimeofday (&startTime, NULL);
237 memcpy (fb, testImage, fbSize);
238 gettimeofday (&endTime, NULL);
239
240 long secsDiff = endTime.tv_sec - startTime.tv_sec;
241 results[run] =
242 secsDiff * 1000000 + (endTime.tv_usec - startTime.tv_usec);
243
244 free (testImage);
245 }
246
247 average = 0;
248 for (i = 0; i < PERFORMANCE_RUN_COUNT; ++i)
249 average += results[i];
250 average = average / PERFORMANCE_RUN_COUNT;
251
252 printf (" Average: %llu usecs\n", average);
253 printf (" Bandwidth: %.03f MByte/Sec\n",
254 (fbSize / 1048576.0) / ((double) average / 1000000.0));
255 printf (" Max. FPS: %.03f fps\n\n",
256 1000000.0 / (double) average);
257
258 /* Clear the framebuffer back to black again: */
259 memset (fb, 0, fbSize);
260 }
261 //图片解码 将图片解码到bitmap的内存中,然后可以填充到framebuffer中。
262 bool SkFileDecoder( SkBitmap* bitmap, const char srcPath[], int bits_per_pixel)
263 {
264 SkFILEStream stream(srcPath);
265 if (!stream.isValid()) {
266 printf("ERROR: bad filename <%s>\n", srcPath);
267 return false;
268 }
269
270 stream.rewind();
271 SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
272 if (NULL == codec) {
273 printf("ERROR: no codec found for <%s>\n", srcPath);
274 return false;
275 }
276 SkBitmap::Config config;
277 switch (bits_per_pixel)
278 {
279 case 32:
280 config = SkBitmap::kARGB_8888_Config;
281 break;
282 case 16:
283 config = SkBitmap::kRGB_565_Config;
284 break;
285 default:
286 printf ("Warning: drawRect() not implemented for color depth %i\n",bits_per_pixel);
287 break;
288 }
289 SkAutoTDelete ad(codec);
290
291 #if SKIA_SCALE
292 /** \ 图片解码时进行压缩,以720为标准 设置抽样率
293 */
294 SkBitmap tmp_bitmap;
295 stream.rewind();
296 if (!codec->decode(&stream, &tmp_bitmap, config ,
297 SkImageDecoder::kDecodeBounds_Mode)) {
298 printf("ERROR: codec failed for <%s>\n", srcPath);
299 return false;
300 }
301
302 int maxpix = (tmp_bitmap.width() > tmp_bitmap.height()) ? tmp_bitmap.width():tmp_bitmap.width();
303 int minpix = (tmp_bitmap.width() < tmp_bitmap.height()) ? tmp_bitmap.width():tmp_bitmap.width();
304 int sample1 = maxpix/1028 + 1;
305 int sample2 = maxpix/726 + 1;
306
307 codec->setSampleSize(sample1>sample2 ? sample1:sample2);
308 #endif
309
310 stream.rewind();
311 if (!codec->decode(&stream, bitmap, config,
312 SkImageDecoder::kDecodePixels_Mode)) {
313 printf("ERROR: codec failed for <%s>\n", srcPath);
314 return false;
315 }
316 return true;
317 }
318
319 int
320 main (int argc, char **argv)
321 {
322 const char *devfile = "/dev/fb0";
323 long int screensize = 0;
324 int fbFd = 0;
325
326
327 /* Open the file for reading and writing */
328 fbFd = open (devfile, O_RDWR);
329 if (fbFd == -1)
330 {
331 perror ("Error: cannot open framebuffer device");
332 exit (1);
333 }
334
335 //获取finfo信息并显示
336 if (ioctl (fbFd, FBIOGET_FSCREENINFO, &finfo) == -1)
337 {
338 perror ("Error reading fixed information");
339 exit (2);
340 }
341 printFixedInfo ();
342 //获取vinfo信息并显示
343 if (ioctl (fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1)
344 {
345 perror ("Error reading variable information");
346 exit (3);
347 }
348 printVariableInfo ();
349
350 /* Figure out the size of the screen in bytes */
351 screensize = finfo.smem_len;
352
353 /* Map the device to memory */
354 frameBuffer =
355 (char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
356 fbFd, 0);
357 if (frameBuffer == MAP_FAILED)
358 {
359 perror ("Error: Failed to map framebuffer device to memory");
360 exit (4);
361 }
362
363 //测试virt fb的性能
364 performSpeedTest (frameBuffer, screensize);
365 memset(frameBuffer, 0, screensize);
366
367 printf ("Will draw 3 rectangles on the screen,\n"
368 "they should be colored red, green and blue (in that order).\n");
369 drawRect (vinfo.xres / 8, vinfo.yres / 8,
370 vinfo.xres / 4, vinfo.yres / 4, 0xffff0000);
371 drawRect (vinfo.xres * 3 / 8, vinfo.yres * 3 / 8,
372 vinfo.xres / 4, vinfo.yres / 4, 0xff00ff00);
373 drawRect (vinfo.xres * 5 / 8, vinfo.yres * 5 / 8,
374 vinfo.xres / 4, vinfo.yres / 4, 0xff0000ff);
375
376 sleep (5);
377 printf (" Done.\n");
378 memset(frameBuffer, 0, screensize);
379
380 SkBitmap::Config config;
381 switch (vinfo.bits_per_pixel)
382 {
383 case 32:
384 config = SkBitmap::kARGB_8888_Config;
385 break;
386 case 16:
387 config = SkBitmap::kRGB_565_Config;
388 break;
389 default:
390 break;
391 }
392
393 SkBitmap bitmap;
394 bitmap.setConfig( config, vinfo.xres, vinfo.yres);
395 bitmap.allocPixels();
396 SkCanvas canvas(bitmap);
397 SkRect r;
398 SkColor color =0;
399
400 SkPaint paint;
401 paint.setARGB(255, 255, 0, 0);
402 paint.setStrokeWidth(4);
403
404 canvas.drawPoint(80, 80, 0xffff0000);
405 memcpy(frameBuffer, bitmap.getPixels(), screensize);
406 sleep(1);
407
408 bitmap.eraseColor(0);
409 SkIRect rect{100, 100, 300, 300 };
410 canvas.drawIRect(rect, paint);
411 memcpy(frameBuffer, bitmap.getPixels(), screensize);
412 sleep(1);
413
414 bitmap.eraseColor(0);
415 canvas.drawCircle(400, 300, 50, paint);
416 memcpy(frameBuffer, bitmap.getPixels(), screensize);
417 sleep(1);
418
419 bitmap.eraseColor(0);
420 canvas.drawLine(160,10,320,110,paint);
421 memcpy(frameBuffer, bitmap.getPixels(), screensize);
422 sleep(1);
423 bitmap.eraseColor(0);
424 paint.setARGB(255, 255, 0, 0);
425 canvas.drawCircle(400, 300, 200, paint);
426 paint.setARGB(255, 255, 0, 155);
427 canvas.drawCircle(400, 300, 195, paint);
428 paint.setARGB(255, 0, 255, 255);
429 canvas.drawLine(220, 300, 400, 300, paint);
430 memcpy(frameBuffer, bitmap.getPixels(), screensize);
431
432 for(int i = 0; i <= 0xffffffff; i++)
433 {
434 bitmap.eraseColor(0);
435 SkBitmap Ibitmap;
436 char name[32] ="";
437 snprintf(name, sizeof(name), "/work/pictures/%d.png", i%7);
438 SkFileDecoder( &Ibitmap, name, vinfo.bits_per_pixel);
439
440 SkIRect src{0, 0, bitmap.width(), bitmap.height()};
441 SkRect dst{0, 0, Ibitmap.width(), bitmap.height()};
442 canvas.drawBitmapRect(Ibitmap, &src, dst);
443 //SkScalar degree = 0;
444 //SkScalar scal = 1;
445 //SkScalar x = bitmap.width();
446 //SkScalar y = bitmap.height();
447 memcpy(frameBuffer, bitmap.getPixels(), screensize);
448 sleep(2);
449 }
450 munmap (frameBuffer, screensize); //解除内存映射,与mmap对应
451 close (fbFd);
452 return 0;
453 }
阅读(2679) | 评论(0) | 转发(0) |