1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.perftest; 18 19import android.os.Environment; 20import android.content.res.Resources; 21import android.graphics.Bitmap; 22import android.graphics.BitmapFactory; 23import android.renderscript.*; 24import android.renderscript.Element.DataKind; 25import android.renderscript.Element.DataType; 26import android.renderscript.Allocation.MipmapControl; 27import android.renderscript.Program.TextureType; 28import android.renderscript.ProgramStore.DepthFunc; 29import android.renderscript.ProgramStore.BlendSrcFunc; 30import android.renderscript.ProgramStore.BlendDstFunc; 31import android.renderscript.RenderScript.RSMessageHandler; 32import android.renderscript.Mesh.Primitive; 33import android.renderscript.Matrix4f; 34import android.renderscript.ProgramVertexFixedFunction; 35 36import android.util.Log; 37 38 39public class UiTest implements RsBenchBaseTest{ 40 41 private static final String TAG = "UiTest"; 42 private static final String SAMPLE_TEXT = "Bench Test"; 43 private static final String LIST_TEXT = 44 "This is a sample list of text to show in the list view"; 45 private static int PARTICLES_COUNT = 12000; 46 47 private RenderScriptGL mRS; 48 private Resources mRes; 49 50 Font mFontSans; 51 52 private ScriptField_ListAllocs_s mTextureAllocs; 53 private ScriptField_ListAllocs_s mSampleTextAllocs; 54 private ScriptField_ListAllocs_s mSampleListViewAllocs; 55 private ScriptField_VpConsts mPvStarAlloc; 56 private ProgramVertexFixedFunction.Constants mPvProjectionAlloc; 57 58 private Mesh mSingleMesh; 59 private Mesh mParticlesMesh; 60 61 private ScriptC_ui_test mUiScript; 62 63 private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); 64 65 ScriptField_TestScripts_s.Item[] mTests; 66 67 private final String[] mNames = { 68 "UI test with icon display 10 by 10", 69 "UI test with icon display 100 by 100", 70 "UI test with image and text display 3 pages", 71 "UI test with image and text display 5 pages", 72 "UI test with list view", 73 "UI test with live wallpaper" 74 }; 75 76 public UiTest() { 77 } 78 79 void addTest(int index, int testId, int user1, int user2, int user3) { 80 mTests[index] = new ScriptField_TestScripts_s.Item(); 81 mTests[index].testScript = mUiScript; 82 mTests[index].testName = Allocation.createFromString(mRS, 83 mNames[index], 84 Allocation.USAGE_SCRIPT); 85 mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS, 86 mNames[index], 87 Allocation.USAGE_SCRIPT); 88 89 ScriptField_UiTestData_s.Item dataItem = new ScriptField_UiTestData_s.Item(); 90 dataItem.testId = testId; 91 dataItem.user1 = user1; 92 dataItem.user2 = user2; 93 dataItem.user3 = user3; 94 ScriptField_UiTestData_s testData = new ScriptField_UiTestData_s(mRS, 1); 95 testData.set(dataItem, 0, true); 96 mTests[index].testData = testData.getAllocation(); 97 } 98 99 public boolean init(RenderScriptGL rs, Resources res) { 100 mRS = rs; 101 mRes = res; 102 mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8); 103 mSingleMesh = getSingleMesh(1, 1); // a unit size mesh 104 105 initUiScript(); 106 mTests = new ScriptField_TestScripts_s.Item[mNames.length]; 107 108 int index = 0; 109 110 addTest(index++, 0, 0 /*meshMode*/, 0 /*unused*/, 0 /*unused*/); 111 addTest(index++, 0, 1 /*meshMode*/, 0 /*unused*/, 0 /*unused*/); 112 addTest(index++, 1, 7 /*wResolution*/, 5 /*hResolution*/, 0 /*meshMode*/); 113 addTest(index++, 1, 7 /*wResolution*/, 5 /*hResolution*/, 1 /*meshMode*/); 114 addTest(index++, 2, 0 /*unused*/, 0 /*unused*/, 0 /*unused*/); 115 addTest(index++, 3, 7 /*wResolution*/, 5 /*hResolution*/, 0 /*unused*/); 116 117 return true; 118 } 119 120 public ScriptField_TestScripts_s.Item[] getTests() { 121 return mTests; 122 } 123 124 public String[] getTestNames() { 125 return mNames; 126 } 127 128 private Allocation loadTextureRGB(int id) { 129 return Allocation.createFromBitmapResource(mRS, mRes, id, 130 Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, 131 Allocation.USAGE_GRAPHICS_TEXTURE); 132 } 133 134 private Allocation loadTextureARGB(int id) { 135 Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB); 136 return Allocation.createFromBitmap(mRS, b, 137 Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, 138 Allocation.USAGE_GRAPHICS_TEXTURE); 139 } 140 141 private void createParticlesMesh() { 142 ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT); 143 144 final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS); 145 meshBuilder.addVertexAllocation(p.getAllocation()); 146 final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex(); 147 meshBuilder.addIndexSetType(Primitive.POINT); 148 mParticlesMesh = meshBuilder.create(); 149 150 mUiScript.set_gParticlesMesh(mParticlesMesh); 151 mUiScript.bind_Particles(p); 152 } 153 154 /** 155 * Create a mesh with a single quad for the given width and height. 156 */ 157 private Mesh getSingleMesh(float width, float height) { 158 Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 159 2, Mesh.TriangleMeshBuilder.TEXTURE_0); 160 float xOffset = width/2; 161 float yOffset = height/2; 162 tmb.setTexture(0, 0); 163 tmb.addVertex(-1.0f * xOffset, -1.0f * yOffset); 164 tmb.setTexture(1, 0); 165 tmb.addVertex(xOffset, -1.0f * yOffset); 166 tmb.setTexture(1, 1); 167 tmb.addVertex(xOffset, yOffset); 168 tmb.setTexture(0, 1); 169 tmb.addVertex(-1.0f * xOffset, yOffset); 170 tmb.addTriangle(0, 3, 1); 171 tmb.addTriangle(1, 3, 2); 172 return tmb.create(true); 173 } 174 175 private Matrix4f getProjectionNormalized(int w, int h) { 176 // range -1,1 in the narrow axis at z = 0. 177 Matrix4f m1 = new Matrix4f(); 178 Matrix4f m2 = new Matrix4f(); 179 180 if(w > h) { 181 float aspect = ((float)w) / h; 182 m1.loadFrustum(-aspect,aspect, -1,1, 1,100); 183 } else { 184 float aspect = ((float)h) / w; 185 m1.loadFrustum(-1,1, -aspect,aspect, 1,100); 186 } 187 188 m2.loadRotate(180, 0, 1, 0); 189 m1.loadMultiply(m1, m2); 190 191 m2.loadScale(-2, 2, 1); 192 m1.loadMultiply(m1, m2); 193 194 m2.loadTranslate(0, 0, 2); 195 m1.loadMultiply(m1, m2); 196 return m1; 197 } 198 199 private void updateProjectionMatrices() { 200 Matrix4f projNorm = getProjectionNormalized(1280, 720); 201 ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); 202 i.Proj = projNorm; 203 i.MVP = projNorm; 204 mPvStarAlloc.set(i, 0, true); 205 mPvProjectionAlloc.setProjection(projNorm); 206 } 207 208 void initUiScript() { 209 mUiScript = new ScriptC_ui_test(mRS, mRes, R.raw.ui_test); 210 211 ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS); 212 colBuilder.setVaryingColor(false); 213 ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS); 214 texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, 215 ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); 216 217 ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); 218 ProgramVertexFixedFunction progVertex = pvb.create(); 219 ProgramVertexFixedFunction.Constants PVA = new ProgramVertexFixedFunction.Constants(mRS); 220 ((ProgramVertexFixedFunction)progVertex).bindConstants(PVA); 221 Matrix4f proj = new Matrix4f(); 222 proj.loadOrthoWindow(1280, 720); 223 PVA.setProjection(proj); 224 225 mUiScript.set_gProgVertex(progVertex); 226 mUiScript.set_gProgFragmentColor(colBuilder.create()); 227 mUiScript.set_gProgFragmentTexture(texBuilder.create()); 228 mUiScript.set_gProgStoreBlendAlpha(ProgramStore.BLEND_ALPHA_DEPTH_NONE(mRS)); 229 230 mUiScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); 231 232 mUiScript.set_gTexTorus(loadTextureRGB(R.drawable.torusmap)); 233 mUiScript.set_gTexOpaque(loadTextureRGB(R.drawable.data)); 234 mUiScript.set_gTexGlobe(loadTextureRGB(R.drawable.globe)); 235 mUiScript.set_gSingleMesh(mSingleMesh); 236 237 // For GALAXY 238 ProgramStore.Builder psb = new ProgramStore.Builder(mRS); 239 psb.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); 240 mRS.bindProgramStore(psb.create()); 241 242 psb.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); 243 mUiScript.set_gPSLights(psb.create()); 244 245 // For Galaxy live wallpaper drawing 246 ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); 247 builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, 248 ProgramFragmentFixedFunction.Builder.Format.RGB, 0); 249 ProgramFragment pfb = builder.create(); 250 pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0); 251 mUiScript.set_gPFBackground(pfb); 252 253 builder = new ProgramFragmentFixedFunction.Builder(mRS); 254 builder.setPointSpriteTexCoordinateReplacement(true); 255 builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, 256 ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); 257 builder.setVaryingColor(true); 258 ProgramFragment pfs = builder.create(); 259 pfs.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0); 260 mUiScript.set_gPFStars(pfs); 261 262 mTextureAllocs = new ScriptField_ListAllocs_s(mRS, 100); 263 for (int i = 0; i < 100; i++) { 264 ScriptField_ListAllocs_s.Item texElem = new ScriptField_ListAllocs_s.Item(); 265 texElem.item = loadTextureRGB(R.drawable.globe); 266 mTextureAllocs.set(texElem, i, false); 267 } 268 mTextureAllocs.copyAll(); 269 mUiScript.bind_gTexList100(mTextureAllocs); 270 271 mSampleTextAllocs = new ScriptField_ListAllocs_s(mRS, 100); 272 for (int i = 0; i < 100; i++) { 273 ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); 274 textElem.item = Allocation.createFromString(mRS, SAMPLE_TEXT, Allocation.USAGE_SCRIPT); 275 mSampleTextAllocs.set(textElem, i, false); 276 } 277 mSampleTextAllocs.copyAll(); 278 mUiScript.bind_gSampleTextList100(mSampleTextAllocs); 279 280 mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000); 281 for (int i = 0; i < 1000; i++) { 282 ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); 283 textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT); 284 mSampleListViewAllocs.set(textElem, i, false); 285 } 286 mSampleListViewAllocs.copyAll(); 287 mUiScript.bind_gListViewText(mSampleListViewAllocs); 288 289 // For galaxy live wallpaper 290 mPvStarAlloc = new ScriptField_VpConsts(mRS, 1); 291 mUiScript.bind_vpConstants(mPvStarAlloc); 292 mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS); 293 updateProjectionMatrices(); 294 295 pvb = new ProgramVertexFixedFunction.Builder(mRS); 296 ProgramVertex pvbp = pvb.create(); 297 ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc); 298 mUiScript.set_gPVBkProj(pvbp); 299 300 createParticlesMesh(); 301 302 ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS); 303 String t = "varying vec4 varColor;\n" + 304 "varying vec2 varTex0;\n" + 305 "void main() {\n" + 306 " float dist = ATTRIB_position.y;\n" + 307 " float angle = ATTRIB_position.x;\n" + 308 " float x = dist * sin(angle);\n" + 309 " float y = dist * cos(angle) * 0.892;\n" + 310 " float p = dist * 5.5;\n" + 311 " float s = cos(p);\n" + 312 " float t = sin(p);\n" + 313 " vec4 pos;\n" + 314 " pos.x = t * x + s * y;\n" + 315 " pos.y = s * x - t * y;\n" + 316 " pos.z = ATTRIB_position.z;\n" + 317 " pos.w = 1.0;\n" + 318 " gl_Position = UNI_MVP * pos;\n" + 319 " gl_PointSize = ATTRIB_color.a * 10.0;\n" + 320 " varColor.rgb = ATTRIB_color.rgb;\n" + 321 " varColor.a = 1.0;\n" + 322 "}\n"; 323 sb.setShader(t); 324 sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement()); 325 sb.addConstant(mPvStarAlloc.getType()); 326 ProgramVertex pvs = sb.create(); 327 pvs.bindConstants(mPvStarAlloc.getAllocation(), 0); 328 mUiScript.set_gPVStars(pvs); 329 330 // For Galaxy live wallpaper 331 mUiScript.set_gTSpace(loadTextureRGB(R.drawable.space)); 332 mUiScript.set_gTLight1(loadTextureRGB(R.drawable.light1)); 333 mUiScript.set_gTFlares(loadTextureARGB(R.drawable.flares)); 334 335 mUiScript.set_gFontSans(mFontSans); 336 } 337} 338