1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core
3e5c31af7Sopenharmony_ci * ----------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Raspberry PI platform.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "tcuRaspiPlatform.hpp"
25e5c31af7Sopenharmony_ci#include "egluNativeDisplay.hpp"
26e5c31af7Sopenharmony_ci#include "egluNativeWindow.hpp"
27e5c31af7Sopenharmony_ci#include "egluGLContextFactory.hpp"
28e5c31af7Sopenharmony_ci#include "deMemory.h"
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_citcu::Platform* createPlatform (void)
31e5c31af7Sopenharmony_ci{
32e5c31af7Sopenharmony_ci	return new tcu::rpi::Platform();
33e5c31af7Sopenharmony_ci}
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_cinamespace tcu
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_cinamespace rpi
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_cienum
41e5c31af7Sopenharmony_ci{
42e5c31af7Sopenharmony_ci	DEFAULT_WINDOW_WIDTH	= 400,
43e5c31af7Sopenharmony_ci	DEFAULT_WINDOW_HEIGHT	= 300
44e5c31af7Sopenharmony_ci};
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_cistatic const eglu::NativeDisplay::Capability	DISPLAY_CAPABILITIES	= eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY;
47e5c31af7Sopenharmony_cistatic const eglu::NativeWindow::Capability		WINDOW_CAPABILITIES		= eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY;
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ciclass Display : public eglu::NativeDisplay
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_cipublic:
52e5c31af7Sopenharmony_ci								Display				(void) : eglu::NativeDisplay(DISPLAY_CAPABILITIES) {}
53e5c31af7Sopenharmony_ci								~Display			(void) {}
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ci	EGLNativeDisplayType		getLegacyNative		(void) { return EGL_DEFAULT_DISPLAY; }
56e5c31af7Sopenharmony_ci};
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ciclass DisplayFactory : public eglu::NativeDisplayFactory
59e5c31af7Sopenharmony_ci{
60e5c31af7Sopenharmony_cipublic:
61e5c31af7Sopenharmony_ci								DisplayFactory		(void);
62e5c31af7Sopenharmony_ci								~DisplayFactory		(void) {}
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_ci	eglu::NativeDisplay*		createDisplay		(const EGLAttrib* attribList) const;
65e5c31af7Sopenharmony_ci};
66e5c31af7Sopenharmony_ci
67e5c31af7Sopenharmony_ciclass Window : public eglu::NativeWindow
68e5c31af7Sopenharmony_ci{
69e5c31af7Sopenharmony_cipublic:
70e5c31af7Sopenharmony_ci								Window				(int width, int height);
71e5c31af7Sopenharmony_ci								~Window				(void);
72e5c31af7Sopenharmony_ci
73e5c31af7Sopenharmony_ci	EGLNativeWindowType			getLegacyNative		(void) { return &m_nativeWindow; }
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci	IVec2						getSize				(void) const;
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_ciprivate:
78e5c31af7Sopenharmony_ci	DISPMANX_DISPLAY_HANDLE_T	m_dispmanDisplay;
79e5c31af7Sopenharmony_ci	DISPMANX_ELEMENT_HANDLE_T	m_dispmanElement;
80e5c31af7Sopenharmony_ci	EGL_DISPMANX_WINDOW_T		m_nativeWindow;
81e5c31af7Sopenharmony_ci};
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_ciclass WindowFactory : public eglu::NativeWindowFactory
84e5c31af7Sopenharmony_ci{
85e5c31af7Sopenharmony_cipublic:
86e5c31af7Sopenharmony_ci								WindowFactory		(void) : eglu::NativeWindowFactory("dispman", "Dispman Window", WINDOW_CAPABILITIES) {}
87e5c31af7Sopenharmony_ci								~WindowFactory		(void) {}
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ci	eglu::NativeWindow*			createWindow		(eglu::NativeDisplay* display, const eglu::WindowParams& params) const;
90e5c31af7Sopenharmony_ci};
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_ci// DisplayFactory
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ciDisplayFactory::DisplayFactory (void)
95e5c31af7Sopenharmony_ci	: eglu::NativeDisplayFactory("default", "EGL_DEFAULT_DISPLAY", DISPLAY_CAPABILITIES)
96e5c31af7Sopenharmony_ci{
97e5c31af7Sopenharmony_ci	m_nativeWindowRegistry.registerFactory(new WindowFactory());
98e5c31af7Sopenharmony_ci}
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_cieglu::NativeDisplay* DisplayFactory::createDisplay (const EGLAttrib*) const
101e5c31af7Sopenharmony_ci{
102e5c31af7Sopenharmony_ci	return new Display();
103e5c31af7Sopenharmony_ci}
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci// WindowFactory
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_cieglu::NativeWindow* WindowFactory::createWindow (eglu::NativeDisplay*, const eglu::WindowParams& params) const
108e5c31af7Sopenharmony_ci{
109e5c31af7Sopenharmony_ci	const int	width	= params.width	!= eglu::WindowParams::SIZE_DONT_CARE ? params.width	: DEFAULT_WINDOW_WIDTH;
110e5c31af7Sopenharmony_ci	const int	height	= params.height	!= eglu::WindowParams::SIZE_DONT_CARE ? params.height	: DEFAULT_WINDOW_HEIGHT;
111e5c31af7Sopenharmony_ci
112e5c31af7Sopenharmony_ci	return new Window(width, height);
113e5c31af7Sopenharmony_ci}
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_ci// Window
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ciWindow::Window (int width, int height)
118e5c31af7Sopenharmony_ci	: eglu::NativeWindow(WINDOW_CAPABILITIES)
119e5c31af7Sopenharmony_ci	, m_dispmanDisplay	(0)
120e5c31af7Sopenharmony_ci	, m_dispmanElement	(0)
121e5c31af7Sopenharmony_ci{
122e5c31af7Sopenharmony_ci	DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0;
123e5c31af7Sopenharmony_ci
124e5c31af7Sopenharmony_ci	// \todo [pyry] Error handling.
125e5c31af7Sopenharmony_ci	deMemset(&m_nativeWindow, 0, sizeof(m_nativeWindow));
126e5c31af7Sopenharmony_ci
127e5c31af7Sopenharmony_ci	VC_RECT_T dstRect, srcRect;
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci	dstRect.x = 0;
130e5c31af7Sopenharmony_ci	dstRect.y = 0;
131e5c31af7Sopenharmony_ci	dstRect.width = width;
132e5c31af7Sopenharmony_ci	dstRect.height = height;
133e5c31af7Sopenharmony_ci
134e5c31af7Sopenharmony_ci	srcRect.x = 0;
135e5c31af7Sopenharmony_ci	srcRect.y = 0;
136e5c31af7Sopenharmony_ci	srcRect.width = width << 16;
137e5c31af7Sopenharmony_ci	srcRect.height = height << 16;
138e5c31af7Sopenharmony_ci
139e5c31af7Sopenharmony_ci	m_dispmanDisplay = vc_dispmanx_display_open(0);
140e5c31af7Sopenharmony_ci	TCU_CHECK(m_dispmanDisplay);
141e5c31af7Sopenharmony_ci
142e5c31af7Sopenharmony_ci	dispmanUpdate = vc_dispmanx_update_start(0);
143e5c31af7Sopenharmony_ci	TCU_CHECK(dispmanUpdate);
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_ci	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);
146e5c31af7Sopenharmony_ci	TCU_CHECK(m_dispmanElement);
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ci	vc_dispmanx_update_submit_sync(dispmanUpdate);
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ci	m_nativeWindow.element	= m_dispmanElement;
151e5c31af7Sopenharmony_ci	m_nativeWindow.width	= width;
152e5c31af7Sopenharmony_ci	m_nativeWindow.height	= height;
153e5c31af7Sopenharmony_ci}
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ciWindow::~Window (void)
156e5c31af7Sopenharmony_ci{
157e5c31af7Sopenharmony_ci	DISPMANX_UPDATE_HANDLE_T dispmanUpdate = 0;
158e5c31af7Sopenharmony_ci	dispmanUpdate = vc_dispmanx_update_start(0);
159e5c31af7Sopenharmony_ci	if (dispmanUpdate)
160e5c31af7Sopenharmony_ci	{
161e5c31af7Sopenharmony_ci		vc_dispmanx_element_remove(dispmanUpdate, m_dispmanElement);
162e5c31af7Sopenharmony_ci		vc_dispmanx_update_submit_sync(dispmanUpdate);
163e5c31af7Sopenharmony_ci	}
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ci	vc_dispmanx_display_close(m_dispmanDisplay);
166e5c31af7Sopenharmony_ci}
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ciIVec2 Window::getSize (void) const
169e5c31af7Sopenharmony_ci{
170e5c31af7Sopenharmony_ci	return IVec2(m_nativeWindow.width, m_nativeWindow.height);
171e5c31af7Sopenharmony_ci}
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci// Platform
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_ciPlatform::Platform (void)
176e5c31af7Sopenharmony_ci{
177e5c31af7Sopenharmony_ci	bcm_host_init();
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci	m_nativeDisplayFactoryRegistry.registerFactory(new DisplayFactory());
180e5c31af7Sopenharmony_ci	m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
181e5c31af7Sopenharmony_ci}
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_ciPlatform::~Platform (void)
184e5c31af7Sopenharmony_ci{
185e5c31af7Sopenharmony_ci}
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ci} // rpi
188e5c31af7Sopenharmony_ci} // tcu
189