Home | History | Annotate | Download | only in perftest
      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 "shader_def.rsh"
     21 #include "subtest_def.rsh"
     22 
     23 // Parameters for galaxy live wallpaper
     24 rs_allocation gTSpace;
     25 rs_allocation gTLight1;
     26 rs_allocation gTFlares;
     27 rs_mesh gParticlesMesh;
     28 
     29 rs_program_fragment gPFBackground;
     30 rs_program_fragment gPFStars;
     31 rs_program_vertex gPVStars;
     32 rs_program_vertex gPVBkProj;
     33 rs_program_store gPSLights;
     34 
     35 float gXOffset = 0.5f;
     36 
     37 #define ELLIPSE_RATIO 0.892f
     38 #define PI 3.1415f
     39 #define TWO_PI 6.283f
     40 #define ELLIPSE_TWIST 0.023333333f
     41 
     42 static float angle = 50.f;
     43 static int gOldWidth;
     44 static int gOldHeight;
     45 static int gWidth;
     46 static int gHeight;
     47 static float gSpeed[12000];
     48 static int gGalaxyRadius = 300;
     49 static rs_allocation gParticlesBuffer;
     50 
     51 typedef struct __attribute__((packed, aligned(4))) Particle {
     52     uchar4 color;
     53     float3 position;
     54 } Particle_t;
     55 Particle_t *Particles;
     56 
     57 typedef struct VpConsts {
     58     rs_matrix4x4 Proj;
     59     rs_matrix4x4 MVP;
     60 } VpConsts_t;
     61 VpConsts_t *vpConstants;
     62 // End of parameters for galaxy live wallpaper
     63 
     64 rs_program_vertex gProgVertex;
     65 rs_program_fragment gProgFragmentColor;
     66 rs_program_fragment gProgFragmentTexture;
     67 
     68 rs_program_store gProgStoreBlendAlpha;
     69 
     70 rs_allocation gTexOpaque;
     71 rs_allocation gTexTorus;
     72 rs_allocation gTexGlobe;
     73 
     74 typedef struct ListAllocs_s {
     75     rs_allocation item;
     76 } ListAllocs;
     77 
     78 ListAllocs *gTexList100;
     79 ListAllocs *gSampleTextList100;
     80 ListAllocs *gListViewText;
     81 
     82 rs_mesh gSingleMesh;
     83 
     84 rs_font gFontSans;
     85 
     86 rs_sampler gLinearClamp;
     87 
     88 typedef struct UiTestData_s {
     89     int testId;
     90     int user1;
     91     int user2;
     92     int user3;
     93 } UiTestData;
     94 UiTestData *gData;
     95 
     96 static float gDt = 0;
     97 
     98 
     99 void init() {
    100 }
    101 
    102 static int gRenderSurfaceW;
    103 static int gRenderSurfaceH;
    104 
    105 static void bindProgramVertexOrtho() {
    106     // Default vertex shader
    107     rsgBindProgramVertex(gProgVertex);
    108     // Setup the projection matrix
    109     rs_matrix4x4 proj;
    110     rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500);
    111     rsgProgramVertexLoadProjectionMatrix(&proj);
    112 }
    113 
    114 /**
    115   * Methods to draw the galaxy live wall paper
    116   */
    117 static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) {
    118     return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
    119 }
    120 
    121 /**
    122  * Helper function to generate the stars.
    123  */
    124 static float randomGauss() {
    125     float x1;
    126     float x2;
    127     float w = 2.f;
    128 
    129     while (w >= 1.0f) {
    130         x1 = rsRand(2.0f) - 1.0f;
    131         x2 = rsRand(2.0f) - 1.0f;
    132         w = x1 * x1 + x2 * x2;
    133     }
    134 
    135     w = sqrt(-2.0f * log(w) / w);
    136     return x1 * w;
    137 }
    138 
    139 /**
    140  * Generates the properties for a given star.
    141  */
    142 static void createParticle(Particle_t *part, int idx, float scale) {
    143     float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
    144     float id = d / gGalaxyRadius;
    145     float z = randomGauss() * 0.4f * (1.0f - id);
    146     float p = -d * ELLIPSE_TWIST;
    147 
    148     if (d < gGalaxyRadius * 0.33f) {
    149         part->color.x = (uchar) (220 + id * 35);
    150         part->color.y = 220;
    151         part->color.z = 220;
    152     } else {
    153         part->color.x = 180;
    154         part->color.y = 180;
    155         part->color.z = (uchar) clamp(140.f + id * 115.f, 140.f, 255.f);
    156     }
    157     // Stash point size * 10 in Alpha
    158     part->color.w = (uchar) (rsRand(1.2f, 2.1f) * 60);
    159 
    160     if (d > gGalaxyRadius * 0.15f) {
    161         z *= 0.6f * (1.0f - id);
    162     } else {
    163         z *= 0.72f;
    164     }
    165 
    166     // Map to the projection coordinates (viewport.x = -1.0 -> 1.0)
    167     d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d);
    168 
    169     part->position.x = rsRand(TWO_PI);
    170     part->position.y = d;
    171     gSpeed[idx] = rsRand(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f;
    172 
    173     part->position.z = z / 5.0f;
    174 }
    175 
    176 /**
    177  * Initialize all the starts, called from Java
    178  */
    179 void initParticles() {
    180     Particle_t *part = Particles;
    181     float scale = gGalaxyRadius / (gWidth * 0.5f);
    182     int count = rsAllocationGetDimX(gParticlesBuffer);
    183     for (int i = 0; i < count; i ++) {
    184         createParticle(part, i, scale);
    185         part++;
    186     }
    187 }
    188 
    189 static void drawSpace() {
    190     rsgBindProgramFragment(gPFBackground);
    191     rsgBindTexture(gPFBackground, 0, gTSpace);
    192     rsgDrawQuadTexCoords(
    193             0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
    194             gWidth, 0.0f, 0.0f, 2.0f, 1.0f,
    195             gWidth, gHeight, 0.0f, 2.0f, 0.0f,
    196             0.0f, gHeight, 0.0f, 0.0f, 0.0f);
    197 }
    198 
    199 static void drawLights() {
    200     rsgBindProgramVertex(gPVBkProj);
    201     rsgBindProgramFragment(gPFBackground);
    202     rsgBindTexture(gPFBackground, 0, gTLight1);
    203 
    204     float scale = 512.0f / gWidth;
    205     float x = -scale - scale * 0.05f;
    206     float y = -scale;
    207 
    208     scale *= 2.0f;
    209 
    210     rsgDrawQuad(x, y, 0.0f,
    211              x + scale * 1.1f, y, 0.0f,
    212              x + scale * 1.1f, y + scale, 0.0f,
    213              x, y + scale, 0.0f);
    214 }
    215 
    216 static void drawParticles(float offset) {
    217     float a = offset * angle;
    218     float absoluteAngle = fabs(a);
    219 
    220     rs_matrix4x4 matrix;
    221     rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, 10.0f - 6.0f * absoluteAngle / 50.0f);
    222     if (gHeight > gWidth) {
    223         rsMatrixScale(&matrix, 6.6f, 6.0f, 1.0f);
    224     } else {
    225         rsMatrixScale(&matrix, 12.6f, 12.0f, 1.0f);
    226     }
    227     rsMatrixRotate(&matrix, absoluteAngle, 1.0f, 0.0f, 0.0f);
    228     rsMatrixRotate(&matrix, a, 0.0f, 0.4f, 0.1f);
    229     rsMatrixLoad(&vpConstants->MVP, &vpConstants->Proj);
    230     rsMatrixMultiply(&vpConstants->MVP, &matrix);
    231     rsgAllocationSyncAll(rsGetAllocation(vpConstants));
    232 
    233     rsgBindProgramVertex(gPVStars);
    234     rsgBindProgramFragment(gPFStars);
    235     rsgBindProgramStore(gPSLights);
    236     rsgBindTexture(gPFStars, 0, gTFlares);
    237 
    238     Particle_t *vtx = Particles;
    239     int count = rsAllocationGetDimX(gParticlesBuffer);
    240     for (int i = 0; i < count; i++) {
    241         vtx->position.x = vtx->position.x + gSpeed[i];
    242         vtx++;
    243     }
    244 
    245     rsgDrawMesh(gParticlesMesh);
    246 }
    247 /* end of methods for drawing galaxy */
    248 
    249 // Display sample images in a mesh with different texture
    250 static void displayIcons(int meshMode) {
    251     bindProgramVertexOrtho();
    252 
    253     // Fragment shader with texture
    254     rsgBindProgramStore(gProgStoreBlendAlpha);
    255     rsgBindProgramFragment(gProgFragmentTexture);
    256     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    257     rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
    258     rsgDrawQuadTexCoords(
    259             0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
    260             0.0f, gRenderSurfaceH, 0.0f, 0.0f, 1.0f,
    261             gRenderSurfaceW, gRenderSurfaceH, 0.0f, 1.0f, 1.0f,
    262             gRenderSurfaceW, 0.0f, 0.0f, 1.0f, 0.0f);
    263 
    264     int meshCount = (int)pow(10.0f, (float)(meshMode + 1));
    265 
    266     float wSize = gRenderSurfaceW/(float)meshCount;
    267     float hSize = gRenderSurfaceH/(float)meshCount;
    268     rs_matrix4x4 matrix;
    269     rsMatrixLoadScale(&matrix, wSize, hSize, 1.0);
    270 
    271     float yPos = 0;
    272     float yPad = hSize / 2;
    273     float xPad = wSize / 2;
    274     for (int y = 0; y < meshCount; y++) {
    275         yPos = y * hSize + yPad;
    276         float xPos = 0;
    277         for (int x = 0; x < meshCount; x++) {
    278             xPos = x * wSize + xPad;
    279             rs_matrix4x4 transMatrix;
    280             rsMatrixLoadTranslate(&transMatrix, xPos, yPos, 0);
    281             rsMatrixMultiply(&transMatrix, &matrix);
    282             rsgProgramVertexLoadModelMatrix(&transMatrix);
    283             int i = (x + y * meshCount) % 100;
    284             rsgBindTexture(gProgFragmentTexture, 0, gTexList100[i].item);
    285             rsgDrawMesh(gSingleMesh);
    286         }
    287     }
    288 }
    289 
    290 // Draw meshes in a single page with top left corner coordinates (xStart, yStart)
    291 static void drawMeshInPage(float xStart, float yStart, int wResolution, int hResolution) {
    292     // Draw wResolution * hResolution meshes in one page
    293     float wMargin = 100.0f;
    294     float hMargin = 100.0f;
    295     float xPad = 50.0f;
    296     float yPad = 20.0f;
    297     float size = 100.0f;  // size of images
    298 
    299     // font info
    300     rs_font font = gFontSans;
    301     rsgBindFont(font);
    302     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    303 
    304     // Measure text size
    305     int left = 0, right = 0, top = 0, bottom = 0;
    306     rsgMeasureText(gSampleTextList100[0].item, &left, &right, &top, &bottom);
    307     float textHeight = (float)(top - bottom);
    308     float textWidth = (float)(right - left);
    309 
    310     rs_matrix4x4 matrix;
    311     rsMatrixLoadScale(&matrix, size, size, 1.0);
    312 
    313     for (int y = 0; y < hResolution; y++) {
    314         float yPos = yStart + hMargin + y * size + y * yPad;
    315         for (int x = 0; x < wResolution; x++) {
    316             float xPos = xStart + wMargin + x * size + x * xPad;
    317 
    318             rs_matrix4x4 transMatrix;
    319             rsMatrixLoadTranslate(&transMatrix, xPos + size/2, yPos + size/2, 0);
    320             rsMatrixMultiply(&transMatrix, &matrix);  // scale the mesh
    321             rsgProgramVertexLoadModelMatrix(&transMatrix);
    322 
    323             int i = (y * wResolution + x) % 100;
    324             rsgBindTexture(gProgFragmentTexture, 0, gTexList100[i].item);
    325             rsgDrawMesh(gSingleMesh);
    326             rsgDrawText(gSampleTextList100[i].item, xPos, yPos + size + yPad/2 + textHeight);
    327         }
    328     }
    329 }
    330 
    331 // Display both images and text as shown in launcher and homepage
    332 // meshMode will decide how many pages we draw
    333 // meshMode = 0: draw 3 pages of meshes
    334 // meshMode = 1: draw 5 pages of meshes
    335 static void displayImageWithText(int wResolution, int hResolution, int meshMode) {
    336     bindProgramVertexOrtho();
    337 
    338     // Fragment shader with texture
    339     rsgBindProgramStore(gProgStoreBlendAlpha);
    340     rsgBindProgramFragment(gProgFragmentTexture);
    341     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    342 
    343     drawMeshInPage(0, 0, wResolution, hResolution);
    344     drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    345     drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    346     if (meshMode == 1) {
    347         // draw another two pages of meshes
    348         drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    349         drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    350     }
    351 }
    352 
    353 // Display a list of text as the list view
    354 static void displayListView() {
    355     // set text color
    356     rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
    357     rsgBindFont(gFontSans);
    358 
    359     // get the size of the list
    360     rs_allocation textAlloc;
    361     textAlloc = rsGetAllocation(gListViewText);
    362     int allocSize = rsAllocationGetDimX(textAlloc);
    363 
    364     int listItemHeight = 80;
    365     int yOffset = listItemHeight;
    366 
    367     // set the color for the list divider
    368     rsgBindProgramFragment(gProgFragmentColor);
    369     rsgProgramFragmentConstantColor(gProgFragmentColor, 1.0, 1.0, 1.0, 1);
    370 
    371     // draw the list with divider
    372     for (int i = 0; i < allocSize; i++) {
    373         if (yOffset - listItemHeight > gRenderSurfaceH) {
    374             break;
    375         }
    376         rsgDrawRect(0, yOffset - 1, gRenderSurfaceW, yOffset, 0);
    377         rsgDrawText(gListViewText[i].item, 20, yOffset - 10);
    378         yOffset += listItemHeight;
    379     }
    380 }
    381 
    382 static void drawGalaxy() {
    383     rsgClearColor(0.f, 0.f, 0.f, 1.f);
    384     gParticlesBuffer = rsGetAllocation(Particles);
    385     rsgBindProgramFragment(gPFBackground);
    386 
    387     gWidth = rsgGetWidth();
    388     gHeight = rsgGetHeight();
    389     if ((gWidth != gOldWidth) || (gHeight != gOldHeight)) {
    390         initParticles();
    391         gOldWidth = gWidth;
    392         gOldHeight = gHeight;
    393     }
    394 
    395     float offset = mix(-1.0f, 1.0f, gXOffset);
    396     drawSpace();
    397     drawParticles(offset);
    398     drawLights();
    399 }
    400 
    401 // Display images and text with live wallpaper in the background
    402 static void displayLiveWallPaper(int wResolution, int hResolution) {
    403     bindProgramVertexOrtho();
    404 
    405     drawGalaxy();
    406 
    407     rsgBindProgramVertex(gProgVertex);
    408     rsgBindProgramStore(gProgStoreBlendAlpha);
    409     rsgBindProgramFragment(gProgFragmentTexture);
    410     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    411 
    412     drawMeshInPage(0, 0, wResolution, hResolution);
    413     drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    414     drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    415     drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    416     drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution);
    417 }
    418 
    419 void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
    420     TestData *testData = (TestData*)usrData;
    421     gRenderSurfaceW = testData->renderSurfaceW;
    422     gRenderSurfaceH = testData->renderSurfaceH;
    423     gDt = testData->dt;
    424 
    425     gData = (UiTestData*)v_in;
    426 
    427     switch(gData->testId) {
    428         case 0:
    429             displayIcons(gData->user1);
    430             break;
    431         case 1:
    432             displayImageWithText(gData->user1, gData->user2, gData->user3);
    433             break;
    434         case 2:
    435             displayListView();
    436             break;
    437         case 3:
    438             displayLiveWallPaper(gData->user1, gData->user2);
    439             break;
    440         default:
    441             rsDebug("Wrong test number", 0);
    442             break;
    443     }
    444 }
    445