Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.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 OpenGL E.S.2.0:非常不一致的帧率_Android_Opengl Es - Fatal编程技术网

Android OpenGL E.S.2.0:非常不一致的帧率

Android OpenGL E.S.2.0:非常不一致的帧率,android,opengl-es,Android,Opengl Es,我创建了一个简单的Android应用程序,如下所示: 活动: public class MainActivity extends Activity { private GLSurfaceView mGLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new MyGL

我创建了一个简单的Android应用程序,如下所示:

活动:

public class MainActivity extends Activity {
    private GLSurfaceView mGLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLView = new MyGLSurfaceView(this);
        setContentView(mGLView);
    }
}
class MyGLSurfaceView extends GLSurfaceView {

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(new MyGL20Renderer());
    }
}
public class MyGL20Renderer implements GLSurfaceView.Renderer {

    private long mCurrentTime;

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    }

    @Override
    public void onDrawFrame(GL10 unused) {

        final long newTime = getSystemTime();
        final long dt = newTime - mCurrentTime;
        mCurrentTime = newTime;

        Log.e("test", "dt: "+dt);

        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    @Override
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }

    private long getSystemTime() {
        return System.nanoTime()/1000L;
    }

}
OpenGL曲面:

public class MainActivity extends Activity {
    private GLSurfaceView mGLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLView = new MyGLSurfaceView(this);
        setContentView(mGLView);
    }
}
class MyGLSurfaceView extends GLSurfaceView {

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(new MyGL20Renderer());
    }
}
public class MyGL20Renderer implements GLSurfaceView.Renderer {

    private long mCurrentTime;

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    }

    @Override
    public void onDrawFrame(GL10 unused) {

        final long newTime = getSystemTime();
        final long dt = newTime - mCurrentTime;
        mCurrentTime = newTime;

        Log.e("test", "dt: "+dt);

        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    @Override
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }

    private long getSystemTime() {
        return System.nanoTime()/1000L;
    }

}
渲染器:

public class MainActivity extends Activity {
    private GLSurfaceView mGLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLView = new MyGLSurfaceView(this);
        setContentView(mGLView);
    }
}
class MyGLSurfaceView extends GLSurfaceView {

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(new MyGL20Renderer());
    }
}
public class MyGL20Renderer implements GLSurfaceView.Renderer {

    private long mCurrentTime;

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    }

    @Override
    public void onDrawFrame(GL10 unused) {

        final long newTime = getSystemTime();
        final long dt = newTime - mCurrentTime;
        mCurrentTime = newTime;

        Log.e("test", "dt: "+dt);

        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    @Override
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }

    private long getSystemTime() {
        return System.nanoTime()/1000L;
    }

}
如你所见,对于每一帧,我取奈米时间除以1000得到微秒的时间

现在,当我查看在
onDrawFrame()
中生成的输出时,我得到了各种不同的值:

(此处为原始尺寸:)

x标度仅是帧。每帧一个值。y-刻度是在
onDrawFrame()
中计算的增量时间dt。这是上一帧绘制所用的时间(以微秒为单位)

现在我完全明白了,由于以下原因,值不能保持在16666:

  • 增量时间不能完全确定。此外,将nanotime除以1000并将其转换为
    long
    会导致一些计算错误
  • 系统必须等待
    eglSwapBuffers()
  • 函数
    onDrawFrame()
    完成后,这只意味着OpenGL命令已发送到管道。但这并不意味着命令已经被处理
但我仍然不明白为什么我会得到如此高的抖动结果,而我基本上什么都不计算

问题的根源可能是什么

测试环境:

  • 宏达一号
  • CyanogenMod 10.2(安卓4.3)

如果其他人能够重现这一点,我将非常高兴。

您将发现不一致的帧速率是由于Log语句造成的。如果您存储数据点,然后同时记录它们,您将看到帧率更加一致。使用类似以下的方法来记录数据。我每1000帧做一次,得到的dt大约为16500-18500

    mDt[mStoredDtCount] = dt;
    mStoredDtCount++;
    if (mStoredDtCount == DT_MAX_COUNT) {
        while (mStoredDtCount > 0) {
            mStoredDtCount--;
            Log.e("test2", "dt: "+mDt[mStoredDtCount]);
        }
    }

嗯,我不确定这是不是真的。我已经用你的方法完成了,现在得到了这个图(大约捕获了一分钟):我唯一的另一个想法是看看你的设备是否在帧之间进行垃圾收集。我已经从日志输出中删除了过滤器,并将其设置为“verbose”。在整个运行期间,没有一条关于GC的消息。如果您想将源代码压缩并上传到某个地方,我将在我的设备上尝试您的代码。嗨,levis501,谢谢您的回答。我在这里上传了一个zip:它包含.apk和源代码。