Test GL Texture with rotation and glDrawTexfOES
address issue mentioned in https://groups.google.com/group/android-developers/browse_thread/thread/9c0ccb1a215586a8/2f28259213340eab?hl=en&lnk=gst&q=opengl+galaxy#2f28259213340eab

Change-Id: I98ce3c0250b83eccb62de2997bf8c4a7ec5cea51
diff --git a/tests/tests/openglperf/AndroidManifest.xml b/tests/tests/openglperf/AndroidManifest.xml
index d687246..e47c0bc 100644
--- a/tests/tests/openglperf/AndroidManifest.xml
+++ b/tests/tests/openglperf/AndroidManifest.xml
@@ -42,6 +42,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name="android.openglperf.cts.TextureTestActivity" />
     </application>
 
 </manifest>
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java
new file mode 100644
index 0000000..6a0a14e
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 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 android.openglperf.cts;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+/**
+ * check TextureTestRenderer for details
+ */
+public class GlTextureCoordTest extends
+        ActivityInstrumentationTestCase2<TextureTestActivity> {
+
+    public GlTextureCoordTest() {
+        super(TextureTestActivity.class);
+    }
+
+    public void testTextureCoord() throws InterruptedException {
+        getActivity();
+        Thread.sleep(3000); // give some time to render some frames
+    }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java
new file mode 100644
index 0000000..4d7d641
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 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 android.openglperf.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class TextureTestActivity extends Activity {
+    private GLSurfaceView mGLView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mGLView = new TextureTestSurfaceView(this);
+        setContentView(mGLView);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGLView.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGLView.onResume();
+    }
+}
+
+class TextureTestSurfaceView extends GLSurfaceView {
+
+    public TextureTestSurfaceView(Context context){
+        super(context);
+        setRenderer(new TextureTestRenderer());
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java
new file mode 100644
index 0000000..96b2e44
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 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 android.openglperf.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+import junit.framework.Assert;
+
+/**
+ * This test is for checking an issue
+ * mentioned in https://groups.google.com/group/android-developers/browse_thread/thread/
+ * 9c0ccb1a215586a8/2f28259213340eab?hl=en&lnk=gst&q=opengl+galaxy#2f28259213340eab
+ * The GPU driver seems to change texture coordinates inside glDrawTexfOES, and
+ * texture inside following drawing does not work as expected.
+ * The thread also mentions texture malfunctioning with rotation,
+ * but that was not observed, but the case will cover both.
+ */
+public class TextureTestRenderer implements GLSurfaceView.Renderer {
+    private static final String TAG = "TextureTest";
+    private static final float[] mVerticesData = {
+        // X, Y, Z, s, t
+        -1.0f, -1.0f, 0, 0.6f, 0.f,
+        1.0f, -1.0f, 0, 0.7f, 0.f,
+        -1.0f,  1.0f, 0, 0.6f, 0.1f,
+        1.0f,   1.0f, 0, 0.7f, 0.1f,
+    };
+    private static final int FLOAT_SIZE_BYTES = 4;
+    private static final int GEOMETRY_STRIDE = 20;
+
+    private final FloatBuffer mVertices;
+    private final Bitmap mBitmap;
+    private int mTextureID;
+    private boolean mOesDrawTextureSupported = false;
+    private int mWidth;
+    private int mHeight;
+    private float mRotationAngle = 0f;
+
+    public TextureTestRenderer() {
+        mVertices = ByteBuffer.allocateDirect(mVerticesData.length
+                * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mVertices.put(mVerticesData).position(0);
+        // 4x4 texture with 4 colors
+        int[] colors = {
+                Color.RED, Color.RED, Color.BLUE, Color.BLUE,
+                Color.RED, Color.RED, Color.BLUE, Color.BLUE,
+                Color.GREEN, Color.GREEN, Color.CYAN, Color.CYAN,
+                Color.GREEN, Color.GREEN, Color.CYAN, Color.CYAN
+        };
+        mBitmap = Bitmap.createBitmap(colors, 4, 4, Bitmap.Config.ARGB_8888);
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        // Redraw background color
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                GL10.GL_REPLACE);
+
+        // Set GL_MODELVIEW transformation mode
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity(); // reset the matrix to its default state
+
+        // When using GL_MODELVIEW, you must set the view point
+        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+        gl.glActiveTexture(GL10.GL_TEXTURE0);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+
+        // red for default color
+        gl.glColor4f(1.0f, 0f, 0f, 1.0f);
+        gl.glVertexPointer(3, GL10.GL_FLOAT, GEOMETRY_STRIDE, mVertices);
+        gl.glTexCoordPointer(2, GL10.GL_FLOAT, GEOMETRY_STRIDE, mVertices
+                .duplicate().position(3));
+        if (mOesDrawTextureSupported) {
+            // left / bottom / width / height (negative w/h flip the image)
+            int crop[] = new int[] { 0, 0, 4, 4 };
+
+            ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
+                    GL11Ext.GL_TEXTURE_CROP_RECT_OES, crop, 0);
+            // 4x4 drawing in left-bottom corner
+            ((GL11Ext) gl).glDrawTexfOES(0, 0, 0, 4, 4);
+        }
+        gl.glPushMatrix();
+        gl.glRotatef(mRotationAngle, 0f, 0f, 1f);
+        mRotationAngle += 10f;
+        if (mRotationAngle > 360f) {
+            mRotationAngle = 0f;
+        }
+        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
+        gl.glPopMatrix();
+        // for one pixel
+        IntBuffer pixel = ByteBuffer.allocateDirect(4).asIntBuffer();
+        gl.glReadPixels(mWidth / 2, mHeight / 2, 1, 1, GL10.GL_RGBA,
+                GL10.GL_UNSIGNED_BYTE, pixel);
+        pixel.position(0);
+        Log.i(TAG, "pixel read " + Integer.toHexString(pixel.get(0)));
+
+        Assert.assertEquals(0x0000ffff, pixel.get(0)); // BLUE in RGBA
+
+        checkGlError(gl, "onDrawFrame");
+    }
+
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        gl.glViewport(0, 0, width, height);
+
+        // make adjustments for screen ratio
+        float ratio = (float) width / height;
+        gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
+        gl.glLoadIdentity(); // reset the matrix to its default state
+        gl.glFrustumf(-2 * ratio, 2 * ratio, -2, 2, 3, 7);
+        checkGlError(gl, "onSurfaceChanged");
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
+        Log.i(TAG, "extensions: " + extensions);
+        if (extensions.contains("GL_OES_draw_texture")) {
+            mOesDrawTextureSupported = true;
+        }
+        // Set the background frame color
+        gl.glClearColor(0f, 0f, 0f, 1.0f);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+        int[] textures = new int[1];
+        gl.glGenTextures(1, textures, 0);
+
+        mTextureID = textures[0];
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+                GL10.GL_NEAREST);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
+                GL10.GL_NEAREST); // necessary due to low resolution texture
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                GL10.GL_CLAMP_TO_EDGE);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                GL10.GL_CLAMP_TO_EDGE);
+        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
+        checkGlError(gl, "onSurfaceCreated");
+    }
+
+    private void checkGlError(GL10 gl, String op) {
+        int error;
+        while ((error = gl.glGetError()) != GL10.GL_NO_ERROR) {
+            Log.e(TAG, op + ": glError " + error);
+            throw new IllegalStateException(op + ": glError " + error);
+        }
+    }
+}