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