Chinaunix首页 | 论坛 | 博客
  • 博客访问: 453594
  • 博文数量: 89
  • 博客积分: 1126
  • 博客等级: 少尉
  • 技术积分: 1432
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-11 23:37
文章分类

全部博文(89)

文章存档

2016年(6)

2015年(2)

2014年(1)

2013年(3)

2012年(23)

2011年(54)

分类: 嵌入式

2012-03-29 17:12:32

    最近在做一个android的新平台,涉及到了SurfaceFlinger的使用。又要在另外一个平台上实现一个抓屏的功能,被折磨的囧啊。最近终于能够闲下来整理一下这块的东西了。网上有很多讲解SurfaceFlinger的文章,但大部分都是原理分析,看的头大。下面是一个测试小例子,测试SurfaceFlinger的使用,并结合skia测试了软合成shotsceen的性能。

点击(此处)折叠或打开

  1. /**
  2.  * =====================================================================================
  3.  * Filename: surface.cpp
  4.  * Created: 2012年03月24日 13时39分28秒
  5.  * Author: louie (),
  6.  * Company: sunniwell.net
  7.  * Description: surface test
  8.  * =====================================================================================
  9.  */

  10. #define LOG_TAG "SurfaceTest"

  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <sys/mman.h>
  14. #include <fcntl.h>
  15. #include <dirent.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #include <linux/fb.h>

  19. #include <binder/IPCThreadState.h>
  20. #include <binder/ProcessState.h>
  21. #include <binder/IMemory.h>
  22. #include <binder/IPCThreadState.h>
  23. #include <binder/IServiceManager.h>
  24. #include <binder/MemoryHeapBase.h>
  25. #include <binder/MemoryBase.h>
  26. #include <binder/Binder.h>
  27. #include <utils/Log.h>

  28. #include <cutils/atomic.h>
  29. #include <cutils/properties.h>
  30. #include <utils/threads.h>
  31. #include <utils/Atomic.h>
  32. #include <utils/String16.h>
  33. #include <android_runtime/AndroidRuntime.h>
  34. #include <android_runtime/ActivityManager.h>

  35. #include <media/AudioTrack.h>
  36. #include <media/RobotWrapper.h>

  37. #include <surfaceflinger/Surface.h>
  38. #include <surfaceflinger/ISurface.h>
  39. #include <surfaceflinger/ISurfaceComposer.h>
  40. #include <surfaceflinger/SurfaceComposerClient.h>
  41. #include <ui/DisplayInfo.h>

  42. #include <SkTypeface.h>
  43. #include <SkTemplates.h>
  44. #include <SkRegion.h>
  45. #include <SkDevice.h>
  46. #include <SkRect.h>
  47. #include <SkCanvas.h>
  48. #include <SkBitmap.h>
  49. #include <SkStream.h>
  50. #include <SkImageDecoder.h>
  51. #include <SkImageEncoder.h>
  52. #include "hi_unf_disp.h"

  53. using namespace android;

  54. bool SkFileDecoder( SkBitmap* bitmap, const char srcPath[], int bits_per_pixel)
  55. {
  56.     SkFILEStream stream(srcPath);
  57.     if (!stream.isValid()) {
  58.         LOGE("ERROR: bad filename <%s>\n", srcPath);
  59.         return false;
  60.     }

  61.     stream.rewind();
  62.     SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
  63.     if (NULL == codec) {
  64.         LOGE("ERROR: no codec found for <%s>\n", srcPath);
  65.         return false;
  66.     }

  67.     SkBitmap::Config config;
  68.     switch (bits_per_pixel)
  69.     {
  70.         case 32:
  71.             config = SkBitmap::kARGB_8888_Config;
  72.             break;
  73.         case 16:
  74.             config = SkBitmap::kRGB_565_Config;
  75.             break;
  76.         default:
  77.             LOGE ("Warning: drawRect() not implemented for color depth %i\n",bits_per_pixel);
  78.             break;
  79.     }
  80.     SkAutoTDelete<SkImageDecoder> ad(codec);

  81.     stream.rewind();
  82.     if (!codec->decode(&stream, bitmap, config,
  83.                 SkImageDecoder::kDecodePixels_Mode)) {
  84.         LOGE("ERROR: codec failed for <%s>\n", srcPath);
  85.         return false;
  86.     }
  87.     return true;
  88. }

  89. int main( )
  90. {
  91.     sp<SurfaceComposerClient> surfaceclient;
  92.     sp<SurfaceControl> surfaceControl;
  93.     sp<Surface> surface;
  94.     SkBitmap bitmap;
  95.     Surface::SurfaceInfo info;
  96.     DisplayInfo display;

  97.     //surface 的名字以pid开头
  98.     LOGE("[%s %s %d] \n", __FUNCTION__, __FILE__, __LINE__, getpid());
  99.     surfaceclient = new SurfaceComposerClient();
  100.     surfaceclient->getDisplayInfo(0, &display);
  101.     LOGE("display < %d %d>", display.w, display.h);
  102.     surfaceControl = surfaceclient->createSurface(getpid(), 0, display.w, display.h, PIXEL_FORMAT_RGBA_8888);

  103.     //composer parameters必须在一对open/close transaction之间当close调用时,
  104.     //参数被提交给服务端参数值的改变都存放在/frameworks/base/include/private/surfaceflinger/LayerState.h:layer_state_t中,
  105.     //当调用closeTransaction时,结构体才会被传送到服务端。这样可以明显简化C/S接口、加快C/S通信速度。
  106.     surfaceclient->openTransaction();
  107.     surfaceControl->setLayer(1000);
  108.     surfaceControl->setSize(display.w, display.h);
  109.     surfaceControl->setPosition(1, 1);
  110.     surfaceControl->show( );
  111.     surfaceclient->closeTransaction();

  112.     surface = surfaceControl->getSurface();

  113.     surface->lock(&info);
  114.     bitmap.setConfig(SkBitmap::kARGB_8888_Config, fb_w, fb_h);
  115.     bitmap.setIsOpaque(true);    
  116.     bitmap.setPixels(info.bits);
  117.     SkCanvas* canvas = new SkCanvas(bitmap);
  118.     surface->unlockAndPost();

  119.     int A = 150, R = 128, G = 128, B = 128 ;
  120.     while( A < 256)
  121.     {
  122.         LOGE("Surface <%d %d %d %d>\n", A, R, G, B);
  123.         surface->lock(&info);
  124.         /*bitmap 的buffer 被重置,surface 为双缓冲,前后buffer被替换 因此每次都要重新设置bitmap的内存*/
  125.         bitmap.setPixels(info.bits);
  126.         bitmap.eraseARGB(A, R, G, B);
  127.         surface->unlockAndPost();
  128.         A += 20;
  129.         sleep(3);
  130.     }

  131.     SkPaint paint;
  132.     int color = 0xff00ff77;
  133.     paint.setARGB(color>>24 & 0xff, color>>16 & 0xff, color>>8 & 0xff, color & 0xff);

  134.     surface->lock(&info);
  135.     bitmap.setPixels(info.bits);
  136.     bitmap.eraseARGB(0, 0, 0, 0);
  137.     canvas->setBitmapDevice(bitmap);
  138.     canvas->drawLine(100, 100, 500, 500, paint);
  139.     surface->unlockAndPost();
  140.     sleep(3);

  141.     surface->lock(&info);
  142.     bitmap.setPixels(info.bits);
  143.     bitmap.eraseARGB(0, 0, 0, 0);
  144.     SkRect rect;
  145.     rect.fLeft = 200;
  146.     rect.fTop = 200;
  147.     rect.fRight = 400;
  148.     rect.fBottom = 400;
  149.     color = 0xffff0077;
  150.     paint.setARGB(color>>24 & 0xff, color>>16 & 0xff, color>>8 & 0xff, color & 0xff);
  151.     canvas->setBitmapDevice(bitmap);
  152.     canvas->drawRect(rect, paint);
  153.     surface->unlockAndPost();
  154.     sleep(3);

  155.     surface->lock(&info);
  156.     bitmap.setPixels(info.bits);
  157.     bitmap.eraseARGB(0, 0, 0, 0);
  158.     color = 0xff0f00ff;
  159.     paint.setARGB(color>>24 & 0xff, color>>16 & 0xff, color>>8 & 0xff, color & 0xff);
  160.     canvas->setBitmapDevice(bitmap);
  161.     canvas->drawCircle(640, 260, 100, paint);
  162.     surface->unlockAndPost();
  163.     sleep(3);

  164.     surface->lock(&info);
  165.     bitmap.setIsOpaque(false);    
  166.     bitmap.setPixels(info.bits);
  167.     bitmap.eraseColor(0);
  168.     canvas->setBitmapDevice(bitmap);
  169.     /* 在这里原来使用的是bitmap,但是没有显示出来,仔细分析了一下,觉得原因在图片解码的时候,
  170.      * bitmap内存被重新分配。可以看一下skia的源码。在这里画出的2.png的位置有点问题,但是jpg的
  171.      * 图片的位置时正确的,没找到原因。
  172.      */
  173.     SkBitmap Ibitmap;
  174.     SkFileDecoder(&Ibitmap, "/swcommon/1.png", 32);
  175.     SkRect dst{0, 0, bitmap.width(), bitmap.height()};
  176.     SkIRect src{0, 0, Ibitmap.width(), Ibitmap.height()};
  177.     canvas->drawBitmapRect(Ibitmap, &src, dst);
  178.     Ibitmap.eraseColor(0);
  179.     SkFileDecoder(&Ibitmap, "/swcommon/2.png", 32);
  180.     SkRect dst2{200, 200, 700, 500};
  181.     canvas->drawBitmapRect(Ibitmap, &src, dst2);
  182.     surface->unlockAndPost();
  183.     sleep(3);

  184.     surface->lock(&info);
  185.     bitmap.setPixels(info.bits);
  186.     bitmap.eraseColor(0);
  187.     canvas->setBitmapDevice(bitmap);
  188.     Ibitmap.eraseColor(0);
  189.     SkFileDecoder(&Ibitmap, "/swcommon/1.jpg", 32);
  190.     SkIRect srcj{0, 0, Ibitmap.width(), Ibitmap.height()};
  191.     canvas->drawBitmapRect(Ibitmap, &srcj, dst);

  192.     Ibitmap.eraseColor(0);
  193.     SkFileDecoder(&Ibitmap, "/swcommon/2.jpg", 32);
  194.     SkRect dst4{200, 200, 700, 500};
  195.     canvas->drawBitmapRect(Ibitmap, &src, dst4);
  196.     SkImageEncoder::EncodeFile("/swcommon/screenshot.jpg", bitmap, SkImageEncoder::kJPEG_Type, 100);

  197.     surface->unlockAndPost();
  198.     sleep(3);

  199.     LOGE("[%s %s %d] END !\n", __FUNCTION__, __FILE__, __LINE__);
  200.     return 0;
  201. }

阅读(4467) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

sno_guo2012-07-17 16:41:42

你好,博主,刚才编译了下您的代码,发现,在131行的 error: 'fb_w' was not declared in this scope, 没有定义
请问下,这个是在哪里定义的,谢谢!

sno_guo2012-07-10 23:49:08

你好,博主,感谢提供这么好的学习例子,谢谢分享!
请问下:这个程序我如何编译成android的可执行程序呢, 编译好后有该如何运行呢,谢谢!

我可以正常的编译android2。3。3的源代码,可以使用ndk-build把ffmpeg编译成android的动态库。呵呵