Android 无法跟踪从其他线程渲染的帧
我们公司为移动平台开发了几种游戏,包括Android。我们将OpenGL用于所有可视化项目,包括UI(更多技术细节如下) 在发布前的报告中,我们从谷歌Play控制台收到了一些奇怪的警告,比如“你的应用程序花了20764毫秒才发布”。在本报告提供的视频中,游戏用了大约一秒钟的时间开始 经过一些调查,我们发现Android Systrace无法检测从另一个线程生成的OpenGL绘图。因此,发布前测试认为(错误地)我们的游戏非常慢 是否有某种方法通知系统已绘制框架?似乎eglSwapBuffers()还不够 有一个链接指向Cocos2d的相同问题: 一些细节 当一个新版本发布到Google Play控制台时,一些自动测试会在不同的设备上执行。这些测试的结果可以在Google Play控制台的发布前报告部分找到 从四月初开始,我们在一些设备上收到奇怪的性能警告(总是相同的)。两个例子:Android 无法跟踪从其他线程渲染的帧,android,opengl-es,systrace,Android,Opengl Es,Systrace,我们公司为移动平台开发了几种游戏,包括Android。我们将OpenGL用于所有可视化项目,包括UI(更多技术细节如下) 在发布前的报告中,我们从谷歌Play控制台收到了一些奇怪的警告,比如“你的应用程序花了20764毫秒才发布”。在本报告提供的视频中,游戏用了大约一秒钟的时间开始 经过一些调查,我们发现Android Systrace无法检测从另一个线程生成的OpenGL绘图。因此,发布前测试认为(错误地)我们的游戏非常慢 是否有某种方法通知系统已绘制框架?似乎eglSwapBuffers()
- 启动时间:您的应用程序启动时间为20764毫秒
- 冻结帧:33.33%的帧渲染时间超过700毫秒
public class MyActivity extends Activity
{
protected Thread worker = null;
private native void Run();
@Override
protected void onStart()
{
super.onStart();
if(worker == null)
{
worker = new Thread()
{
public void run()
{
Run();
}
};
worker.start();
}
}
}
线程唯一要做的就是Run()本机函数。此函数可以分解为以下内容:
void MyActivity::Run()
{
initApp();
while(!destroyRequested())
{
// Process the game logic.
if (activated && window != NULL)
{
time->process();
input->process();
sound->process();
logic->process();
graphics->draw();
}
}
clearApp();
}
如您所见,辅助线程不断旋转更新和绘制循环。Vsync可防止环路性能过高。诸如资源加载之类的繁重操作是异步完成的,以避免冻结
从用户的角度来看,这种方法效果很好。游戏加载速度快且运行平稳。一种解决方案可能是从辅助线程向主线程发送消息,以便在主线程中进行渲染。另一个解决方案是,因为只是ASystrace抱怨,欺骗ASystrace,例如在主线程中渲染初始启动屏幕。是的,我们考虑过将渲染移动到主线程。但这需要一些额外的同步代码。简单的乒乓同步可能会引入传统的延迟,而更复杂的版本最初可能会有bug。我们的游戏已经售出,而且警告不会(尚未)带来任何后果,因此我们有点害怕对引擎进行重大更改。至于启动屏幕,这可能有助于处理“20秒启动”,但可能无法解决关于冻结帧的警告,因为它只会在systrace找到的其他3或4帧的基础上再添加一帧。或者我有什么不对劲?