/*-------------------------------------------------------------------------
 * 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 (ctxType.getAPI() == ApiType::es(3, 2))
	{
		version					= "OpenGL ES 3.2";
		shadingLanguageVersion	= "OpenGL ES GLSL ES 3.2";
	}
	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 if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 5)
	{
		version					= "4.5.0";
		shadingLanguageVersion	= "4.50";
	}
	else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 6)
	{
		version					= "4.6.0";
		shadingLanguageVersion	= "4.60";
	}
	else if (glu::isContextTypeGLCompatibility(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 2)
	{
		version					= "4.2.0";
		shadingLanguageVersion	= "4.20";
	}
	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)
{
}

void RenderContext::makeCurrent (void)
{
}

} // null
} // tcu
