我们公司开发了多种移动平台游戏,包括Android。我们将OpenGL用于所有可视项,包括UI(更多技术细节在下面)。
我们在发布前的报告中从Google Play控制台收到了一些奇怪的警告,例如“您的应用启动需要20764毫秒”。在此报告随附的视频中,游戏耗时约一秒钟开始。
经过一些调查,我们发现Android Systrace无法检测到从另一个线程进行的OpenGL绘制。因此,发布前测试(错误地)认为我们的游戏非常慢。
是否有某种方法可以通知系统已绘制边框?似乎eglSwapBuffers()不够。
与Cocos2d相同的问题有一个链接:https://discuss.cocos2d-x.org/t/frozen-frames-warnings-by-google-play-pre-launch-report-for-3-17-cocos-demo-app/42894
将新版本发布到Google Play控制台后,会在不同设备上执行一些自动测试。这些测试的结果可在Google Play控制台的预发布报告部分中找到。
从4月初开始,我们在某些设备(总是相同的设备)上收到奇怪的性能警告。两个例子:
这两个问题听起来都是可怕的-他们会是真的吗?但是,当我们检查测试视频时,我们看不到任何问题。所有游戏的启动速度都非常快,并且运行时不会出现视觉卡顿现象。
这是systrace的图片,显示了我们游戏开始5秒钟(我画了矩形)。
如您所见,systrace仅发现了从RenderThread绘制的4个渲染帧(粉红色矩形)。但是由于某种原因,Android无法检测到我们在其他线程(蓝色矩形)中执行的GL绘制调用。
发布前报告还仅显示3到4帧,每帧长300-400毫秒。
我们的游戏引擎在单独的线程中运行所有游戏逻辑并渲染代码。这是简化的初始化代码。
工作线程是通过Activity的onStart()重写方法创建的。
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可防止环路性能过高。资源加载等繁重的操作是异步完成的,以避免冻结。
从用户方面来看,这种方法很好用。游戏加载迅速且运行顺利。