Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无法跟踪从其他线程渲染的帧_Android_Opengl Es_Systrace - Fatal编程技术网

Android 无法跟踪从其他线程渲染的帧

Android 无法跟踪从其他线程渲染的帧,android,opengl-es,systrace,Android,Opengl Es,Systrace,我们公司为移动平台开发了几种游戏,包括Android。我们将OpenGL用于所有可视化项目,包括UI(更多技术细节如下) 在发布前的报告中,我们从谷歌Play控制台收到了一些奇怪的警告,比如“你的应用程序花了20764毫秒才发布”。在本报告提供的视频中,游戏用了大约一秒钟的时间开始 经过一些调查,我们发现Android Systrace无法检测从另一个线程生成的OpenGL绘图。因此,发布前测试认为(错误地)我们的游戏非常慢 是否有某种方法通知系统已绘制框架?似乎eglSwapBuffers()

我们公司为移动平台开发了几种游戏,包括Android。我们将OpenGL用于所有可视化项目,包括UI(更多技术细节如下)

在发布前的报告中,我们从谷歌Play控制台收到了一些奇怪的警告,比如“你的应用程序花了20764毫秒才发布”。在本报告提供的视频中,游戏用了大约一秒钟的时间开始

经过一些调查,我们发现Android Systrace无法检测从另一个线程生成的OpenGL绘图。因此,发布前测试认为(错误地)我们的游戏非常慢

是否有某种方法通知系统已绘制框架?似乎eglSwapBuffers()还不够

有一个链接指向Cocos2d的相同问题:

一些细节 当一个新版本发布到Google Play控制台时,一些自动测试会在不同的设备上执行。这些测试的结果可以在Google Play控制台的发布前报告部分找到

从四月初开始,我们在一些设备上收到奇怪的性能警告(总是相同的)。两个例子:

  • 启动时间:您的应用程序启动时间为20764毫秒
  • 冻结帧:33.33%的帧渲染时间超过700毫秒
这两个问题听起来都很可怕——如果是真的话。但当我们检查测试视频时,我们没有发现任何问题。所有的游戏开始都很快,运行起来没有视觉上的口吃

Systrace报告 这是systrace的图片,显示游戏开始的5秒(矩形是我画的)

如您所见,systrace仅找到4个渲染帧(粉红色矩形),它们是从RenderRead绘制的。但由于某种原因,Android无法检测到在另一个线程(蓝色矩形)中执行的GL draw调用

发射前报告也仅显示3到4帧,每帧长300-400毫秒

初始化代码 我们的游戏引擎在一个单独的线程中运行所有游戏逻辑和渲染代码。这是简化的初始化代码

工作线程是从活动的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可防止环路性能过高。诸如资源加载之类的繁重操作是异步完成的,以避免冻结


从用户的角度来看,这种方法效果很好。游戏加载速度快且运行平稳。

一种解决方案可能是从辅助线程向主线程发送消息,以便在主线程中进行渲染。另一个解决方案是,因为只是ASystrace抱怨,欺骗ASystrace,例如在主线程中渲染初始启动屏幕。是的,我们考虑过将渲染移动到主线程。但这需要一些额外的同步代码。简单的乒乓同步可能会引入传统的延迟,而更复杂的版本最初可能会有bug。我们的游戏已经售出,而且警告不会(尚未)带来任何后果,因此我们有点害怕对引擎进行重大更改。至于启动屏幕,这可能有助于处理“20秒启动”,但可能无法解决关于冻结帧的警告,因为它只会在systrace找到的其他3或4帧的基础上再添加一帧。或者我有什么不对劲?