• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
16 #include "glinterface.h"
17 #include "main.h"
18 #include "utils.h"
19 
20 
GenerateAndBindTexture()21 GLuint 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);
27   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);
29   return name;
30 }
31 
CreateBitmap(int w,int h)32 unsigned char* CreateBitmap(int w, int h) {
33   unsigned char* bitmap = new unsigned char[4 * w * h];
34   unsigned char* pixel = bitmap;
35   float w2 = 0.5f * w;
36   float h2 = 0.5f * h;
37   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;
45       *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;
52       pixel++;
53     }
54   }
55   return bitmap;
56 }
57 
58 
59 const char kVertexShader[] =
60     "attribute vec4 vertices;"
61     "varying vec2 v1;"
62     "void main() {"
63     "    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);"
65     "}";
66 
67 const char kFragmentShader[] =
68     "uniform sampler2D tex;"
69     "uniform vec4 color;"
70     "varying vec2 v1;"
71     "void main() {"
72     "    gl_FragColor = color * texture2D(tex, v1);"
73     "}";
74 
75 // Command line flags
76 DEFINE_double(screenshot1_sec, 2.f, "seconds delay before screenshot1_cmd");
77 DEFINE_double(screenshot2_sec, 1.f, "seconds delay before screenshot2_cmd");
78 DEFINE_string(screenshot1_cmd, "", "system command to take a screen shot 1");
79 DEFINE_string(screenshot2_cmd, "", "system command to take a screen shot 2");
80 DEFINE_double(cooldown_sec, 1.f, "seconds delay after all screenshots");
81 
main(int argc,char * argv[])82 int main(int argc, char* argv[]) {
83   // Configure full screen
84   g_width = -1;
85   g_height = -1;
86 
87   google::ParseCommandLineFlags(&argc, &argv, true);
88 
89   g_main_gl_interface.reset(GLInterface::Create());
90   if (!g_main_gl_interface->Init()) {
91     printf("# Error: Failed to initialize %s.\n", argv[0]);
92     return 1;
93   }
94 
95   GLint viewport[2];
96   glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport);
97   printf("# MAX_VIEWPORT_DIMS=(%d, %d)\n", viewport[0], viewport[1]);
98   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);
103 
104   unsigned char* bitmap = CreateBitmap(g_height, g_width);
105   GLuint texture = GenerateAndBindTexture();
106   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_height, g_width, 0,
107                GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
108 
109   GLfloat vertices[8] = {
110     -1.f, -1.f,
111     1.f, -1.f,
112     -1.f, 1.f,
113     1.f, 1.f,
114   };
115 
116   GLuint program = glbench::InitShaderProgram(kVertexShader, kFragmentShader);
117   int attribute_index = glGetAttribLocation(program, "vertices");
118   glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices);
119   glEnableVertexAttribArray(attribute_index);
120 
121   int texture_sampler = glGetUniformLocation(program, "tex");
122   glUniform1i(texture_sampler, 0);
123 
124   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[] = {
136       static_cast<float>(FLAGS_screenshot1_sec),
137       static_cast<float>(FLAGS_screenshot2_sec),
138       static_cast<float>(FLAGS_cooldown_sec),
139       0
140   };
141 
142   do {
143     // Draw
144     glClear(GL_COLOR_BUFFER_BIT);
145     if (state == kStateScreenShot1)
146       glUniform4fv(display_color, 1, white);
147     else
148       glUniform4fv(display_color, 1, blue);
149     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
150     g_main_gl_interface->SwapBuffers();
151     // 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);
174 
175   glDeleteTextures(1, &texture);
176   g_main_gl_interface->Cleanup();
177   return 0;
178 }
179