blob: 94f2c073cf74476ea9054fe1d8f5159fb08fa7d9 [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
32
33unsigned char* CreateBitmap(int w, int h) {
34 unsigned char* bitmap = new unsigned char[w * h];
35 unsigned char* pixel = bitmap;
36 float w2 = w/2.0f;
37 float h2 = h/2.0f;
38 for (int y = 0; y < h; y++) {
39 for (int x = 0; x < w; x++) {
40 // Fill with soft ellipse
41 float dx = fabs((x - w2) / w2);
42 float dy = fabs((y - h2) / h2);
43 float dist2 = dx*dx + dy*dy;
44 if (dist2 > 1.f)
45 dist2 = 1.f;
46 *pixel = (1.f-dist2) * 255.f;
47 pixel++;
48 }
49 }
50 return bitmap;
51}
52
53
54const char kVertexShader[] =
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070055 "attribute vec4 vertices;"
Kenneth Watersca03c732010-12-20 12:26:44 -080056 "varying vec4 v1;"
Vincent Scheibc5114c12010-04-08 08:49:50 -070057 "void main() {"
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070058 " gl_Position = vertices;"
Stuart Abercrombieb8f4e7a2011-09-26 18:07:55 -070059 " v1 = vec4(vertices.yx, 0.0, 0.0);"
Vincent Scheibc5114c12010-04-08 08:49:50 -070060 "}";
61
62const char kFragmentShader[] =
63 "uniform sampler2D tex;"
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070064 "uniform vec4 color;"
Kenneth Watersca03c732010-12-20 12:26:44 -080065 "varying vec4 v1;"
Vincent Scheibc5114c12010-04-08 08:49:50 -070066 "void main() {"
Stuart Abercrombieb8f4e7a2011-09-26 18:07:55 -070067 " gl_FragColor = color * texture2D(tex, v1.xy);"
Vincent Scheibc5114c12010-04-08 08:49:50 -070068 "}";
69
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070070// Command line flags
71DEFINE_double(screenshot1_sec, 2.f, "seconds delay before screenshot1_cmd");
72DEFINE_double(screenshot2_sec, 1.f, "seconds delay before screenshot2_cmd");
73DEFINE_string(screenshot1_cmd, "", "system command to take a screen shot 1");
74DEFINE_string(screenshot2_cmd, "", "system command to take a screen shot 2");
75DEFINE_double(cooldown_sec, 1.f, "seconds delay after all screenshots");
Vincent Scheibc5114c12010-04-08 08:49:50 -070076
77int main(int argc, char* argv[]) {
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070078 // Configure full screen
Vincent Scheibc5114c12010-04-08 08:49:50 -070079 g_width = -1;
80 g_height = -1;
Vincent Scheibdf7d51e2010-05-06 12:34:36 -070081
Vincent Scheibc5114c12010-04-08 08:49:50 -070082 google::ParseCommandLineFlags(&argc, &argv, true);
83
Simon Que7f840e72012-12-19 12:05:42 -080084 g_main_gl_interface.reset(GLInterface::Create());
85 if (!g_main_gl_interface->Init()) {
Ilja H. Friedel8faad302011-04-26 14:40:49 -070086 printf("# Error: Failed to initialize %s.\n", argv[0]);
Vincent Scheibc5114c12010-04-08 08:49:50 -070087 return 1;
88 }
89
Simon Que7f840e72012-12-19 12:05:42 -080090 g_main_gl_interface->InitContext();
Vincent Scheibc5114c12010-04-08 08:49:50 -070091 glViewport(-g_width, -g_height, g_width*2, g_height*2);
92
93 unsigned char* bitmap = CreateBitmap(g_height, g_width);
94 GLuint texture = GenerateAndBindTexture();
95 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, g_height, g_width, 0,
96 GL_LUMINANCE, GL_UNSIGNED_BYTE, bitmap);
97
98 GLfloat vertices[8] = {
99 0.f, 0.f,
100 1.f, 0.f,
101 0.f, 1.f,
102 1.f, 1.f,
103 };
104
Alexey Marinichev9f9b8732010-05-20 19:33:44 -0700105 GLuint program = glbench::InitShaderProgram(kVertexShader, kFragmentShader);
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700106 int attribute_index = glGetAttribLocation(program, "vertices");
Vincent Scheibc5114c12010-04-08 08:49:50 -0700107 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices);
108 glEnableVertexAttribArray(attribute_index);
109
110 int texture_sampler = glGetUniformLocation(program, "tex");
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700111 glUniform1i(texture_sampler, 0);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700112
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700113 int display_color = glGetUniformLocation(program, "color");
114 float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
115 float blue[4] = {0.5f, 0.5f, 1.0f, 1.0f};
116
117 uint64_t last_event_time = GetUTime();
118 enum State {
119 kStateScreenShot1,
120 kStateScreenShot2,
121 kStateCooldown,
122 kStateExit
123 } state = kStateScreenShot1;
124 float seconds_delay_for_next_state[] = {
Han Shen387edd72012-06-19 16:47:14 -0700125 static_cast<float>(FLAGS_screenshot1_sec),
126 static_cast<float>(FLAGS_screenshot2_sec),
127 static_cast<float>(FLAGS_cooldown_sec),
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700128 0
129 };
130
Vincent Scheibc5114c12010-04-08 08:49:50 -0700131 do {
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700132 // Draw
Vincent Scheibc5114c12010-04-08 08:49:50 -0700133 glClear(GL_COLOR_BUFFER_BIT);
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700134 if (state == kStateScreenShot1)
135 glUniform4fv(display_color, 1, white);
136 else
137 glUniform4fv(display_color, 1, blue);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700138 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Simon Que7f840e72012-12-19 12:05:42 -0800139 g_main_gl_interface->SwapBuffers();
Vincent Scheibdf7d51e2010-05-06 12:34:36 -0700140
141 // Loop until next event
142 float seconds_since_last_event =
143 static_cast<float>(GetUTime() - last_event_time) / 1000000ULL;
144 if (seconds_since_last_event < seconds_delay_for_next_state[state])
145 continue;
146
147 // State change. Perform action.
148 switch(state) {
149 case kStateScreenShot1:
150 system(FLAGS_screenshot1_cmd.c_str());
151 break;
152 case kStateScreenShot2:
153 system(FLAGS_screenshot2_cmd.c_str());
154 break;
155 default:
156 break;
157 }
158
159 // Advance to next state
160 last_event_time = GetUTime();
161 state = static_cast<State>(state + 1);
162
163 } while (state != kStateExit);
Vincent Scheibc5114c12010-04-08 08:49:50 -0700164
165 glDeleteTextures(1, &texture);
Simon Que7f840e72012-12-19 12:05:42 -0800166 g_main_gl_interface->DestroyContext();
Vincent Scheibc5114c12010-04-08 08:49:50 -0700167 return 0;
168}