/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief WGL Utilities.
 *//*--------------------------------------------------------------------*/

#include "tcuWGL.hpp"
#include "tcuWin32Window.hpp"
#include "deDynamicLibrary.hpp"
#include "deMemory.h"
#include "deStringUtil.hpp"
#include "tcuFormatUtil.hpp"
#include "gluRenderConfig.hpp"

#include <WinGDI.h>

// WGL_ARB_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_ARB				0x2000
#define WGL_DRAW_TO_WINDOW_ARB						0x2001
#define WGL_DRAW_TO_BITMAP_ARB						0x2002
#define WGL_ACCELERATION_ARB						0x2003
#define WGL_NEED_PALETTE_ARB						0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB					0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB					0x2006
#define WGL_SWAP_METHOD_ARB							0x2007
#define WGL_NUMBER_OVERLAYS_ARB						0x2008
#define WGL_NUMBER_UNDERLAYS_ARB					0x2009
#define WGL_TRANSPARENT_ARB							0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB				0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB				0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB				0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB				0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB				0x203B
#define WGL_SHARE_DEPTH_ARB							0x200C
#define WGL_SHARE_STENCIL_ARB						0x200D
#define WGL_SHARE_ACCUM_ARB							0x200E
#define WGL_SUPPORT_GDI_ARB							0x200F
#define WGL_SUPPORT_OPENGL_ARB						0x2010
#define WGL_DOUBLE_BUFFER_ARB						0x2011
#define WGL_STEREO_ARB								0x2012
#define WGL_PIXEL_TYPE_ARB							0x2013
#define WGL_COLOR_BITS_ARB							0x2014
#define WGL_RED_BITS_ARB							0x2015
#define WGL_RED_SHIFT_ARB							0x2016
#define WGL_GREEN_BITS_ARB							0x2017
#define WGL_GREEN_SHIFT_ARB							0x2018
#define WGL_BLUE_BITS_ARB							0x2019
#define WGL_BLUE_SHIFT_ARB							0x201A
#define WGL_ALPHA_BITS_ARB							0x201B
#define WGL_ALPHA_SHIFT_ARB							0x201C
#define WGL_ACCUM_BITS_ARB							0x201D
#define WGL_ACCUM_RED_BITS_ARB						0x201E
#define WGL_ACCUM_GREEN_BITS_ARB					0x201F
#define WGL_ACCUM_BLUE_BITS_ARB						0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB					0x2021
#define WGL_DEPTH_BITS_ARB							0x2022
#define WGL_STENCIL_BITS_ARB						0x2023
#define WGL_AUX_BUFFERS_ARB							0x2024

#define WGL_NO_ACCELERATION_ARB						0x2025
#define WGL_GENERIC_ACCELERATION_ARB				0x2026
#define WGL_FULL_ACCELERATION_ARB					0x2027

#define WGL_TYPE_RGBA_ARB							0x202B
#define WGL_TYPE_COLORINDEX_ARB						0x202C

// WGL_ARB_color_buffer_float
#define WGL_TYPE_RGBA_FLOAT_ARB						0x21A0

// WGL_EXT_pixel_type_packed_float
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT			0x20A8

// WGL_ARB_multisample
#define WGL_SAMPLE_BUFFERS_ARB						0x2041
#define WGL_SAMPLES_ARB								0x2042

// WGL_ARB_create_context
#define WGL_CONTEXT_MAJOR_VERSION_ARB				0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB				0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB					0x2093
#define WGL_CONTEXT_FLAGS_ARB						0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB				0x9126
#define WGL_CONTEXT_DEBUG_BIT_ARB					0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB		0x0002
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB			0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB	0x00000002
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT				0x00000004

// WGL_ARB_create_context_robustness
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB			0x0004
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB	0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB				0x8261
#define WGL_LOSE_CONTEXT_ON_RESET_ARB				0x8252

DE_BEGIN_EXTERN_C

// WGL core
typedef HGLRC	(WINAPI* wglCreateContextFunc)				(HDC hdc);
typedef BOOL	(WINAPI* wglDeleteContextFunc)				(HGLRC hglrc);
typedef BOOL	(WINAPI* wglMakeCurrentFunc)				(HDC hdc, HGLRC hglrc);
typedef PROC	(WINAPI* wglGetProcAddressFunc)				(LPCSTR lpszProc);
typedef BOOL	(WINAPI* wglSwapLayerBuffersFunc)			(HDC dhc, UINT fuPlanes);

// WGL_ARB_pixel_format
typedef BOOL	(WINAPI* wglGetPixelFormatAttribivARBFunc)	(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL	(WINAPI* wglGetPixelFormatAttribfvARBFunc)	(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL	(WINAPI* wglChoosePixelFormatARBFunc)		(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);

// WGL_ARB_create_context
typedef HGLRC	(WINAPI* wglCreateContextAttribsARBFunc)	(HDC hdc, HGLRC hshareContext, const int* attribList);

DE_END_EXTERN_C

namespace tcu
{
namespace wgl
{

// Functions

struct Functions
{
	// Core
	wglCreateContextFunc				createContext;
	wglDeleteContextFunc				deleteContext;
	wglMakeCurrentFunc					makeCurrent;
	wglGetProcAddressFunc				getProcAddress;
	wglSwapLayerBuffersFunc				swapLayerBuffers;

	// WGL_ARB_pixel_format
	wglGetPixelFormatAttribivARBFunc	getPixelFormatAttribivARB;
	wglGetPixelFormatAttribfvARBFunc	getPixelFormatAttribfvARB;
	wglChoosePixelFormatARBFunc			choosePixelFormatARB;

	// WGL_ARB_create_context
	wglCreateContextAttribsARBFunc		createContextAttribsARB;

	Functions (void)
		: createContext				(DE_NULL)
		, deleteContext				(DE_NULL)
		, makeCurrent				(DE_NULL)
		, getProcAddress			(DE_NULL)
		, swapLayerBuffers			(DE_NULL)
		, getPixelFormatAttribivARB	(DE_NULL)
		, getPixelFormatAttribfvARB	(DE_NULL)
		, choosePixelFormatARB		(DE_NULL)
		, createContextAttribsARB	(DE_NULL)
	{
	}
};

// Library

class Library
{
public:
								Library			(HINSTANCE instance);
								~Library		(void);

	const Functions&			getFunctions	(void) const	{ return m_functions;	}
	const de::DynamicLibrary&	getGLLibrary	(void) const	{ return m_library;		}

private:
	de::DynamicLibrary			m_library;
	Functions					m_functions;
};

Library::Library (HINSTANCE instance)
	: m_library("opengl32.dll")
{
	// Temporary 1x1 window for creating context
	win32::Window tmpWindow(instance, 1, 1);

	// Load WGL core.
	m_functions.createContext		= (wglCreateContextFunc)		m_library.getFunction("wglCreateContext");
	m_functions.deleteContext		= (wglDeleteContextFunc)		m_library.getFunction("wglDeleteContext");
	m_functions.getProcAddress		= (wglGetProcAddressFunc)		m_library.getFunction("wglGetProcAddress");
	m_functions.makeCurrent			= (wglMakeCurrentFunc)			m_library.getFunction("wglMakeCurrent");
	m_functions.swapLayerBuffers	= (wglSwapLayerBuffersFunc)		m_library.getFunction("wglSwapLayerBuffers");

	if (!m_functions.createContext		||
		!m_functions.deleteContext		||
		!m_functions.getProcAddress		||
		!m_functions.makeCurrent		||
		!m_functions.swapLayerBuffers)
		throw ResourceError("Failed to load core WGL functions");

	{
		PIXELFORMATDESCRIPTOR pixelFormatDesc;
		deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc));

		pixelFormatDesc.nSize			= sizeof(pixelFormatDesc);
		pixelFormatDesc.nVersion		= 1;
		pixelFormatDesc.dwFlags			= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
		pixelFormatDesc.iPixelType		= PFD_TYPE_RGBA;
		pixelFormatDesc.iLayerType		= PFD_MAIN_PLANE;

		int pixelFormat = ChoosePixelFormat(tmpWindow.getDeviceContext(), &pixelFormatDesc);
		if (!SetPixelFormat(tmpWindow.getDeviceContext(), pixelFormat, &pixelFormatDesc))
			throw ResourceError("Failed to set pixel format for temporary context creation");
	}

	// Create temporary context for loading extension functions.
	HGLRC tmpCtx = m_functions.createContext(tmpWindow.getDeviceContext());
	if (!tmpCtx || !m_functions.makeCurrent(tmpWindow.getDeviceContext(), tmpCtx))
	{
		if (tmpCtx)
			m_functions.deleteContext(tmpCtx);
		throw ResourceError("Failed to create temporary WGL context");
	}

	// WGL_ARB_pixel_format
	m_functions.getPixelFormatAttribivARB	= (wglGetPixelFormatAttribivARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribivARB");
	m_functions.getPixelFormatAttribfvARB	= (wglGetPixelFormatAttribfvARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribfvARB");
	m_functions.choosePixelFormatARB		= (wglChoosePixelFormatARBFunc)m_functions.getProcAddress("wglChoosePixelFormatARB");

	// WGL_ARB_create_context
	m_functions.createContextAttribsARB		= (wglCreateContextAttribsARBFunc)m_functions.getProcAddress("wglCreateContextAttribsARB");

	m_functions.makeCurrent(tmpWindow.getDeviceContext(), NULL);
	m_functions.deleteContext(tmpCtx);

	if (!m_functions.getPixelFormatAttribivARB	||
		!m_functions.getPixelFormatAttribfvARB	||
		!m_functions.choosePixelFormatARB		||
		!m_functions.createContextAttribsARB)
		throw ResourceError("Failed to load WGL extension functions");
}

Library::~Library (void)
{
}

// Core

Core::Core (HINSTANCE instance)
	: m_library(new Library(instance))
{
}

Core::~Core (void)
{
	delete m_library;
}

std::vector<int> Core::getPixelFormats (HDC deviceCtx) const
{
	const Functions& wgl = m_library->getFunctions();

	int attribs[] = { WGL_NUMBER_PIXEL_FORMATS_ARB };
	int values[DE_LENGTH_OF_ARRAY(attribs)];

	if (!wgl.getPixelFormatAttribivARB(deviceCtx, 0, 0, DE_LENGTH_OF_ARRAY(attribs), &attribs[0], &values[0]))
		throw ResourceError("Failed to query number of WGL pixel formats");

	// \todo [2013-04-14 pyry] Do we need to filter values at all?
	std::vector<int> pixelFormats(values[0]);
	for (int i = 0; i < values[0]; i++)
		pixelFormats[i] = i+1;

	return pixelFormats;
}

static PixelFormatInfo::Acceleration translateAcceleration (int accel)
{
	switch (accel)
	{
		case WGL_NO_ACCELERATION_ARB:		return PixelFormatInfo::ACCELERATION_NONE;
		case WGL_GENERIC_ACCELERATION_ARB:	return PixelFormatInfo::ACCELERATION_GENERIC;
		case WGL_FULL_ACCELERATION_ARB:		return PixelFormatInfo::ACCELERATION_FULL;
		default:							return PixelFormatInfo::ACCELERATION_UNKNOWN;
	}
}

static PixelFormatInfo::PixelType translatePixelType (int type)
{
	switch (type)
	{
		case WGL_TYPE_RGBA_ARB:					return PixelFormatInfo::PIXELTYPE_RGBA;
		case WGL_TYPE_RGBA_FLOAT_ARB:			return PixelFormatInfo::PIXELTYPE_RGBA_FLOAT;
		case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:	return PixelFormatInfo::PIXELTYPE_RGBA_UNSIGNED_FLOAT;
		case WGL_TYPE_COLORINDEX_ARB:			return PixelFormatInfo::PIXELTYPE_COLOR_INDEX;
		default:								return PixelFormatInfo::PIXELTYPE_UNKNOWN;
	}
}

PixelFormatInfo Core::getPixelFormatInfo (HDC deviceCtx, int pixelFormat) const
{
	const Functions& wgl = m_library->getFunctions();

	int attribs	[14];
	int values	[DE_LENGTH_OF_ARRAY(attribs)];
	attribs[0]	= WGL_DRAW_TO_WINDOW_ARB;
	attribs[1]	= WGL_DRAW_TO_BITMAP_ARB;
	attribs[2]	= WGL_ACCELERATION_ARB;
	attribs[3]	= WGL_SUPPORT_OPENGL_ARB;
	attribs[4]	= WGL_DOUBLE_BUFFER_ARB;
	attribs[5]	= WGL_PIXEL_TYPE_ARB;
	attribs[6]	= WGL_RED_BITS_ARB;
	attribs[7]	= WGL_GREEN_BITS_ARB;
	attribs[8]	= WGL_BLUE_BITS_ARB;
	attribs[9]	= WGL_ALPHA_BITS_ARB;
	attribs[10]	= WGL_DEPTH_BITS_ARB;
	attribs[11]	= WGL_STENCIL_BITS_ARB;
	attribs[12]	= WGL_SAMPLE_BUFFERS_ARB;
	attribs[13]	= WGL_SAMPLES_ARB;

	deMemset(&values[0], 0, sizeof(values));
	if (!wgl.getPixelFormatAttribivARB(deviceCtx, pixelFormat, 0, DE_LENGTH_OF_ARRAY(attribs), &attribs[0], &values[0]))
		throw ResourceError("Pixel format query failed");

	// Translate values.
	PixelFormatInfo info;

	info.pixelFormat	= pixelFormat;
	info.surfaceTypes	|= (values[0] ? PixelFormatInfo::SURFACE_WINDOW : 0);
	info.surfaceTypes	|= (values[1] ? PixelFormatInfo::SURFACE_PIXMAP : 0);
	info.acceleration	= translateAcceleration(values[2]);
	info.supportOpenGL	= values[3] != 0;
	info.doubleBuffer	= values[4] != 0;
	info.pixelType		= translatePixelType(values[5]);
	info.redBits		= values[6];
	info.greenBits		= values[7];
	info.blueBits		= values[8];
	info.alphaBits		= values[9];
	info.depthBits		= values[10];
	info.stencilBits	= values[11];
	info.sampleBuffers	= values[12];
	info.samples		= values[13];

	return info;
}

// Context

Context::Context (const Core* core, HDC deviceCtx, glu::ContextType ctxType, int pixelFormat)
	: m_core		(core)
	, m_deviceCtx	(deviceCtx)
	, m_context		(0)
{
	const Functions& wgl = core->getLibrary()->getFunctions();

	// Map context type & flags.
	int	profileBit	= 0;
	int	flags		= 0;

	switch (ctxType.getProfile())
	{
		case glu::PROFILE_CORE:
			profileBit = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
			break;

		case glu::PROFILE_ES:
			profileBit = WGL_CONTEXT_ES_PROFILE_BIT_EXT;
			break;

		case glu::PROFILE_COMPATIBILITY:
			profileBit = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
			break;

		default:
			throw NotSupportedError("Unsupported context type for WGL");
	}

	if ((ctxType.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0)
		flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;

	if ((ctxType.getFlags() & glu::CONTEXT_DEBUG) != 0)
		flags |= WGL_CONTEXT_DEBUG_BIT_ARB;

	if ((ctxType.getFlags() & glu::CONTEXT_ROBUST) != 0)
		flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;

	const int attribList[] =
	{
		WGL_CONTEXT_MAJOR_VERSION_ARB,	ctxType.getMajorVersion(),
		WGL_CONTEXT_MINOR_VERSION_ARB,	ctxType.getMinorVersion(),
		WGL_CONTEXT_PROFILE_MASK_ARB,	profileBit,
		WGL_CONTEXT_FLAGS_ARB,			flags,
		0
	};

	// Set pixel format
	{
		PIXELFORMATDESCRIPTOR pixelFormatDesc;
		deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc));

		if (!DescribePixelFormat(deviceCtx, pixelFormat, sizeof(pixelFormatDesc), &pixelFormatDesc))
			throw ResourceError("DescribePixelFormat() failed");

		if (!SetPixelFormat(deviceCtx, pixelFormat, &pixelFormatDesc))
			throw ResourceError("Failed to set pixel format");
	}

	// Create context
	m_context = wgl.createContextAttribsARB(deviceCtx, NULL, attribList);

	if (!m_context)
		throw ResourceError("Failed to create WGL context");

	if (!wgl.makeCurrent(deviceCtx, m_context))
	{
		wgl.deleteContext(m_context);
		throw ResourceError("wglMakeCurrent() failed");
	}
}

Context::~Context (void)
{
	const Functions& wgl = m_core->getLibrary()->getFunctions();

	wgl.makeCurrent(m_deviceCtx, NULL);
	wgl.deleteContext(m_context);
}

FunctionPtr Context::getGLFunction (const char* name) const
{
	FunctionPtr ptr = DE_NULL;

	// Try first with wglGeProcAddress()
	ptr = (FunctionPtr)m_core->getLibrary()->getFunctions().getProcAddress(name);

	// Fall-back to dynlib
	if (!ptr)
		ptr = (FunctionPtr)m_core->getLibrary()->getGLLibrary().getFunction(name);

	return ptr;
}

void Context::swapBuffers (void) const
{
	const Functions& wgl = m_core->getLibrary()->getFunctions();
	if (!wgl.swapLayerBuffers(m_deviceCtx, WGL_SWAP_MAIN_PLANE))
		throw ResourceError("wglSwapBuffers() failed");
}

int choosePixelFormat (const Core& wgl, HDC deviceCtx, const glu::RenderConfig& config)
{
	std::vector<int> pixelFormats = wgl.getPixelFormats(deviceCtx);

	for (std::vector<int>::const_iterator fmtIter = pixelFormats.begin(); fmtIter != pixelFormats.end(); ++fmtIter)
	{
		PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, *fmtIter);

		// Base rules: Must be OpenGL-compatible, RGBA, double-buffered, and window-renderable
		if (!info.supportOpenGL											||
			!(info.pixelType == wgl::PixelFormatInfo::PIXELTYPE_RGBA)	||
			!info.doubleBuffer											||
			!(info.surfaceTypes & wgl::PixelFormatInfo::SURFACE_WINDOW))
			continue;

		if (config.redBits != glu::RenderConfig::DONT_CARE &&
			config.redBits != info.redBits)
			continue;

		if (config.greenBits != glu::RenderConfig::DONT_CARE &&
			config.greenBits != info.greenBits)
			continue;

		if (config.blueBits != glu::RenderConfig::DONT_CARE &&
			config.blueBits != info.blueBits)
			continue;

		if (config.alphaBits != glu::RenderConfig::DONT_CARE &&
			config.alphaBits != info.alphaBits)
			continue;

		if (config.depthBits != glu::RenderConfig::DONT_CARE &&
			config.depthBits != info.depthBits)
			continue;

		if (config.stencilBits != glu::RenderConfig::DONT_CARE &&
			config.stencilBits != info.stencilBits)
			continue;

		if (config.numSamples != glu::RenderConfig::DONT_CARE &&
			config.numSamples != info.samples)
			continue;

		// Passed all tests - select this.
		return info.pixelFormat;
	}

	return -1;
}

} // wgl
} // tcu
