如何在Android原生中升级和渲染远程(RGB565)帧缓冲?

时间:2015-06-20 12:54:48

标签: android graphics android-ndk android-gui surfaceflinger

我在Android 4.2.2上移植了远程帧缓冲区接收C代码,它以RGB565格式从主机接收帧缓冲区。能够在标准的android示例框架/ native / services / surfaceflinger / tests / resize / resize.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但Android设备屏幕为1024 * 786 也有以下疑虑,
 1.以原生方式创建表面以正确的方式来处理这类问题吗?  2.如何在Android原生图像上进行高档原始图像和渲染?  3.在编写应用程序时,应用程序是否可以控制此表面是否在本机上创建?

我是Android新手,如果有人可以指导我正确处理这个问题,那将会很棒

1 个答案:

答案 0 :(得分:0)

您目前正在使用需要特权访问的私有SurfaceFlinger API。如果你需要这样做,我你想使用setSize()调用来改变窗口的大小(这与底层Surface的大小无关)。 arch doc中的This section显示了如何阅读部分adb shell dumpsys SurfaceFlinger输出以查看实际大小是什么 - 它会告诉您呼叫是否正常工作。 (通常情况下,您需要通过窗口管理器,但是您绕过了大部分Android框架。)

如果您可以在非特权应用中执行所需操作,那么您的代码将更具可移植性,并且不太可能破坏操作系统的更改。最好的方法是创建一个OpenGL ES纹理和#34;上传&#34;具有glTexImage2D()GL_UNSIGNED_SHORT_5_6_5纹理的像素。 (我有理由相信GLES 565格式符合Android gralloc格式,但我还没有尝试过。)一旦你有GLES纹理的图像,你可以随心所欲地呈现它 - 你&# 39;不再局限于矩形。

可以在Grafika中找到一些示例。尤其是"texture upload benchmark&#34;活动演示上传和渲染纹理。 (它是一个基准,所以它使用了屏幕外的纹理,但其他活动,例如&#34;来自相机的纹理&#34;显示如何在屏幕上进行操作。)

基于GLES的方法工作要多得多,但是你可以从Grafika中取出大部分作品。 Java语言GLES代码通常只是本机等价物的一个薄包装器,因此如果您决定使用NDK进行GLES工作,那么它是一个相当直接的转换。但是,由于所有繁重工作都是由图形驱动程序完成的,因此使用NDK并没有太大意义。 (如果像素是通过纯本机代码到达的,请使用&#34; direct&#34; ByteBuffer包装缓冲区以从Java语言代码访问。)