OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <gflags/gflags.h> |
5 #include <stdio.h> | 6 #include <stdio.h> |
6 #include <stdlib.h> | 7 #include <stdlib.h> |
7 #include <string.h> | 8 #include <string.h> |
8 #include <time.h> | 9 #include <time.h> |
9 | 10 |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 | 12 |
12 #include "main.h" | 13 #include "main.h" |
13 #include "utils.h" | 14 #include "utils.h" |
14 #include "xlib_window.h" | 15 #include "xlib_window.h" |
15 | 16 |
16 #include "teartest.h" | 17 #include "teartest.h" |
17 | 18 |
18 | 19 |
19 static Pixmap pixmap = 0; | 20 static Pixmap pixmap = 0; |
20 static int shift_uniform = 0; | 21 static int shift_uniform = 0; |
| 22 DEFINE_int32(refresh, 0, |
| 23 "If 1 or more, target refresh rate; otherwise enable vsync"); |
21 | 24 |
22 GLuint GenerateAndBindTexture() { | 25 GLuint GenerateAndBindTexture() { |
23 GLuint name = ~0; | 26 GLuint name = ~0; |
24 glGenTextures(1, &name); | 27 glGenTextures(1, &name); |
25 glBindTexture(GL_TEXTURE_2D, name); | 28 glBindTexture(GL_TEXTURE_2D, name); |
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
27 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 30 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
28 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | 31 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | 32 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
30 return name; | 33 return name; |
31 } | 34 } |
32 | 35 |
33 | 36 |
34 const char *vertex_shader = | 37 const char *vertex_shader = |
35 "attribute vec4 c;" | 38 "attribute vec4 c;" |
36 "uniform float shift;" | 39 "uniform float shift;" |
37 "void main() {" | 40 "void main() {" |
38 " gl_Position = c;" | 41 " gl_Position = c;" |
39 " gl_TexCoord[0] = vec4(c.y, c.x - shift, 0.0, 0.0);" | 42 " gl_TexCoord[0] = vec4(c.y, c.x - shift, 0.0, 0.0);" |
40 "}"; | 43 "}"; |
41 | 44 |
42 const char *fragment_shader = | 45 const char *fragment_shader = |
43 "uniform sampler2D tex;" | 46 "uniform sampler2D tex;" |
44 "void main() {" | 47 "void main() {" |
45 " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);" | 48 " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);" |
46 "}"; | 49 "}"; |
47 | 50 |
48 | 51 |
49 // If refresh is set to zero, we enable vsync. Otherwise we redraw that many | |
50 // times a second. | |
51 struct timespec* g_sleep_duration = NULL; | |
52 static void ParseArgs(int argc, char* argv[]) { | |
53 bool refresh_arg = false; | |
54 for (int i = 0; i < argc; i++) { | |
55 if (refresh_arg) { | |
56 refresh_arg = false; | |
57 | |
58 int refresh = atoi(argv[i]); | |
59 if (refresh > 1) { | |
60 delete g_sleep_duration; | |
61 g_sleep_duration = new struct timespec; | |
62 g_sleep_duration->tv_sec = 0; | |
63 g_sleep_duration->tv_nsec = static_cast<long>(1.e9 / refresh); | |
64 } else { | |
65 printf("-r requires integer greater than one.\n"); | |
66 } | |
67 } else if (strcmp("-o", argv[i]) == 0) { | |
68 g_override_redirect = true; | |
69 } else if (strcmp("-r", argv[i]) == 0) { | |
70 refresh_arg = true; | |
71 } | |
72 } | |
73 } | |
74 | |
75 | |
76 void AllocatePixmap() { | 52 void AllocatePixmap() { |
77 XWindowAttributes attributes; | 53 XWindowAttributes attributes; |
78 XGetWindowAttributes(g_xlib_display, g_xlib_window, &attributes); | 54 XGetWindowAttributes(g_xlib_display, g_xlib_window, &attributes); |
79 pixmap = XCreatePixmap(g_xlib_display, g_xlib_window, | 55 pixmap = XCreatePixmap(g_xlib_display, g_xlib_window, |
80 g_height, g_width, attributes.depth); | 56 g_height, g_width, attributes.depth); |
81 } | 57 } |
82 | 58 |
83 void InitializePixmap() { | 59 void InitializePixmap() { |
84 GC gc = DefaultGC(g_xlib_display, 0); | 60 GC gc = DefaultGC(g_xlib_display, 0); |
85 XSetForeground(g_xlib_display, gc, 0xffffff); | 61 XSetForeground(g_xlib_display, gc, 0xffffff); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 129 } |
154 | 130 |
155 | 131 |
156 Test test[] = { | 132 Test test[] = { |
157 UpdateUniform, | 133 UpdateUniform, |
158 UpdateTexImage2D, | 134 UpdateTexImage2D, |
159 UpdateBindTexImage | 135 UpdateBindTexImage |
160 }; | 136 }; |
161 | 137 |
162 int main(int argc, char* argv[]) { | 138 int main(int argc, char* argv[]) { |
163 g_override_redirect = false; | 139 struct timespec* sleep_duration = NULL; |
164 g_height = -1; | 140 g_height = -1; |
165 ParseArgs(argc, argv); | 141 google::ParseCommandLineFlags(&argc, &argv, true); |
| 142 if (FLAGS_refresh >= 1) { |
| 143 sleep_duration = new struct timespec; |
| 144 sleep_duration->tv_sec = 0; |
| 145 sleep_duration->tv_nsec = static_cast<long>(1.e9 / FLAGS_refresh); |
| 146 } |
166 if (!Init()) { | 147 if (!Init()) { |
167 printf("# Failed to initialize.\n"); | 148 printf("# Failed to initialize.\n"); |
168 return 1; | 149 return 1; |
169 } | 150 } |
170 | 151 |
171 InitContext(); | 152 InitContext(); |
172 glViewport(-g_width, -g_height, g_width*2, g_height*2); | 153 glViewport(-g_width, -g_height, g_width*2, g_height*2); |
173 | 154 |
174 GLuint texture = GenerateAndBindTexture(); | 155 GLuint texture = GenerateAndBindTexture(); |
175 | 156 |
176 AllocatePixmap(); | 157 AllocatePixmap(); |
177 InitNative(pixmap); | 158 InitNative(pixmap); |
178 | 159 |
179 GLfloat vertices[8] = { | 160 GLfloat vertices[8] = { |
180 0.f, 0.f, | 161 0.f, 0.f, |
181 1.f, 0.f, | 162 1.f, 0.f, |
182 0.f, 1.f, | 163 0.f, 1.f, |
183 1.f, 1.f, | 164 1.f, 1.f, |
184 }; | 165 }; |
185 | 166 |
186 GLuint program = InitShaderProgram(vertex_shader, fragment_shader); | 167 GLuint program = InitShaderProgram(vertex_shader, fragment_shader); |
187 int attribute_index = glGetAttribLocation(program, "c"); | 168 int attribute_index = glGetAttribLocation(program, "c"); |
188 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices); | 169 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices); |
189 glEnableVertexAttribArray(attribute_index); | 170 glEnableVertexAttribArray(attribute_index); |
190 | 171 |
191 int texture_sampler = glGetUniformLocation(program, "tex"); | 172 int texture_sampler = glGetUniformLocation(program, "tex"); |
192 glUniform1f(texture_sampler, 0); | 173 glUniform1f(texture_sampler, 0); |
193 | 174 |
194 shift_uniform = glGetUniformLocation(program, "shift"); | 175 shift_uniform = glGetUniformLocation(program, "shift"); |
195 SwapInterval(g_sleep_duration ? 0 : 1); | 176 SwapInterval(sleep_duration ? 0 : 1); |
196 | 177 |
197 for (unsigned int i = 0; i < sizeof(test)/sizeof(*test); i++) | 178 for (unsigned int i = 0; i < sizeof(test)/sizeof(*test); i++) |
198 { | 179 { |
199 XEvent event; | 180 XEvent event; |
200 if (!test[i](TestStart, 0)) | 181 if (!test[i](TestStart, 0)) |
201 continue; | 182 continue; |
202 | 183 |
203 Bool got_event = False; | 184 Bool got_event = False; |
204 for (int x = 0; !got_event; x = (x + 4) % (2 * g_width)) { | 185 for (int x = 0; !got_event; x = (x + 4) % (2 * g_width)) { |
205 const int shift = x < g_width ? x : 2 * g_width - x; | 186 const int shift = x < g_width ? x : 2 * g_width - x; |
206 | 187 |
207 test[i](TestLoop, shift); | 188 test[i](TestLoop, shift); |
208 | 189 |
209 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 190 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
210 glFlush(); | 191 glFlush(); |
211 | 192 |
212 if (g_sleep_duration) | 193 if (sleep_duration) |
213 nanosleep(g_sleep_duration, NULL); | 194 nanosleep(sleep_duration, NULL); |
214 | 195 |
215 SwapBuffers(); | 196 SwapBuffers(); |
216 | 197 |
217 got_event = XCheckWindowEvent(g_xlib_display, g_xlib_window, | 198 got_event = XCheckWindowEvent(g_xlib_display, g_xlib_window, |
218 KeyPressMask, &event); | 199 KeyPressMask, &event); |
219 } | 200 } |
220 | 201 |
221 test[i](TestStop, 0); | 202 test[i](TestStop, 0); |
222 } | 203 } |
223 | 204 |
224 // TODO: clean teardown. | 205 // TODO: clean teardown. |
225 | 206 |
226 glDeleteTextures(1, &texture); | 207 glDeleteTextures(1, &texture); |
227 DestroyContext(); | 208 DestroyContext(); |
228 return 0; | 209 return 0; |
229 } | 210 } |
OLD | NEW |