/*-------------------------------------------------------------------------
 * 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 "tcuTextureUtil.hpp"
#include "tcuResultCollector.hpp"

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

#include "eglwLibrary.hpp"
#include "eglwEnums.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 eglu::AttribMap;
using eglu::NativeDisplay;
using eglu::NativeWindow;
using eglu::ScopedCurrentContext;
using eglu::UniqueSurface;
using eglu::UniqueContext;
using eglu::NativeWindowFactory;
using eglu::WindowParams;
using namespace eglw;

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 Library& egl, const EGLDisplay eglDisplay, EGLenum surfaceType)
{
	AttribMap attribMap;

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

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

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

	const Library&				egl				= m_eglTestCtx.getLibrary();
	const CommandLine&			cmdLine			= m_testCtx.getCommandLine();
	const EGLDisplay			eglDisplay		= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
	const EGLConfig				eglConfig		= getEGLConfig(egl, eglDisplay, surfaceType());
	const EGLint				ctxAttribs[]	=
	{
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};
	EGLContext					eglContext		= egl.createContext(eglDisplay,
																   eglConfig,
																   EGL_NO_CONTEXT,
																   ctxAttribs);
	EGLU_CHECK_MSG(egl, "eglCreateContext()");
	MovePtr<UniqueContext>		context			(new UniqueContext(egl, eglDisplay, eglContext));
	const EGLint				configId		= eglu::getConfigAttribInt(egl,
																		   eglDisplay,
																		   eglConfig,
																		   EGL_CONFIG_ID);
	const Visibility			visibility		= eglu::parseWindowVisibility(cmdLine);
	NativeDisplay&				nativeDisplay	= m_eglTestCtx.getNativeDisplay();
	const NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(),
																				  cmdLine);

	const WindowParams			windowParams	(m_oldSize.x(), m_oldSize.y(), visibility);
	MovePtr<NativeWindow>		nativeWindow	(windowFactory.createWindow(&nativeDisplay,
																			 eglDisplay,
																			 eglConfig,
																			 DE_NULL,
																			 windowParams));
	const EGLSurface			eglSurface		= eglu::createWindowSurface(nativeDisplay,
																			*nativeWindow,
																			eglDisplay,
																			eglConfig,
																			DE_NULL);
	MovePtr<UniqueSurface>		surface			(new UniqueSurface(egl, eglDisplay, eglSurface));

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

	m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2, 0));
	m_config		= eglConfig;
	m_surface		= surface;
	m_context		= context;
	m_display		= eglDisplay;
	m_nativeWindow	= nativeWindow;
	EGLU_CHECK_MSG(egl, "init");
}

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

	if (m_display != EGL_NO_DISPLAY)
	{
		m_eglTestCtx.getLibrary().terminate(m_display);
		m_display	= EGL_NO_DISPLAY;
	}
}

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	=
				getSubregion(oldSurface.getAccess(), oldX, oldY, minWidth, minHeight);
			ConstPixelBufferAccess	newAccess	=
				getSubregion(newSurface.getAccess(), 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 (const Library&		egl,
						EGLDisplay			eglDisplay,
						EGLSurface			eglSurface,
						const NativeWindow&	nativeWindow,
						IVec2				reqSize,
						ResultCollector&	status)
{
	const IVec2		nativeSize	= getNativeSurfaceSize(nativeWindow, reqSize);
	IVec2			eglSize		= eglu::getSurfaceSize(egl, 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)
{
	const Library&			egl			= m_eglTestCtx.getLibrary();
	ScopedCurrentContext	currentCtx	(egl, m_display, **m_surface, **m_surface, **m_context);
	egl.swapBuffers(m_display, **m_surface);
	IVec2					oldEglSize	= checkSurfaceSize(egl,
														   m_display,
														   **m_surface,
														   *m_nativeWindow,
														   m_oldSize,
														   m_status);

	initSurface(m_gl, oldEglSize);

	this->resize(m_newSize);

	egl.swapBuffers(m_display, **m_surface);
	EGLU_CHECK_MSG(egl, "eglSwapBuffers()");
	checkSurfaceSize(egl, 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)
{
	const Library&			egl			= m_eglTestCtx.getLibrary();
	ScopedCurrentContext	currentCtx	(egl, m_display, **m_surface, **m_surface, **m_context);

	EGLU_CHECK_CALL(egl, surfaceAttrib(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(egl, 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);

			egl.swapBuffers(m_display, **m_surface);
			this->resize(m_newSize);
			egl.swapBuffers(m_display, **m_surface);
			EGLU_CHECK_MSG(egl, "eglSwapBuffers()");

			{
				const IVec2		newEglSize	= eglu::getSurfaceSize(egl, 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.checkResult(compareCorners(oldSurface, newSurface),
									 QP_TEST_RESULT_QUALITY_WARNING,
									 "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)
{
	const Interval margin(-1.0, 1.0); // The resolution may be rounded

	return (Interval(i) + margin) & Interval(0.0, TCU_INFINITY);
}

IvVec2 UpdateResolutionCase::getNativePixelsPerInch	(void)
{
	const Library&	egl			= m_eglTestCtx.getLibrary();
	const int		inchPer10km	= 254 * EGL_DISPLAY_SCALING;
	const IVec2		bufSize		= eglu::getSurfaceSize(egl, m_display, **m_surface);
	const IVec2		winSize		= m_nativeWindow->getScreenSize();
	const IVec2		bufPp10km	= eglu::getSurfaceResolution(egl, m_display, **m_surface);
	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)
{
	const Library&			egl			= m_eglTestCtx.getLibrary();
	ScopedCurrentContext	currentCtx	(egl, 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(egl, m_display, **m_surface);
		initSurface(m_gl, oldEglSize);
	}
	{
		const IvVec2 oldPpi = this->getNativePixelsPerInch();
		this->resize(m_newSize);
		EGLU_CHECK_CALL(egl, swapBuffers(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
