// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "glbench/teartest.h"

#include <gflags/gflags.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <map>
#include <string>
#include <vector>

#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"

#include "glbench/glinterface.h"
#include "glbench/main.h"
#include "glbench/utils.h"
#include "glbench/xlib_window.h"

typedef std::map<std::string, Test*> TestMap;


DEFINE_int32(refresh, 0,
             "If 1 or more, target refresh rate; otherwise enable vsync.");

DEFINE_string(tests, "uniform,teximage2d,pixmap_to_texture",
              "Comma-separated list of tests to run.");

DEFINE_int32(seconds_to_run, 5, "Seconds to run a test case for.");

GLuint GenerateAndBindTexture() {
  GLuint name = ~0;
  glGenTextures(1, &name);
  glBindTexture(GL_TEXTURE_2D, name);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  return name;
}

const char *vertex_shader =
    "attribute vec4 c;"
    "uniform float shift;"
    "varying vec4 v1;"
    "void main() {"
    "    gl_Position = vec4(2.0 * c.x - 1.0, 2.0 * c.y - 1.0, 0.0, 1.0);"
    "    v1 = vec4(c.y, c.x - shift, 0.0, 0.0);"
    "}";

const char *fragment_shader =
    "uniform sampler2D tex;"
    "varying vec4 v1;"
    "void main() {"
    "    gl_FragColor = texture2D(tex, v1.xy);"
    "}";


Pixmap AllocatePixmap() {
  XWindowAttributes attributes;
  XGetWindowAttributes(g_xlib_display, g_xlib_window, &attributes);
  Pixmap pixmap = XCreatePixmap(g_xlib_display, g_xlib_window,
                                g_height, g_width, attributes.depth);
  GC gc = DefaultGC(g_xlib_display, 0);
  XSetForeground(g_xlib_display, gc, 0xffffff);
  XFillRectangle(g_xlib_display, pixmap, gc, 0, 0, g_height, g_width);
  UpdatePixmap(pixmap, 0);
  return pixmap;
}


void UpdatePixmap(Pixmap pixmap, int i) {
  static int last_i = 0;
  GC gc = DefaultGC(g_xlib_display, 0);
  XSetForeground(g_xlib_display, gc, 0xffffff);
  XDrawLine(g_xlib_display, pixmap, gc,
            0, last_i, g_height - 1, last_i);
  XDrawLine(g_xlib_display, pixmap, gc,
            0, last_i + 4, g_height - 1, last_i + 4);

  XSetForeground(g_xlib_display, gc, 0x000000);
  XDrawLine(g_xlib_display, pixmap, gc, 0, i, g_height - 1, i);
  XDrawLine(g_xlib_display, pixmap, gc, 0, i + 4, g_height - 1, i + 4);

  last_i = i;
}


void CopyPixmapToTexture(Pixmap pixmap) {
  XImage *xim = XGetImage(g_xlib_display, pixmap, 0, 0, g_height, g_width,
                          AllPlanes, ZPixmap);
  CHECK(xim != NULL);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_height, g_width, 0,
               GL_RGBA, GL_UNSIGNED_BYTE,
               reinterpret_cast<void*>(&xim->data[0]));
  XDestroyImage(xim);
}


// This test needs shift_uniform from outside, don't add it right away.
class UniformTest : public Test {
 public:
  UniformTest() : pixmap_(0), shift_uniform_(-1) {}
  virtual bool Start() {
    printf("# Info: Plain texture draw.\n");
    pixmap_ = AllocatePixmap();
    CopyPixmapToTexture(pixmap_);
    return true;
  }

  virtual bool Loop(int shift) {
    glUniform1f(shift_uniform_, 1.f / g_width * shift);
    return true;
  }

  virtual void Stop() {
    glUniform1f(shift_uniform_, 0.f);
    XFreePixmap(g_xlib_display, pixmap_);
  }

  void SetUniform(int shift_uniform) {
    shift_uniform_ = shift_uniform;
  }

 private:
  Pixmap pixmap_;
  int shift_uniform_;
};

Test* GetUniformTest(int uniform) {
  UniformTest* ret = new UniformTest();
  ret->SetUniform(uniform);
  return ret;
}


class TexImage2DTest : public Test {
 public:
  TexImage2DTest() : pixmap_(0) {}
  virtual bool Start() {
    printf("# Info: Full texture update.\n");
    pixmap_ = AllocatePixmap();
    CopyPixmapToTexture(pixmap_);
    return true;
  }

  virtual bool Loop(int shift) {
    UpdatePixmap(pixmap_, shift);
    // TODO(amarinichev): it's probably much cheaper to not use Pixmap and
    // XImage.
    CopyPixmapToTexture(pixmap_);
    return true;
  }

  virtual void Stop() {
    XFreePixmap(g_xlib_display, pixmap_);
  }

 private:
  Pixmap pixmap_;
};

Test* GetTexImage2DTest() {
  return new TexImage2DTest();
}


int main(int argc, char* argv[]) {
  struct timespec* sleep_duration = NULL;
  g_height = -1;
  TestMap test_map;

  g_main_gl_interface.reset(GLInterface::Create());
  google::ParseCommandLineFlags(&argc, &argv, true);
  if (FLAGS_refresh >= 1) {
    sleep_duration = new struct timespec;
    sleep_duration->tv_sec = 0;
    sleep_duration->tv_nsec = static_cast<long>(1.e9 / FLAGS_refresh);
  }
  if (!g_main_gl_interface->Init()) {
    printf("# Error: Failed to initialize.\n");
    return 1;
  }

  glViewport(0, 0, g_width, g_height);
  GLuint texture = GenerateAndBindTexture();

  GLfloat vertices[8] = {
    0.f, 0.f,
    1.f, 0.f,
    0.f, 1.f,
    1.f, 1.f,
  };

  GLuint program = glbench::InitShaderProgram(vertex_shader, fragment_shader);
  int attribute_index = glGetAttribLocation(program, "c");
  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices);
  glEnableVertexAttribArray(attribute_index);

  int texture_sampler = glGetUniformLocation(program, "tex");
  glUniform1f(texture_sampler, 0);

  // UniformTest needs a uniform from the shader program.  Get the uniform
  // and instantiate the test.
  Test* uniform_test = GetUniformTest(glGetUniformLocation(program, "shift"));
  test_map["uniform"] = uniform_test;
  test_map["teximage2d"] = GetTexImage2DTest();
#if defined(USE_OPENGLES)
  test_map["pixmap_to_texture"] = GetPixmapToTextureTestEGL();
#elif defined(USE_OPENGL)
  test_map["pixmap_to_texture"] = GetPixmapToTextureTest();
#endif

  g_main_gl_interface->SwapInterval(sleep_duration ? 0 : 1);

  std::vector<std::string> tests;
  base::SplitString(FLAGS_tests, ',', &tests);

  int return_code = 0;
  for (const std::string& test : tests) {
    Test* t = test_map[test];
    if (!t || !t->Start()) {
      return_code = 1;
      continue;
    }

    Bool got_event = False;
    uint64_t wait_until = GetUTime() + 1000000ULL * FLAGS_seconds_to_run;
    for (int x = 0;
         !got_event && GetUTime() < wait_until;
         x = (x + 4) % (2 * g_width)) {
      const int shift = x < g_width ? x : 2 * g_width - x;

      t->Loop(shift);

      glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
      glFlush();

      if (sleep_duration)
        nanosleep(sleep_duration, NULL);

      g_main_gl_interface->SwapBuffers();

      XEvent event;
      got_event = XCheckWindowEvent(g_xlib_display, g_xlib_window,
                                    KeyPressMask, &event);
    }

    t->Stop();
  }

  // TODO(amarinichev): cleaner teardown.

  glDeleteTextures(1, &texture);
  g_main_gl_interface->Cleanup();
  return return_code;
}
