• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2010-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 /* Message sent from script to renderscript */
24 const int RS_MSG_TEST_DONE = 100;
25 const int RS_MSG_RESULTS_READY = 101;
26 
27 static const int gMaxModes = 64;
28 int gMaxLoops = 1;
29 int gDisplayMode = 1;
30 
31 // Allocation to write the results into
32 static float gResultBuffer[gMaxModes];
33 
34 rs_font gFontSerif;
35 rs_sampler gLinearClamp;
36 
37 rs_program_vertex gProgVertex;
38 rs_program_fragment gProgFragmentTexture;
39 
40 rs_allocation gRenderBufferColor;
41 rs_allocation gRenderBufferDepth;
42 
43 VertexShaderInputs *gVSInputs;
44 
45 typedef struct TestScripts_s {
46     rs_allocation testData;
47     rs_allocation testName;
48     rs_allocation debugName;
49     rs_script testScript;
50 } TestScripts;
51 TestScripts *gTestScripts;
52 
53 bool gLoadComplete = false;
54 bool gPauseRendering = false;
55 
56 static float gDt = 0;
57 
58 void init() {
59 }
60 
61 static int gRenderSurfaceW;
62 static int gRenderSurfaceH;
63 
64 static void fillSurfaceParams(TestData *testData) {
65     testData->renderSurfaceW = gRenderSurfaceW;
66     testData->renderSurfaceH = gRenderSurfaceH;
67     testData->dt = gDt;
68 }
69 
70 static void setupOffscreenTarget() {
71     rsgBindColorTarget(gRenderBufferColor, 0);
72     rsgBindDepthTarget(gRenderBufferDepth);
73 }
74 
75 static void bindProgramVertexOrtho() {
76     // Default vertex shader
77     rsgBindProgramVertex(gProgVertex);
78     // Setup the projection matrix
79     rs_matrix4x4 proj;
80     rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500);
81     rsgProgramVertexLoadProjectionMatrix(&proj);
82 }
83 
84 static void runSubTest(int index) {
85     TestData testData;
86     fillSurfaceParams(&testData);
87 
88     rs_allocation null_alloc;
89     rsForEach(gTestScripts[index].testScript,
90               gTestScripts[index].testData,
91               null_alloc,
92               &testData,
93               sizeof(testData));
94 }
95 
96 
97 static bool checkInit() {
98 
99     static int countdown = 3;
100 
101     // Perform all the uploads so we only measure rendered time
102     if(countdown > 1) {
103         int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts));
104         for(int i = 0; i < testCount; i ++) {
105             rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
106             runSubTest(i);
107             rsgFinish();
108         }
109         countdown --;
110         rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
111 
112         rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
113         rsgBindFont(gFontSerif);
114         if (countdown == 1) {
115             rsgDrawText("Rendering", 50, 50);
116         } else {
117             rsgDrawText("Initializing", 50, 50);
118         }
119 
120         return false;
121     }
122 
123     return true;
124 }
125 
126 static int benchMode = 0;
127 static bool benchmarkSingleTest = false;
128 static int benchSubMode = 0;
129 static int runningLoops = 0;
130 static bool sendMsgFlag = false;
131 
132 static bool gIsDebugMode = false;
133 void setDebugMode(int testNumber) {
134     gIsDebugMode = true;
135     benchMode = testNumber;
136     rsgClearAllRenderTargets();
137 }
138 
139 void setBenchmarkMode(int testNumber) {
140     gIsDebugMode = false;
141     if (testNumber == -1) {
142         benchmarkSingleTest = false;
143         benchMode = 0;
144     } else {
145         benchmarkSingleTest = true;
146         benchMode = testNumber;
147     }
148 
149     runningLoops = 0;
150 }
151 
152 static void drawOffscreenResult(int posX, int posY, int width, int height) {
153     bindProgramVertexOrtho();
154 
155     rs_matrix4x4 matrix;
156     rsMatrixLoadIdentity(&matrix);
157     rsgProgramVertexLoadModelMatrix(&matrix);
158 
159     rsgBindProgramFragment(gProgFragmentTexture);
160 
161     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
162     rsgBindTexture(gProgFragmentTexture, 0, gRenderBufferColor);
163 
164     float startX = posX, startY = posY;
165     rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
166                          startX, startY + height, 0, 0, 0,
167                          startX + width, startY + height, 0, 1, 0,
168                          startX + width, startY, 0, 1, 1);
169 }
170 
171 static void benchmark() {
172 
173     gDt = 1.0f / 60.0f;
174 
175     rsgFinish();
176     int64_t start = rsUptimeMillis();
177 
178     int drawPos = 0;
179     int frameCount = 100;
180     for(int i = 0; i < frameCount; i ++) {
181         setupOffscreenTarget();
182         gRenderSurfaceW = rsAllocationGetDimX(gRenderBufferColor);
183         gRenderSurfaceH = rsAllocationGetDimY(gRenderBufferColor);
184         rsgClearColor(0.1f, 0.1f, 0.1f, 1.0f);
185         rsgClearDepth(1.0f);
186 
187         runSubTest(benchMode);
188         rsgClearAllRenderTargets();
189         gRenderSurfaceW = rsgGetWidth();
190         gRenderSurfaceH = rsgGetHeight();
191         int size = 8;
192         // draw each frame at (8, 3/4 gRenderSurfaceH) with size
193         drawOffscreenResult((drawPos+=size)%gRenderSurfaceW, (gRenderSurfaceH * 3) / 4, size, size);
194     }
195 
196     rsgFinish();
197 
198     int64_t end = rsUptimeMillis();
199     float fps = (float)(frameCount) / ((float)(end - start)*0.001f);
200     const char *testName = rsGetElementAt(gTestScripts[benchMode].debugName, 0);
201     rsDebug(testName, fps);
202 
203     gResultBuffer[benchMode] = fps;
204     int bufferW = rsAllocationGetDimX(gRenderBufferColor);
205     int bufferH = rsAllocationGetDimY(gRenderBufferColor);
206 
207     int quadW = gRenderSurfaceW / 2;
208     int quadH = (quadW * bufferH) / bufferW;
209     drawOffscreenResult(0, 0, quadW, quadH);
210 
211     int left = 0, right = 0, top = 0, bottom = 0;
212     uint width = rsgGetWidth();
213     uint height = rsgGetHeight();
214     rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
215     rsgBindFont(gFontSerif);
216     rsgMeasureText(gTestScripts[benchMode].testName, &left, &right, &top, &bottom);
217     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
218     rsgDrawText(gTestScripts[benchMode].testName, 2 -left, height - 2 + bottom);
219 
220     if (benchmarkSingleTest) {
221         return;
222     }
223 
224     benchMode ++;
225     int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts));
226     if (benchMode == testCount) {
227         rsSendToClientBlocking(RS_MSG_RESULTS_READY, gResultBuffer, testCount*sizeof(float));
228         benchMode = 0;
229         runningLoops++;
230         if ((gMaxLoops > 0) && (runningLoops > gMaxLoops) && !sendMsgFlag) {
231             //Notifiy the test to stop and get results
232             rsDebug("gMaxLoops and runningLoops: ", gMaxLoops, runningLoops);
233             rsSendToClientBlocking(RS_MSG_TEST_DONE);
234             sendMsgFlag = true;
235         }
236     }
237 }
238 
239 static void debug() {
240     gDt = rsGetDt();
241     runSubTest(benchMode);
242 }
243 
244 int root(void) {
245     gRenderSurfaceW = rsgGetWidth();
246     gRenderSurfaceH = rsgGetHeight();
247     rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f);
248     rsgClearDepth(1.0f);
249 
250     if (!gLoadComplete) {
251         rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
252         rsgBindFont(gFontSerif);
253         rsgDrawText("Loading", 50, 50);
254         return 0;
255     }
256 
257     if(!checkInit()) {
258         return 1;
259     }
260 
261     if (gPauseRendering) {
262         rsgDrawText("Paused", 50, 50);
263         return 30;
264     }
265     if (gIsDebugMode) {
266         debug();
267     } else {
268         benchmark();
269     }
270 
271     return 1;
272 }
273