renderscript tests that touch graphics apis

Change-Id: Ic5093290fd1fa499dd7223f57a97064f01b54c08
diff --git a/tests/src/android/renderscript/cts/graphics_runner.rs b/tests/src/android/renderscript/cts/graphics_runner.rs
new file mode 100644
index 0000000..6119574a
--- /dev/null
+++ b/tests/src/android/renderscript/cts/graphics_runner.rs
@@ -0,0 +1,39 @@
+// Copyright (C) 2011 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.
+
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+#include "structs.rsh"
+
+static void drawQuad() {
+    float startX = 0, startY = 0;
+    float width = 4, height = 4;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
+}
+
+void testProgramVertex(rs_program_vertex pv) {
+    rsDebug("Set Program, drew quad", 0);
+    rsgBindProgramVertex(pv);
+    drawQuad();
+}
+
+// Just draw a quad with previously setup state
+int root(int launchID) {
+    rsDebug("Running script", 0);
+    return 0;
+}
diff --git a/tests/src/android/renderscript/cts/structs.rsh b/tests/src/android/renderscript/cts/structs.rsh
new file mode 100644
index 0000000..bfc57c6
--- /dev/null
+++ b/tests/src/android/renderscript/cts/structs.rsh
@@ -0,0 +1,38 @@
+// Copyright (C) 2011 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.
+
+typedef struct ConstMatrix {
+    rs_matrix4x4 MVP;
+} ConstMatrix_s;
+ConstMatrix_s *c1;
+
+typedef struct ConstComplex {
+    rs_matrix4x4 MVP;
+    rs_matrix4x4 EXTRA;
+    float extra1;
+    float2 extra2;
+    float3 extra3;
+    float4 extra4;
+} ConstComplex_s;
+ConstComplex_s *c2;
+
+typedef struct ConstExtra {
+    rs_matrix4x4 EXTRA;
+    float extra1;
+    float2 extra2;
+    float3 extra3;
+    float4 extra4;
+} ConstExtra_s;
+ConstExtra_s *c3;
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FontTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FontTest.java
new file mode 100644
index 0000000..1336ed9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/FontTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.Font;
+
+public class FontTest extends RSBaseGraphics {
+
+    public void testCreateFont() {
+        for (int fontSize = 8; fontSize <= 12; fontSize += 2) {
+            Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, fontSize);
+            Font.create(mRS, mRes, "serif", Font.Style.NORMAL, fontSize);
+            // Create fonts by family and style
+            Font.create(mRS, mRes, "serif", Font.Style.BOLD, fontSize);
+            Font.create(mRS, mRes, "serif", Font.Style.ITALIC, fontSize);
+            Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, fontSize);
+            Font.create(mRS, mRes, "mono", Font.Style.NORMAL, fontSize);
+        }
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/MeshTest.java b/tests/tests/renderscript/src/android/renderscript/cts/MeshTest.java
new file mode 100644
index 0000000..970df90
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/MeshTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.Allocation;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element;
+import android.renderscript.Type;
+import android.renderscript.Mesh;
+import android.renderscript.Mesh.Primitive;
+import android.renderscript.Mesh.AllocationBuilder;
+import android.renderscript.Mesh.Builder;
+import android.renderscript.Mesh.TriangleMeshBuilder;
+
+public class MeshTest extends RSBaseGraphics {
+
+    Allocation mAttrAlloc;
+    Allocation mIndexAlloc;
+    Element mPosElem;
+    Type mPosType;
+    Type mIndexType;
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Element.Builder eb = new Element.Builder(mRS);
+        eb.add(Element.F32_4(mRS), "position");
+        mPosElem = eb.create();
+        Type.Builder typeB = new Type.Builder(mRS, mPosElem);
+        mPosType = typeB.setX(3).create();
+        typeB = new Type.Builder(mRS, Element.U16(mRS));
+        mIndexType = typeB.setX(3).create();
+
+        mAttrAlloc = Allocation.createSized(mRS, mPosElem, 3);
+        mIndexAlloc = Allocation.createSized(mRS, Element.U16(mRS), 3);
+    }
+
+    public void testMeshAllocationBuilder() {
+        Mesh.AllocationBuilder mab;
+        for(Primitive prim : Primitive.values()) {
+            mab = new Mesh.AllocationBuilder(mRS);
+            mab.addVertexAllocation(mAttrAlloc);
+            mab.getCurrentVertexTypeIndex();
+            mab.addIndexSetType(prim);
+            assertTrue(mab.create() != null);
+
+            mab = new Mesh.AllocationBuilder(mRS);
+            mab.addVertexAllocation(mAttrAlloc);
+            mab.getCurrentVertexTypeIndex();
+            mab.addIndexSetAllocation(mIndexAlloc, prim);
+            mab.getCurrentIndexSetIndex();
+            mab.addIndexSetType(prim);
+            assertTrue(mab.create() != null);
+        }
+    }
+
+    public void testMeshBuilder() {
+        Mesh.Builder mb;
+        for(Primitive prim : Primitive.values()) {
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosElem, 3);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(prim);
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosElem, 3);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(Element.U16(mRS), 3, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosElem, 3);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(mIndexType, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosType);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(prim);
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosType);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(Element.U16(mRS), 3, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosType);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(mIndexType, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+        }
+    }
+
+    void triangleMeshBuilderHelper(int size, int flags) {
+        // Test various num vertices and triangles
+        for (int numVerts = 3; numVerts < 100; numVerts += 15) {
+            for (int numTries = 1; numTries < 100; numTries += 15) {
+                Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, size, flags);
+                // Append all the vertices
+                for (int numVertsI = 0; numVertsI < numVerts; numVertsI++) {
+                    if (size == 2) {
+                        tmb.addVertex(1.0f, 1.0f);
+                    } else {
+                        tmb.addVertex(1.0f, 1.0f, 1.0f);
+                    }
+                    if ((flags & TriangleMeshBuilder.COLOR) != 0) {
+                        tmb.setColor(1.0f, 1.0f, 1.0f, 1.0f);
+                    }
+                    if ((flags & TriangleMeshBuilder.NORMAL) != 0) {
+                        tmb.setNormal(1.0f, 1.0f, 1.0f);
+                    }
+                    if ((flags & TriangleMeshBuilder.TEXTURE_0) != 0) {
+                        tmb.setTexture(1.0f, 1.0f);
+                    }
+                }
+                // Add triangles to index them
+                for (int numTriesI = 0; numTriesI < numTries; numTriesI ++) {
+                    tmb.addTriangle(0, 1, 2);
+                }
+                assertTrue(tmb.create(false) != null);
+                assertTrue(tmb.create(true) != null);
+            }
+        }
+    }
+
+    public void testMeshTriangleMeshBuilder() {
+        for (int size = 2; size <= 3; size ++) {
+            triangleMeshBuilderHelper(size, 0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR |
+                                            TriangleMeshBuilder.NORMAL);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR |
+                                            TriangleMeshBuilder.TEXTURE_0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR |
+                                            TriangleMeshBuilder.NORMAL |
+                                            TriangleMeshBuilder.TEXTURE_0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.NORMAL);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.NORMAL|
+                                            TriangleMeshBuilder.TEXTURE_0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.TEXTURE_0);
+        }
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexTest.java
new file mode 100644
index 0000000..7655bf4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexTest.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2011 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.FieldPacker;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramVertex;
+import android.renderscript.ProgramVertex.Builder;
+import android.renderscript.ScriptC;
+
+public class ProgramVertexTest extends RSBaseGraphics {
+
+    ScriptC_graphics_runner mScript;
+    Element mAttrPosElem;
+    Element mAttrNormTexElem;
+    Element mAttrPosNormTexElem;
+    Element mAttrExtra;
+
+    Allocation mConstMatrix;
+    Allocation mConstComplex;
+    Allocation mConstExtra;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Build elements for shader inputs
+        Element.Builder eb = new Element.Builder(mRS);
+        eb.add(Element.F32_4(mRS), "position");
+        mAttrPosElem = eb.create();
+
+        eb = new Element.Builder(mRS);
+        eb.add(Element.F32_3(mRS), "normal");
+        eb.add(Element.F32_2(mRS), "texture0");
+        mAttrNormTexElem = eb.create();
+
+        eb = new Element.Builder(mRS);
+        eb.add(Element.F32_4(mRS), "position");
+        eb.add(Element.F32_3(mRS), "normal");
+        eb.add(Element.F32_2(mRS), "texture0");
+        mAttrPosNormTexElem = eb.create();
+
+        eb.add(Element.F32(mRS), "extra1");
+        eb.add(Element.F32_2(mRS), "extra2");
+        eb.add(Element.F32_3(mRS), "extra3");
+        eb.add(Element.F32_4(mRS), "extra4");
+        mAttrExtra = eb.create();
+
+        ScriptField_ConstMatrix c1 = new ScriptField_ConstMatrix(mRS, 1,
+                                                                 Allocation.USAGE_SCRIPT |
+                                                                 Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c1.set(new ScriptField_ConstMatrix.Item(), 0, true);
+        mConstMatrix = c1.getAllocation();
+
+        ScriptField_ConstComplex c2 = new ScriptField_ConstComplex(mRS, 1,
+                                                                   Allocation.USAGE_SCRIPT |
+                                                                   Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c2.set(new ScriptField_ConstComplex.Item(), 0, true);
+        mConstComplex = c2.getAllocation();
+
+        ScriptField_ConstExtra c3 = new ScriptField_ConstExtra(mRS, 1,
+                                                               Allocation.USAGE_SCRIPT |
+                                                               Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c3.set(new ScriptField_ConstExtra.Item(), 0, true);
+        mConstExtra = c3.getAllocation();
+
+        mScript = new ScriptC_graphics_runner(mRS, mRes, R.raw.graphics_runner);
+        mRS.bindRootScript(mScript);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mRS.bindRootScript(null);
+        super.tearDown();
+    }
+
+    ProgramVertex buildShader(Element[] input, Allocation[] constInput, String shader) {
+        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        if (input != null) {
+            for (int i = 0; i < input.length; i++) {
+                pvb.addInput(input[i]);
+            }
+        }
+        if (constInput != null) {
+            for (int i = 0; i < constInput.length; i++) {
+                pvb.addConstant(constInput[i].getType());
+            }
+        }
+
+        pvb.setShader(shader);
+        ProgramVertex pv = pvb.create();
+        if (constInput != null) {
+            for (int i = 0; i < constInput.length; i++) {
+                pv.bindConstants(constInput[i], i);
+            }
+        }
+        return pv;
+    }
+
+    void testProgramVertexBuilderHelper(boolean testBind) {
+        String simpleAttr = "void main() {\n"+
+                            "  gl_Position = ATTRIB_position;\n"+
+                            "}";
+
+        String multiAttr = "void main() {\n"+
+                           "  vec4 temp = ATTRIB_position;\n"+
+                           "  temp.xyz += ATTRIB_normal;\n"+
+                           "  temp.xy += ATTRIB_texture0;\n"+
+                           "  gl_Position = temp;\n"+
+                           "}";
+
+        String multiAttr2 = "void main() {\n"+
+                            "  vec4 temp = ATTRIB_position;\n"+
+                            "  temp.xyz += ATTRIB_normal;\n"+
+                            "  temp.xy += ATTRIB_texture0;\n"+
+                            "  temp += ATTRIB_extra4;\n"+
+                            "  temp.xyz += ATTRIB_extra3;\n "+
+                            "  temp.xy += ATTRIB_extra2;\n"+
+                            "  temp.x += ATTRIB_extra1;\n"+
+                            "  gl_Position = temp;\n"+
+                            "}";
+
+        String simpleAttrSimpleUni = "void main() {\n"+
+                                     "  gl_Position = UNI_MVP * ATTRIB_position;\n"+
+                                     "}";
+
+        String multiAttrMultiUni = "void main() {\n"+
+                                   "  vec4 temp = UNI_MVP * ATTRIB_position;\n"+
+                                   "  temp = UNI_EXTRA * temp;\n"+
+                                   "  temp.xyz += ATTRIB_normal;\n"+
+                                   "  temp.xy += ATTRIB_texture0;\n"+
+                                   "  temp += UNI_extra4;\n"+
+                                   "  temp.xyz += UNI_extra3;\n "+
+                                   "  temp.xy += UNI_extra2;\n"+
+                                   "  temp.x += UNI_extra1;\n"+
+                                   "  gl_Position = temp;\n"+
+                                   "}";
+
+        // Create a series of shaders that do nothing useful
+        // but exercise creation pipeline
+        Element[] inputs = new Element[1];
+        inputs[0] = mAttrPosElem;
+        ProgramVertex pv = buildShader(inputs, null, simpleAttr);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        inputs[0] = mAttrPosNormTexElem;
+        pv = buildShader(inputs, null, multiAttr);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        inputs[0] = mAttrExtra;
+        pv = buildShader(inputs, null, multiAttr2);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        // Now with constant inputs
+        Allocation[] constInput = new Allocation[1];
+        inputs[0] = mAttrPosElem;
+        constInput[0] = mConstMatrix;
+        pv = buildShader(inputs, constInput, simpleAttrSimpleUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        inputs[0] = mAttrPosNormTexElem;
+        constInput[0] = mConstComplex;
+        pv = buildShader(inputs, constInput, multiAttrMultiUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        // Now with multiple input and const structs
+        constInput = new Allocation[2];
+        constInput[0] = mConstMatrix;
+        constInput[1] = mConstExtra;
+        inputs[0] = mAttrPosNormTexElem;
+        pv = buildShader(inputs, constInput, multiAttrMultiUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        inputs = new Element[2];
+        inputs[0] = mAttrPosElem;
+        inputs[1] = mAttrNormTexElem;
+        pv = buildShader(inputs, null, multiAttr);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+
+        constInput[0] = mConstMatrix;
+        constInput[1] = mConstExtra;
+        inputs[0] = mAttrPosElem;
+        inputs[1] = mAttrNormTexElem;
+        pv = buildShader(inputs, constInput, multiAttrMultiUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+    }
+
+    public void testProgramVertexBuilder() {
+        testProgramVertexBuilderHelper(false);
+    }
+
+    public void testProgramVertexCreation() {
+        testProgramVertexBuilderHelper(true);
+    }
+}
+
+