Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     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