0

我在 Android 4.2.2 上移植了远程帧缓冲区接收 C 代码,它以 RGB565 格式从主机接收帧缓冲区。能够按照标准 android 示例 frameworks/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. 在写app的时候,app是否可以控制这个在native上创建的surface?

我是 android 新手,如果有人能引导我走上正确的道路来处理这个问题,那就太好了

4

1 回答 1

0

您当前正在使用私有 SurfaceFlinger API,这需要特权访问。如果您需要这样做,我认为您想使用setSize()调用来更改窗口的大小(这与底层 Surface 的大小无关)。 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 语言代码中访问。)

于 2015-06-21T17:10:56.603 回答