Home | History | Annotate | Download | only in shaderperf
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. 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 distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 #include "ShaderPerfRenderer.h"
     15 #include <graphics/GLUtils.h>
     16 
     17 #include <math.h>
     18 
     19 #include <Trace.h>
     20 
     21 static const float GOLDEN_RATIO = (1.0f + sqrt(5.0f)) / 2.0f;
     22 
     23 static const int SP_NUM_VERTICES = 6;
     24 
     25 static const float SP_VERTICES[SP_NUM_VERTICES * 3] = {
     26         1.0f, 1.0f, -1.0f,
     27         -1.0f, 1.0f, -1.0f,
     28         -1.0f, -1.0f, -1.0f,
     29         -1.0f, -1.0f, -1.0f,
     30         1.0f, -1.0f, -1.0f,
     31         1.0f, 1.0f, -1.0f };
     32 
     33 static const float SP_TEX_COORDS[SP_NUM_VERTICES * 2] = {
     34         1.0f, 1.0f,
     35         0.0f, 1.0f,
     36         0.0f, 0.0f,
     37         0.0f, 0.0f,
     38         1.0f, 0.0f,
     39         1.0f, 1.0f };
     40 
     41 static const char* SP_VERTEX =
     42         "attribute vec4 a_Position;"
     43         "attribute vec2 a_TexCoord;"
     44         "varying vec2 v_TexCoord;"
     45         "void main() {"
     46         "  v_TexCoord = a_TexCoord;"
     47         "  gl_Position = a_Position;"
     48         "}";
     49 
     50 static const char* SP_FRAGMENT_1 =
     51         "precision mediump float;"
     52         "uniform vec2 u_Seed;"
     53         "uniform sampler2D u_Texture;"
     54         "varying vec2 v_TexCoord;"
     55         "void main() {"
     56         "  int count = ";
     57 
     58 //Add workload here
     59 
     60 static const char* SP_FRAGMENT_2 =
     61         " * 4;"//workload * 4 (4 is a tweaking number, bigger = more work)
     62         "  vec2 z;"
     63         "  z.x = 3.0 * (v_TexCoord.x - 0.5);"
     64         "  z.y = 2.0 * (v_TexCoord.y - 0.5);"
     65         "  float u = 0.0;"
     66         "  for (int i = 0; i < count; i++) {"
     67         "    float x = (z.x * z.x - z.y * z.y) + u_Seed.x;"
     68         "    float y = (z.y * z.x + z.x * z.y) + u_Seed.y;"
     69         "    if (((x * x + y * y) > 4.0) && (u == 0.0)) {"
     70         "      u = float(i) / float(count);"
     71         "    }"
     72         "    z.x = x;"
     73         "    z.y = y;"
     74         "  }"
     75         "  gl_FragColor = texture2D(u_Texture, vec2(u, 0.0));"
     76         "}";
     77 
     78 // Copies the source array from 0 up to and including the '\0' character to the
     79 // destination array starting from the given start position. Unlike strcpy, this
     80 // returns the number of characters which were copied.
     81 static int charCopy(const char* source, char* dest, int destStart) {
     82     int srcAddr = 0;
     83     int destAddr = destStart;
     84     char current;
     85     do {
     86         current = source[srcAddr];
     87         dest[destAddr] = current;
     88         srcAddr++;
     89         destAddr++;
     90     } while (current != '\0');
     91     return destAddr - destStart;
     92 }
     93 
     94 ShaderPerfRenderer::ShaderPerfRenderer(ANativeWindow* window, bool offscreen) :
     95         Renderer(window, offscreen) {
     96 }
     97 
     98 bool ShaderPerfRenderer::setUp(int workload) {
     99     SCOPED_TRACE();
    100     if (!Renderer::setUp(workload)) {
    101         return false;
    102     }
    103 
    104     const int MAX_FRAGMENT_SHADER_SIZE = 1000;
    105     char* spFragment = new char[MAX_FRAGMENT_SHADER_SIZE];
    106     // Add the first part.
    107     int index = charCopy(SP_FRAGMENT_1, spFragment, 0);
    108     // Add the count, overwriting the '\0' added by charCopy.
    109     spFragment[index - 1] = (char) (((int) '0') + workload);
    110     // Add the second part.
    111     index += charCopy(SP_FRAGMENT_2, spFragment, index);
    112     // Create program.
    113     mProgramId = GLUtils::createProgram(&SP_VERTEX, const_cast<const char**>(&spFragment));
    114     delete[] spFragment;
    115     if (mProgramId == 0) {
    116         return false;
    117     }
    118     // Bind attributes.
    119     mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
    120     mSeedUniformHandle = glGetUniformLocation(mProgramId, "u_Seed");
    121     mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
    122     mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
    123 
    124     const int SIZE = 256;
    125     uint32_t* m = new uint32_t[SIZE];
    126     if (m != NULL) {
    127         uint32_t* d = m;
    128         for (int i = 0; i < SIZE; i++) {
    129             *d = 0xff000000 | ((i & 0xff) << 16);
    130             d++;
    131         }
    132         glGenTextures(1, &mTextureId);
    133         glBindTexture(GL_TEXTURE_2D, mTextureId);
    134         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
    135         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    136         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    137         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    138     }
    139     delete[] m;
    140 
    141     return true;
    142 }
    143 
    144 void ShaderPerfRenderer::drawWorkload() {
    145     SCOPED_TRACE();
    146     glUseProgram(mProgramId);
    147     // Set the background clear color.
    148     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    149     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    150 
    151     // No culling of back faces
    152     glDisable(GL_CULL_FACE);
    153 
    154     // Bind the texture.
    155     glActiveTexture(GL_TEXTURE0);
    156     glBindTexture(GL_TEXTURE_2D, mTextureId);
    157     glUniform1i(mTextureUniformHandle, 0);
    158 
    159     // Bind the seed.
    160     glUniform2f(mSeedUniformHandle, GOLDEN_RATIO - 2.0f, GOLDEN_RATIO - 1.0f);
    161 
    162     // Bind the vertices.
    163     glEnableVertexAttribArray(mPositionHandle);
    164     glEnableVertexAttribArray(mTexCoordHandle);
    165     glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, SP_VERTICES);
    166     glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, SP_TEX_COORDS);
    167 
    168     glDrawArrays(GL_TRIANGLES, 0, SP_NUM_VERTICES);
    169 }
    170