/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * 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 Render context implementation that does no rendering.
 *//*--------------------------------------------------------------------*/

#include "tcuNullRenderContext.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "deThreadLocal.hpp"
#include "gluRenderConfig.hpp"
#include "gluTextureUtil.hpp"
#include "glwEnums.hpp"

#include <string>
#include <vector>

namespace tcu
{
namespace null
{

using namespace glw;

#include "tcuNullRenderContextFuncs.inl"

using namespace glu;
using std::string;
using std::vector;

class ObjectManager
{
public:
	ObjectManager (void)
		: m_lastObject(0)
	{
	}

	deUint32 allocate (void)
	{
		deUint32 object = ++m_lastObject;
		if (object == 0)
			object = ++m_lastObject; // Just ignore overflow.
		return object;
	}

	void free (deUint32 object)
	{
		DE_UNREF(object);
	}

private:
	deUint32 m_lastObject;
};

class Context
{
public:
							Context				(ContextType ctxType_);
							~Context			(void);

private:
							Context				(const Context&);
	Context&				operator=			(const Context&);

	void					addExtension		(const char* name);

public:
	// GL state exposed to implementation functions.
	const ContextType		ctxType;

	string					vendor;
	string					version;
	string					renderer;
	string					shadingLanguageVersion;
	string					extensions;
	vector<string>			extensionList;
	vector<deUint32>		compressedTextureList;

	GLenum					lastError;

	int						pixelPackRowLength;
	int						pixelPackSkipRows;
	int						pixelPackSkipPixels;
	int						pixelPackAlignment;

	GLuint					pixelPackBufferBufferBinding;

	ObjectManager			shaders;
	ObjectManager			programs;
	ObjectManager			textures;
	ObjectManager			buffers;
	ObjectManager			renderbuffers;
	ObjectManager			framebuffers;
	ObjectManager			samplers;
	ObjectManager			vertexArrays;
	ObjectManager			queries;
	ObjectManager			transformFeedbacks;
	ObjectManager			programPipelines;
};

Context::Context (ContextType ctxType_)
	: ctxType						(ctxType_)
	, vendor						("drawElements")
	, renderer						("dummy")
	, lastError						(GL_NO_ERROR)
	, pixelPackRowLength			(0)
	, pixelPackSkipRows				(0)
	, pixelPackSkipPixels			(0)
	, pixelPackAlignment			(0)
	, pixelPackBufferBufferBinding	(0)
{
	using glu::ApiType;

	if (ctxType.getAPI() == ApiType::es(2, 0))
	{
		version					= "OpenGL ES 2.0";
		shadingLanguageVersion	= "OpenGL ES GLSL ES 1.0";
	}
	else if (ctxType.getAPI() == ApiType::es(3, 0))
	{
		version					= "OpenGL ES 3.0";
		shadingLanguageVersion	= "OpenGL ES GLSL ES 3.0";
	}
	else if (ctxType.getAPI() == ApiType::es(3, 1))
	{
		version					= "OpenGL ES 3.1";
		shadingLanguageVersion	= "OpenGL ES GLSL ES 3.1";
		addExtension("GL_OES_texture_stencil8");
		addExtension("GL_OES_sample_shading");
		addExtension("GL_OES_sample_variables");
		addExtension("GL_OES_shader_multisample_interpolation");
		addExtension("GL_OES_shader_image_atomic");
		addExtension("GL_OES_texture_storage_multisample_2d_array");
		addExtension("GL_KHR_blend_equation_advanced");
		addExtension("GL_KHR_blend_equation_advanced_coherent");
		addExtension("GL_EXT_shader_io_blocks");
		addExtension("GL_EXT_geometry_shader");
		addExtension("GL_EXT_geometry_point_size");
		addExtension("GL_EXT_tessellation_shader");
		addExtension("GL_EXT_tessellation_point_size");
		addExtension("GL_EXT_gpu_shader5");
		addExtension("GL_EXT_shader_implicit_conversions");
		addExtension("GL_EXT_texture_buffer");
		addExtension("GL_EXT_texture_cube_map_array");
		addExtension("GL_EXT_draw_buffers_indexed");
		addExtension("GL_EXT_texture_sRGB_decode");
		addExtension("GL_EXT_texture_border_clamp");
		addExtension("GL_KHR_debug");
		addExtension("GL_EXT_primitive_bounding_box");
		addExtension("GL_ANDROID_extension_pack_es31a");
		addExtension("GL_EXT_copy_image");
	}
	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 3)
	{
		version					= "3.3.0";
		shadingLanguageVersion	= "3.30";
	}
	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 4)
	{
		version					= "4.4.0";
		shadingLanguageVersion	= "4.40";
	}
	else
		throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__);

	if (isContextTypeES(ctxType))
	{
		addExtension("GL_EXT_color_buffer_float");
		addExtension("GL_EXT_color_buffer_half_float");
	}

	// support compressed formats
	{
		static deUint32 compressedFormats[] =
		{
			GL_ETC1_RGB8_OES,
			GL_COMPRESSED_R11_EAC,
			GL_COMPRESSED_SIGNED_R11_EAC,
			GL_COMPRESSED_RG11_EAC,
			GL_COMPRESSED_SIGNED_RG11_EAC,
			GL_COMPRESSED_RGB8_ETC2,
			GL_COMPRESSED_SRGB8_ETC2,
			GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
			GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
			GL_COMPRESSED_RGBA8_ETC2_EAC,
			GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
			GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
			GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
			GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
			GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
			GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
			GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
			GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
			GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
			GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
			GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
			GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
			GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
			GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
			GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
			GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
		};

		addExtension("GL_KHR_texture_compression_astc_hdr");
		addExtension("GL_KHR_texture_compression_astc_ldr");
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compressedFormats); ++ndx)
			compressedTextureList.push_back(compressedFormats[ndx]);
	}
}

Context::~Context (void)
{
}

void Context::addExtension (const char* name)
{
	if (!extensions.empty())
		extensions += " ";
	extensions += name;

	extensionList.push_back(name);
}

static de::ThreadLocal s_currentCtx;

void setCurrentContext (Context* context)
{
	s_currentCtx.set((void*)context);
}

Context* getCurrentContext (void)
{
	return (Context*)s_currentCtx.get();
}

GLW_APICALL GLenum GLW_APIENTRY glGetError (void)
{
	Context* const	ctx		= getCurrentContext();
	const GLenum	lastErr	= ctx->lastError;

	ctx->lastError = GL_NO_ERROR;

	return lastErr;
}

GLW_APICALL void GLW_APIENTRY glGetIntegerv (GLenum pname, GLint* params)
{
	Context* const ctx = getCurrentContext();

	switch (pname)
	{
		case GL_NUM_EXTENSIONS:
			*params = (int)ctx->extensionList.size();
			break;

		case GL_MAX_VERTEX_ATTRIBS:
			*params = 32;
			break;

		case GL_MAX_DRAW_BUFFERS:
		case GL_MAX_COLOR_ATTACHMENTS:
			*params = 8;
			break;

		case GL_MAX_TEXTURE_IMAGE_UNITS:
		case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
		case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
		case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
		case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS:
		case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS:
			*params = 32;
			break;

		case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
		case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
		case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS:
		case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS:
		case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS:
		case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
			*params = 8;
			break;

		case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
		case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
		case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS:
		case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS:
		case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS:
		case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
			*params = 8;
			break;

		case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
			*params = 1u << 25;
			break;

		case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
			*params = 256;
			break;

		case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
			*params = 2048;
			break;

		case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
			*params = 4;
			break;

		case GL_MAX_COLOR_TEXTURE_SAMPLES:
			*params = 8;
			break;

		case GL_MAX_TEXTURE_SIZE:
		case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
		case GL_MAX_3D_TEXTURE_SIZE:
		case GL_MAX_RENDERBUFFER_SIZE:
		case GL_MAX_TEXTURE_BUFFER_SIZE:
			*params = 2048;
			break;

		case GL_MAX_ARRAY_TEXTURE_LAYERS:
			*params = 128;
			break;

		case GL_NUM_SHADER_BINARY_FORMATS:
			*params = 0;
			break;

		case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
			*params = (int)ctx->compressedTextureList.size();
			break;

		case GL_COMPRESSED_TEXTURE_FORMATS:
			deMemcpy(params, &ctx->compressedTextureList[0], ctx->compressedTextureList.size()*sizeof(deUint32));
			break;

		case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
			*params = 16;
			break;

		case GL_MAX_UNIFORM_BUFFER_BINDINGS:
			*params = 32;
			break;

		case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
			*params = 16;
			break;

		case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
			*params = GL_RGBA;
			break;

		case GL_IMPLEMENTATION_COLOR_READ_TYPE:
			*params = GL_UNSIGNED_BYTE;
			break;

		case GL_SAMPLE_BUFFERS:
			*params = 0;
			break;

		default:
			break;
	}
}

GLW_APICALL void GLW_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params)
{
	switch (pname)
	{
		case GL_SHADER_COMPILER:
			*params = GL_TRUE;
			break;

		default:
			break;
	}
}

GLW_APICALL void GLW_APIENTRY glGetFloatv (GLenum pname, GLfloat* params)
{
	switch (pname)
	{
		case GL_ALIASED_LINE_WIDTH_RANGE:
		case GL_ALIASED_POINT_SIZE_RANGE:
			params[0] = 0.0f;
			params[1] = 64.0f;
			break;

		default:
			break;
	}
}

GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
{
	static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 };

	DE_UNREF(internalformat);
	DE_UNREF(target);

	switch (pname)
	{
		case GL_NUM_SAMPLE_COUNTS:
			if (bufSize >= 1)
				*params = DE_LENGTH_OF_ARRAY(s_sampleCounts);
			break;

		case GL_SAMPLES:
			deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts)));
			break;

		default:
			break;
	}
}

GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name)
{
	Context* const ctx = getCurrentContext();

	switch (name)
	{
		case GL_VENDOR:						return (const glw::GLubyte*)ctx->vendor.c_str();
		case GL_VERSION:					return (const glw::GLubyte*)ctx->version.c_str();
		case GL_RENDERER:					return (const glw::GLubyte*)ctx->renderer.c_str();
		case GL_SHADING_LANGUAGE_VERSION:	return (const glw::GLubyte*)ctx->shadingLanguageVersion.c_str();
		case GL_EXTENSIONS:					return (const glw::GLubyte*)ctx->extensions.c_str();
		default:
			ctx->lastError = GL_INVALID_ENUM;
			return DE_NULL;
	}
}

GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetStringi (GLenum name, GLuint index)
{
	Context* const ctx = getCurrentContext();

	if (name == GL_EXTENSIONS)
	{
		if ((size_t)index < ctx->extensionList.size())
			return (const glw::GLubyte*)ctx->extensionList[index].c_str();
		else
		{
			ctx->lastError = GL_INVALID_VALUE;
			return DE_NULL;
		}
	}
	else
	{
		ctx->lastError = GL_INVALID_ENUM;
		return DE_NULL;
	}
}

GLW_APICALL GLuint GLW_APIENTRY glCreateProgram ()
{
	Context* const ctx = getCurrentContext();
	return (GLuint)ctx->programs.allocate();
}

GLW_APICALL GLuint GLW_APIENTRY glCreateShader (GLenum type)
{
	Context* const ctx = getCurrentContext();
	DE_UNREF(type);
	return (GLuint)ctx->shaders.allocate();
}

GLW_APICALL void GLW_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params)
{
	DE_UNREF(shader);

	if (pname == GL_COMPILE_STATUS)
		*params = GL_TRUE;
}

GLW_APICALL void GLW_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params)
{
	DE_UNREF(program);

	if (pname == GL_LINK_STATUS)
		*params = GL_TRUE;
}

GLW_APICALL void GLW_APIENTRY glGenTextures (GLsizei n, GLuint* textures)
{
	Context* const ctx = getCurrentContext();

	if (textures)
	{
		for (int ndx = 0; ndx < n; ndx++)
			textures[ndx] = ctx->textures.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenQueries (GLsizei n, GLuint* ids)
{
	Context* const ctx = getCurrentContext();

	if (ids)
	{
		for (int ndx = 0; ndx < n; ndx++)
			ids[ndx] = ctx->queries.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers)
{
	Context* const ctx = getCurrentContext();

	if (buffers)
	{
		for (int ndx = 0; ndx < n; ndx++)
			buffers[ndx] = ctx->buffers.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
{
	Context* const ctx = getCurrentContext();

	if (renderbuffers)
	{
		for (int ndx = 0; ndx < n; ndx++)
			renderbuffers[ndx] = ctx->renderbuffers.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers)
{
	Context* const ctx = getCurrentContext();

	if (framebuffers)
	{
		for (int ndx = 0; ndx < n; ndx++)
			framebuffers[ndx] = ctx->framebuffers.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays)
{
	Context* const ctx = getCurrentContext();

	if (arrays)
	{
		for (int ndx = 0; ndx < n; ndx++)
			arrays[ndx] = ctx->vertexArrays.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers)
{
	Context* const ctx = getCurrentContext();

	if (samplers)
	{
		for (int ndx = 0; ndx < count; ndx++)
			samplers[ndx] = ctx->samplers.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids)
{
	Context* const ctx = getCurrentContext();

	if (ids)
	{
		for (int ndx = 0; ndx < n; ndx++)
			ids[ndx] = ctx->transformFeedbacks.allocate();
	}
}

GLW_APICALL void GLW_APIENTRY glGenProgramPipelines (GLsizei n, GLuint* pipelines)
{
	Context* const ctx = getCurrentContext();

	if (pipelines)
	{
		for (int ndx = 0; ndx < n; ndx++)
			pipelines[ndx] = ctx->programPipelines.allocate();
	}
}

GLW_APICALL GLvoid* GLW_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
	Context* const ctx = getCurrentContext();

	DE_UNREF(target);
	DE_UNREF(offset);
	DE_UNREF(length);
	DE_UNREF(access);

	if (ctx->lastError == GL_NO_ERROR)
		ctx->lastError = GL_INVALID_OPERATION;

	return (GLvoid*)0;
}

GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target)
{
	DE_UNREF(target);
	return GL_FRAMEBUFFER_COMPLETE;
}

GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
	DE_UNREF(x);
	DE_UNREF(y);

	Context* const					ctx					= getCurrentContext();
	const tcu::Vec4					clearColor			(0.0f, 0.0f, 0.0f, 1.0f); // black
	const tcu::TextureFormat		transferFormat		= glu::mapGLTransferFormat(format, type);

	// invalid formats
	if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST)
	{
		if (ctx->lastError == GL_NO_ERROR)
			ctx->lastError = GL_INVALID_ENUM;
		return;
	}

	// unsupported formats
	if (!(format == GL_RGBA			&& type == GL_UNSIGNED_BYTE)	&&
		!(format == GL_RGBA_INTEGER	&& type == GL_INT)				&&
		!(format == GL_RGBA_INTEGER	&& type == GL_UNSIGNED_INT)		&&
		!(format == GL_RGBA			&& type == GL_FLOAT))
	{
		if (ctx->lastError == GL_NO_ERROR)
			ctx->lastError = GL_INVALID_ENUM;
		return;
	}

	// invalid arguments
	if (width < 0 || height < 0)
	{
		if (ctx->lastError == GL_NO_ERROR)
			ctx->lastError = GL_INVALID_OPERATION;
		return;
	}

	// read to buffer
	if (ctx->pixelPackBufferBufferBinding)
		return;

	// read to use pointer
	{
		const int						targetRowLength		= (ctx->pixelPackRowLength != 0) ? (ctx->pixelPackRowLength) : (width);
		const int						targetSkipRows		= ctx->pixelPackSkipRows;
		const int						targetSkipPixels	= ctx->pixelPackSkipPixels;
		const int						infiniteHeight		= targetSkipRows + height; // as much as needed
		const int						targetRowPitch		= (ctx->pixelPackAlignment == 0) ? (targetRowLength * transferFormat.getPixelSize()) : (deAlign32(targetRowLength * transferFormat.getPixelSize(), ctx->pixelPackAlignment));

		// Create access to the whole copy target
		const tcu::PixelBufferAccess	targetAccess		(transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels);

		// Select (skip_pixels, skip_rows, width, height) subregion from it. Clip to horizontal boundaries
		const tcu::PixelBufferAccess	targetRectAccess	= tcu::getSubregion(targetAccess,
																				de::clamp(targetSkipPixels, 0, targetAccess.getWidth()-1),
																				targetSkipRows,
																				de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)),
																				height);

		tcu::clear(targetRectAccess, clearColor);
	}
}

GLW_APICALL void GLW_APIENTRY glBindBuffer (GLenum target, GLuint buffer)
{
	Context* const ctx = getCurrentContext();

	if (target == GL_PIXEL_PACK_BUFFER)
		ctx->pixelPackBufferBufferBinding = buffer;
}

GLW_APICALL void GLW_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers)
{
	Context* const ctx = getCurrentContext();

	for (GLsizei ndx = 0; ndx < n; ++ndx)
		if (buffers[ndx] && buffers[ndx] == ctx->pixelPackBufferBufferBinding)
			ctx->pixelPackBufferBufferBinding = 0;
}

GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
{
	DE_UNREF(program);
	return (GLint)(deStringHash(name) & 0x7FFFFFFF);
}

void initFunctions (glw::Functions* gl)
{
#	include "tcuNullRenderContextInitFuncs.inl"
}

static tcu::RenderTarget toRenderTarget (const RenderConfig& renderCfg)
{
	const int		width			= getValueOrDefault(renderCfg, &RenderConfig::width,		256);
	const int		height			= getValueOrDefault(renderCfg, &RenderConfig::height,		256);
	const int		redBits			= getValueOrDefault(renderCfg, &RenderConfig::redBits,		8);
	const int		greenBits		= getValueOrDefault(renderCfg, &RenderConfig::greenBits,	8);
	const int		blueBits		= getValueOrDefault(renderCfg, &RenderConfig::blueBits,		8);
	const int		alphaBits		= getValueOrDefault(renderCfg, &RenderConfig::alphaBits,	8);
	const int		depthBits		= getValueOrDefault(renderCfg, &RenderConfig::depthBits,	24);
	const int		stencilBits		= getValueOrDefault(renderCfg, &RenderConfig::stencilBits,	8);
	const int		numSamples		= getValueOrDefault(renderCfg, &RenderConfig::numSamples,	0);

	return tcu::RenderTarget(width, height, tcu::PixelFormat(redBits, greenBits, blueBits, alphaBits), depthBits, stencilBits, numSamples);
}

RenderContext::RenderContext (const RenderConfig& renderCfg)
	: m_ctxType			(renderCfg.type)
	, m_renderTarget	(toRenderTarget(renderCfg))
	, m_context			(DE_NULL)
{
	m_context = new Context(m_ctxType);

	initFunctions(&m_functions);
	setCurrentContext(m_context);
}

RenderContext::~RenderContext (void)
{
	setCurrentContext(DE_NULL);
	delete m_context;
}

void RenderContext::postIterate (void)
{
}

} // null
} // tcu
