分享

framebuffer 和skia 结合搭建GUI

 quasiceo 2016-08-03

framebuffer 和skia 结合搭建GUI

(2011-04-11 15:01:32)
开启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 }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多