普通应用使用Surface的方法

Android的NDK提供了Surface类,可供应用向屏幕绘图,但使用这个类,有很多机关,
如果不注意,代码就不会正常工作。
下面是我们使用的时候遇到的问题与解决方法。

1,在C++代码里要使用Surface类,必须在APK的工程文件Android.mk里增加权限

uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
如果没有这句,则创建Surface会失败。

2,创建Surface

//sp client;
client = new SurfaceComposerClient();
// 然后向 Surfaceflinger 申请一个 Surface , surface 类型为 PushBuffers

DisplayInfo dispInfo;
client->getDisplayInfo(0,&dispInfo);

int ok = client->initCheck();

// 创建Surface,颜色为32位;ePushBuffers表示buffer由我们提供
surfaceControl = client->createSurface(getpid(), 0, 800, 600,
PIXEL_FORMAT_RGBA_8888, ISurfaceComposer::ePushBuffers);
if (surfaceControl == NULL) {
return JNI_FALSE;
}

// 设置位置,大小以及Z-order
client->openTransaction();
surfaceControl->setPosition(0, 0);
surfaceControl->setSize(800, 600);
surfaceControl->setLayer(99999);
surfaceControl->show();
client->closeTransaction();

3,获取ISurface对象
// 这一句需要权限,要在surface.h里加入frends class
isurface = Test::getISurface(surfaceControl);
这里使用了一个技巧,具体参见“欺骗编译器取得ISurface对象的方法”

4,注册buffer

static const char* pmem = "/dev/pmem";

// 这一句需要root权限
heap = new MemoryHeapBase(pmem, 800 * 600 * 4);
if (heap->heapID() < 0) {
return JNI_FALSE;
}
sp pmemHeap = new MemoryHeapPmem(heap, 0);
if (pmemHeap->getHeapID() >= 0) {
// pmemHeap->slap();
// heap.clear();
// pmemHeap.clear();
return JNI_FALSE;
}

mBufferHeap = ISurface::BufferHeap(800, 600,
800, 600, PIXEL_FORMAT_BGRA_8888, pmemHeap);

int ret = isurface->registerBuffers(mBufferHeap);
这里,因为要打开/dev/pmem设备文件,因此需要有权限,方法很简单,就是root手机,
然后使用命令
chmod a+rw /dev/pmem
来增加权限。
用完后记得复原,否则可能有安全风险。
在代码里修改权限参见“调用Su命令修改设备文件权限的Java代码”。

5,得到buffer指针
char * bp = static_cast(mBufferHeap.heap->base());

6,向buffer写位图数据,注意要是32位的
具体写的代码请参见“向Surface写位图数据的方法”

7,提交修改,通知Surface Flinger更新屏幕
isurface->postBuffer(0);

这样屏幕上就可以看到显示了。


http://blog.sina.com.cn/s/blog_53d1e55b0100ne4x.html

你可能感兴趣的:(java,android,jni,null,buffer,编译器)