开启framebuff以后,测试framebuff。
下边frambuffer.cpp程序修改自http://bbs./thread-1932291-1-1.html#。在此对
“曾有你的森林” 表示感谢。
将发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
15
16 #include
<stdlib.h>
17 #include
<unistd.h>
18 #include
<stdio.h>
19 #include
<fcntl.h>
20 #include
<linux/fb.h>
21 #include
<linux/kd.h>
22 #include
<sys/mman.h>
23 #include
<sys/ioctl.h>
24 #include
<sys/time.h>
25 #include
<string.h>
26 #include
<errno.h>
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: -, length: -,
msb_right: -\n"
82
"\tgreen: offset: -, length:
-, msb_right: -\n"
83
"\tblue: offset: -, length: -,
msb_right: -\n"
84
"\ttransp: offset: -, length:
-, msb_right: -\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
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
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<SkImageDecoder>
ad(codec);
290
291 #if SKIA_SCALE
292
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
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
351
screensize = finfo.smem_len;
352
353
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 }