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