1

我之前的问题将我引向了这个问题,我需要将一些代码从 Java 移动到本机。我加载了很多纹理(RGBA888 中的数据高达 2GiB,不允许压缩(例如 565,ETC ......))并丢弃旧的,所以在加载过程中我得到了很多垃圾收集。我能够从 OpenGL 线程中部分移动 GC,因此它不会减慢 FPS,但会以更长的纹理加载时间为代价,因为它们被 GC 暂停。

所以我想通过在 C 中解码和上传图像来完全删除 GC。现在我使用生产者-消费者模式,一个生产者和两个消费者。为此,我使用 Java 的 LinkedBlockingDeque 和消费者扩展 Thread 类并在无限循环中从队列中获取项目。项目携带有关图像文件路径的信息,我在工作线程中解码并使用 GLSurfaceView 的 queueEvent() 方法发送到 GL 线程。

所有图像 (PNG) 都在没有压缩的 zip 文件中,我直接将它们从其中流出(Android 的 APK 扩展文件机制)。我有很多 C/C++ 经验,但没有 JNI 经验。我目前正在阅读 Android 的 JNI 示例。

问题是如何将 InputStream 发送到本机代码,在那里解码 png(我将使用 libpng),现在是棘手的部分:然后将其发送到 GL 线程并将其作为纹理上传并返回纹理 ID 并准备就绪标志回Java?或者我可以使用 java.nio ByteBuffer,它将填充本机代码,然后发送回 Java,在那里我将使用 glTexImage2D 方法将其上传,该方法采用缓冲区而不是位图?这个 java.nio 缓冲区会阻止垃圾收集,还是我必须在 C 中做所有事情?

我的目标是 Android 3.2 及更高版本。

4

0 回答 0