// 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. #pragma version(1) #pragma rs java_package_name(com.android.perftest) #include "rs_graphics.rsh" #include "subtest_def.rsh" #include "shader_def.rsh" rs_program_vertex gProgVertex; rs_program_fragment gProgFragmentColor; rs_program_fragment gProgFragmentTexture; rs_program_store gProgStoreBlendNoneDepth; rs_mesh gTorusMesh; rs_program_raster gCullBack; rs_program_raster gCullFront; // Custom vertex shader compunents VertexShaderConstants *gVSConstants; FragentShaderConstants *gFSConstants; VertexShaderConstants3 *gVSConstPixel; FragentShaderConstants3 *gFSConstPixel; // Custom shaders we use for lighting rs_program_vertex gProgVertexCustom; rs_program_fragment gProgFragmentCustom; rs_sampler gLinearClamp; rs_allocation gTexTorus; rs_program_vertex gProgVertexPixelLight; rs_program_vertex gProgVertexPixelLightMove; rs_program_fragment gProgFragmentPixelLight; typedef struct TorusTestData_s { int testId; int user1; int user2; } TorusTestData; TorusTestData *gData; static float gDt = 0.0f; static int gRenderSurfaceW; static int gRenderSurfaceH; static float gTorusRotation = 0; static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) { if (buffer == 0) { rsgProgramVertexLoadModelMatrix(matrix); } else { rsgAllocationSyncAll(rsGetAllocation(buffer)); } } static void drawToruses(int numMeshes, rs_matrix4x4 *matrix, void *buffer) { if (numMeshes == 1) { rsMatrixLoadTranslate(matrix, 0.0f, 0.0f, -7.5f); rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); updateModelMatrix(matrix, buffer); rsgDrawMesh(gTorusMesh); return; } if (numMeshes == 2) { rsMatrixLoadTranslate(matrix, -1.6f, 0.0f, -7.5f); rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); updateModelMatrix(matrix, buffer); rsgDrawMesh(gTorusMesh); rsMatrixLoadTranslate(matrix, 1.6f, 0.0f, -7.5f); rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); updateModelMatrix(matrix, buffer); rsgDrawMesh(gTorusMesh); return; } float startX = -5.0f; float startY = -1.5f; float startZ = -15.0f; float dist = 3.2f; for (int h = 0; h < 4; h ++) { for (int v = 0; v < 2; v ++) { // Position our model on the screen rsMatrixLoadTranslate(matrix, startX + dist * h, startY + dist * v, startZ); rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); updateModelMatrix(matrix, buffer); rsgDrawMesh(gTorusMesh); } } } // Quick hack to get some geometry numbers static void displaySimpleGeoSamples(bool useTexture, int numMeshes) { rsgBindProgramVertex(gProgVertex); rsgBindProgramRaster(gCullBack); // Setup the projection matrix with 30 degree field of view rs_matrix4x4 proj; float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH; rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); rsgProgramVertexLoadProjectionMatrix(&proj); // Fragment shader with texture rsgBindProgramStore(gProgStoreBlendNoneDepth); if (useTexture) { rsgBindProgramFragment(gProgFragmentTexture); } else { rsgBindProgramFragment(gProgFragmentColor); rsgProgramFragmentConstantColor(gProgFragmentColor, 0.1, 0.7, 0.1, 1); } rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); rsgBindTexture(gProgFragmentTexture, 0, gTexTorus); // Apply a rotation to our mesh gTorusRotation += 50.0f * gDt; if (gTorusRotation > 360.0f) { gTorusRotation -= 360.0f; } rs_matrix4x4 matrix; drawToruses(numMeshes, &matrix, 0); } float gLight0Rotation = 0; float gLight1Rotation = 0; static void setupCustomShaderLights() { float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f}; float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f}; float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f}; float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f}; float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f}; float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f}; gLight0Rotation += 50.0f * gDt; if (gLight0Rotation > 360.0f) { gLight0Rotation -= 360.0f; } gLight1Rotation -= 50.0f * gDt; if (gLight1Rotation > 360.0f) { gLight1Rotation -= 360.0f; } rs_matrix4x4 l0Mat; rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f); light0Pos = rsMatrixMultiply(&l0Mat, light0Pos); rs_matrix4x4 l1Mat; rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f); light1Pos = rsMatrixMultiply(&l1Mat, light1Pos); // Set light 0 properties gVSConstants->light0_Posision = light0Pos; gVSConstants->light0_Diffuse = 1.0f; gVSConstants->light0_Specular = 0.5f; gVSConstants->light0_CosinePower = 10.0f; // Set light 1 properties gVSConstants->light1_Posision = light1Pos; gVSConstants->light1_Diffuse = 1.0f; gVSConstants->light1_Specular = 0.7f; gVSConstants->light1_CosinePower = 25.0f; rsgAllocationSyncAll(rsGetAllocation(gVSConstants)); // Update fragment shader constants // Set light 0 colors gFSConstants->light0_DiffuseColor = light0DiffCol; gFSConstants->light0_SpecularColor = light0SpecCol; // Set light 1 colors gFSConstants->light1_DiffuseColor = light1DiffCol; gFSConstants->light1_SpecularColor = light1SpecCol; rsgAllocationSyncAll(rsGetAllocation(gFSConstants)); // Set light 0 properties for per pixel lighting gFSConstPixel->light0_Posision = light0Pos; gFSConstPixel->light0_Diffuse = 1.0f; gFSConstPixel->light0_Specular = 0.5f; gFSConstPixel->light0_CosinePower = 10.0f; gFSConstPixel->light0_DiffuseColor = light0DiffCol; gFSConstPixel->light0_SpecularColor = light0SpecCol; // Set light 1 properties gFSConstPixel->light1_Posision = light1Pos; gFSConstPixel->light1_Diffuse = 1.0f; gFSConstPixel->light1_Specular = 0.7f; gFSConstPixel->light1_CosinePower = 25.0f; gFSConstPixel->light1_DiffuseColor = light1DiffCol; gFSConstPixel->light1_SpecularColor = light1SpecCol; rsgAllocationSyncAll(rsGetAllocation(gFSConstPixel)); } static void displayCustomShaderSamples(int numMeshes) { // Update vertex shader constants // Load model matrix // Apply a rotation to our mesh gTorusRotation += 50.0f * gDt; if (gTorusRotation > 360.0f) { gTorusRotation -= 360.0f; } // Setup the projection matrix float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH; rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f); setupCustomShaderLights(); rsgBindProgramVertex(gProgVertexCustom); // Fragment shader with texture rsgBindProgramStore(gProgStoreBlendNoneDepth); rsgBindProgramFragment(gProgFragmentCustom); rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp); rsgBindTexture(gProgFragmentCustom, 0, gTexTorus); // Use back face culling rsgBindProgramRaster(gCullBack); drawToruses(numMeshes, &gVSConstants->model, gVSConstants); } static void displayPixelLightSamples(int numMeshes, bool heavyVertex) { // Update vertex shader constants // Load model matrix // Apply a rotation to our mesh gTorusRotation += 30.0f * gDt; if (gTorusRotation > 360.0f) { gTorusRotation -= 360.0f; } gVSConstPixel->time = rsUptimeMillis()*0.005; // Setup the projection matrix float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH; rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f); setupCustomShaderLights(); if (heavyVertex) { rsgBindProgramVertex(gProgVertexPixelLightMove); } else { rsgBindProgramVertex(gProgVertexPixelLight); } // Fragment shader with texture rsgBindProgramStore(gProgStoreBlendNoneDepth); rsgBindProgramFragment(gProgFragmentPixelLight); rsgBindSampler(gProgFragmentPixelLight, 0, gLinearClamp); rsgBindTexture(gProgFragmentPixelLight, 0, gTexTorus); // Use back face culling rsgBindProgramRaster(gCullBack); drawToruses(numMeshes, &gVSConstPixel->model, gVSConstPixel); } void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { TestData *testData = (TestData*)usrData; gRenderSurfaceW = testData->renderSurfaceW; gRenderSurfaceH = testData->renderSurfaceH; gDt = testData->dt; gData = (TorusTestData*)v_in; switch(gData->testId) { case 0: displaySimpleGeoSamples(gData->user1 == 1 ? true : false, gData->user2); break; case 1: displayCustomShaderSamples(gData->user1); break; case 2: displayPixelLightSamples(gData->user1, gData->user2 == 1 ? true : false); break; default: rsDebug("Wrong test number", gData->testId); break; } }