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 X11Egl Display Factory.
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuLnxX11EglDisplayFactory.hpp"
25 #include "tcuLnxX11.hpp"
26 #include "egluGLContextFactory.hpp"
27 #include "eglwLibrary.hpp"
28 #include "eglwFunctions.hpp"
29 #include "eglwEnums.hpp"
30 #include "deUniquePtr.hpp"
31
32 namespace tcu
33 {
34 namespace lnx
35 {
36 namespace x11
37 {
38 namespace egl
39 {
40
41 typedef ::Display *EGLNativeDisplayType;
42 typedef ::Pixmap EGLNativePixmapType;
43 typedef ::Window EGLNativeWindowType;
44
45 DE_STATIC_ASSERT(sizeof(EGLNativeDisplayType) <= sizeof(eglw::EGLNativeDisplayType));
46 DE_STATIC_ASSERT(sizeof(EGLNativePixmapType) <= sizeof(eglw::EGLNativePixmapType));
47 DE_STATIC_ASSERT(sizeof(EGLNativeWindowType) <= sizeof(eglw::EGLNativeWindowType));
48
49 extern "C"
50 {
51
52 typedef EGLW_APICALL eglw::EGLDisplay(EGLW_APIENTRY *eglX11GetDisplayFunc)(EGLNativeDisplayType display_id);
53 typedef EGLW_APICALL eglw::EGLBoolean(EGLW_APIENTRY *eglX11CopyBuffersFunc)(eglw::EGLDisplay dpy,
54 eglw::EGLSurface surface,
55 EGLNativePixmapType target);
56 typedef EGLW_APICALL eglw::EGLSurface(EGLW_APIENTRY *eglX11CreatePixmapSurfaceFunc)(
57 eglw::EGLDisplay dpy, eglw::EGLConfig config, EGLNativePixmapType pixmap, const eglw::EGLint *attrib_list);
58 typedef EGLW_APICALL eglw::EGLSurface(EGLW_APIENTRY *eglX11CreateWindowSurfaceFunc)(
59 eglw::EGLDisplay dpy, eglw::EGLConfig config, EGLNativeWindowType win, const eglw::EGLint *attrib_list);
60 }
61
62 using std::string;
63
64 using de::MovePtr;
65 using de::UniquePtr;
66 using eglu::GLContextFactory;
67 using eglu::NativeDisplay;
68 using eglu::NativeDisplayFactory;
69 using eglu::NativePixmap;
70 using eglu::NativePixmapFactory;
71 using eglu::NativeWindow;
72 using eglu::NativeWindowFactory;
73 using eglu::WindowParams;
74 using glu::ContextFactory;
75 using tcu::TextureLevel;
76
77 class Library : public eglw::DefaultLibrary
78 {
79 public:
Library(void)80 Library(void) : eglw::DefaultLibrary("libEGL.so")
81 {
82 }
83
copyBuffers(eglw::EGLDisplay dpy,eglw::EGLSurface surface,eglw::EGLNativePixmapType target) const84 eglw::EGLBoolean copyBuffers(eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLNativePixmapType target) const
85 {
86 return (m_egl.copyBuffers)(dpy, surface, reinterpret_cast<EGLNativePixmapType *>(target));
87 }
88
createPixmapSurface(eglw::EGLDisplay dpy,eglw::EGLConfig config,eglw::EGLNativePixmapType pixmap,const eglw::EGLint * attrib_list) const89 eglw::EGLSurface createPixmapSurface(eglw::EGLDisplay dpy, eglw::EGLConfig config, eglw::EGLNativePixmapType pixmap,
90 const eglw::EGLint *attrib_list) const
91 {
92 return (m_egl.createPixmapSurface)(dpy, config, reinterpret_cast<EGLNativePixmapType *>(pixmap), attrib_list);
93 }
94
createWindowSurface(eglw::EGLDisplay dpy,eglw::EGLConfig config,eglw::EGLNativeWindowType win,const eglw::EGLint * attrib_list) const95 eglw::EGLSurface createWindowSurface(eglw::EGLDisplay dpy, eglw::EGLConfig config, eglw::EGLNativeWindowType win,
96 const eglw::EGLint *attrib_list) const
97 {
98 return (m_egl.createWindowSurface)(dpy, config, reinterpret_cast<EGLNativeWindowType *>(win), attrib_list);
99 }
100
getDisplay(eglw::EGLNativeDisplayType display_id) const101 eglw::EGLDisplay getDisplay(eglw::EGLNativeDisplayType display_id) const
102 {
103 return ((eglX11GetDisplayFunc)m_egl.getDisplay)(reinterpret_cast<EGLNativeDisplayType>(display_id));
104 }
105 };
106
107 class Display : public NativeDisplay
108 {
109 public:
110 static const Capability CAPABILITIES =
111 Capability(CAPABILITY_GET_DISPLAY_LEGACY | CAPABILITY_GET_DISPLAY_PLATFORM_EXT);
112
Display(MovePtr<XlibDisplay> x11Display)113 Display(MovePtr<XlibDisplay> x11Display)
114 : NativeDisplay(CAPABILITIES, EGL_PLATFORM_X11_EXT, "EGL_EXT_platform_x11")
115 , m_display(x11Display)
116 {
117 }
118
getPlatformNative(void)119 void *getPlatformNative(void)
120 {
121 return m_display->getXDisplay();
122 }
getPlatformExtension(void)123 eglw::EGLNativeDisplayType getPlatformExtension(void)
124 {
125 return reinterpret_cast<eglw::EGLNativeDisplayType>(m_display->getXDisplay());
126 }
getLegacyNative(void)127 eglw::EGLNativeDisplayType getLegacyNative(void)
128 {
129 return reinterpret_cast<eglw::EGLNativeDisplayType>(m_display->getXDisplay());
130 }
131
getX11Display(void)132 XlibDisplay &getX11Display(void)
133 {
134 return *m_display;
135 }
getLibrary(void) const136 const eglw::Library &getLibrary(void) const
137 {
138 return m_library;
139 }
getPlatformAttributes(void) const140 const eglw::EGLAttrib *getPlatformAttributes(void) const
141 {
142 return nullptr;
143 }
144
145 private:
146 UniquePtr<XlibDisplay> m_display;
147 Library m_library;
148 };
149
150 class Window : public NativeWindow
151 {
152 public:
153 static const Capability CAPABILITIES =
154 Capability(CAPABILITY_CREATE_SURFACE_LEGACY | CAPABILITY_CREATE_SURFACE_PLATFORM |
155 CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION | CAPABILITY_GET_SURFACE_SIZE |
156 CAPABILITY_SET_SURFACE_SIZE | CAPABILITY_GET_SCREEN_SIZE);
157
158 Window(Display &display, const WindowParams ¶ms, Visual *visual);
159
getLegacyNative(void)160 eglw::EGLNativeWindowType getLegacyNative(void)
161 {
162 return reinterpret_cast<eglw::EGLNativeWindowType>(m_window.getXID());
163 }
getPlatformExtension(void)164 void *getPlatformExtension(void)
165 {
166 return &m_window.getXID();
167 }
getPlatformNative(void)168 void *getPlatformNative(void)
169 {
170 return &m_window.getXID();
171 }
172
173 IVec2 getSurfaceSize(void) const;
174 void setSurfaceSize(IVec2 size);
getScreenSize(void) const175 IVec2 getScreenSize(void) const
176 {
177 return getSurfaceSize();
178 }
179
180 private:
181 XlibWindow m_window;
182 };
183
Window(Display & display,const WindowParams & params,Visual * visual)184 Window::Window(Display &display, const WindowParams ¶ms, Visual *visual)
185 : NativeWindow(CAPABILITIES)
186 , m_window(display.getX11Display(), params.width, params.height, visual)
187 {
188 m_window.setVisibility((params.visibility != WindowParams::VISIBILITY_HIDDEN));
189 }
190
getSurfaceSize(void) const191 IVec2 Window::getSurfaceSize(void) const
192 {
193 IVec2 ret;
194 m_window.getDimensions(&ret.x(), &ret.y());
195 return ret;
196 }
197
setSurfaceSize(IVec2 size)198 void Window::setSurfaceSize(IVec2 size)
199 {
200 m_window.setDimensions(size.x(), size.y());
201 }
202
203 class WindowFactory : public NativeWindowFactory
204 {
205 public:
206 WindowFactory(void);
207
208 NativeWindow *createWindow(NativeDisplay *nativeDisplay, const WindowParams ¶ms) const;
209
210 NativeWindow *createWindow(NativeDisplay *nativeDisplay, eglw::EGLDisplay display, eglw::EGLConfig config,
211 const eglw::EGLAttrib *attribList, const WindowParams ¶ms) const;
212 };
213
WindowFactory(void)214 WindowFactory::WindowFactory(void) : NativeWindowFactory("window", "X11 Window", Window::CAPABILITIES)
215 {
216 }
217
createWindow(NativeDisplay * nativeDisplay,const WindowParams & params) const218 NativeWindow *WindowFactory::createWindow(NativeDisplay *nativeDisplay, const WindowParams ¶ms) const
219 {
220 Display &display = *dynamic_cast<Display *>(nativeDisplay);
221
222 return new Window(display, params, nullptr);
223 }
224
createWindow(NativeDisplay * nativeDisplay,eglw::EGLDisplay eglDisplay,eglw::EGLConfig config,const eglw::EGLAttrib * attribList,const WindowParams & params) const225 NativeWindow *WindowFactory::createWindow(NativeDisplay *nativeDisplay, eglw::EGLDisplay eglDisplay,
226 eglw::EGLConfig config, const eglw::EGLAttrib *attribList,
227 const WindowParams ¶ms) const
228 {
229 DE_UNREF(attribList);
230
231 Display &display = *dynamic_cast<Display *>(nativeDisplay);
232 eglw::EGLint visualID = 0;
233 ::Visual *visual = nullptr;
234 nativeDisplay->getLibrary().getConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &visualID);
235
236 if (visualID != 0)
237 visual = display.getX11Display().getVisual(visualID);
238
239 return new Window(display, params, visual);
240 }
241
242 #if 0
243 class Pixmap : public NativePixmap
244 {
245 public:
246 enum {
247 CAPABILITIES = (CAPABILITY_CREATE_SURFACE_LEGACY |
248 CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION |
249 CAPABILITY_READ_PIXELS)
250 };
251
252 Pixmap (MovePtr<x11::Pixmap> x11Pixmap)
253 : NativePixmap (CAPABILITIES)
254 , m_pixmap (x11Pixmap) {}
255
256 void* getPlatformNative (void) { return &m_pixmap.getXID(); }
257 void readPixels (TextureLevel* dst);
258
259 private:
260 UniquePtr<x11::Pixmap> m_pixmap;
261 };
262
263 class PixmapFactory : public NativePixmapFactory
264 {
265 public:
266 PixmapFactory (void)
267 : NativePixmapFactory ("pixmap", "X11 Pixmap", Pixmap::CAPABILITIES) {}
268
269 NativePixmap* createPixmap (NativeDisplay* nativeDisplay,
270 int width,
271 int height) const;
272 };
273
274 NativePixmap* PixmapFactory::createPixmap (NativeDisplay* nativeDisplay,
275 int width,
276 int height) const
277
278 {
279 Display* display = dynamic_cast<Display*>(nativeDisplay);
280 MovePtr<x11::Pixmap> x11Pixmap (new x11::Pixmap(display->getX11Display(),
281 width, height));
282 return new Pixmap(x11Pixmap);
283 }
284 #endif
285
286 class DisplayFactory : public NativeDisplayFactory
287 {
288 public:
289 DisplayFactory(EventState &eventState);
290
291 NativeDisplay *createDisplay(const eglw::EGLAttrib *attribList) const;
292
293 private:
294 EventState &m_eventState;
295 };
296
DisplayFactory(EventState & eventState)297 DisplayFactory::DisplayFactory(EventState &eventState)
298 : NativeDisplayFactory("x11", "Native X11 Display", Display::CAPABILITIES, EGL_PLATFORM_X11_SCREEN_EXT,
299 "EGL_EXT_platform_x11")
300 , m_eventState(eventState)
301 {
302 m_nativeWindowRegistry.registerFactory(new WindowFactory());
303 // m_nativePixmapRegistry.registerFactory(new PixmapFactory());
304 }
305
createDisplay(const eglw::EGLAttrib * attribList) const306 NativeDisplay *DisplayFactory::createDisplay(const eglw::EGLAttrib *attribList) const
307 {
308 DE_UNREF(attribList);
309
310 //! \todo [2014-03-18 lauri] Somehow make the display configurable from command line
311 MovePtr<XlibDisplay> x11Display(new XlibDisplay(m_eventState, nullptr));
312
313 return new Display(x11Display);
314 }
315
createDisplayFactory(EventState & eventState)316 NativeDisplayFactory *createDisplayFactory(EventState &eventState)
317 {
318 return new DisplayFactory(eventState);
319 }
320
321 } // namespace egl
322 } // namespace x11
323 } // namespace lnx
324 } // namespace tcu
325