/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * 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 Raspberry PI platform.
 *//*--------------------------------------------------------------------*/

#include "tcuRaspiPlatform.hpp"
#include "egluNativeDisplay.hpp"
#include "egluNativeWindow.hpp"
#include "egluGLContextFactory.hpp"
#include "deMemory.h"

tcu::Platform* createPlatform (void)
{
	return new tcu::rpi::Platform();
}

namespace tcu
{
namespace rpi
{

enum
{
	DEFAULT_WINDOW_WIDTH	= 400,
	DEFAULT_WINDOW_HEIGHT	= 300
};

static const eglu::NativeDisplay::Capability	DISPLAY_CAPABILITIES	= eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY;
static const eglu::NativeWindow::Capability		WINDOW_CAPABILITIES		= eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY;

class Display : public eglu::NativeDisplay
{
public:
								Display				(void) : eglu::NativeDisplay(DISPLAY_CAPABILITIES) {}
								~Display			(void) {}

	EGLNativeDisplayType		getLegacyNative		(void) { return EGL_DEFAULT_DISPLAY; }
};

class DisplayFactory : public eglu::NativeDisplayFactory
{
public:
								DisplayFactory		(void);
								~DisplayFactory		(void) {}

	eglu::NativeDisplay*		createDisplay		(const EGLAttrib* attribList) const;
};

class Window : public eglu::NativeWindow
{
public:
								Window				(int width, int height);
								~Window				(void);

	EGLNativeWindowType			getLegacyNative		(void) { return &m_nativeWindow; }

	IVec2						getSize				(void) const;

private:
	DISPMANX_DISPLAY_HANDLE_T	m_dispmanDisplay;
	DISPMANX_ELEMENT_HANDLE_T	m_dispmanElement;
	EGL_DISPMANX_WINDOW_T		m_nativeWindow;
};

class WindowFactory : public eglu::NativeWindowFactory
{
public:
								WindowFactory		(void) : eglu::NativeWindowFactory("dispman", "Dispman Window", WINDOW_CAPABILITIES) {}
								~WindowFactory		(void) {}

	eglu::NativeWindow*			createWindow		(eglu::NativeDisplay* display, const eglu::WindowParams& params) const;
};

// DisplayFactory

DisplayFactory::DisplayFactory (void)
	: eglu::NativeDisplayFactory("default", "EGL_DEFAULT_DISPLAY", DISPLAY_CAPABILITIES)
{
	m_nativeWindowRegistry.registerFactory(new WindowFactory());
}

eglu::NativeDisplay* DisplayFactory::createDisplay (const EGLAttrib*) const
{
	return new Display();
}

// WindowFactory

eglu::NativeWindow* WindowFactory::createWindow (eglu::NativeDisplay*, const eglu::WindowParams& params) const
{
	const int	width	= params.width	!= eglu::WindowParams::SIZE_DONT_CARE ? params.width	: DEFAULT_WINDOW_WIDTH;
	const int	height	= params.height	!= eglu::WindowParams::SIZE_DONT_CARE ? params.height	: DEFAULT_WINDOW_HEIGHT;

	return new Window(width, height);
}

// Window

Window::Window (int width, int height)
	: eglu::NativeWindow(WINDOW_CAPABILITIES)
	, m_dispmanDisplay	(0)
	, m_dispmanElement	(0)
{
	DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0;

	// \todo [pyry] Error handling.
	deMemset(&m_nativeWindow, 0, sizeof(m_nativeWindow));

	VC_RECT_T dstRect, srcRect;

	dstRect.x = 0;
	dstRect.y = 0;
	dstRect.width = width;
	dstRect.height = height;

	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.width = width << 16;
	srcRect.height = height << 16;

	m_dispmanDisplay = vc_dispmanx_display_open(0);
	TCU_CHECK(m_dispmanDisplay);

	dispmanUpdate = vc_dispmanx_update_start(0);
	TCU_CHECK(dispmanUpdate);

	m_dispmanElement = vc_dispmanx_element_add(dispmanUpdate, m_dispmanDisplay, 0/*layer*/, &dstRect, 0/*src*/, &srcRect, DISPMANX_PROTECTION_NONE, 0/*alpha*/, 0/*clamp*/, DISPMANX_NO_ROTATE);
	TCU_CHECK(m_dispmanElement);

	vc_dispmanx_update_submit_sync(dispmanUpdate);

	m_nativeWindow.element	= m_dispmanElement;
	m_nativeWindow.width	= width;
	m_nativeWindow.height	= height;
}

Window::~Window (void)
{
	DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0;
	dispmanUpdate = vc_dispmanx_update_start(0);
	if (dispmanUpdate)
	{
		vc_dispmanx_element_remove(dispmanUpdate, m_dispmanElement);
		vc_dispmanx_update_submit_sync(dispmanUpdate);
	}

	vc_dispmanx_display_close(m_dispmanDisplay);
}

IVec2 Window::getSize (void) const
{
	return IVec2(m_nativeWindow.width, m_nativeWindow.height);
}

// Platform

Platform::Platform (void)
{
	bcm_host_init();

	m_nativeDisplayFactoryRegistry.registerFactory(new DisplayFactory());
	m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
}

Platform::~Platform (void)
{
}

} // rpi
} // tcu
