| 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 |