1257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma/*
2257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * Copyright (C) 2009 The Android Open Source Project
3257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma *
4257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * Licensed under the Apache License, Version 2.0 (the "License");
5257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * you may not use this file except in compliance with the License.
6257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * You may obtain a copy of the License at
7257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma *
8257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma *      http://www.apache.org/licenses/LICENSE-2.0
9257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma *
10257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * Unless required by applicable law or agreed to in writing, software
11257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * distributed under the License is distributed on an "AS IS" BASIS,
12257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * See the License for the specific language governing permissions and
14257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma * limitations under the License.
15257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma */
16257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
17257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumapackage com.android.testframerate;
18257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
19257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.content.Context;
20257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.opengl.GLSurfaceView;
21257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.os.SystemProperties;
22257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.util.AttributeSet;
23257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.util.Log;
24257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.view.KeyEvent;
25257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.view.MotionEvent;
26257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
27257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport java.nio.ByteBuffer;
28257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport java.nio.ByteOrder;
29257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport java.nio.FloatBuffer;
30257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
31257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport javax.microedition.khronos.egl.EGL10;
32257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport javax.microedition.khronos.egl.EGLConfig;
33257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport javax.microedition.khronos.egl.EGLContext;
34257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport javax.microedition.khronos.egl.EGLDisplay;
35257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport javax.microedition.khronos.opengles.GL10;
36257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
37257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaimport android.opengl.GLES20;
38257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
39257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shumaclass TestFramerateView extends GLSurfaceView {
40257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    private static String TAG = "TestFramerateView";
41257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
42257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    public TestFramerateView(Context context) {
43257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        super(context);
44257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        setEGLContextClientVersion(2);
45257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        setRenderer(new Renderer());
46257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    }
47257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
48257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    private long mLastTime_us = 0;
49257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    private long mNumShortFramesElapsed = 0;
50257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    private void registerTime(long now_us) {
51257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        long longFrameTime_ms = Integer.parseInt(SystemProperties.get("debug.longframe_ms", "16"));
52257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        long elapsedTime_us = now_us - mLastTime_us;
53257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        float fps = 1000000.f / elapsedTime_us;
54257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        if (mLastTime_us > 0 && elapsedTime_us > longFrameTime_ms*1000) {
55257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma          Log.v(TAG, "Long frame: " + elapsedTime_us/1000.f + " ms (" + fps + " fps)");
56257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma          if (mNumShortFramesElapsed > 0) {
57257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            Log.v(TAG, "  Short frames since last long frame: " + mNumShortFramesElapsed);
58257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            mNumShortFramesElapsed = 0;
59257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma          }
60257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        } else {
61257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            ++mNumShortFramesElapsed;
62257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        }
63257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
64257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        mLastTime_us = now_us;
65257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    }
66257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
67257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    private class Renderer implements GLSurfaceView.Renderer {
68257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        public Renderer() {
69257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        }
70257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
71257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
72257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        public void onDrawFrame(GL10 gl) {
73257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            long now_us = System.nanoTime() / 1000;
74257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            registerTime(now_us);
75257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
76257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            float red = (now_us % 1000000) / 1000000.f;
77257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            float green = (now_us % 2000000) / 2000000.f;
78257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            float blue = (now_us % 3000000) / 3000000.f;
79257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            GLES20.glClearColor(red, green, blue, 1.0f);
80257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
81257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        }
82257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
83257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        public void onSurfaceChanged(GL10 gl, int width, int height) {
84257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma            GLES20.glViewport(0, 0, width, height);
85257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        }
86257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
87257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
88257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma        }
89257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma
90257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma    }
91257d2bbcbf275757f4009e3b02bd6657e6c13b27Jim Shuma}
92