/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL 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 Tests for resizing the native window of a surface.
 *//*--------------------------------------------------------------------*/

#include "teglResizeTests.hpp"

#include "teglSimpleConfigCase.hpp"

#include "tcuImageCompare.hpp"
#include "tcuSurface.hpp"
#include "tcuPlatform.hpp"
#include "tcuTestLog.hpp"
#include "tcuInterval.hpp"

#include "egluNativeDisplay.hpp"
#include "egluNativeWindow.hpp"
#include "egluNativePixmap.hpp"
#include "egluUnique.hpp"
#include "egluUtil.hpp"

#include "gluDefs.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "tcuTestLog.hpp"
#include "tcuVector.hpp"

#include "deThread.h"
#include "deUniquePtr.hpp"

#include <sstream>

namespace deqp
{
namespace egl
{

using	std::vector;
using	std::string;
using	std::ostringstream;
using	de::MovePtr;
using	tcu::CommandLine;
using	tcu::ConstPixelBufferAccess;
using	tcu::Interval;
using	tcu::IVec2;
using	tcu::Vec3;
using	tcu::Vec4;
using	tcu::UVec4;
using	tcu::ResultCollector;
using	tcu::Surface;
using	tcu::TestLog;
using	tcu::egl::Display;
using	eglu::AttribMap;
using	eglu::NativeDisplay;
using	eglu::NativeWindow;
using	eglu::ScopedCurrentContext;
using	eglu::UniqueSurface;
using	eglu::UniqueContext;

typedef	eglu::WindowParams::Visibility	Visibility;
typedef	TestCase::IterateResult			IterateResult;

struct ResizeParams
{
	string	name;
	string	description;
	IVec2	oldSize;
	IVec2	newSize;
};

class ResizeTest : public TestCase
{
public:
								ResizeTest	(EglTestContext&		eglTestCtx,
											 const ResizeParams&	params)
									: TestCase	(eglTestCtx,
												 params.name.c_str(),
												 params.description.c_str())
									, m_oldSize	(params.oldSize)
									, m_newSize	(params.newSize)
									, m_display	(EGL_NO_DISPLAY)
									, m_config	(DE_NULL)
									, m_log		(m_testCtx.getLog())
									, m_status	(m_log) {}

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

protected:
	virtual EGLenum				surfaceType	(void) const { return EGL_WINDOW_BIT; }
	void						resize		(IVec2 size);

	const IVec2					m_oldSize;
	const IVec2					m_newSize;
	EGLDisplay					m_display;
	EGLConfig					m_config;
	MovePtr<NativeWindow>		m_nativeWindow;
	MovePtr<UniqueSurface>		m_surface;
	MovePtr<UniqueContext>		m_context;
	TestLog&					m_log;
	ResultCollector				m_status;
	glw::Functions				m_gl;
};

EGLConfig getEGLConfig (const EGLDisplay eglDisplay, EGLenum surfaceType)
{
	AttribMap attribMap;

	attribMap[EGL_SURFACE_TYPE]		= surfaceType;
	attribMap[EGL_RENDERABLE_TYPE]	= EGL_OPENGL_ES2_BIT;

	return eglu::chooseSingleConfig(eglDisplay, attribMap);
}

void ResizeTest::init (void)
{
	TestCase::init();

	const CommandLine&		cmdLine			= m_testCtx.getCommandLine();
	const EGLDisplay		eglDisplay		= m_eglTestCtx.getDisplay().getEGLDisplay();
	const EGLConfig			eglConfig		= getEGLConfig(eglDisplay, surfaceType());
	const EGLint			ctxAttribs[]	=
	{
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};
	EGLContext				eglContext		= eglCreateContext(eglDisplay,
															   eglConfig,
															   EGL_NO_CONTEXT,
															   ctxAttribs);
	EGLU_CHECK_MSG("eglCreateContext()");
	MovePtr<UniqueContext>	context			(new UniqueContext(eglDisplay, eglContext));
	const EGLint			configId		= eglu::getConfigAttribInt(eglDisplay,
																	   eglConfig,
																	   EGL_CONFIG_ID);
	const Visibility		visibility		= eglu::parseWindowVisibility(cmdLine);
	NativeDisplay&			nativeDisplay	= m_eglTestCtx.getNativeDisplay();
	MovePtr<NativeWindow>	nativeWindow	(m_eglTestCtx.createNativeWindow(eglDisplay,
																			 eglConfig,
																			 DE_NULL,
																			 m_oldSize.x(),
																			 m_oldSize.y(),
																			 visibility));
	const EGLSurface		eglSurface		= eglu::createWindowSurface(nativeDisplay,
																		*nativeWindow,
																		eglDisplay,
																		eglConfig,
																		DE_NULL);
	MovePtr<UniqueSurface>	surface			(new UniqueSurface(eglDisplay, eglSurface));

	m_log << TestLog::Message
		  << "Chose EGLConfig with id " << configId << ".\n"
		  << "Created initial surface with size " << m_oldSize
		  << TestLog::EndMessage;

	m_eglTestCtx.getGLFunctions(m_gl, glu::ApiType::es(2, 0));
	m_config		= eglConfig;
	m_surface		= surface;
	m_context		= context;
	m_display		= eglDisplay;
	m_nativeWindow	= nativeWindow;
	EGLU_CHECK();
}

void ResizeTest::deinit (void)
{
	m_config		= DE_NULL;
	m_display		= EGL_NO_DISPLAY;
	m_context.clear();
	m_surface.clear();
	m_nativeWindow.clear();
}

void ResizeTest::resize (IVec2 size)
{
	m_nativeWindow->setSurfaceSize(size);
	m_testCtx.getPlatform().processEvents();
	m_log << TestLog::Message
		  << "Resized surface to size " << size
		  << TestLog::EndMessage;
}

class ChangeSurfaceSizeCase : public ResizeTest
{
public:
					ChangeSurfaceSizeCase	(EglTestContext&		eglTestCtx,
											 const ResizeParams&	params)
						: ResizeTest(eglTestCtx, params) {}

	IterateResult	iterate					(void);
};

void drawRectangle (const glw::Functions& gl, IVec2 pos, IVec2 size, Vec3 color)
{
	gl.clearColor(color.x(), color.y(), color.z(), 1.0);
	gl.scissor(pos.x(), pos.y(), size.x(), size.y());
	gl.enable(GL_SCISSOR_TEST);
	gl.clear(GL_COLOR_BUFFER_BIT);
	gl.disable(GL_SCISSOR_TEST);
	GLU_EXPECT_NO_ERROR(gl.getError(),
						"Rectangle drawing with glScissor and glClear failed.");
}

void initSurface (const glw::Functions& gl, IVec2 oldSize)
{
	const Vec3	frameColor	(0.0f, 0.0f, 1.0f);
	const Vec3	fillColor	(1.0f, 0.0f, 0.0f);
	const Vec3	markColor	(0.0f, 1.0f, 0.0f);

	drawRectangle(gl, IVec2(0, 0), oldSize, frameColor);
	drawRectangle(gl, IVec2(2, 2), oldSize - IVec2(4, 4), fillColor);

	drawRectangle(gl, IVec2(0, 0), IVec2(8, 4), markColor);
	drawRectangle(gl, oldSize - IVec2(16, 16), IVec2(8, 4), markColor);
	drawRectangle(gl, IVec2(0, oldSize.y() - 16), IVec2(8, 4), markColor);
	drawRectangle(gl, IVec2(oldSize.x() - 16, 0), IVec2(8, 4), markColor);
}

bool compareRectangles (const ConstPixelBufferAccess& rectA,
						const ConstPixelBufferAccess& rectB)
{
	const int width		= rectA.getWidth();
	const int height	= rectA.getHeight();
	const int depth		= rectA.getDepth();

	if (rectB.getWidth() != width || rectB.getHeight() != height || rectB.getDepth() != depth)
		return false;

	for (int z = 0; z < depth; ++z)
		for (int y = 0; y < height; ++y)
			for (int x = 0; x < width; ++x)
				if (rectA.getPixel(x, y, z) != rectB.getPixel(x, y, z))
					return false;

	return true;
}

// Check whether `oldSurface` and `newSurface` share a common corner.
bool compareCorners (const Surface& oldSurface, const Surface& newSurface)
{
	const int	oldWidth	= oldSurface.getWidth();
	const int	oldHeight	= oldSurface.getHeight();
	const int	newWidth	= newSurface.getWidth();
	const int	newHeight	= newSurface.getHeight();
	const int	minWidth	= de::min(oldWidth, newWidth);
	const int	minHeight	= de::min(oldHeight, newHeight);

	for (int xCorner = 0; xCorner < 2; ++xCorner)
	{
		const int oldX = xCorner == 0 ? 0 : oldWidth - minWidth;
		const int newX = xCorner == 0 ? 0 : newWidth - minWidth;

		for (int yCorner = 0; yCorner < 2; ++yCorner)
		{
			const int				oldY		= yCorner == 0 ? 0 : oldHeight - minHeight;
			const int				newY		= yCorner == 0 ? 0 : newHeight - minHeight;
			ConstPixelBufferAccess	oldAccess	=
				oldSurface.getSubAccess(oldX, oldY, minWidth, minHeight);
			ConstPixelBufferAccess	newAccess	=
				newSurface.getSubAccess(newX, newY, minWidth, minHeight);

			if (compareRectangles(oldAccess, newAccess))
				return true;
		}
	}

	return false;
}

Surface readSurface (const glw::Functions& gl, IVec2 size)
{
	Surface ret (size.x(), size.y());
	gl.readPixels(0, 0, size.x(), size.y(), GL_RGBA, GL_UNSIGNED_BYTE,
				  ret.getAccess().getDataPtr());

	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed");
	return ret;
}

template <typename T>
inline bool hasBits (T bitSet, T requiredBits)
{
	return (bitSet & requiredBits) == requiredBits;
}

IVec2 getNativeSurfaceSize (const NativeWindow& nativeWindow,
							IVec2				reqSize)
{
	if (hasBits(nativeWindow.getCapabilities(), NativeWindow::CAPABILITY_GET_SURFACE_SIZE))
		return nativeWindow.getSurfaceSize();
	return reqSize; // assume we got the requested size
}

IVec2 checkSurfaceSize (EGLDisplay			eglDisplay,
						EGLSurface			eglSurface,
						const NativeWindow&	nativeWindow,
						IVec2				reqSize,
						ResultCollector&	status)
{
	const IVec2		nativeSize	= getNativeSurfaceSize(nativeWindow, reqSize);
	IVec2			eglSize		= eglu::getSurfaceSize(eglDisplay, eglSurface);
	ostringstream	oss;

	oss << "Size of EGL surface " << eglSize
		<< " differs from size of native window " << nativeSize;
	status.check(eglSize == nativeSize, oss.str());

	return eglSize;
}

IterateResult ChangeSurfaceSizeCase::iterate (void)
{
	EGLU_CHECK();
	Surface					oldSurface;
	Surface					newSurface;
	ScopedCurrentContext	currentCtx	(m_display, **m_surface, **m_surface, **m_context);
	IVec2					oldEglSize	= checkSurfaceSize(m_display,
														   **m_surface,
														   *m_nativeWindow,
														   m_oldSize,
														   m_status);

	initSurface(m_gl, oldEglSize);

	this->resize(m_newSize);

	eglSwapBuffers(m_display, **m_surface);
	checkSurfaceSize(m_display, **m_surface, *m_nativeWindow, m_newSize, m_status);

	m_status.setTestContextResult(m_testCtx);
	return STOP;
}

class PreserveBackBufferCase : public ResizeTest
{
public:
					PreserveBackBufferCase	(EglTestContext&		eglTestCtx,
											 const ResizeParams&	params)
						: ResizeTest(eglTestCtx, params) {}

	IterateResult	iterate					(void);
	EGLenum			surfaceType				(void) const;
};

EGLenum PreserveBackBufferCase::surfaceType (void) const
{
	return EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
}

IterateResult PreserveBackBufferCase::iterate (void)
{
	ScopedCurrentContext	currentCtx	(m_display, **m_surface, **m_surface, **m_context);

	EGLU_CHECK_CALL(
		eglSurfaceAttrib(m_display, **m_surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "GL state erroneous upon initialization!");

	{
		const IVec2 oldEglSize = eglu::getSurfaceSize(m_display, **m_surface);
		initSurface(m_gl, oldEglSize);

		m_gl.finish();
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFinish() failed");

		{
			const Surface oldSurface = readSurface(m_gl, oldEglSize);

			eglSwapBuffers(m_display, **m_surface);
			this->resize(m_newSize);
			eglSwapBuffers(m_display, **m_surface);

			{
				const IVec2		newEglSize	= eglu::getSurfaceSize(m_display, **m_surface);
				const Surface	newSurface	= readSurface(m_gl, newEglSize);

				m_log << TestLog::ImageSet("Corner comparison",
										   "Comparing old and new surfaces at all corners")
					  << TestLog::Image("Before resizing", "Before resizing", oldSurface)
					  << TestLog::Image("After resizing", "After resizing", newSurface)
					  << TestLog::EndImageSet;

				m_status.check(compareCorners(oldSurface, newSurface),
							   "Resizing the native window changed the contents of "
							   "the EGL surface");
			}
		}
	}

	m_status.setTestContextResult(m_testCtx);
	return STOP;
}

typedef tcu::Vector<Interval, 2> IvVec2;

class UpdateResolutionCase : public ResizeTest
{
public:
					UpdateResolutionCase	(EglTestContext&		eglTestCtx,
											 const ResizeParams&	params)
						: ResizeTest(eglTestCtx, params) {}

	IterateResult	iterate					(void);

private:
	IvVec2			getNativePixelsPerInch	(void);
};

IvVec2 ivVec2 (const IVec2& vec)
{
	return IvVec2(double(vec.x()), double(vec.y()));
}

Interval approximateInt (int i)
{
	return (Interval(i) + Interval(-1.0, 1.0)) & Interval(0.0, TCU_INFINITY);
}

IvVec2 UpdateResolutionCase::getNativePixelsPerInch	(void)
{
	const int		inchPer10km	= 254 * EGL_DISPLAY_SCALING;
	const IVec2		bufSize		= eglu::getSurfaceSize(m_display, **m_surface);
	const IVec2		winSize		= m_nativeWindow->getScreenSize();
	const IVec2		bufPp10km	= eglu::getSurfaceResolution(m_display, **m_surface);
	const Interval	margin		(-1.0, 1.0); // The resolution may be rounded
	const IvVec2	bufPpiI		= (IvVec2(approximateInt(bufPp10km.x()),
										  approximateInt(bufPp10km.y()))
								   / Interval(inchPer10km));
	const IvVec2	winPpiI		= ivVec2(winSize) * bufPpiI / ivVec2(bufSize);
	const IVec2		winPpi		(int(winPpiI.x().midpoint()), int(winPpiI.y().midpoint()));

	m_log << TestLog::Message
		  << "EGL surface size: "							<< bufSize		<< "\n"
		  << "EGL surface pixel density (pixels / 10 km): "	<< bufPp10km	<< "\n"
		  << "Native window size: "							<< winSize		<< "\n"
		  << "Native pixel density (ppi): "					<< winPpi		<< "\n"
		  << TestLog::EndMessage;

	m_status.checkResult(bufPp10km.x() >= 1 && bufPp10km.y() >= 1,
						 QP_TEST_RESULT_QUALITY_WARNING,
						 "Surface pixel density is less than one pixel per 10 km. "
						 "Is the surface really visible from space?");

	return winPpiI;
}

IterateResult UpdateResolutionCase::iterate (void)
{
	ScopedCurrentContext	currentCtx	(m_display, **m_surface, **m_surface, **m_context);

	if (!hasBits(m_nativeWindow->getCapabilities(),
				 NativeWindow::CAPABILITY_GET_SCREEN_SIZE))
		TCU_THROW(NotSupportedError, "Unable to determine surface size in screen pixels");

	{
		const IVec2 oldEglSize = eglu::getSurfaceSize(m_display, **m_surface);
		initSurface(m_gl, oldEglSize);
	}
	{
		const IvVec2 oldPpi = this->getNativePixelsPerInch();
		this->resize(m_newSize);
		eglSwapBuffers(m_display, **m_surface);
		{
			const IvVec2 newPpi = this->getNativePixelsPerInch();
			m_status.check(oldPpi.x().intersects(newPpi.x()) &&
						   oldPpi.y().intersects(newPpi.y()),
						   "Window PPI differs after resizing");
		}
	}

	m_status.setTestContextResult(m_testCtx);
	return STOP;
}

ResizeTests::ResizeTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "resize", "Tests resizing the native surface")
{
}

template <class Case>
TestCaseGroup* createCaseGroup(EglTestContext&	eglTestCtx,
							   const string&	name,
							   const string&	desc)
{
	const ResizeParams		params[]	=
	{
		{ "shrink",			"Shrink in both dimensions",
		  IVec2(128, 128),	IVec2(32, 32) },
		{ "grow",			"Grow in both dimensions",
		  IVec2(32, 32),	IVec2(128, 128) },
		{ "stretch_width",	"Grow horizontally, shrink vertically",
		  IVec2(32, 128),	IVec2(128, 32) },
		{ "stretch_height",	"Grow vertically, shrink horizontally",
		  IVec2(128, 32),	IVec2(32, 128) },
	};
	TestCaseGroup* const	group		=
		new TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str());

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(params); ++ndx)
		group->addChild(new Case(eglTestCtx, params[ndx]));

	return group;
}

void ResizeTests::init (void)
{
	addChild(createCaseGroup<ChangeSurfaceSizeCase>(m_eglTestCtx,
													"surface_size",
													"EGL surface size update"));
	addChild(createCaseGroup<PreserveBackBufferCase>(m_eglTestCtx,
													 "back_buffer",
													 "Back buffer contents"));
	addChild(createCaseGroup<UpdateResolutionCase>(m_eglTestCtx,
												   "pixel_density",
												   "Pixel density"));
}

} // egl
} // deqp
