我在Android 4.2.2上移植了远程帧缓冲区接收C代码,该代码以RGB565格式从主机接收帧缓冲区。能够按照标准的android示例frameworks/native/services/surfaceflinger/tests/resize/resie.cpp呈现接收到的帧缓冲区。以下是使用的代码片段
sp<Surface> surface = client->createSurface(String8("resize"),
800, 480, PIXEL_FORMAT_RGB_565, 0);
SurfaceComposerClient::openGlobalTransaction();
surface->setLayer(100000);
SurfaceComposerClient::closeGlobalTransaction();
Surface::SurfaceInfo info;
surface->lock(&info);
ssize_t bpr = info.s * bytesPerPixel(info.format);
/* rfb is the remote famebuffer filled by C stack*/
memcpy((uint16_t*)info.bits, rfb, 800*480*2);
surface->unlockAndPost();
但我无法升级接收到的缓冲区以在android上渲染全屏。例如:-主机发送800*480,但安卓设备屏幕是1024*786还有以下疑虑,
1.以原生方式创建曲面是否是处理此类问题的正确方法
2.如何在Android原生平台上进行高级原始图像和渲染
3.在编写应用程序时,应用程序是否可以控制在本机上创建的这个表面?
我是安卓系统的新手,如果有人能引导我走上正确的道路来处理这个问题,那就太好了。
您当前使用的是私有的SurfaceFlinger API,需要特权访问。如果需要这样做,我认为您希望使用setSize()
调用来更改窗口的大小(这与基础曲面的大小无关)。arch-doc中的这一部分显示了如何读取adb shell dumpsys SurfaceFlinger
输出的一部分,以查看实际大小——这将告诉您调用是否有效。(通常情况下,你会通过窗口管理器,但你绕过了大部分Android框架。)
如果你能在一个没有特权的应用程序中做你需要的事情,你的代码将更具可移植性,而且不太可能随着操作系统的更改而中断。最好的方法是创建OpenGL ES纹理,并将具有glTexImage2D()
的像素"上传"到GL_UNSIGNED_SHORT_5_6_5
纹理。(我有理由相信GLES 565格式与Android gralloc格式匹配,但我还没有尝试过。)一旦你有了GLES纹理的图像,你就可以随心所欲地渲染它——你不再局限于矩形。
Grafika中有一些例子。特别是,"纹理上传基准"活动演示了上传和渲染纹理。(这是一个基准,所以它使用了屏幕外的纹理,但其他活动,如"来自相机的纹理",显示了如何在屏幕上做事情。)
基于GLES的方法要多得多,但你可以从Grafika中提取大部分内容。Java语言GLES代码通常只是对本地等效代码的一个薄薄的包装,因此,如果您决定将NDK用于GLES工作,这是一个相当直接的转换。不过,由于所有繁重的工作都是由图形驱动程序完成的,因此使用NDK并没有多大意义。(如果像素是通过纯原生代码到达的,请使用"直接"ByteBuffer包装缓冲区,以从Java语言代码获得访问权限。)