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