最近在做一个android的新平台,涉及到了SurfaceFlinger的使用。又要在另外一个平台上实现一个抓屏的功能,被折磨的囧啊。最近终于能够闲下来整理一下这块的东西了。网上有很多讲解SurfaceFlinger的文章,但大部分都是原理分析,看的头大。下面是一个测试小例子,测试SurfaceFlinger的使用,并结合skia测试了软合成shotsceen的性能。
- /**
- * =====================================================================================
- * Filename: surface.cpp
- * Created: 2012年03月24日 13时39分28秒
- * Author: louie (),
- * Company: sunniwell.net
- * Description: surface test
- * =====================================================================================
- */
- #define LOG_TAG "SurfaceTest"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <string.h>
- #include <linux/fb.h>
- #include <binder/IPCThreadState.h>
- #include <binder/ProcessState.h>
- #include <binder/IMemory.h>
- #include <binder/IPCThreadState.h>
- #include <binder/IServiceManager.h>
- #include <binder/MemoryHeapBase.h>
- #include <binder/MemoryBase.h>
- #include <binder/Binder.h>
- #include <utils/Log.h>
- #include <cutils/atomic.h>
- #include <cutils/properties.h>
- #include <utils/threads.h>
- #include <utils/Atomic.h>
- #include <utils/String16.h>
- #include <android_runtime/AndroidRuntime.h>
- #include <android_runtime/ActivityManager.h>
- #include <media/AudioTrack.h>
- #include <media/RobotWrapper.h>
- #include <surfaceflinger/Surface.h>
- #include <surfaceflinger/ISurface.h>
- #include <surfaceflinger/ISurfaceComposer.h>
- #include <surfaceflinger/SurfaceComposerClient.h>
- #include <ui/DisplayInfo.h>
- #include <SkTypeface.h>
- #include <SkTemplates.h>
- #include <SkRegion.h>
- #include <SkDevice.h>
- #include <SkRect.h>
- #include <SkCanvas.h>
- #include <SkBitmap.h>
- #include <SkStream.h>
- #include <SkImageDecoder.h>
- #include <SkImageEncoder.h>
- #include "hi_unf_disp.h"
- using namespace android;
- bool SkFileDecoder( SkBitmap* bitmap, const char srcPath[], int bits_per_pixel)
- {
- SkFILEStream stream(srcPath);
- if (!stream.isValid()) {
- LOGE("ERROR: bad filename <%s>\n", srcPath);
- return false;
- }
- stream.rewind();
- SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
- if (NULL == codec) {
- LOGE("ERROR: no codec found for <%s>\n", srcPath);
- return false;
- }
- SkBitmap::Config config;
- switch (bits_per_pixel)
- {
- case 32:
- config = SkBitmap::kARGB_8888_Config;
- break;
- case 16:
- config = SkBitmap::kRGB_565_Config;
- break;
- default:
- LOGE ("Warning: drawRect() not implemented for color depth %i\n",bits_per_pixel);
- break;
- }
- SkAutoTDelete<SkImageDecoder> ad(codec);
- stream.rewind();
- if (!codec->decode(&stream, bitmap, config,
- SkImageDecoder::kDecodePixels_Mode)) {
- LOGE("ERROR: codec failed for <%s>\n", srcPath);
- return false;
- }
- return true;
- }
- int main( )
- {
- sp<SurfaceComposerClient> surfaceclient;
- sp<SurfaceControl> surfaceControl;
- sp<Surface> surface;
- SkBitmap bitmap;
- Surface::SurfaceInfo info;
- DisplayInfo display;
- //surface 的名字以pid开头
- LOGE("[%s %s %d] \n", __FUNCTION__, __FILE__, __LINE__, getpid());
- surfaceclient = new SurfaceComposerClient();
- surfaceclient->getDisplayInfo(0, &display);
- LOGE("display < %d %d>", display.w, display.h);
- surfaceControl = surfaceclient->createSurface(getpid(), 0, display.w, display.h, PIXEL_FORMAT_RGBA_8888);
- //composer parameters必须在一对open/close transaction之间当close调用时,
- //参数被提交给服务端参数值的改变都存放在/frameworks/base/include/private/surfaceflinger/LayerState.h:layer_state_t中,
- //当调用closeTransaction时,结构体才会被传送到服务端。这样可以明显简化C/S接口、加快C/S通信速度。
- surfaceclient->openTransaction();
- surfaceControl->setLayer(1000);
- surfaceControl->setSize(display.w, display.h);
- surfaceControl->setPosition(1, 1);
- surfaceControl->show( );
- surfaceclient->closeTransaction();
- surface = surfaceControl->getSurface();
- surface->lock(&info);
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, fb_w, fb_h);
- bitmap.setIsOpaque(true);
- bitmap.setPixels(info.bits);
- SkCanvas* canvas = new SkCanvas(bitmap);
- surface->unlockAndPost();
- int A = 150, R = 128, G = 128, B = 128 ;
- while( A < 256)
- {
- LOGE("Surface <%d %d %d %d>\n", A, R, G, B);
- surface->lock(&info);
- /*bitmap 的buffer 被重置,surface 为双缓冲,前后buffer被替换 因此每次都要重新设置bitmap的内存*/
- bitmap.setPixels(info.bits);
- bitmap.eraseARGB(A, R, G, B);
- surface->unlockAndPost();
- A += 20;
- sleep(3);
- }
- SkPaint paint;
- int color = 0xff00ff77;
- paint.setARGB(color>>24 & 0xff, color>>16 & 0xff, color>>8 & 0xff, color & 0xff);
- surface->lock(&info);
- bitmap.setPixels(info.bits);
- bitmap.eraseARGB(0, 0, 0, 0);
- canvas->setBitmapDevice(bitmap);
- canvas->drawLine(100, 100, 500, 500, paint);
- surface->unlockAndPost();
- sleep(3);
- surface->lock(&info);
- bitmap.setPixels(info.bits);
- bitmap.eraseARGB(0, 0, 0, 0);
- SkRect rect;
- rect.fLeft = 200;
- rect.fTop = 200;
- rect.fRight = 400;
- rect.fBottom = 400;
- color = 0xffff0077;
- paint.setARGB(color>>24 & 0xff, color>>16 & 0xff, color>>8 & 0xff, color & 0xff);
- canvas->setBitmapDevice(bitmap);
- canvas->drawRect(rect, paint);
- surface->unlockAndPost();
- sleep(3);
- surface->lock(&info);
- bitmap.setPixels(info.bits);
- bitmap.eraseARGB(0, 0, 0, 0);
- color = 0xff0f00ff;
- paint.setARGB(color>>24 & 0xff, color>>16 & 0xff, color>>8 & 0xff, color & 0xff);
- canvas->setBitmapDevice(bitmap);
- canvas->drawCircle(640, 260, 100, paint);
- surface->unlockAndPost();
- sleep(3);
- surface->lock(&info);
- bitmap.setIsOpaque(false);
- bitmap.setPixels(info.bits);
- bitmap.eraseColor(0);
- canvas->setBitmapDevice(bitmap);
- /* 在这里原来使用的是bitmap,但是没有显示出来,仔细分析了一下,觉得原因在图片解码的时候,
- * bitmap内存被重新分配。可以看一下skia的源码。在这里画出的2.png的位置有点问题,但是jpg的
- * 图片的位置时正确的,没找到原因。
- */
- SkBitmap Ibitmap;
- SkFileDecoder(&Ibitmap, "/swcommon/1.png", 32);
- SkRect dst{0, 0, bitmap.width(), bitmap.height()};
- SkIRect src{0, 0, Ibitmap.width(), Ibitmap.height()};
- canvas->drawBitmapRect(Ibitmap, &src, dst);
- Ibitmap.eraseColor(0);
- SkFileDecoder(&Ibitmap, "/swcommon/2.png", 32);
- SkRect dst2{200, 200, 700, 500};
- canvas->drawBitmapRect(Ibitmap, &src, dst2);
- surface->unlockAndPost();
- sleep(3);
- surface->lock(&info);
- bitmap.setPixels(info.bits);
- bitmap.eraseColor(0);
- canvas->setBitmapDevice(bitmap);
- Ibitmap.eraseColor(0);
- SkFileDecoder(&Ibitmap, "/swcommon/1.jpg", 32);
- SkIRect srcj{0, 0, Ibitmap.width(), Ibitmap.height()};
- canvas->drawBitmapRect(Ibitmap, &srcj, dst);
- Ibitmap.eraseColor(0);
- SkFileDecoder(&Ibitmap, "/swcommon/2.jpg", 32);
- SkRect dst4{200, 200, 700, 500};
- canvas->drawBitmapRect(Ibitmap, &src, dst4);
- SkImageEncoder::EncodeFile("/swcommon/screenshot.jpg", bitmap, SkImageEncoder::kJPEG_Type, 100);
- surface->unlockAndPost();
- sleep(3);
- LOGE("[%s %s %d] END !\n", __FUNCTION__, __FILE__, __LINE__);
- return 0;
- }
阅读(4531) | 评论(2) | 转发(0) |