dol*_*hin 5 java-native-interface android opengl-es-2.0
下面两个问题.
我们有一个图形OpenGL ES 2应用程序,在Windows,Linux,MacOS,iPhone,iPad和Android手机上运行了好几年.在过去的几个月里,我们开始收到一些Android设备用户的反馈(如Toshiba Thrive,HTC One X,Nexus 7或Asus Transformer,API 15和17),关于黑屏或闪烁屏幕的问题,或很少,应用程序崩溃.我们的应用程序针对API 9及以上,它是使用NativeActivity在NDK中编写的,直接基于nvidia android示例和演示,它已经在所有平台上进行了彻底测试,没有内存泄漏,没有无效的内存访问,它很少调用一些小的java码.
看看LogCat,我们注意到这些设备上有两种错误消息:
(1) JNI ERROR: env->self != thread-self (0x11734c0 vs. 0xd6d360); auto-correcting
(2)NvRmChannelSubmit failed (err = 196623, SyncPointValue = 0)其次是GL_OUT_OF_MEMORY
关于(1),我们知道线程与JNI问题,我们希望知道如何解决这个问题.我已经阅读了这些信息,我的问题是:"自动更正"是否意味着我们必须担心一些错误,或者它只是一个警告意味着代码在未来会表现得很糟糕,但现在它运行得很好(更正!)这与问题(2)无关?我问的原因是有时候我们也会看到以下几行:
E/libEGL: call to OpenGL ES API with no current context (logged once per thread)
E/NvEGLUtil: Failure: eglSwapBuffers, error = 0x0000300d (swap:422)
Run Code Online (Sandbox Code Playgroud)
哪个看起来很认真 我们已经在启用了JNIcheck的API 17模拟器上测试了我们的应用程序 - 没有报告任何问题,并且应用程序运行良好.
现在,关于消息(2),我找到了一些论坛(例如这里,这里也是这个),人们报告了这个消息,原因尚不清楚.看起来像固件或驱动程序问题,或GPU内存泄漏或内存碎片...许多游戏都受到屏幕闪烁的影响,人们正在尝试重启/重置设备,清除缓存,升级等,但问题似乎仍然存在.这个问题涉及很多流行的设备.尽管有GL_OUT_OF_MEMORY错误代码,但"没有足够的内存"是不合理的,因为我们用于测试的应用程序使用的是小型32x32纹理而不是常规版本中使用的512x512纹理(这些更大的纹理在旧设备上运行得非常好).任何人都有如何解决这个问题的经验,这在我们这方面是否可以解决?这是官方确认的硬件/固件/操作系统错误吗?我正在寻找一个已知的原因和这个问题的真正解决方案,而不是一个在不知道原因的情况下会意外帮助的试错工作方法.
谢谢!
因此,经过几年的尝试找出问题所在,是时候给出答案了:-) 这个问题非常痛苦、耗时且难以(几乎不可能)调试,它是不确定的、罕见的,只会影响某些特定设备,它似乎与系统的特定版本相关,甚至与同时运行(或不运行)其他程序相关......
\n\n在我们的 C++ 代码中,在 nvidia 框架函数的末尾,bool Engine::initUI()我们调用了我们自己的keepScreenOn(getApp())函数,该函数使用当前活动的参数,调用了我们自己的静态 java 方法:
//Keep the screen on.\n//Note that flag modification must be done in the UI thread:\n//https://android-developers.googleblog.com/2009/05/painless-threading.html\nstatic void keepScreenOn(Activity a) {\n final Window w = a.getWindow();\n if (w != null) {\n a.runOnUiThread(new Runnable() {\n public void run() {\n w.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n }\n });\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n据我了解,修改 Window 标志会导致窗口被销毁并重新创建(如果我错了,请纠正我),这在应用程序启动过程中显然不是一个好主意。似乎这就是导致 \xe2\x80\x93 的原因,尽管极其罕见 \xe2\x80\x93 线程之间的一些竞争条件或某些图形驱动程序的问题......这导致延迟的错误消息,例如“NvRmChannelSubmit failed (err = 196623) ,SyncPointValue = 0)”,然后是“GL_OUT_OF_MEMORY”。
\n\n设置窗口标志导致如此延迟的 GL 问题的事实令人惊讶,并且不是通过演绎发现的(我们花了几年时间试图在 OpenGL 代码中找到此问题的原因)。它是通过无望地注释掉任何可能影响显示的代码片段而发现的......解决方案是引入我们自己的子类,该子类NativeActivity从一开始就使用正确的标志创建主应用程序窗口:
public class OurSubclassOfNativeActivity extends NativeActivity\n{\n @Override\n protected void onCreate(Bundle savedInstanceState)\n {\n getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); \n super.onCreate(savedInstanceState);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我们想避免引入我们自己的 子类NativeActivity,但似乎需要设置强制FLAG_KEEP_SCREEN_ON我们这样做。
| 归档时间: |
|
| 查看次数: |
877 次 |
| 最近记录: |