summaryrefslogtreecommitdiffstats
path: root/opengl
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2010-09-22 12:13:02 -0700
committerJack Palevich <jackpal@google.com>2010-09-22 12:13:02 -0700
commitd0259a47fc90a0a3c69724a686580b29b4c36e69 (patch)
treefb4d206364dee7b8498a95415a7b29d33b01f0be /opengl
parent2867be8820963e03a091fb86ea4569ec9a2a4101 (diff)
downloadframeworks_base-d0259a47fc90a0a3c69724a686580b29b4c36e69.zip
frameworks_base-d0259a47fc90a0a3c69724a686580b29b4c36e69.tar.gz
frameworks_base-d0259a47fc90a0a3c69724a686580b29b4c36e69.tar.bz2
Add simple interactive end-to-end latency test.
Change-Id: I4c2f2acf797a3a753f8a6061db3d2bcdc7d642f0
Diffstat (limited to 'opengl')
-rw-r--r--opengl/tests/testLatency/Android.mk20
-rw-r--r--opengl/tests/testLatency/AndroidManifest.xml37
-rw-r--r--opengl/tests/testLatency/res/values/strings.xml29
-rw-r--r--opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java47
-rw-r--r--opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java267
5 files changed, 400 insertions, 0 deletions
diff --git a/opengl/tests/testLatency/Android.mk b/opengl/tests/testLatency/Android.mk
new file mode 100644
index 0000000..96417c7
--- /dev/null
+++ b/opengl/tests/testLatency/Android.mk
@@ -0,0 +1,20 @@
+#########################################################################
+# Test end-to-end latency.
+#########################################################################
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SDK_VERSION := 8
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := TestLatency
+
+include $(BUILD_PACKAGE)
diff --git a/opengl/tests/testLatency/AndroidManifest.xml b/opengl/tests/testLatency/AndroidManifest.xml
new file mode 100644
index 0000000..741266e
--- /dev/null
+++ b/opengl/tests/testLatency/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.testlatency">
+ <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" />
+
+ <application
+ android:label="@string/testLatency_activity">
+ <activity android:name="TestLatencyActivity"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/opengl/tests/testLatency/res/values/strings.xml b/opengl/tests/testLatency/res/values/strings.xml
new file mode 100644
index 0000000..0309991
--- /dev/null
+++ b/opengl/tests/testLatency/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+ them to be changed based on the locale and options. -->
+
+<resources>
+ <!-- Simple strings. -->
+ <string name="testLatency_activity">TestLatency</string>
+
+</resources>
+
diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java
new file mode 100644
index 0000000..ed993cb
--- /dev/null
+++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testlatency;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class TestLatencyActivity extends Activity {
+
+ TestLatencyView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new TestLatencyView(getApplication());
+ setContentView(mView);
+ mView.setFocusableInTouchMode(true);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java
new file mode 100644
index 0000000..d62bf17
--- /dev/null
+++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testlatency;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation. This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class TestLatencyView extends GLSurfaceView {
+ private static String TAG = "TestLatencyiew";
+ private float mX;
+ private float mY;
+ private float mDX;
+ private float mDY;
+ private long mT;
+ private long mDT;
+
+ public TestLatencyView(Context context) {
+ super(context);
+ setEGLContextClientVersion(2);
+ setRenderer(new Renderer());
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_MOVE:
+ float x = event.getX();
+ float y = event.getY();
+ long t = event.getEventTime();
+ synchronized(this) {
+ mDT = t - mT;
+ mT = t;
+ mDX = x - mX;
+ mX = x;
+ mDY = y - mY;
+ mY = y;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ private class Renderer implements GLSurfaceView.Renderer {
+ private float mScaleX, mScaleY, mOffsetX, mOffsetY;
+ private final float MS_PER_FRAME = 1000 / 60;
+ public Renderer() {
+ mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ }
+
+
+ public void onDrawFrame(GL10 gl) {
+ GLES20.glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
+ GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+ GLES20.glUseProgram(mProgram);
+ checkGlError("glUseProgram");
+
+ float x, y, dx, dy;
+ long t, dt;
+ synchronized(TestLatencyView.this) {
+ x = mX;
+ y = mY;
+ dx = mDX;
+ dy = mDY;
+ dt = mDT;
+ }
+
+ if (dt > 0) {
+ dx = dx * MS_PER_FRAME / dt;
+ dy = dy * MS_PER_FRAME / dt;
+ }
+
+ GLES20.glEnableVertexAttribArray(mvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ GLES20.glEnableVertexAttribArray(mvColorHandle);
+ checkGlError("glEnableVertexAttribArray");
+ for(int step = 0; step < 8; step++) {
+ float sx = (x + dx * step) * mScaleX + mOffsetX;
+ float sy = (y + dy * step) * mScaleY + mOffsetY;
+ int cbase = step * 4;
+
+ for (int i = 0; i < mTriangleVerticesData.length; i += 6) {
+ mTriangleVerticesData2[i] = sx + mTriangleVerticesData[i];
+ mTriangleVerticesData2[i+1] = -sy + mTriangleVerticesData[i+1];
+ mTriangleVerticesData2[i+2] = mColors[cbase];
+ mTriangleVerticesData2[i+3] = mColors[cbase+1];
+ mTriangleVerticesData2[i+4] = mColors[cbase+2];
+ mTriangleVerticesData2[i+5] = mColors[cbase+3];
+ }
+ mTriangleVertices.position(0);
+ mTriangleVertices.put(mTriangleVerticesData2).position(0);
+
+ GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices);
+ checkGlError("glVertexAttribPointer mvPosition");
+ mTriangleVertices.put(mTriangleVerticesData2).position(2);
+ GLES20.glVertexAttribPointer(mvColorHandle, 4, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices);
+ checkGlError("glVertexAttribPointer mvColor");
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+ }
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GLES20.glViewport(0, 0, width, height);
+ mScaleX = 2.0f / width;
+ mScaleY = 2.0f / height;
+ mOffsetX = -1f;
+ mOffsetY = -1f;
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ mProgram = createProgram(mVertexShader, mFragmentShader);
+ if (mProgram == 0) {
+ return;
+ }
+ mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
+ checkGlError("glGetAttribLocation");
+ if (mvPositionHandle == -1) {
+ throw new RuntimeException("Could not get attrib location for vPosition");
+ }
+ mvColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
+ checkGlError("glGetAttribLocation");
+ if (mvColorHandle == -1) {
+ throw new RuntimeException("Could not get attrib location for vColor");
+ }
+ }
+
+ private int loadShader(int shaderType, String source) {
+ int shader = GLES20.glCreateShader(shaderType);
+ if (shader != 0) {
+ GLES20.glShaderSource(shader, source);
+ GLES20.glCompileShader(shader);
+ int[] compiled = new int[1];
+ GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+ if (compiled[0] == 0) {
+ Log.e(TAG, "Could not compile shader " + shaderType + ":");
+ Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+ GLES20.glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ return shader;
+ }
+
+ private int createProgram(String vertexSource, String fragmentSource) {
+ int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+ if (vertexShader == 0) {
+ return 0;
+ }
+
+ int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+ if (pixelShader == 0) {
+ return 0;
+ }
+
+ int program = GLES20.glCreateProgram();
+ if (program != 0) {
+ GLES20.glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader vertexShader");
+ GLES20.glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader pixelShader");
+ GLES20.glLinkProgram(program);
+ int[] linkStatus = new int[1];
+ GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+ if (linkStatus[0] != GLES20.GL_TRUE) {
+ Log.e(TAG, "Could not link program: ");
+ Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+ GLES20.glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+ }
+
+ private void checkGlError(String op) {
+ int error;
+ while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ throw new RuntimeException(op + ": glError " + error);
+ }
+ }
+
+ // X, Y, R G B A
+ private final float[] mTriangleVerticesData = {
+ -0.025f, 0.3f, 0.0f, 1.0f, 0.0f, 1.0f,
+ 0.0f , 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
+ 0.025f, 0.3f, 1.0f, 1.0f, 255.0f, 1.0f
+ };
+
+ // Color cascade:
+ private final float[] mColors = {
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.5f, 0.0f, 1.0f,
+ 0.5f, 0.5f, 0.0f, 1.0f,
+
+ 0.0f, 0.0f, 0.5f, 1.0f,
+ 1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f, 1.0f
+ };
+
+ private float[] mTriangleVerticesData2 = new float[mTriangleVerticesData.length];
+ private FloatBuffer mTriangleVertices;
+
+ private final String mVertexShader = "attribute vec4 aPosition;\n"
+ + "attribute vec4 aColor;\n"
+ + "varying vec4 vColor;\n"
+ + "void main() {\n"
+ + " gl_Position = aPosition;\n"
+ + " vColor = aColor;\n"
+ + "}\n";
+
+ private final String mFragmentShader = "precision mediump float;\n"
+ + "varying vec4 vColor;\n"
+ + "void main() {\n"
+ + " gl_FragColor = vColor;\n"
+ + "}\n";
+
+ private int mProgram;
+ private int mvPositionHandle;
+ private int mvColorHandle;
+
+ }
+}
+