1 // Copyright (C) 2011 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma version(1) 16 17 #pragma rs java_package_name(com.android.perftest) 18 19 #include "rs_graphics.rsh" 20 #include "subtest_def.rsh" 21 #include "shader_def.rsh" 22 23 rs_program_vertex gProgVertex; 24 rs_program_fragment gProgFragmentColor; 25 rs_program_fragment gProgFragmentTexture; 26 27 rs_program_store gProgStoreBlendNoneDepth; 28 rs_mesh gTorusMesh; 29 30 rs_program_raster gCullBack; 31 rs_program_raster gCullFront; 32 33 // Custom vertex shader compunents 34 VertexShaderConstants *gVSConstants; 35 FragentShaderConstants *gFSConstants; 36 VertexShaderConstants3 *gVSConstPixel; 37 FragentShaderConstants3 *gFSConstPixel; 38 39 // Custom shaders we use for lighting 40 rs_program_vertex gProgVertexCustom; 41 rs_program_fragment gProgFragmentCustom; 42 43 rs_sampler gLinearClamp; 44 rs_allocation gTexTorus; 45 46 rs_program_vertex gProgVertexPixelLight; 47 rs_program_vertex gProgVertexPixelLightMove; 48 rs_program_fragment gProgFragmentPixelLight; 49 50 typedef struct TorusTestData_s { 51 int testId; 52 int user1; 53 int user2; 54 } TorusTestData; 55 TorusTestData *gData; 56 57 static float gDt = 0.0f; 58 59 static int gRenderSurfaceW; 60 static int gRenderSurfaceH; 61 62 63 static float gTorusRotation = 0; 64 static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) { 65 if (buffer == 0) { 66 rsgProgramVertexLoadModelMatrix(matrix); 67 } else { 68 rsgAllocationSyncAll(rsGetAllocation(buffer)); 69 } 70 } 71 72 static void drawToruses(int numMeshes, rs_matrix4x4 *matrix, void *buffer) { 73 74 if (numMeshes == 1) { 75 rsMatrixLoadTranslate(matrix, 0.0f, 0.0f, -7.5f); 76 rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); 77 updateModelMatrix(matrix, buffer); 78 rsgDrawMesh(gTorusMesh); 79 return; 80 } 81 82 if (numMeshes == 2) { 83 rsMatrixLoadTranslate(matrix, -1.6f, 0.0f, -7.5f); 84 rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); 85 updateModelMatrix(matrix, buffer); 86 rsgDrawMesh(gTorusMesh); 87 88 rsMatrixLoadTranslate(matrix, 1.6f, 0.0f, -7.5f); 89 rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); 90 updateModelMatrix(matrix, buffer); 91 rsgDrawMesh(gTorusMesh); 92 return; 93 } 94 95 float startX = -5.0f; 96 float startY = -1.5f; 97 float startZ = -15.0f; 98 float dist = 3.2f; 99 100 for (int h = 0; h < 4; h ++) { 101 for (int v = 0; v < 2; v ++) { 102 // Position our model on the screen 103 rsMatrixLoadTranslate(matrix, startX + dist * h, startY + dist * v, startZ); 104 rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); 105 updateModelMatrix(matrix, buffer); 106 rsgDrawMesh(gTorusMesh); 107 } 108 } 109 } 110 111 112 // Quick hack to get some geometry numbers 113 static void displaySimpleGeoSamples(bool useTexture, int numMeshes) { 114 rsgBindProgramVertex(gProgVertex); 115 rsgBindProgramRaster(gCullBack); 116 // Setup the projection matrix with 30 degree field of view 117 rs_matrix4x4 proj; 118 float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH; 119 rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); 120 rsgProgramVertexLoadProjectionMatrix(&proj); 121 122 // Fragment shader with texture 123 rsgBindProgramStore(gProgStoreBlendNoneDepth); 124 if (useTexture) { 125 rsgBindProgramFragment(gProgFragmentTexture); 126 } else { 127 rsgBindProgramFragment(gProgFragmentColor); 128 rsgProgramFragmentConstantColor(gProgFragmentColor, 0.1, 0.7, 0.1, 1); 129 } 130 rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); 131 rsgBindTexture(gProgFragmentTexture, 0, gTexTorus); 132 133 // Apply a rotation to our mesh 134 gTorusRotation += 50.0f * gDt; 135 if (gTorusRotation > 360.0f) { 136 gTorusRotation -= 360.0f; 137 } 138 139 rs_matrix4x4 matrix; 140 drawToruses(numMeshes, &matrix, 0); 141 } 142 143 float gLight0Rotation = 0; 144 float gLight1Rotation = 0; 145 146 static void setupCustomShaderLights() { 147 float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f}; 148 float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f}; 149 float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f}; 150 float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f}; 151 float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f}; 152 float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f}; 153 154 gLight0Rotation += 50.0f * gDt; 155 if (gLight0Rotation > 360.0f) { 156 gLight0Rotation -= 360.0f; 157 } 158 gLight1Rotation -= 50.0f * gDt; 159 if (gLight1Rotation > 360.0f) { 160 gLight1Rotation -= 360.0f; 161 } 162 163 rs_matrix4x4 l0Mat; 164 rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f); 165 light0Pos = rsMatrixMultiply(&l0Mat, light0Pos); 166 rs_matrix4x4 l1Mat; 167 rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f); 168 light1Pos = rsMatrixMultiply(&l1Mat, light1Pos); 169 170 // Set light 0 properties 171 gVSConstants->light0_Posision = light0Pos; 172 gVSConstants->light0_Diffuse = 1.0f; 173 gVSConstants->light0_Specular = 0.5f; 174 gVSConstants->light0_CosinePower = 10.0f; 175 // Set light 1 properties 176 gVSConstants->light1_Posision = light1Pos; 177 gVSConstants->light1_Diffuse = 1.0f; 178 gVSConstants->light1_Specular = 0.7f; 179 gVSConstants->light1_CosinePower = 25.0f; 180 rsgAllocationSyncAll(rsGetAllocation(gVSConstants)); 181 182 // Update fragment shader constants 183 // Set light 0 colors 184 gFSConstants->light0_DiffuseColor = light0DiffCol; 185 gFSConstants->light0_SpecularColor = light0SpecCol; 186 // Set light 1 colors 187 gFSConstants->light1_DiffuseColor = light1DiffCol; 188 gFSConstants->light1_SpecularColor = light1SpecCol; 189 rsgAllocationSyncAll(rsGetAllocation(gFSConstants)); 190 191 // Set light 0 properties for per pixel lighting 192 gFSConstPixel->light0_Posision = light0Pos; 193 gFSConstPixel->light0_Diffuse = 1.0f; 194 gFSConstPixel->light0_Specular = 0.5f; 195 gFSConstPixel->light0_CosinePower = 10.0f; 196 gFSConstPixel->light0_DiffuseColor = light0DiffCol; 197 gFSConstPixel->light0_SpecularColor = light0SpecCol; 198 // Set light 1 properties 199 gFSConstPixel->light1_Posision = light1Pos; 200 gFSConstPixel->light1_Diffuse = 1.0f; 201 gFSConstPixel->light1_Specular = 0.7f; 202 gFSConstPixel->light1_CosinePower = 25.0f; 203 gFSConstPixel->light1_DiffuseColor = light1DiffCol; 204 gFSConstPixel->light1_SpecularColor = light1SpecCol; 205 rsgAllocationSyncAll(rsGetAllocation(gFSConstPixel)); 206 } 207 208 static void displayCustomShaderSamples(int numMeshes) { 209 210 // Update vertex shader constants 211 // Load model matrix 212 // Apply a rotation to our mesh 213 gTorusRotation += 50.0f * gDt; 214 if (gTorusRotation > 360.0f) { 215 gTorusRotation -= 360.0f; 216 } 217 218 // Setup the projection matrix 219 float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH; 220 rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f); 221 setupCustomShaderLights(); 222 223 rsgBindProgramVertex(gProgVertexCustom); 224 225 // Fragment shader with texture 226 rsgBindProgramStore(gProgStoreBlendNoneDepth); 227 rsgBindProgramFragment(gProgFragmentCustom); 228 rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp); 229 rsgBindTexture(gProgFragmentCustom, 0, gTexTorus); 230 231 // Use back face culling 232 rsgBindProgramRaster(gCullBack); 233 234 drawToruses(numMeshes, &gVSConstants->model, gVSConstants); 235 } 236 237 static void displayPixelLightSamples(int numMeshes, bool heavyVertex) { 238 239 // Update vertex shader constants 240 // Load model matrix 241 // Apply a rotation to our mesh 242 gTorusRotation += 30.0f * gDt; 243 if (gTorusRotation > 360.0f) { 244 gTorusRotation -= 360.0f; 245 } 246 247 gVSConstPixel->time = rsUptimeMillis()*0.005; 248 249 // Setup the projection matrix 250 float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH; 251 rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f); 252 setupCustomShaderLights(); 253 254 if (heavyVertex) { 255 rsgBindProgramVertex(gProgVertexPixelLightMove); 256 } else { 257 rsgBindProgramVertex(gProgVertexPixelLight); 258 } 259 260 // Fragment shader with texture 261 rsgBindProgramStore(gProgStoreBlendNoneDepth); 262 rsgBindProgramFragment(gProgFragmentPixelLight); 263 rsgBindSampler(gProgFragmentPixelLight, 0, gLinearClamp); 264 rsgBindTexture(gProgFragmentPixelLight, 0, gTexTorus); 265 266 // Use back face culling 267 rsgBindProgramRaster(gCullBack); 268 269 drawToruses(numMeshes, &gVSConstPixel->model, gVSConstPixel); 270 } 271 272 273 void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { 274 TestData *testData = (TestData*)usrData; 275 gRenderSurfaceW = testData->renderSurfaceW; 276 gRenderSurfaceH = testData->renderSurfaceH; 277 gDt = testData->dt; 278 279 gData = (TorusTestData*)v_in; 280 281 switch(gData->testId) { 282 case 0: 283 displaySimpleGeoSamples(gData->user1 == 1 ? true : false, gData->user2); 284 break; 285 case 1: 286 displayCustomShaderSamples(gData->user1); 287 break; 288 case 2: 289 displayPixelLightSamples(gData->user1, gData->user2 == 1 ? true : false); 290 break; 291 default: 292 rsDebug("Wrong test number", gData->testId); 293 break; 294 } 295 } 296