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 Legacy EGL utilities
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuEgl.hpp"
25 #include "egluStrUtil.hpp"
26 #include "egluConfigInfo.hpp"
27 #include "deString.h"
28
29 #include <sstream>
30
31 using std::vector;
32 using std::string;
33
34 namespace tcu
35 {
36 namespace egl
37 {
38
Display(EGLDisplay display,EGLint majorVersion,EGLint minorVersion)39 Display::Display (EGLDisplay display, EGLint majorVersion, EGLint minorVersion)
40 : m_display(display)
41 {
42 m_version[0] = majorVersion;
43 m_version[1] = minorVersion;
44 }
45
Display(EGLNativeDisplayType nativeDisplay)46 Display::Display (EGLNativeDisplayType nativeDisplay)
47 : m_display (EGL_NO_DISPLAY)
48 {
49 m_display = eglGetDisplay(nativeDisplay);
50 TCU_CHECK_EGL();
51 TCU_CHECK(m_display != EGL_NO_DISPLAY);
52
53 TCU_CHECK_EGL_CALL(eglInitialize(m_display, &m_version[0], &m_version[1]));
54 }
55
~Display()56 Display::~Display ()
57 {
58 if (m_display)
59 eglTerminate(m_display);
60 }
61
getConfigs(std::vector<EGLConfig> & configs) const62 void Display::getConfigs (std::vector<EGLConfig>& configs) const
63 {
64 EGLint numConfigs = 0;
65 TCU_CHECK_EGL_CALL(eglGetConfigs(m_display, DE_NULL, 0, &numConfigs));
66 configs.resize(numConfigs);
67 if (numConfigs > 0)
68 TCU_CHECK_EGL_CALL(eglGetConfigs(m_display, &configs[0], (EGLint)configs.size(), &numConfigs));
69 }
70
chooseConfig(const EGLint * attribList,std::vector<EGLConfig> & configs) const71 void Display::chooseConfig (const EGLint* attribList, std::vector<EGLConfig>& configs) const
72 {
73 EGLint numConfigs = 0;
74 TCU_CHECK_EGL_CALL(eglChooseConfig(m_display, attribList, DE_NULL, 0, &numConfigs));
75 configs.resize(numConfigs);
76 if (numConfigs > 0)
77 TCU_CHECK_EGL_CALL(eglChooseConfig(m_display, attribList, &configs[0], (EGLint)configs.size(), &numConfigs));
78 }
79
getConfigAttrib(EGLConfig config,EGLint attribute) const80 EGLint Display::getConfigAttrib (EGLConfig config, EGLint attribute) const
81 {
82 EGLint value = 0;
83 TCU_CHECK_EGL_CALL(eglGetConfigAttrib(m_display, config, attribute, &value));
84 return value;
85 }
86
describeConfig(EGLConfig config,tcu::PixelFormat & pf) const87 void Display::describeConfig (EGLConfig config, tcu::PixelFormat& pf) const
88 {
89 eglGetConfigAttrib(m_display, config, EGL_RED_SIZE, &pf.redBits);
90 eglGetConfigAttrib(m_display, config, EGL_GREEN_SIZE, &pf.greenBits);
91 eglGetConfigAttrib(m_display, config, EGL_BLUE_SIZE, &pf.blueBits);
92 eglGetConfigAttrib(m_display, config, EGL_ALPHA_SIZE, &pf.alphaBits);
93 TCU_CHECK_EGL();
94 }
95
describeConfig(EGLConfig config,eglu::ConfigInfo & info) const96 void Display::describeConfig (EGLConfig config, eglu::ConfigInfo& info) const
97 {
98 eglu::queryConfigInfo(m_display, config, &info);
99 }
100
split(vector<string> & dst,const string & src)101 static void split (vector<string>& dst, const string& src)
102 {
103 size_t start = 0;
104 size_t end = string::npos;
105
106 while ((end = src.find(' ', start)) != string::npos)
107 {
108 dst.push_back(src.substr(start, end-start));
109 start = end+1;
110 }
111
112 if (start < end)
113 dst.push_back(src.substr(start, end-start));
114 }
115
getExtensions(vector<string> & dst) const116 void Display::getExtensions (vector<string>& dst) const
117 {
118 const char* extStr = eglQueryString(m_display, EGL_EXTENSIONS);
119 TCU_CHECK_EGL_MSG("eglQueryString(EGL_EXTENSIONS");
120 TCU_CHECK(extStr);
121 split(dst, extStr);
122 }
123
getString(EGLint name,std::string & dst) const124 void Display::getString (EGLint name, std::string& dst) const
125 {
126 const char* retStr = eglQueryString(m_display, name);
127 TCU_CHECK_EGL_MSG("eglQueryString()");
128 TCU_CHECK(retStr);
129 dst = retStr;
130 }
131
getAttribute(EGLint attribute) const132 EGLint Surface::getAttribute (EGLint attribute) const
133 {
134 EGLint value;
135 TCU_CHECK_EGL_CALL(eglQuerySurface(m_display.getEGLDisplay(), m_surface, attribute, &value));
136 return value;
137 }
138
setAttribute(EGLint attribute,EGLint value)139 void Surface::setAttribute (EGLint attribute, EGLint value)
140 {
141 TCU_CHECK_EGL_CALL(eglSurfaceAttrib(m_display.getEGLDisplay(), m_surface, attribute, value));
142 }
143
getWidth(void) const144 int Surface::getWidth (void) const
145 {
146 return getAttribute(EGL_WIDTH);
147 }
148
getHeight(void) const149 int Surface::getHeight (void) const
150 {
151 return getAttribute(EGL_HEIGHT);
152 }
153
getSize(int & x,int & y) const154 void Surface::getSize (int& x, int& y) const
155 {
156 x = getWidth();
157 y = getHeight();
158 }
159
WindowSurface(Display & display,EGLSurface windowSurface)160 WindowSurface::WindowSurface (Display& display, EGLSurface windowSurface)
161 : Surface (display)
162 {
163 m_surface = windowSurface;
164 }
165
WindowSurface(Display & display,EGLConfig config,EGLNativeWindowType nativeWindow,const EGLint * attribList)166 WindowSurface::WindowSurface (Display& display, EGLConfig config, EGLNativeWindowType nativeWindow, const EGLint* attribList)
167 : Surface (display)
168 {
169 m_surface = eglCreateWindowSurface(display.getEGLDisplay(), config, nativeWindow, attribList);
170 TCU_CHECK_EGL();
171 TCU_CHECK(m_surface != EGL_NO_SURFACE);
172 }
173
~WindowSurface(void)174 WindowSurface::~WindowSurface (void)
175 {
176 eglDestroySurface(m_display.getEGLDisplay(), m_surface);
177 m_surface = EGL_NO_SURFACE;
178 }
179
swapBuffers(void)180 void WindowSurface::swapBuffers (void)
181 {
182 TCU_CHECK_EGL_CALL(eglSwapBuffers(m_display.getEGLDisplay(), m_surface));
183 }
184
PixmapSurface(Display & display,EGLSurface surface)185 PixmapSurface::PixmapSurface (Display& display, EGLSurface surface)
186 : Surface (display)
187 {
188 m_surface = surface;
189 }
190
PixmapSurface(Display & display,EGLConfig config,EGLNativePixmapType nativePixmap,const EGLint * attribList)191 PixmapSurface::PixmapSurface (Display& display, EGLConfig config, EGLNativePixmapType nativePixmap, const EGLint* attribList)
192 : Surface (display)
193 {
194 m_surface = eglCreatePixmapSurface(m_display.getEGLDisplay(), config, nativePixmap, attribList);
195 TCU_CHECK_EGL();
196 TCU_CHECK(m_surface != EGL_NO_SURFACE);
197 }
198
~PixmapSurface(void)199 PixmapSurface::~PixmapSurface (void)
200 {
201 eglDestroySurface(m_display.getEGLDisplay(), m_surface);
202 m_surface = EGL_NO_SURFACE;
203 }
204
205 #if 0 // \todo [mika] Fix borken
206 void PixmapSurface::copyBuffers (void)
207 {
208 TCU_CHECK_EGL_CALL(eglCopyBuffers(m_display.getEGLDisplay(), m_surface, m_nativePixmap));
209 }
210 #endif
211
PbufferSurface(Display & display,EGLConfig config,const EGLint * attribList)212 PbufferSurface::PbufferSurface (Display& display, EGLConfig config, const EGLint* attribList)
213 : Surface(display)
214 {
215 m_surface = eglCreatePbufferSurface(m_display.getEGLDisplay(), config, attribList);
216 TCU_CHECK_EGL();
217 TCU_CHECK(m_surface != EGL_NO_SURFACE);
218 }
219
~PbufferSurface(void)220 PbufferSurface::~PbufferSurface (void)
221 {
222 eglDestroySurface(m_display.getEGLDisplay(), m_surface);
223 m_surface = EGL_NO_SURFACE;
224 }
225
Context(const Display & display,EGLConfig config,const EGLint * attribList,EGLenum api)226 Context::Context (const Display& display, EGLConfig config, const EGLint* attribList, EGLenum api)
227 : m_display(display)
228 , m_config(config)
229 , m_api(api)
230 , m_context(EGL_NO_CONTEXT)
231 {
232 TCU_CHECK_EGL_CALL(eglBindAPI(m_api));
233 m_context = eglCreateContext(m_display.getEGLDisplay(), config, EGL_NO_CONTEXT, attribList);
234 TCU_CHECK_EGL();
235 TCU_CHECK(m_context);
236 }
237
~Context(void)238 Context::~Context (void)
239 {
240 if (m_context)
241 {
242 /* If this is current surface, remove binding. */
243 EGLContext curContext = EGL_NO_CONTEXT;
244 eglBindAPI(m_api);
245 curContext = eglGetCurrentContext();
246 if (curContext == m_context)
247 eglMakeCurrent(m_display.getEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
248
249 eglDestroyContext(m_display.getEGLDisplay(), m_context);
250 }
251 }
252
makeCurrent(const Surface & draw,const Surface & read)253 void Context::makeCurrent (const Surface& draw, const Surface& read)
254 {
255 TCU_CHECK_EGL_CALL(eglMakeCurrent(m_display.getEGLDisplay(), draw.getEGLSurface(), read.getEGLSurface(), m_context));
256 }
257
258 } // egl
259 } // tcu
260