/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * 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 Multisampling tests.
 *//*--------------------------------------------------------------------*/

#include "es2fMultisampleTests.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "tcuSurface.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuCommandLine.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"

#include "glw.h"

#include <string>
#include <vector>

namespace deqp
{
namespace gles2
{
namespace Functional
{

using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::TestLog;
using std::vector;

static const float SQRT_HALF = 0.707107f;

namespace
{

struct QuadCorners
{
	Vec2 p0;
	Vec2 p1;
	Vec2 p2;
	Vec2 p3;

	QuadCorners(const Vec2& p0_, const Vec2& p1_, const Vec2& p2_, const Vec2& p3_) : p0(p0_), p1(p1_), p2(p2_), p3(p3_) {}
};

} // anonymous

static inline int getIterationCount (const tcu::TestContext& ctx, int defaultCount)
{
	int cmdLineValue = ctx.getCommandLine().getTestIterationCount();
	return cmdLineValue > 0 ? cmdLineValue : defaultCount;
}

static inline int getGLInteger (GLenum name)
{
	int result;
	GLU_CHECK_CALL(glGetIntegerv(name, &result));
	return result;
}

template<typename T>
static inline T min4 (T a, T b, T c, T d)
{
	return de::min(de::min(de::min(a, b), c), d);
}

template<typename T>
static inline T max4 (T a, T b, T c, T d)
{
	return de::max(de::max(de::max(a, b), c), d);
}

static inline bool isInsideQuad (const IVec2& point, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
{
	int dot0 = (point.x()-p0.x()) * (p1.y()-p0.y()) + (point.y()-p0.y()) * (p0.x()-p1.x());
	int dot1 = (point.x()-p1.x()) * (p2.y()-p1.y()) + (point.y()-p1.y()) * (p1.x()-p2.x());
	int dot2 = (point.x()-p2.x()) * (p3.y()-p2.y()) + (point.y()-p2.y()) * (p2.x()-p3.x());
	int dot3 = (point.x()-p3.x()) * (p0.y()-p3.y()) + (point.y()-p3.y()) * (p3.x()-p0.x());

	return (dot0 > 0) == (dot1 > 0) && (dot1 > 0) == (dot2 > 0) && (dot2 > 0) == (dot3 > 0);
}

/*--------------------------------------------------------------------*//*!
 * \brief Check if a region in an image is unicolored.
 *
 * Checks if the pixels in img inside the convex quadilateral defined by
 * p0, p1, p2 and p3 are all (approximately) of the same color.
 *//*--------------------------------------------------------------------*/
static bool isPixelRegionUnicolored (const tcu::Surface& img, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
{
	int			xMin				= de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMin				= de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	int			xMax				= de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMax				= de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	bool		insideEncountered	= false;	//!< Whether we have already seen at least one pixel inside the region.
	tcu::RGBA	insideColor;					//!< Color of the first pixel inside the region.

	for (int y = yMin; y <= yMax; y++)
	for (int x = xMin; x <= xMax; x++)
	{
		if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
		{
			tcu::RGBA pixColor = img.getPixel(x, y);

			if (insideEncountered)
			{
				if (!tcu::compareThreshold(pixColor, insideColor, tcu::RGBA(3, 3, 3, 3))) // Pixel color differs from already-detected color inside same region - region not unicolored.
					return false;
			}
			else
			{
				insideEncountered = true;
				insideColor = pixColor;
			}
		}
	}

	return true;
}

static bool drawUnicolorTestErrors (tcu::Surface& img, const tcu::PixelBufferAccess& errorImg, const IVec2& p0, const IVec2& p1, const IVec2& p2, const IVec2& p3)
{
	int			xMin		= de::clamp(min4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMin		= de::clamp(min4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	int			xMax		= de::clamp(max4(p0.x(), p1.x(), p2.x(), p3.x()), 0, img.getWidth()-1);
	int			yMax		= de::clamp(max4(p0.y(), p1.y(), p2.y(), p3.y()), 0, img.getHeight()-1);
	tcu::RGBA	refColor	= img.getPixel((xMin + xMax) / 2, (yMin + yMax) / 2);

	for (int y = yMin; y <= yMax; y++)
	for (int x = xMin; x <= xMax; x++)
	{
		if (isInsideQuad(IVec2(x, y), p0, p1, p2, p3))
		{
			if (!tcu::compareThreshold(img.getPixel(x, y), refColor, tcu::RGBA(3, 3, 3, 3)))
			{
				img.setPixel(x, y, tcu::RGBA::red());
				errorImg.setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
			}
		}
	}

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Abstract base class handling common stuff for multisample cases.
 *//*--------------------------------------------------------------------*/
class MultisampleCase : public TestCase
{
public:
						MultisampleCase			(Context& context, const char* name, const char* desc);
	virtual				~MultisampleCase		(void);

	virtual void		init					(void);
	virtual void		deinit					(void);

protected:
	virtual int			getDesiredViewportSize	(void) const = 0;

	void				renderTriangle			(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
	void				renderTriangle			(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const;
	void				renderTriangle			(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const;
	void				renderTriangle			(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const;
	void				renderQuad				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const;
	void				renderQuad				(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const;
	void				renderLine				(const Vec2& p0, const Vec2& p1, const Vec4& color) const;

	void				randomizeViewport		(void);
	void				readImage				(tcu::Surface& dst) const;

	int					m_numSamples;

	int					m_viewportSize;

private:
						MultisampleCase			(const MultisampleCase& other);
	MultisampleCase&	operator=				(const MultisampleCase& other);

	glu::ShaderProgram*	m_program;
	int					m_attrPositionLoc;
	int					m_attrColorLoc;

	int					m_viewportX;
	int					m_viewportY;
	de::Random			m_rnd;
};

MultisampleCase::MultisampleCase (Context& context, const char* name, const char* desc)
	: TestCase			(context, name, desc)
	, m_numSamples		(0)
	, m_viewportSize	(0)
	, m_program			(DE_NULL)
	, m_attrPositionLoc	(-1)
	, m_attrColorLoc	(-1)
	, m_viewportX		(0)
	, m_viewportY		(0)
	, m_rnd				(deStringHash(name))
{
}

void MultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
{
	float vertexPositions[] =
	{
		p0.x(), p0.y(), p0.z(), 1.0f,
		p1.x(), p1.y(), p1.z(), 1.0f,
		p2.x(), p2.y(), p2.z(), 1.0f
	};
	float vertexColors[] =
	{
		c0.x(), c0.y(), c0.z(), c0.w(),
		c1.x(), c1.y(), c1.z(), c1.w(),
		c2.x(), c2.y(), c2.z(), c2.w(),
	};

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));

	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
}

void MultisampleCase::renderTriangle (const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec4& color) const
{
	renderTriangle(p0, p1, p2, color, color, color);
}

void MultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& c0, const Vec4& c1, const Vec4& c2) const
{
	renderTriangle(Vec3(p0.x(), p0.y(), 0.0f),
				   Vec3(p1.x(), p1.y(), 0.0f),
				   Vec3(p2.x(), p2.y(), 0.0f),
				   c0, c1, c2);
}

void MultisampleCase::renderTriangle (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec4& color) const
{
	renderTriangle(p0, p1, p2, color, color, color);
}

void MultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& c0, const Vec4& c1, const Vec4& c2, const Vec4& c3) const
{
	renderTriangle(p0, p1, p2, c0, c1, c2);
	renderTriangle(p2, p1, p3, c2, c1, c3);
}

void MultisampleCase::renderQuad (const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, const Vec4& color) const
{
	renderQuad(p0, p1, p2, p3, color, color, color, color);
}

void MultisampleCase::renderLine (const Vec2& p0, const Vec2& p1, const Vec4& color) const
{
	float vertexPositions[] =
	{
		p0.x(), p0.y(), 0.0f, 1.0f,
		p1.x(), p1.y(), 0.0f, 1.0f
	};
	float vertexColors[] =
	{
		color.x(), color.y(), color.z(), color.w(),
		color.x(), color.y(), color.z(), color.w()
	};

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrPositionLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrPositionLoc, 4, GL_FLOAT, false, 0, &vertexPositions[0]));

	GLU_CHECK_CALL(glEnableVertexAttribArray(m_attrColorLoc));
	GLU_CHECK_CALL(glVertexAttribPointer(m_attrColorLoc, 4, GL_FLOAT, false, 0, &vertexColors[0]));

	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
	GLU_CHECK_CALL(glDrawArrays(GL_LINES, 0, 2));
}

void MultisampleCase::randomizeViewport (void)
{
	m_viewportX = m_rnd.getInt(0, m_context.getRenderTarget().getWidth() - m_viewportSize);
	m_viewportY = m_rnd.getInt(0, m_context.getRenderTarget().getHeight() - m_viewportSize);

	GLU_CHECK_CALL(glViewport(m_viewportX, m_viewportY, m_viewportSize, m_viewportSize));
}

void MultisampleCase::readImage (tcu::Surface& dst) const
{
	glu::readPixels(m_context.getRenderContext(), m_viewportX, m_viewportY, dst.getAccess());
}

void MultisampleCase::init (void)
{
	static const char* vertShaderSource =
		"attribute highp vec4 a_position;\n"
		"attribute mediump vec4 a_color;\n"
		"varying mediump vec4 v_color;\n"
		"void main()\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"	v_color = a_color;\n"
		"}\n";

	static const char* fragShaderSource =
		"varying mediump vec4 v_color;\n"
		"void main()\n"
		"{\n"
		"	gl_FragColor = v_color;\n"
		"}\n";

	// Check multisample support.

	if (m_context.getRenderTarget().getNumSamples() <= 1)
		throw tcu::NotSupportedError("No multisample buffers");

	// Prepare program.

	DE_ASSERT(!m_program);

	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
	if (!m_program->isOk())
		throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__);

	GLU_CHECK_CALL(m_attrPositionLoc	= glGetAttribLocation(m_program->getProgram(), "a_position"));
	GLU_CHECK_CALL(m_attrColorLoc		= glGetAttribLocation(m_program->getProgram(), "a_color"));

	if (m_attrPositionLoc < 0 || m_attrColorLoc < 0)
	{
		delete m_program;
		throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__);
	}

	// Get suitable viewport size.

	m_viewportSize = de::min<int>(getDesiredViewportSize(), de::min(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight()));
	randomizeViewport();

	// Query and log number of samples per pixel.

	m_numSamples = getGLInteger(GL_SAMPLES);
	m_testCtx.getLog() << TestLog::Message << "GL_SAMPLES = " << m_numSamples << TestLog::EndMessage;
}

MultisampleCase::~MultisampleCase (void)
{
	delete m_program;
}

void MultisampleCase::deinit (void)
{
	delete m_program;

	m_program = DE_NULL;
}

/*--------------------------------------------------------------------*//*!
 * \brief Base class for cases testing the value of GL_SAMPLES.
 *
 * Draws a test pattern (defined by renderPattern() of an inheriting class)
 * and counts the number of distinct colors in the resulting image. That
 * number should be at least the value of GL_SAMPLES plus one. This is
 * repeated with increased values of m_currentIteration until this correct
 * number of colors is detected or m_currentIteration reaches
 * m_maxNumIterations.
 *//*--------------------------------------------------------------------*/
class NumSamplesCase : public MultisampleCase
{
public:
						NumSamplesCase			(Context& context, const char* name, const char* description);
						~NumSamplesCase			(void) {}

	IterateResult		iterate					(void);

protected:
	int					getDesiredViewportSize	(void) const { return 256; }
	virtual void		renderPattern			(void) const = 0;

	int					m_currentIteration;

private:
	enum { DEFAULT_MAX_NUM_ITERATIONS = 16 };

	const int			m_maxNumIterations;
	vector<tcu::RGBA>	m_detectedColors;
};

NumSamplesCase::NumSamplesCase (Context& context, const char* name, const char* description)
	: MultisampleCase		(context, name, description)
	, m_currentIteration	(0)
	, m_maxNumIterations	(getIterationCount(m_testCtx, DEFAULT_MAX_NUM_ITERATIONS))
{
}

NumSamplesCase::IterateResult NumSamplesCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	renderPattern();

	// Read and log rendered image.

	readImage(renderedImg);

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	// Detect new, previously unseen colors from image.

	int requiredNumDistinctColors = m_numSamples + 1;

	for (int y = 0; y < renderedImg.getHeight() && (int)m_detectedColors.size() < requiredNumDistinctColors; y++)
	for (int x = 0; x < renderedImg.getWidth() && (int)m_detectedColors.size() < requiredNumDistinctColors; x++)
	{
		tcu::RGBA color = renderedImg.getPixel(x, y);

		int i;
		for (i = 0; i < (int)m_detectedColors.size(); i++)
		{
			if (tcu::compareThreshold(color, m_detectedColors[i], tcu::RGBA(3, 3, 3, 3)))
				break;
		}

		if (i == (int)m_detectedColors.size())
			m_detectedColors.push_back(color); // Color not previously detected.
	}

	// Log results.

	log << TestLog::Message
		<< "Number of distinct colors detected so far: "
		<< ((int)m_detectedColors.size() >= requiredNumDistinctColors ? "at least " : "")
		<< de::toString(m_detectedColors.size())
		<< TestLog::EndMessage;

	if ((int)m_detectedColors.size() < requiredNumDistinctColors)
	{
		// Haven't detected enough different colors yet.

		m_currentIteration++;

		if (m_currentIteration >= m_maxNumIterations)
		{
			log << TestLog::Message << "Failure: Number of distinct colors detected is lower than GL_SAMPLES+1" << TestLog::EndMessage;
			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
			return STOP;
		}
		else
		{
			log << TestLog::Message << "The number of distinct colors detected is lower than GL_SAMPLES+1 - trying again with a slightly altered pattern" << TestLog::EndMessage;
			return CONTINUE;
		}
	}
	else
	{
		log << TestLog::Message << "Success: The number of distinct colors detected is at least GL_SAMPLES+1" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
}

class PolygonNumSamplesCase : public NumSamplesCase
{
public:
			PolygonNumSamplesCase	(Context& context, const char* name, const char* description);
			~PolygonNumSamplesCase	(void) {}

protected:
	void	renderPattern			(void) const;
};

PolygonNumSamplesCase::PolygonNumSamplesCase (Context& context, const char* name, const char* description)
	: NumSamplesCase(context, name, description)
{
}

void PolygonNumSamplesCase::renderPattern (void) const
{
	// The test pattern consists of several triangles with edges at different angles.

	const int numTriangles = 25;
	for (int i = 0; i < numTriangles; i++)
	{
		float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles + 0.001f*(float)m_currentIteration;
		float angle1 = 2.0f*DE_PI * ((float)i + 0.5f)	/ (float)numTriangles + 0.001f*(float)m_currentIteration;

		renderTriangle(Vec2(0.0f, 0.0f),
					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
					   Vec4(1.0f));
	}
}

class LineNumSamplesCase : public NumSamplesCase
{
public:
			LineNumSamplesCase		(Context& context, const char* name, const char* description);
			~LineNumSamplesCase		(void) {}

protected:
	void	renderPattern			(void) const;
};

LineNumSamplesCase::LineNumSamplesCase (Context& context, const char* name, const char* description)
	: NumSamplesCase (context, name, description)
{
}

void LineNumSamplesCase::renderPattern (void) const
{
	// The test pattern consists of several lines at different angles.

	// We scale the number of lines based on the viewport size. This is because a gl line's thickness is
	// constant in pixel units, i.e. they get relatively thicker as viewport size decreases. Thus we must
	// decrease the number of lines in order to decrease the extent of overlap among the lines in the
	// center of the pattern.
	const int numLines = (int)(100.0f * deFloatSqrt((float)m_viewportSize / 256.0f));

	for (int i = 0; i < numLines; i++)
	{
		float angle = 2.0f*DE_PI * (float)i / (float)numLines + 0.001f*(float)m_currentIteration;
		renderLine(Vec2(0.0f, 0.0f), Vec2(deFloatCos(angle)*0.95f, deFloatSin(angle)*0.95f), Vec4(1.0f));
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Case testing behaviour of common edges when multisampling.
 *
 * Draws a number of test patterns, each with a number of quads, each made
 * of two triangles, rotated at different angles. The inner edge inside the
 * quad (i.e. the common edge of the two triangles) still should not be
 * visible, despite multisampling - i.e. the two triangles forming the quad
 * should never get any common coverage bits in any pixel.
 *//*--------------------------------------------------------------------*/
class CommonEdgeCase : public MultisampleCase
{
public:
	enum CaseType
	{
		CASETYPE_SMALL_QUADS = 0,				//!< Draw several small quads per iteration.
		CASETYPE_BIGGER_THAN_VIEWPORT_QUAD,		//!< Draw one bigger-than-viewport quad per iteration.
		CASETYPE_FIT_VIEWPORT_QUAD,				//!< Draw one exactly viewport-sized, axis aligned quad per iteration.

		CASETYPE_LAST
	};

					CommonEdgeCase			(Context& context, const char* name, const char* description, CaseType caseType);
					~CommonEdgeCase			(void) {}

	void			init					(void);

	IterateResult	iterate					(void);

protected:
	int				getDesiredViewportSize	(void) const { return m_caseType == CASETYPE_SMALL_QUADS ? 128 : 32; }

private:
	enum
	{
		DEFAULT_SMALL_QUADS_ITERATIONS					= 16,
		DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS	= 8*8
		// \note With CASETYPE_FIT_VIEWPORT_QUAD, we don't do rotations other than multiples of 90 deg -> constant number of iterations.
	};

	const CaseType	m_caseType;

	const int		m_numIterations;
	int				m_currentIteration;
};

CommonEdgeCase::CommonEdgeCase (Context& context, const char* name, const char* description, CaseType caseType)
	: MultisampleCase		(context, name, description)
	, m_caseType			(caseType)
	, m_numIterations		(caseType == CASETYPE_SMALL_QUADS					? getIterationCount(m_testCtx, DEFAULT_SMALL_QUADS_ITERATIONS)
							: caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD	? getIterationCount(m_testCtx, DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS)
							: 8)
	, m_currentIteration	(0)
{
}

void CommonEdgeCase::init (void)
{
	MultisampleCase::init();

	if (m_caseType == CASETYPE_SMALL_QUADS)
	{
		// Check for a big enough viewport. With too small viewports the test case can't analyze the resulting image well enough.

		const int minViewportSize = 32;

		DE_ASSERT(minViewportSize <= getDesiredViewportSize());

		if (m_viewportSize < minViewportSize)
			throw tcu::InternalError("Render target width or height too low (is " + de::toString(m_viewportSize) + ", should be at least " + de::toString(minViewportSize) + ")");
	}

	GLU_CHECK_CALL(glEnable(GL_BLEND));
	GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
	GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));

	m_testCtx.getLog() << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;
}

CommonEdgeCase::IterateResult CommonEdgeCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
	tcu::Surface	errorImg		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	// Draw test pattern. Test patterns consist of quads formed with two triangles.
	// After drawing the pattern, we check that the interior pixels of each quad are
	// all the same color - this is meant to verify that there are no artifacts on the inner edge.

	vector<QuadCorners> unicoloredRegions;

	if (m_caseType == CASETYPE_SMALL_QUADS)
	{
		// Draw several quads, rotated at different angles.

		const float		quadDiagLen = 2.0f / 3.0f * 0.9f; // \note Fit 3 quads in both x and y directions.
		float			angleCos;
		float			angleSin;

		// \note First and second iteration get exact 0 (and 90, 180, 270) and 45 (and 135, 225, 315) angle quads, as they are kind of a special case.

		if (m_currentIteration == 0)
		{
			angleCos = 1.0f;
			angleSin = 0.0f;
		}
		else if (m_currentIteration == 1)
		{
			angleCos = SQRT_HALF;
			angleSin = SQRT_HALF;
		}
		else
		{
			float angle = 0.5f * DE_PI * (float)(m_currentIteration-1) / (float)(m_numIterations-1);
			angleCos = deFloatCos(angle);
			angleSin = deFloatSin(angle);
		}

		Vec2 corners[4] =
		{
			0.5f * quadDiagLen * Vec2( angleCos,  angleSin),
			0.5f * quadDiagLen * Vec2(-angleSin,  angleCos),
			0.5f * quadDiagLen * Vec2(-angleCos, -angleSin),
			0.5f * quadDiagLen * Vec2( angleSin, -angleCos)
		};

		unicoloredRegions.reserve(8);

		// Draw 8 quads.
		// First four are rotated at angles angle+0, angle+90, angle+180 and angle+270.
		// Last four are rotated the same angles as the first four, but the ordering of the last triangle's vertices is reversed.

		for (int quadNdx = 0; quadNdx < 8; quadNdx++)
		{
			Vec2 center = (2.0f-quadDiagLen) * Vec2((float)(quadNdx%3), (float)(quadNdx/3)) / 2.0f - 0.5f*(2.0f-quadDiagLen);

			renderTriangle(corners[(0+quadNdx) % 4] + center,
						   corners[(1+quadNdx) % 4] + center,
						   corners[(2+quadNdx) % 4] + center,
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));

			if (quadNdx >= 4)
			{
				renderTriangle(corners[(3+quadNdx) % 4] + center,
							   corners[(2+quadNdx) % 4] + center,
							   corners[(0+quadNdx) % 4] + center,
							   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
			}
			else
			{
				renderTriangle(corners[(0+quadNdx) % 4] + center,
							   corners[(2+quadNdx) % 4] + center,
							   corners[(3+quadNdx) % 4] + center,
							   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
			}

			// The size of the "interior" of a quad is assumed to be approximately unicolorRegionScale*<actual size of quad>.
			// By "interior" we here mean the region of non-boundary pixels of the rendered quad for which we can safely assume
			// that it has all coverage bits set to 1, for every pixel.
			float unicolorRegionScale = 1.0f - 6.0f*2.0f / (float)m_viewportSize / quadDiagLen;
			unicoloredRegions.push_back(QuadCorners((center + corners[0]*unicolorRegionScale),
													(center + corners[1]*unicolorRegionScale),
													(center + corners[2]*unicolorRegionScale),
													(center + corners[3]*unicolorRegionScale)));
		}
	}
	else if (m_caseType == CASETYPE_BIGGER_THAN_VIEWPORT_QUAD)
	{
		// Draw a bigger-than-viewport quad, rotated at an angle depending on m_currentIteration.

		int				quadBaseAngleNdx		= m_currentIteration / 8;
		int				quadSubAngleNdx			= m_currentIteration % 8;
		float			angleCos;
		float			angleSin;

		if (quadBaseAngleNdx == 0)
		{
			angleCos = 1.0f;
			angleSin = 0.0f;
		}
		else if (quadBaseAngleNdx == 1)
		{
			angleCos = SQRT_HALF;
			angleSin = SQRT_HALF;
		}
		else
		{
			float angle = 0.5f * DE_PI * (float)(m_currentIteration-1) / (float)(m_numIterations-1);
			angleCos = deFloatCos(angle);
			angleSin = deFloatSin(angle);
		}

		float quadDiagLen = 2.5f / de::max(angleCos, angleSin);

		Vec2 corners[4] =
		{
			0.5f * quadDiagLen * Vec2( angleCos,  angleSin),
			0.5f * quadDiagLen * Vec2(-angleSin,  angleCos),
			0.5f * quadDiagLen * Vec2(-angleCos, -angleSin),
			0.5f * quadDiagLen * Vec2( angleSin, -angleCos)
		};

		renderTriangle(corners[(0+quadSubAngleNdx) % 4],
					   corners[(1+quadSubAngleNdx) % 4],
					   corners[(2+quadSubAngleNdx) % 4],
					   Vec4(0.5f, 0.5f, 0.5f, 1.0f));

		if (quadSubAngleNdx >= 4)
		{
			renderTriangle(corners[(3+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(0+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}
		else
		{
			renderTriangle(corners[(0+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(3+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}

		float unicolorRegionScale = 1.0f - 6.0f*2.0f / (float)m_viewportSize / quadDiagLen;
		unicoloredRegions.push_back(QuadCorners((corners[0]*unicolorRegionScale),
												(corners[1]*unicolorRegionScale),
												(corners[2]*unicolorRegionScale),
												(corners[3]*unicolorRegionScale)));
	}
	else if (m_caseType == CASETYPE_FIT_VIEWPORT_QUAD)
	{
		// Draw an exactly viewport-sized quad, rotated by multiples of 90 degrees angle depending on m_currentIteration.

		int quadSubAngleNdx = m_currentIteration % 8;

		Vec2 corners[4] =
		{
			Vec2( 1.0f,  1.0f),
			Vec2(-1.0f,  1.0f),
			Vec2(-1.0f, -1.0f),
			Vec2( 1.0f, -1.0f)
		};

		renderTriangle(corners[(0+quadSubAngleNdx) % 4],
					   corners[(1+quadSubAngleNdx) % 4],
					   corners[(2+quadSubAngleNdx) % 4],
					   Vec4(0.5f, 0.5f, 0.5f, 1.0f));

		if (quadSubAngleNdx >= 4)
		{
			renderTriangle(corners[(3+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(0+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}
		else
		{
			renderTriangle(corners[(0+quadSubAngleNdx) % 4],
						   corners[(2+quadSubAngleNdx) % 4],
						   corners[(3+quadSubAngleNdx) % 4],
						   Vec4(0.5f, 0.5f, 0.5f, 1.0f));
		}

		unicoloredRegions.push_back(QuadCorners(corners[0], corners[1], corners[2], corners[3]));
	}
	else
		DE_ASSERT(false);

	// Read pixels and check unicolored regions.

	readImage(renderedImg);

	tcu::clear(errorImg.getAccess(), Vec4(0.0f, 1.0f, 0.0f, 1.0f));

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	bool errorsDetected = false;
	for (int i = 0; i < (int)unicoloredRegions.size(); i++)
	{
		const QuadCorners&	region					= unicoloredRegions[i];
		IVec2				p0Win					= ((region.p0+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		IVec2				p1Win					= ((region.p1+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		IVec2				p2Win					= ((region.p2+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		IVec2				p3Win					= ((region.p3+1.0f) * 0.5f * (float)(m_viewportSize-1) + 0.5f).asInt();
		bool				errorsInCurrentRegion	= !isPixelRegionUnicolored(renderedImg, p0Win, p1Win, p2Win, p3Win);

		if (errorsInCurrentRegion)
			drawUnicolorTestErrors(renderedImg, errorImg.getAccess(), p0Win, p1Win, p2Win, p3Win);

		errorsDetected = errorsDetected || errorsInCurrentRegion;
	}

	m_currentIteration++;

	if (errorsDetected)
	{
		log << TestLog::Message << "Failure: Not all quad interiors seem unicolored - common-edge artifacts?" << TestLog::EndMessage;
		log << TestLog::Message << "Erroneous pixels are drawn red in the following image" << TestLog::EndMessage;
		log << TestLog::Image("RenderedImageWithErrors",	"Rendered image with errors marked",	renderedImg,	QP_IMAGE_COMPRESSION_MODE_PNG);
		log << TestLog::Image("ErrorsOnly",					"Image with error pixels only",			errorImg,		QP_IMAGE_COMPRESSION_MODE_PNG);
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}
	else if (m_currentIteration < m_numIterations)
	{
		log << TestLog::Message << "Quads seem OK - moving on to next pattern" << TestLog::EndMessage;
		return CONTINUE;
	}
	else
	{
		log << TestLog::Message << "Success: All quad interiors seem unicolored (no common-edge artifacts)" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Test that depth values are per-sample.
 *
 * Draws intersecting, differently-colored polygons and checks that there
 * are at least GL_SAMPLES+1 distinct colors present, due to some of the
 * samples at the intersection line belonging to one and some to another
 * polygon.
 *//*--------------------------------------------------------------------*/
class SampleDepthCase : public NumSamplesCase
{
public:
						SampleDepthCase			(Context& context, const char* name, const char* description);
						~SampleDepthCase		(void) {}

	void				init					(void);

protected:
	void				renderPattern			(void) const;
};

SampleDepthCase::SampleDepthCase (Context& context, const char* name, const char* description)
	: NumSamplesCase (context, name, description)
{
}

void SampleDepthCase::init (void)
{
	TestLog& log = m_testCtx.getLog();

	if (m_context.getRenderTarget().getDepthBits() == 0)
		TCU_THROW(NotSupportedError, "Test requires depth buffer");

	MultisampleCase::init();

	GLU_CHECK_CALL(glEnable(GL_DEPTH_TEST));
	GLU_CHECK_CALL(glDepthFunc(GL_LESS));

	log << TestLog::Message << "Depth test enabled, depth func is GL_LESS" << TestLog::EndMessage;
	log << TestLog::Message << "Drawing several bigger-than-viewport black or white polygons intersecting each other" << TestLog::EndMessage;
}

void SampleDepthCase::renderPattern (void) const
{
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
	GLU_CHECK_CALL(glClearDepthf(1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

	{
		const int numPolygons = 50;

		for (int i = 0; i < numPolygons; i++)
		{
			Vec4	color	= i % 2 == 0 ? Vec4(1.0f, 1.0f, 1.0f, 1.0f) : Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			float	angle	= 2.0f * DE_PI * (float)i / (float)numPolygons + 0.001f*(float)m_currentIteration;
			Vec3	pt0		(3.0f*deFloatCos(angle + 2.0f*DE_PI*0.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*0.0f/3.0f), 1.0f);
			Vec3	pt1		(3.0f*deFloatCos(angle + 2.0f*DE_PI*1.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*1.0f/3.0f), 0.0f);
			Vec3	pt2		(3.0f*deFloatCos(angle + 2.0f*DE_PI*2.0f/3.0f), 3.0f*deFloatSin(angle + 2.0f*DE_PI*2.0f/3.0f), 0.0f);

			renderTriangle(pt0, pt1, pt2, color);
		}
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Test that stencil buffer values are per-sample.
 *
 * Draws a unicolored pattern and marks drawn samples in stencil buffer;
 * then clears and draws a viewport-size quad with that color and with
 * proper stencil test such that the resulting image should be exactly the
 * same as after the pattern was first drawn.
 *//*--------------------------------------------------------------------*/
class SampleStencilCase : public MultisampleCase
{
public:
						SampleStencilCase		(Context& context, const char* name, const char* description);
						~SampleStencilCase		(void) {}

	void				init					(void);
	IterateResult		iterate					(void);

protected:
	int					getDesiredViewportSize	(void) const { return 256; }
};

SampleStencilCase::SampleStencilCase (Context& context, const char* name, const char* description)
	: MultisampleCase (context, name, description)
{
}

void SampleStencilCase::init (void)
{
	if (m_context.getRenderTarget().getStencilBits() == 0)
		TCU_THROW(NotSupportedError, "Test requires stencil buffer");

	MultisampleCase::init();
}

SampleStencilCase::IterateResult SampleStencilCase::iterate (void)
{
	TestLog&		log					= m_testCtx.getLog();
	tcu::Surface	renderedImgFirst	(m_viewportSize, m_viewportSize);
	tcu::Surface	renderedImgSecond	(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClearStencil(0));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
	GLU_CHECK_CALL(glEnable(GL_STENCIL_TEST));
	GLU_CHECK_CALL(glStencilFunc(GL_ALWAYS, 1, 1));
	GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE));

	log << TestLog::Message << "Drawing a pattern with glStencilFunc(GL_ALWAYS, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)" << TestLog::EndMessage;

	{
		const int numTriangles = 25;
		for (int i = 0; i < numTriangles; i++)
		{
			float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles;
			float angle1 = 2.0f*DE_PI * ((float)i + 0.5f)	/ (float)numTriangles;

			renderTriangle(Vec2(0.0f, 0.0f),
						   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
						   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
						   Vec4(1.0f));
		}
	}

	readImage(renderedImgFirst);
	log << TestLog::Image("RenderedImgFirst", "First image rendered", renderedImgFirst, QP_IMAGE_COMPRESSION_MODE_PNG);

	log << TestLog::Message << "Clearing color buffer to black" << TestLog::EndMessage;

	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	GLU_CHECK_CALL(glStencilFunc(GL_EQUAL, 1, 1));
	GLU_CHECK_CALL(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP));

	{
		log << TestLog::Message << "Checking that color buffer was actually cleared to black" << TestLog::EndMessage;

		tcu::Surface clearedImg(m_viewportSize, m_viewportSize);
		readImage(clearedImg);

		for (int y = 0; y < clearedImg.getHeight(); y++)
		for (int x = 0; x < clearedImg.getWidth(); x++)
		{
			const tcu::RGBA& clr = clearedImg.getPixel(x, y);
			if (clr != tcu::RGBA::black())
			{
				log << TestLog::Message << "Failure: first non-black pixel, color " << clr << ", detected at coordinates (" << x << ", " << y << ")" << TestLog::EndMessage;
				log << TestLog::Image("ClearedImg", "Image after clearing, erroneously non-black", clearedImg);
				m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
				return STOP;
			}
		}
	}

	log << TestLog::Message << "Drawing a viewport-sized quad with glStencilFunc(GL_EQUAL, 1, 1) and glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) - should result in same image as the first" << TestLog::EndMessage;

	renderQuad(Vec2(-1.0f, -1.0f),
			   Vec2( 1.0f, -1.0f),
			   Vec2(-1.0f,  1.0f),
			   Vec2( 1.0f,  1.0f),
			   Vec4(1.0f));

	readImage(renderedImgSecond);
	log << TestLog::Image("RenderedImgSecond", "Second image rendered", renderedImgSecond, QP_IMAGE_COMPRESSION_MODE_PNG);

	bool passed = tcu::pixelThresholdCompare(log,
											 "ImageCompare",
											 "Image comparison",
											 renderedImgFirst,
											 renderedImgSecond,
											 tcu::RGBA(0),
											 tcu::COMPARE_LOG_ON_ERROR);

	if (passed)
		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;

	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
											 passed ? "Passed"				: "Failed");

	return STOP;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests coverage mask generation proportionality property.
 *
 * Tests that the number of coverage bits in a coverage mask created by
 * GL_SAMPLE_ALPHA_TO_COVERAGE or GL_SAMPLE_COVERAGE is, on average,
 * proportional to the alpha or coverage value, respectively. Draws
 * multiple frames, each time increasing the alpha or coverage value used,
 * and checks that the average color is changing appropriately.
 *//*--------------------------------------------------------------------*/
class MaskProportionalityCase : public MultisampleCase
{
public:
	enum CaseType
	{
		CASETYPE_ALPHA_TO_COVERAGE = 0,
		CASETYPE_SAMPLE_COVERAGE,
		CASETYPE_SAMPLE_COVERAGE_INVERTED,

		CASETYPE_LAST
	};

					MaskProportionalityCase				(Context& context, const char* name, const char* description, CaseType type);
					~MaskProportionalityCase			(void) {}

	void			init								(void);

	IterateResult	iterate								(void);

protected:
	int				getDesiredViewportSize				(void) const { return 32; }

private:
	const CaseType	m_type;

	int				m_numIterations;
	int				m_currentIteration;

	deInt32			m_previousIterationColorSum;
};

MaskProportionalityCase::MaskProportionalityCase (Context& context, const char* name, const char* description, CaseType type)
	: MultisampleCase				(context, name, description)
	, m_type						(type)
	, m_numIterations				(0)
	, m_currentIteration			(0)
	, m_previousIterationColorSum	(-1)
{
}

void MaskProportionalityCase::init (void)
{
	TestLog& log = m_testCtx.getLog();

	MultisampleCase::init();

	if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
	{
		GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
	}
	else
	{
		DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);

		GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
	}

	m_numIterations = de::max(2, getIterationCount(m_testCtx, m_numSamples * 5));

	randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate.
}

MaskProportionalityCase::IterateResult MaskProportionalityCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);
	deInt32			numPixels		= (deInt32)renderedImg.getWidth()*(deInt32)renderedImg.getHeight();

	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
	GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
	{
		GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
		log << TestLog::Message << "Using color mask TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
	}

	// Draw quad.

	{
		const Vec2		pt0						(-1.0f, -1.0f);
		const Vec2		pt1						( 1.0f, -1.0f);
		const Vec2		pt2						(-1.0f,  1.0f);
		const Vec2		pt3						( 1.0f,  1.0f);
		Vec4			quadColor				(1.0f, 0.0f, 0.0f, 1.0f);
		float			alphaOrCoverageValue	= (float)m_currentIteration / (float)(m_numIterations-1);

		if (m_type == CASETYPE_ALPHA_TO_COVERAGE)
		{
			log << TestLog::Message << "Drawing a red quad using alpha value " + de::floatToString(alphaOrCoverageValue, 2) << TestLog::EndMessage;
			quadColor.w() = alphaOrCoverageValue;
		}
		else
		{
			DE_ASSERT(m_type == CASETYPE_SAMPLE_COVERAGE || m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED);

			bool	isInverted		= m_type == CASETYPE_SAMPLE_COVERAGE_INVERTED;
			float	coverageValue	= isInverted ? 1.0f - alphaOrCoverageValue : alphaOrCoverageValue;
			log << TestLog::Message << "Drawing a red quad using sample coverage value " + de::floatToString(coverageValue, 2) << (isInverted ? " (inverted)" : "") << TestLog::EndMessage;
			GLU_CHECK_CALL(glSampleCoverage(coverageValue, isInverted ? GL_TRUE : GL_FALSE));
		}

		renderQuad(pt0, pt1, pt2, pt3, quadColor);
	}

	// Read ang log image.

	readImage(renderedImg);

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	// Compute average red component in rendered image.

	deInt32 sumRed = 0;

	for (int y = 0; y < renderedImg.getHeight(); y++)
	for (int x = 0; x < renderedImg.getWidth(); x++)
		sumRed += renderedImg.getPixel(x, y).getRed();

	log << TestLog::Message << "Average red color component: " << de::floatToString((float)sumRed / 255.0f / (float)numPixels, 2) << TestLog::EndMessage;

	// Check if average color has decreased from previous frame's color.

	if (sumRed < m_previousIterationColorSum)
	{
		log << TestLog::Message << "Failure: Current average red color component is lower than previous" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}

	// Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted).

	if (m_currentIteration == 0 && sumRed != 0)
	{
		log << TestLog::Message << "Failure: Image should be completely black" << TestLog::EndMessage;
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}

	if (m_currentIteration == m_numIterations-1 && sumRed != 0xff*numPixels)
	{
		log << TestLog::Message << "Failure: Image should be completely red" << TestLog::EndMessage;

		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
		return STOP;
	}

	m_previousIterationColorSum = sumRed;

	m_currentIteration++;

	if (m_currentIteration >= m_numIterations)
	{
		log << TestLog::Message
			<< "Success: Number of coverage mask bits set appears to be, on average, proportional to "
			<< (m_type == CASETYPE_ALPHA_TO_COVERAGE ? "alpha" : m_type == CASETYPE_SAMPLE_COVERAGE ? "sample coverage value" : "inverted sample coverage value")
			<< TestLog::EndMessage;

		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
	else
		return CONTINUE;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests coverage mask generation constancy property.
 *
 * Tests that the coverage mask created by GL_SAMPLE_ALPHA_TO_COVERAGE or
 * GL_SAMPLE_COVERAGE is constant at given pixel coordinates, with a given
 * alpha component or coverage value, respectively. Draws two quads, with
 * the second one fully overlapping the first one such that at any given
 * pixel, both quads have the same alpha or coverage value. This way, if
 * the constancy property is fulfilled, only the second quad should be
 * visible.
 *//*--------------------------------------------------------------------*/
class MaskConstancyCase : public MultisampleCase
{
public:
	enum CaseType
	{
		CASETYPE_ALPHA_TO_COVERAGE = 0,		//!< Use only alpha-to-coverage.
		CASETYPE_SAMPLE_COVERAGE,			//!< Use only sample coverage.
		CASETYPE_SAMPLE_COVERAGE_INVERTED,	//!< Use only inverted sample coverage.
		CASETYPE_BOTH,						//!< Use both alpha-to-coverage and sample coverage.
		CASETYPE_BOTH_INVERTED,				//!< Use both alpha-to-coverage and inverted sample coverage.

		CASETYPE_LAST
	};

					MaskConstancyCase			(Context& context, const char* name, const char* description, CaseType type);
					~MaskConstancyCase			(void) {}

	IterateResult	iterate						(void);

protected:
	int				getDesiredViewportSize		(void) const { return 256; }

private:
	const bool		m_isAlphaToCoverageCase;
	const bool		m_isSampleCoverageCase;
	const bool		m_isInvertedSampleCoverageCase;
};

MaskConstancyCase::MaskConstancyCase (Context& context, const char* name, const char* description, CaseType type)
	: MultisampleCase					(context, name, description)
	, m_isAlphaToCoverageCase			(type == CASETYPE_ALPHA_TO_COVERAGE			|| type == CASETYPE_BOTH						|| type == CASETYPE_BOTH_INVERTED)
	, m_isSampleCoverageCase			(type == CASETYPE_SAMPLE_COVERAGE			|| type == CASETYPE_SAMPLE_COVERAGE_INVERTED	|| type == CASETYPE_BOTH			|| type == CASETYPE_BOTH_INVERTED)
	, m_isInvertedSampleCoverageCase	(type == CASETYPE_SAMPLE_COVERAGE_INVERTED	|| type == CASETYPE_BOTH_INVERTED)
{
}

MaskConstancyCase::IterateResult MaskConstancyCase::iterate (void)
{
	TestLog&		log				= m_testCtx.getLog();
	tcu::Surface	renderedImg		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	log << TestLog::Message << "Clearing color to black" << TestLog::EndMessage;
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));

	if (m_isAlphaToCoverageCase)
	{
		GLU_CHECK_CALL(glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE));
		GLU_CHECK_CALL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE));
		log << TestLog::Message << "GL_SAMPLE_ALPHA_TO_COVERAGE is enabled" << TestLog::EndMessage;
		log << TestLog::Message << "Color mask is TRUE, TRUE, TRUE, FALSE" << TestLog::EndMessage;
	}

	if (m_isSampleCoverageCase)
	{
		GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
		log << TestLog::Message << "GL_SAMPLE_COVERAGE is enabled" << TestLog::EndMessage;
	}

	log << TestLog::Message
		<< "Drawing several green quads, each fully overlapped by a red quad with the same "
		<< (m_isAlphaToCoverageCase ? "alpha" : "")
		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
		<< (m_isInvertedSampleCoverageCase ? "inverted " : "")
		<< (m_isSampleCoverageCase ? "sample coverage" : "")
		<< " values"
		<< TestLog::EndMessage;

	const int numQuadRowsCols = m_numSamples*4;

	for (int row = 0; row < numQuadRowsCols; row++)
	{
		for (int col = 0; col < numQuadRowsCols; col++)
		{
			float		x0			= (float)(col+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
			float		x1			= (float)(col+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
			float		y0			= (float)(row+0) / (float)numQuadRowsCols * 2.0f - 1.0f;
			float		y1			= (float)(row+1) / (float)numQuadRowsCols * 2.0f - 1.0f;
			const Vec4	baseGreen	(0.0f, 1.0f, 0.0f, 0.0f);
			const Vec4	baseRed		(1.0f, 0.0f, 0.0f, 0.0f);
			Vec4		alpha0		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)col / (float)(numQuadRowsCols-1) : 1.0f);
			Vec4		alpha1		(0.0f, 0.0f, 0.0f, m_isAlphaToCoverageCase ? (float)row / (float)(numQuadRowsCols-1) : 1.0f);

			if (m_isSampleCoverageCase)
			{
				float value = (float)(row*numQuadRowsCols + col) / (float)(numQuadRowsCols*numQuadRowsCols-1);
				GLU_CHECK_CALL(glSampleCoverage(m_isInvertedSampleCoverageCase ? 1.0f - value : value, m_isInvertedSampleCoverageCase ? GL_TRUE : GL_FALSE));
			}

			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseGreen + alpha0,	baseGreen + alpha1,	baseGreen + alpha0,	baseGreen + alpha1);
			renderQuad(Vec2(x0, y0), Vec2(x1, y0), Vec2(x0, y1), Vec2(x1, y1), baseRed + alpha0,	baseRed + alpha1,	baseRed + alpha0,	baseRed + alpha1);
		}
	}

	readImage(renderedImg);

	log << TestLog::Image("RenderedImage", "Rendered image", renderedImg, QP_IMAGE_COMPRESSION_MODE_PNG);

	for (int y = 0; y < renderedImg.getHeight(); y++)
	for (int x = 0; x < renderedImg.getWidth(); x++)
	{
		if (renderedImg.getPixel(x, y).getGreen() > 0)
		{
			log << TestLog::Message << "Failure: Non-zero green color component detected - should have been completely overwritten by red quad" << TestLog::EndMessage;
			m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Failed");
			return STOP;
		}
	}

	log << TestLog::Message
		<< "Success: Coverage mask appears to be constant at a given pixel coordinate with a given "
		<< (m_isAlphaToCoverageCase ? "alpha" : "")
		<< (m_isAlphaToCoverageCase && m_isSampleCoverageCase ? " and " : "")
		<< (m_isSampleCoverageCase ? "coverage value" : "")
		<< TestLog::EndMessage;

	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");

	return STOP;
}

/*--------------------------------------------------------------------*//*!
 * \brief Tests coverage mask inversion validity.
 *
 * Tests that the coverage masks obtained by glSampleCoverage(..., GL_TRUE)
 * and glSampleCoverage(..., GL_FALSE) are indeed each others' inverses.
 * This is done by drawing a pattern, with varying coverage values,
 * overlapped by a pattern that has inverted masks and is otherwise
 * identical. The resulting image is compared to one obtained by drawing
 * the same pattern but with all-ones coverage masks.
 *//*--------------------------------------------------------------------*/
class CoverageMaskInvertCase : public MultisampleCase
{
public:
					CoverageMaskInvertCase		(Context& context, const char* name, const char* description);
					~CoverageMaskInvertCase		(void) {}

	IterateResult	iterate						(void);

protected:
	int				getDesiredViewportSize		(void) const { return 256; }

private:
	void			drawPattern					(bool invertSampleCoverage) const;
};

CoverageMaskInvertCase::CoverageMaskInvertCase (Context& context, const char* name, const char* description)
	: MultisampleCase (context, name, description)
{
}

void CoverageMaskInvertCase::drawPattern (bool invertSampleCoverage) const
{
	const int numTriangles = 25;
	for (int i = 0; i < numTriangles; i++)
	{
		GLU_CHECK_CALL(glSampleCoverage((float)i / (float)(numTriangles-1), invertSampleCoverage ? GL_TRUE : GL_FALSE));

		float angle0 = 2.0f*DE_PI * (float)i			/ (float)numTriangles;
		float angle1 = 2.0f*DE_PI * ((float)i + 0.5f)	/ (float)numTriangles;

		renderTriangle(Vec2(0.0f, 0.0f),
					   Vec2(deFloatCos(angle0)*0.95f, deFloatSin(angle0)*0.95f),
					   Vec2(deFloatCos(angle1)*0.95f, deFloatSin(angle1)*0.95f),
					   Vec4(0.4f + (float)i/(float)numTriangles*0.6f,
							0.5f + (float)i/(float)numTriangles*0.3f,
							0.6f - (float)i/(float)numTriangles*0.5f,
							0.7f - (float)i/(float)numTriangles*0.7f));
	}
}

CoverageMaskInvertCase::IterateResult CoverageMaskInvertCase::iterate (void)
{
	TestLog&		log								= m_testCtx.getLog();
	tcu::Surface	renderedImgNoSampleCoverage		(m_viewportSize, m_viewportSize);
	tcu::Surface	renderedImgSampleCoverage		(m_viewportSize, m_viewportSize);

	randomizeViewport();

	GLU_CHECK_CALL(glEnable(GL_BLEND));
	GLU_CHECK_CALL(glBlendEquation(GL_FUNC_ADD));
	GLU_CHECK_CALL(glBlendFunc(GL_ONE, GL_ONE));
	log << TestLog::Message << "Additive blending enabled in order to detect (erroneously) overlapping samples" << TestLog::EndMessage;

	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE disabled" << TestLog::EndMessage;
	drawPattern(false);
	readImage(renderedImgNoSampleCoverage);

	log << TestLog::Image("RenderedImageNoSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE disabled", renderedImgNoSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);

	log << TestLog::Message << "Clearing color to all-zeros" << TestLog::EndMessage;
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	GLU_CHECK_CALL(glEnable(GL_SAMPLE_COVERAGE));
	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using non-inverted masks" << TestLog::EndMessage;
	drawPattern(false);
	log << TestLog::Message << "Drawing the pattern with GL_SAMPLE_COVERAGE enabled, using same sample coverage values but inverted masks" << TestLog::EndMessage;
	drawPattern(true);
	readImage(renderedImgSampleCoverage);

	log << TestLog::Image("RenderedImageSampleCoverage", "Rendered image with GL_SAMPLE_COVERAGE enabled", renderedImgSampleCoverage, QP_IMAGE_COMPRESSION_MODE_PNG);

	bool passed = tcu::pixelThresholdCompare(log,
											 "CoverageVsNoCoverage",
											 "Comparison of same pattern with GL_SAMPLE_COVERAGE disabled and enabled",
											 renderedImgNoSampleCoverage,
											 renderedImgSampleCoverage,
											 tcu::RGBA(0),
											 tcu::COMPARE_LOG_ON_ERROR);

	if (passed)
		log << TestLog::Message << "Success: The two images rendered are identical" << TestLog::EndMessage;

	m_context.getTestContext().setTestResult(passed ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
											 passed ? "Passed"				: "Failed");

	return STOP;
}

MultisampleTests::MultisampleTests (Context& context)
	: TestCaseGroup(context, "multisample", "Multisampling tests")
{
}

MultisampleTests::~MultisampleTests (void)
{
}

void MultisampleTests::init (void)
{
	addChild(new PolygonNumSamplesCase		(m_context, "num_samples_polygon",			"Test sanity of the value of GL_SAMPLES, with polygons"));
	addChild(new LineNumSamplesCase			(m_context, "num_samples_line",				"Test sanity of the value of GL_SAMPLES, with lines"));
	addChild(new CommonEdgeCase				(m_context, "common_edge_small_quads",		"Test polygons' common edges with small quads",						CommonEdgeCase::CASETYPE_SMALL_QUADS));
	addChild(new CommonEdgeCase				(m_context, "common_edge_big_quad",			"Test polygons' common edges with bigger-than-viewport quads",		CommonEdgeCase::CASETYPE_BIGGER_THAN_VIEWPORT_QUAD));
	addChild(new CommonEdgeCase				(m_context, "common_edge_viewport_quad",	"Test polygons' common edges with exactly viewport-sized quads",	CommonEdgeCase::CASETYPE_FIT_VIEWPORT_QUAD));
	addChild(new SampleDepthCase			(m_context, "depth",						"Test that depth values are per-sample"));
	addChild(new SampleStencilCase			(m_context, "stencil",						"Test that stencil values are per-sample"));
	addChild(new CoverageMaskInvertCase		(m_context, "sample_coverage_invert",		"Test that non-inverted and inverted sample coverage masks are each other's negations"));

	addChild(new MaskProportionalityCase(m_context, "proportionality_alpha_to_coverage",			"Test the proportionality property of GL_SAMPLE_ALPHA_TO_COVERAGE",			MaskProportionalityCase::CASETYPE_ALPHA_TO_COVERAGE));
	addChild(new MaskProportionalityCase(m_context, "proportionality_sample_coverage",				"Test the proportionality property of GL_SAMPLE_COVERAGE",					MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE));
	addChild(new MaskProportionalityCase(m_context, "proportionality_sample_coverage_inverted",		"Test the proportionality property of inverted-mask GL_SAMPLE_COVERAGE",	MaskProportionalityCase::CASETYPE_SAMPLE_COVERAGE_INVERTED));

	addChild(new MaskConstancyCase(m_context, "constancy_alpha_to_coverage",			"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE",											MaskConstancyCase::CASETYPE_ALPHA_TO_COVERAGE));
	addChild(new MaskConstancyCase(m_context, "constancy_sample_coverage",				"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_COVERAGE",													MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE));
	addChild(new MaskConstancyCase(m_context, "constancy_sample_coverage_inverted",		"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using inverted-mask GL_SAMPLE_COVERAGE",									MaskConstancyCase::CASETYPE_SAMPLE_COVERAGE_INVERTED));
	addChild(new MaskConstancyCase(m_context, "constancy_both",							"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and GL_SAMPLE_COVERAGE",					MaskConstancyCase::CASETYPE_BOTH));
	addChild(new MaskConstancyCase(m_context, "constancy_both_inverted",				"Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and inverted-mask GL_SAMPLE_COVERAGE",	MaskConstancyCase::CASETYPE_BOTH_INVERTED));
}

} // Functional
} // gles2
} // deqp
