最近在做一个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. }

更多相关文章

  1. Android中汉字转拼音的内存优化处理
  2. Android(安卓)Go初探
  3. android下使用单元测试
  4. Robotium源代码编译
  5. Android中SparseArray性能优化的使用方法
  6. Android(安卓)Junit单元测试
  7. Android(安卓)App优化:内存优化、电量优化、网络优化等 (2)
  8. 探究android:largeHeap
  9. 北京友好互动科技发展有限公司招聘ios、c++、php等职位

随机推荐

  1. Android中微信支付的调用方法
  2. Android之音频开发基础入门
  3. Android开发-从硬件到APP(一) : 单独编内核
  4. Android布局方式(FrameLayout)学习
  5. 【usb存储挂载】android6.0固定usb存储挂
  6. # Android的按键消息分发机制
  7. [置顶] Android中调用系统相机、系统相册
  8. Android透明状态栏与沉浸模式全解
  9. [程序猿感悟] Android平台开发中的重构三
  10. Android仿搜狗浏览器加载动画