blob: 22e196c3ed011381b9190cf5320217489a2b3af9 [file] [log] [blame]
Vincent Scheibc5114c12010-04-08 08:49:50 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Application that displays graphics using OpenGL [ES] with the intent
6// of being used in functional tests.
7
8#include <gflags/gflags.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <time.h>
13
14#include <cmath>
15
Simon Que7f840e72012-12-19 12:05:42 -080016#include "glinterface.h"
Vincent Scheibc5114c12010-04-08 08:49:50 -070017#include "main.h"
18#include "utils.h"
19
20
21GLuint GenerateAndBindTexture() {
22 GLuint name = ~0;
23 glGenTextures(1, &name);
24 glBindTexture(GL_TEXTURE_2D, name);
25 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Kenneth Watersca03c732010-12-20 12:26:44 -080027 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
28 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Vincent Scheibc5114c12010-04-08 08:49:50 -070029 return name;
30}
31
Vincent Scheibc5114c12010-04-08 08:49:50 -070032unsigned char* CreateBitmap(int w, int h) {
Ilja Friedelc04bdd42013-01-30 18:55:49 -080033 unsigned char* bitmap = new unsigned char[4 * w * h];
Vincent Scheibc5114c12010-04-08 08:49:50 -070034 unsigned char* pixel = bitmap;
Ilja Friedelc04bdd42013-01-30 18:55:49 -080035 float w2 = 0.5f * w;
36 float h2 = 0.5f * h;
Vincent Scheibc5114c12010-04-08 08:49:50 -070037 for (int y = 0; y < h; y++) {
38 for (int x = 0; x < w; x++) {
39 // Fill with soft ellipse
40 float dx = fabs((x - w2) / w2);
41 float dy = fabs((y - h2) / h2);
42 float dist2 = dx*dx + dy*dy;
43 if (dist2 > 1.f)
44 dist2 = 1.f;
Ilja Friedelc04bdd42013-01-30 18:55:49 -080045 *pixel = (1.f - dist2) * 255.f;
46 pixel++;
47 *pixel = (1.f - dist2) * 255.f;
48 pixel++;
49 *pixel = (1.f - dist2) * 255.f;
50 pixel++;
51 *pixel = 0;
Vincent Scheibc5114c12010-04-08 08:49:50 -070052 pixel++;
53 }
54 }
55 return bitmap;
56}
57
58
59const char kVertexShader[] =
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070060 "attribute vec4 vertices;"
Ilja Friedelc04bdd42013-01-30 18:55:49 -080061 "varying vec2 v1;"
Vincent Scheibc5114c12010-04-08 08:49:50 -070062 "void main() {"
Ilja Friedelc04bdd42013-01-30 18:55:49 -080063 " gl_Position = vec4(vertices.x, vertices.y, 0.0, 1.0);"
64 " v1 = vec2(0.5 * vertices.x + 0.5, 0.5 * vertices.y + 0.5);"
Vincent Scheibc5114c12010-04-08 08:49:50 -070065 "}";
66
67const char kFragmentShader[] =
68 "uniform sampler2D tex;"
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070069 "uniform vec4 color;"
Ilja Friedelc04bdd42013-01-30 18:55:49 -080070 "varying vec2 v1;"
Vincent Scheibc5114c12010-04-08 08:49:50 -070071 "void main() {"
Ilja Friedelc04bdd42013-01-30 18:55:49 -080072 " gl_FragColor = color * texture2D(tex, v1);"
Vincent Scheibc5114c12010-04-08 08:49:50 -070073 "}";
74
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070075// Command line flags
76DEFINE_double(screenshot1_sec, 2.f, "seconds delay before screenshot1_cmd");
77DEFINE_double(screenshot2_sec, 1.f, "seconds delay before screenshot2_cmd");
78DEFINE_string(screenshot1_cmd, "", "system command to take a screen shot 1");
79DEFINE_string(screenshot2_cmd, "", "system command to take a screen shot 2");
80DEFINE_double(cooldown_sec, 1.f, "seconds delay after all screenshots");
Vincent Scheibc5114c12010-04-08 08:49:50 -070081
82int main(int argc, char* argv[]) {
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070083 // Configure full screen
Vincent Scheibc5114c12010-04-08 08:49:50 -070084 g_width = -1;
85 g_height = -1;
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070086
Vincent Scheibc5114c12010-04-08 08:49:50 -070087 google::ParseCommandLineFlags(&argc, &argv, true);
88
Simon Que7f840e72012-12-19 12:05:42 -080089 g_main_gl_interface.reset(GLInterface::Create());
90 if (!g_main_gl_interface->Init()) {
Ilja H. Friedel8faad302011-04-26 14:40:49 -070091 printf("# Error: Failed to initialize %s.\n", argv[0]);
Vincent Scheibc5114c12010-04-08 08:49:50 -070092 return 1;
93 }
94
Ilja Friedelc04bdd42013-01-30 18:55:49 -080095 GLint viewport[2];
96 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport);
Ilja Friedel1b180392013-03-12 17:09:06 -070097 printf("# MAX_VIEWPORT_DIMS=(%d, %d)\n", viewport[0], viewport[1]);
Ilja Friedelc04bdd42013-01-30 18:55:49 -080098 if (viewport[0] < g_width || viewport[1] < g_height) {
99 printf("# Error: MAX_VIEWPORT_DIMS too small\n");
100 return 1;
101 }
102 glViewport(0, 0, g_width, g_height);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700103
104 unsigned char* bitmap = CreateBitmap(g_height, g_width);
105 GLuint texture = GenerateAndBindTexture();
Ilja Friedelc04bdd42013-01-30 18:55:49 -0800106 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_height, g_width, 0,
107 GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700108
109 GLfloat vertices[8] = {
Ilja Friedelc04bdd42013-01-30 18:55:49 -0800110 -1.f, -1.f,
111 1.f, -1.f,
112 -1.f, 1.f,
Vincent Scheibc5114c12010-04-08 08:49:50 -0700113 1.f, 1.f,
114 };
115
Alexey Marinichev9f9b8732010-05-20 19:33:44 -0700116 GLuint program = glbench::InitShaderProgram(kVertexShader, kFragmentShader);
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700117 int attribute_index = glGetAttribLocation(program, "vertices");
Vincent Scheibc5114c12010-04-08 08:49:50 -0700118 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices);
119 glEnableVertexAttribArray(attribute_index);
120
121 int texture_sampler = glGetUniformLocation(program, "tex");
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700122 glUniform1i(texture_sampler, 0);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700123
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700124 int display_color = glGetUniformLocation(program, "color");
125 float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
126 float blue[4] = {0.5f, 0.5f, 1.0f, 1.0f};
127
128 uint64_t last_event_time = GetUTime();
129 enum State {
130 kStateScreenShot1,
131 kStateScreenShot2,
132 kStateCooldown,
133 kStateExit
134 } state = kStateScreenShot1;
135 float seconds_delay_for_next_state[] = {
Han Shen387edd72012-06-19 16:47:14 -0700136 static_cast<float>(FLAGS_screenshot1_sec),
137 static_cast<float>(FLAGS_screenshot2_sec),
138 static_cast<float>(FLAGS_cooldown_sec),
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700139 0
140 };
141
Vincent Scheibc5114c12010-04-08 08:49:50 -0700142 do {
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700143 // Draw
Vincent Scheibc5114c12010-04-08 08:49:50 -0700144 glClear(GL_COLOR_BUFFER_BIT);
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700145 if (state == kStateScreenShot1)
146 glUniform4fv(display_color, 1, white);
147 else
148 glUniform4fv(display_color, 1, blue);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700149 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Simon Que7f840e72012-12-19 12:05:42 -0800150 g_main_gl_interface->SwapBuffers();
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700151 // Loop until next event
152 float seconds_since_last_event =
153 static_cast<float>(GetUTime() - last_event_time) / 1000000ULL;
154 if (seconds_since_last_event < seconds_delay_for_next_state[state])
155 continue;
156
157 // State change. Perform action.
158 switch(state) {
159 case kStateScreenShot1:
160 system(FLAGS_screenshot1_cmd.c_str());
161 break;
162 case kStateScreenShot2:
163 system(FLAGS_screenshot2_cmd.c_str());
164 break;
165 default:
166 break;
167 }
168
169 // Advance to next state
170 last_event_time = GetUTime();
171 state = static_cast<State>(state + 1);
172
173 } while (state != kStateExit);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700174
175 glDeleteTextures(1, &texture);
Simon Que06860822012-12-18 13:17:56 -0800176 g_main_gl_interface->Cleanup();
Vincent Scheibc5114c12010-04-08 08:49:50 -0700177 return 0;
178}