// Copyright (c) 2012 The Chromium 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 "ui/gl/gl_surface.h"

#include <dwmapi.h>

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/windows_version.h"
#include "ui/gfx/frame_time.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_surface_osmesa.h"
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gl_surface_wgl.h"

// From ANGLE's egl/eglext.h.
#if !defined(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE)
#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE \
  reinterpret_cast<EGLNativeDisplayType>(-2)
#endif
#if !defined(EGL_PLATFORM_ANGLE_ANGLE)
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
#endif
#if !defined(EGL_PLATFORM_ANGLE_TYPE_ANGLE)
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
#endif
#if !defined(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
#endif
#if !defined(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE)
#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
#endif

namespace gfx {

// This OSMesa GL surface can use GDI to swap the contents of the buffer to a
// view.
class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
 public:
  explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window);
  virtual ~NativeViewGLSurfaceOSMesa();

  // Implement subset of GLSurface.
  virtual bool Initialize() override;
  virtual void Destroy() override;
  virtual bool IsOffscreen() override;
  virtual bool SwapBuffers() override;
  virtual bool SupportsPostSubBuffer() override;
  virtual bool PostSubBuffer(int x, int y, int width, int height) override;

 private:
  gfx::AcceleratedWidget window_;
  HDC device_context_;

  DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
};

class WinVSyncProvider : public VSyncProvider {
 public:
  explicit WinVSyncProvider(gfx::AcceleratedWidget window) :
    window_(window)
  {
    use_dwm_ = (base::win::GetVersion() >= base::win::VERSION_WIN7);
  }

  virtual ~WinVSyncProvider() {}

  virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) {
    TRACE_EVENT0("gpu", "WinVSyncProvider::GetVSyncParameters");

    base::TimeTicks timebase;
    base::TimeDelta interval;
    bool dwm_active = false;

    // Query the DWM timing info first if available. This will provide the most
    // precise values.
    if (use_dwm_) {
      DWM_TIMING_INFO timing_info;
      timing_info.cbSize = sizeof(timing_info);
      HRESULT result = DwmGetCompositionTimingInfo(NULL, &timing_info);
      if (result == S_OK) {
        dwm_active = true;
        if (gfx::FrameTime::TimestampsAreHighRes()) {
          // qpcRefreshPeriod is very accurate but noisy, and must be used with
          // a high resolution timebase to avoid frequently missing Vsync.
          timebase = gfx::FrameTime::FromQPCValue(
              static_cast<LONGLONG>(timing_info.qpcVBlank));
          interval = base::TimeDelta::FromQPCValue(
              static_cast<LONGLONG>(timing_info.qpcRefreshPeriod));
        } else if (timing_info.rateRefresh.uiDenominator > 0 &&
            timing_info.rateRefresh.uiNumerator > 0) {
          // If FrameTime is not high resolution, we do not want to translate
          // the QPC value provided by DWM into the low-resolution timebase,
          // which would be error prone and jittery. As a fallback, we assume
          // the timebase is zero and use rateRefresh, which may be rounded but
          // isn't noisy like qpcRefreshPeriod, instead. The fact that we don't
          // have a timebase here may lead to brief periods of jank when our
          // scheduling becomes offset from the hardware vsync.

          // Swap the numerator/denominator to convert frequency to period.
          interval = base::TimeDelta::FromMicroseconds(
              timing_info.rateRefresh.uiDenominator *
              base::Time::kMicrosecondsPerSecond /
              timing_info.rateRefresh.uiNumerator);
        }
      }
    }

    if (!dwm_active) {
      // When DWM compositing is active all displays are normalized to the
      // refresh rate of the primary display, and won't composite any faster.
      // If DWM compositing is disabled, though, we can use the refresh rates
      // reported by each display, which will help systems that have mis-matched
      // displays that run at different frequencies.
      HMONITOR monitor = MonitorFromWindow(window_, MONITOR_DEFAULTTONEAREST);
      MONITORINFOEX monitor_info;
      monitor_info.cbSize = sizeof(MONITORINFOEX);
      BOOL result = GetMonitorInfo(monitor, &monitor_info);
      if (result) {
        DEVMODE display_info;
        display_info.dmSize = sizeof(DEVMODE);
        display_info.dmDriverExtra = 0;
        result = EnumDisplaySettings(monitor_info.szDevice,
            ENUM_CURRENT_SETTINGS, &display_info);
        if (result && display_info.dmDisplayFrequency > 1) {
          interval = base::TimeDelta::FromMicroseconds(
              (1.0 / static_cast<double>(display_info.dmDisplayFrequency)) *
              base::Time::kMicrosecondsPerSecond);
        }
      }
    }

    if (interval.ToInternalValue() != 0) {
      callback.Run(timebase, interval);
    }
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WinVSyncProvider);

  gfx::AcceleratedWidget window_;
  bool use_dwm_;
};

// Helper routine that does one-off initialization like determining the
// pixel format.
bool GLSurface::InitializeOneOffInternal() {
  switch (GetGLImplementation()) {
    case kGLImplementationDesktopGL:
      if (!GLSurfaceWGL::InitializeOneOff()) {
        LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
        return false;
      }
      break;
    case kGLImplementationEGLGLES2:
      if (!GLSurfaceEGL::InitializeOneOff()) {
        LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
        return false;
      }
      break;
  }
  return true;
}

NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa(
    gfx::AcceleratedWidget window)
    : GLSurfaceOSMesa(OSMesaSurfaceFormatRGBA, gfx::Size(1, 1)),
      window_(window),
      device_context_(NULL) {
  DCHECK(window);
}

NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() {
  Destroy();
}

bool NativeViewGLSurfaceOSMesa::Initialize() {
  if (!GLSurfaceOSMesa::Initialize())
    return false;

  device_context_ = GetDC(window_);
  return true;
}

void NativeViewGLSurfaceOSMesa::Destroy() {
  if (window_ && device_context_)
    ReleaseDC(window_, device_context_);

  device_context_ = NULL;

  GLSurfaceOSMesa::Destroy();
}

bool NativeViewGLSurfaceOSMesa::IsOffscreen() {
  return false;
}

bool NativeViewGLSurfaceOSMesa::SwapBuffers() {
  DCHECK(device_context_);

  gfx::Size size = GetSize();

  // Note: negating the height below causes GDI to treat the bitmap data as row
  // 0 being at the top.
  BITMAPV4HEADER info = { sizeof(BITMAPV4HEADER) };
  info.bV4Width = size.width();
  info.bV4Height = -size.height();
  info.bV4Planes = 1;
  info.bV4BitCount = 32;
  info.bV4V4Compression = BI_BITFIELDS;
  info.bV4RedMask = 0x000000FF;
  info.bV4GreenMask = 0x0000FF00;
  info.bV4BlueMask = 0x00FF0000;
  info.bV4AlphaMask = 0xFF000000;

  // Copy the back buffer to the window's device context. Do not check whether
  // StretchDIBits succeeds or not. It will fail if the window has been
  // destroyed but it is preferable to allow rendering to silently fail if the
  // window is destroyed. This is because the primary application of this
  // class of GLContext is for testing and we do not want every GL related ui /
  // browser test to become flaky if there is a race condition between GL
  // context destruction and window destruction.
  StretchDIBits(device_context_,
                0, 0, size.width(), size.height(),
                0, 0, size.width(), size.height(),
                GetHandle(),
                reinterpret_cast<BITMAPINFO*>(&info),
                DIB_RGB_COLORS,
                SRCCOPY);

  return true;
}

bool NativeViewGLSurfaceOSMesa::SupportsPostSubBuffer() {
  return true;
}

bool NativeViewGLSurfaceOSMesa::PostSubBuffer(
    int x, int y, int width, int height) {
  DCHECK(device_context_);

  gfx::Size size = GetSize();

  // Note: negating the height below causes GDI to treat the bitmap data as row
  // 0 being at the top.
  BITMAPV4HEADER info = { sizeof(BITMAPV4HEADER) };
  info.bV4Width = size.width();
  info.bV4Height = -size.height();
  info.bV4Planes = 1;
  info.bV4BitCount = 32;
  info.bV4V4Compression = BI_BITFIELDS;
  info.bV4RedMask = 0x000000FF;
  info.bV4GreenMask = 0x0000FF00;
  info.bV4BlueMask = 0x00FF0000;
  info.bV4AlphaMask = 0xFF000000;

  // Copy the back buffer to the window's device context. Do not check whether
  // StretchDIBits succeeds or not. It will fail if the window has been
  // destroyed but it is preferable to allow rendering to silently fail if the
  // window is destroyed. This is because the primary application of this
  // class of GLContext is for testing and we do not want every GL related ui /
  // browser test to become flaky if there is a race condition between GL
  // context destruction and window destruction.
  StretchDIBits(device_context_,
                x, size.height() - y - height, width, height,
                x, y, width, height,
                GetHandle(),
                reinterpret_cast<BITMAPINFO*>(&info),
                DIB_RGB_COLORS,
                SRCCOPY);

  return true;
}

scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
    gfx::AcceleratedWidget window) {
  TRACE_EVENT0("gpu", "GLSurface::CreateViewGLSurface");
  switch (GetGLImplementation()) {
    case kGLImplementationOSMesaGL: {
      scoped_refptr<GLSurface> surface(
          new NativeViewGLSurfaceOSMesa(window));
      if (!surface->Initialize())
        return NULL;

      return surface;
    }
    case kGLImplementationEGLGLES2: {
      DCHECK(window != gfx::kNullAcceleratedWidget);
      scoped_refptr<NativeViewGLSurfaceEGL> surface(
          new NativeViewGLSurfaceEGL(window));
      scoped_ptr<VSyncProvider> sync_provider;
      sync_provider.reset(new WinVSyncProvider(window));
      if (!surface->Initialize(sync_provider.Pass()))
        return NULL;

      return surface;
    }
    case kGLImplementationDesktopGL: {
      scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceWGL(
          window));
      if (!surface->Initialize())
        return NULL;

      return surface;
    }
    case kGLImplementationMockGL:
      return new GLSurfaceStub;
    default:
      NOTREACHED();
      return NULL;
  }
}

scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
    const gfx::Size& size) {
  TRACE_EVENT0("gpu", "GLSurface::CreateOffscreenGLSurface");
  switch (GetGLImplementation()) {
    case kGLImplementationOSMesaGL: {
      scoped_refptr<GLSurface> surface(
          new GLSurfaceOSMesa(OSMesaSurfaceFormatRGBA, size));
      if (!surface->Initialize())
        return NULL;

      return surface;
    }
    case kGLImplementationEGLGLES2: {
      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceEGL(size));
      if (!surface->Initialize())
        return NULL;

      return surface;
    }
    case kGLImplementationDesktopGL: {
      scoped_refptr<GLSurface> surface(new PbufferGLSurfaceWGL(size));
      if (!surface->Initialize())
        return NULL;

      return surface;
    }
    case kGLImplementationMockGL:
      return new GLSurfaceStub;
    default:
      NOTREACHED();
      return NULL;
  }
}

EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableD3D11) ||
      base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp))
    return GetDC(NULL);
  return EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE;
}

}  // namespace gfx
