// 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 <stdio.h>

#include "base/logging.h"

#include "glbench/glx_stuff.h"
#include "glbench/main.h"
#include "glbench/teartest.h"
#include "glbench/xlib_window.h"


class PixmapToTextureTest : public Test {
 public:
  PixmapToTextureTest();
  virtual bool Start();
  virtual bool Loop(int shift);
  virtual void Stop();
 private:
  bool InitNative();

  GLXPixmap glxpixmap_;
  Pixmap pixmap_;
  bool init_succeeded;

  GLXInterface* interface_;
};

Test* GetPixmapToTextureTest() {
  return new PixmapToTextureTest();
}


PixmapToTextureTest::PixmapToTextureTest() :
  glxpixmap_(0),
  pixmap_(0),
  init_succeeded(false),
  interface_(static_cast<GLXInterface*>(g_main_gl_interface.get())) {}


bool PixmapToTextureTest::InitNative() {
  int major = 0;
  int minor = 0;
  if (!glXQueryVersion(g_xlib_display, &major, &minor))
    return false;

  if (major < 1 || (major == 1 && minor < 3)) {
    printf("# Warning: GLX 1.3 required for pixmap to texture extension.\n");
    return false;
  }

  if (!glXBindTexImageEXT)
    return false;

  pixmap_ = AllocatePixmap();

  int rgba, rgb;
  glXGetFBConfigAttrib(g_xlib_display, interface_->fb_config(),
                       GLX_BIND_TO_TEXTURE_RGBA_EXT, &rgba);
  glXGetFBConfigAttrib(g_xlib_display, interface_->fb_config(),
                       GLX_BIND_TO_TEXTURE_RGB_EXT, &rgb);
  CHECK(rgba || rgb);
  const int pixmapAttribs[] = {
    GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
    GLX_TEXTURE_FORMAT_EXT,
        rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
    None
  };

  glxpixmap_ = glXCreatePixmap(g_xlib_display, interface_->fb_config(),
                              pixmap_, pixmapAttribs);
  return true;
}


bool PixmapToTextureTest::Start() {
  init_succeeded = InitNative();
  printf("# Info: Update pixmap bound to texture.\n");
  CopyPixmapToTexture(pixmap_);
  glXBindTexImageEXT(g_xlib_display, glxpixmap_, GLX_FRONT_LEFT_EXT, NULL);
  return true;
}


bool PixmapToTextureTest::Loop(int shift) {
  if (!init_succeeded)
    return false;
  glXReleaseTexImageEXT(g_xlib_display, glxpixmap_, GLX_FRONT_LEFT_EXT);
  UpdatePixmap(pixmap_, shift);
  glXBindTexImageEXT(g_xlib_display, glxpixmap_, GLX_FRONT_LEFT_EXT, NULL);
  return true;
}


void PixmapToTextureTest::Stop() {
  glXReleaseTexImageEXT(g_xlib_display, glxpixmap_, GLX_FRONT_LEFT_EXT);
  glFinish();
  glXDestroyPixmap(g_xlib_display, glxpixmap_);
  XFreePixmap(g_xlib_display, pixmap_);
}
