5

我正在尝试在 Android 上使用 OpenGL ES 实现离屏渲染。我的最终目标是提高我在普通 java 和 Bitmap/int[] API 中执行的纹理映射的性能。我尝试了 pbuffer 方法,类似于相关论坛线程中的示例代码。它显示出相当低的性能,glReadPixels在一台设备上调用最多需要 50 毫秒,而在另一台设备上最多需要 15 毫秒。

使用帧缓冲区有更现代的方法。代码示例相当复杂,我预计从帧缓冲区到 Android 位图的传输速度不会比使用 pbuffers 快得多。我的估计是对的吗?

第三种方法是使用像素图。如果我理解正确的文档,他们应该在 OpenGL 和 Dalvik 的内存之间利用比普通副本更复杂的内存共享。问题是 Android SDK 中不存在相关的 API。

Java中没有暴露eglCreateImageKHR和结构。EGLImageKHR我能找到的所有 C++ 示例都依赖于它们。

有,eglCreatePixmapSurface但我无法从文档中弄清楚如何使用它。可能它在参数中接收某种位图句柄native_pixmap,但我找不到任何方法来创建这样的句柄。搜索“eglCreatePixmapSurface android”只会导致问题报告。

我的主要问题是:我可以在不编写本机代码的情况下通过 Java 在 Android 上使用像素图吗?如果我需要本地化,在深入研究 OpenGL 之前,是否有可以用来评估性能的工作代码?

4

1 回答 1

6

在 Android 上提高纹理加载性能的最佳方法是使用您安装的 EGL 图像扩展和带有本机代码的 EGL_NATIVE_BUFFER_ANDROID。我在本文中有一个代码示例。我用这种方法测量了主要的性能改进。

Android 不支持 Pixmaps,并且 pbuffers 不适用于 Nvidia Tegra 设备。您应该改用 FBO 附加的纹理。这就是 Android SurfaceTexture 类的实现方式。

如果您需要 alpha 纹理,这是使用本机代码的另一个原因。Bitmap 和 OpenGL ES 与 alpha 纹理之间存在兼容性问题。

正如本文所讨论的,使用硬件纹理压缩格式(ETC/PVR 而不是 PNG)和 mipmap 也大大提高了纹理渲染的加载性能和质量

最大的问题是 glReadPixels()。EGL_NATIVE_BUFFER_ANDROID 仅适用于写入纹理,不适用于将它们读回位图。Android的平台代码使用glReadPixels()来实现TextureView.getBitmap(),速度很慢。最好的解决方案是不将纹理复制到 Bitmap,而是直接显示渲染的 TextureView,从而避免 glReadPixels()。

我一直在使用 OpenGL ES 2.0,而 3.0 的情况可能有所改善。

于 2014-08-27T19:41:28.377 回答