如何解决 Buffer.put() 和 Android OpenGL 的性能问题

发布于 2024-09-13 14:17:32 字数 208 浏览 5 评论 0原文

一般来说,这是一个 Java 问题,尽管在这种特殊情况下,我在 Android 中使用 OpenGL 的顶点数组。要使用这个基本的 GL 系统,您必须在本机分配模式下使用 Java 的 Buffer 系统。这在 Java 上非常慢。我的整个应用程序大约有 40-50% 的时间花在 buffer.put() 内。

有什么方法可以在使用 Java 的同时加快速度(即不使用本机 sdk)?

It is a Java issue in general, though in this particular case I am using Vertex Arrays in Android for OpenGL. To use this basic GL system, you must use Java's Buffer system in native allocation mode. This is very slow on Java. And roughly 40-50% of my entire application's time is spent inside of buffer.put().

Is there any way to speed this up while staying in Java (ie, don't use the native sdk)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱,才寂寞 2024-09-20 14:17:32

方法将指向缓冲区的指针传递给 Java。

jobject NewDirectByteBuffer(JNIEnv * env, void * address, jlong capacity); 

我在集成 Java 和 JOGL 时遇到了类似的问题 - 我的解决方案是在 C 中管理缓冲区资源,并使用 JNI 使用jni.h 中找到的 当需要更新缓冲区的偏移量时,请使用反射手动修改 java.nio.Buffer 中的“address”字段。如果添加更多元素会导致超出 C 中缓冲区的容量,请在 C 中使用数组列表,并让直接缓冲区指向支持该列表的数组。

I've encountered a similar problem when integrating Java and JOGL - my solution was to manage the buffer resources in C, and use JNI to pass the pointer to the buffer to Java using the method

jobject NewDirectByteBuffer(JNIEnv * env, void * address, jlong capacity); 

found in jni.h. When you need to update the offset into the buffer, use reflection to manually modify the "address" field found in java.nio.Buffer. If adding more elements would cause you to exceed the capacity of the buffer in C, use an array list in C and have the direct buffer point to the array backing for the list.

年华零落成诗 2024-09-20 14:17:32

一般情况下避免分配。使用缓冲区池并根据需要调整它们。您可以有一些标准大小并在最后浪费一些字节以换取性能。另外,当使用 OpenGL 时,您通常不需要每帧重写缓冲区(除非您进行大量的蒙皮或动画?)。通常,您有预先烘焙的数组,使用矩阵转换对象,仅此而已。

Avoid allocations in general. Use a pool of buffers and juggle them around as needed. You can have a few standard sizes and waste a few bytes at the end in exchange for performance. Also, when using OpenGL you typically don't need to rewrite your buffers every frame (unless you do extensive skinning or animation?). Normally, you have your pre-baked arrays, transform objects using matrices, and that's it.

旧情勿念 2024-09-20 14:17:32

您真正能做的唯一一件事就是批处理您的工作,并希望手机中的实现良好,因为惩罚来自锁定和解锁。如果您批量呼叫,驱动程序应锁定和解锁一次。如果你“自发地”这样做,你将一直锁定和解锁,这会给你带来巨大的性能影响。
如果驱动程序不够聪明,只能将缓冲区映射到内存一次,而不是每次调用都映射一次,那么最好的选择就是尽量减少放置次数。

The only thing you can do really is to batch your jobs and hope the implementation in the phone is decent, since the penalty comes from locking and unlocking. If you batch your calls the driver should lock and unlock once. If you do it "spontaneously" you will lock and unlock all the time, which will give you a hefty performance hit.
If the driver isn't clever enough to only map the buffers into ram once instead of for every call your best bet is to simply minimize the number of puts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文