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 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 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 56 Display::~Display () 57 { 58 if (m_display) 59 eglTerminate(m_display); 60 } 61 62 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 71 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 80 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 87 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 96 void Display::describeConfig (EGLConfig config, eglu::ConfigInfo& info) const 97 { 98 eglu::queryConfigInfo(m_display, config, &info); 99 } 100 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 116 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 124 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 132 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 139 void Surface::setAttribute (EGLint attribute, EGLint value) 140 { 141 TCU_CHECK_EGL_CALL(eglSurfaceAttrib(m_display.getEGLDisplay(), m_surface, attribute, value)); 142 } 143 144 int Surface::getWidth (void) const 145 { 146 return getAttribute(EGL_WIDTH); 147 } 148 149 int Surface::getHeight (void) const 150 { 151 return getAttribute(EGL_HEIGHT); 152 } 153 154 void Surface::getSize (int& x, int& y) const 155 { 156 x = getWidth(); 157 y = getHeight(); 158 } 159 160 WindowSurface::WindowSurface (Display& display, EGLSurface windowSurface) 161 : Surface (display) 162 { 163 m_surface = windowSurface; 164 } 165 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 174 WindowSurface::~WindowSurface (void) 175 { 176 eglDestroySurface(m_display.getEGLDisplay(), m_surface); 177 m_surface = EGL_NO_SURFACE; 178 } 179 180 void WindowSurface::swapBuffers (void) 181 { 182 TCU_CHECK_EGL_CALL(eglSwapBuffers(m_display.getEGLDisplay(), m_surface)); 183 } 184 185 PixmapSurface::PixmapSurface (Display& display, EGLSurface surface) 186 : Surface (display) 187 { 188 m_surface = surface; 189 } 190 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 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 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 220 PbufferSurface::~PbufferSurface (void) 221 { 222 eglDestroySurface(m_display.getEGLDisplay(), m_surface); 223 m_surface = EGL_NO_SURFACE; 224 } 225 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 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 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