1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // To use runtime linking, uncomment the #define OPENGL_ES_IMPORT_FUNCTIONS, 6 // and pass libGLESxx.so libEGLxx.so in the command line as input 7 // parameters. 8 // Otherwise, comment out #define OPENGL_ES_IMPORT_FUNCTIONS and pass no 9 // parameters in the command line. 10 11 #include <stdio.h> 12 13 #include <EGL/egl.h> 14 #include <GLES2/gl2.h> 15 16 #include <X11/Xlib.h> 17 #include <X11/Xutil.h> 18 19 #define OPENGL_ES_IMPORT_FUNCTIONS 20 21 #ifdef OPENGL_ES_IMPORT_FUNCTIONS 22 23 #include <dlfcn.h> 24 25 EGLDisplay (*FP_eglGetDisplay)(NativeDisplayType display) = NULL; 26 EGLBoolean (*FP_eglInitialize)(EGLDisplay dpy, 27 EGLint* major, 28 EGLint* minor) = NULL; 29 EGLBoolean (*FP_eglGetConfigs)(EGLDisplay dpy, 30 EGLConfig* configs, 31 EGLint config_size, 32 EGLint* num_config) = NULL; 33 EGLBoolean (*FP_eglChooseConfig)(EGLDisplay dpy, 34 const EGLint* attrib_list, 35 EGLConfig* configs, 36 EGLint config_size, 37 EGLint* num_config) = NULL; 38 EGLContext (*FP_eglCreateContext)(EGLDisplay dpy, 39 EGLConfig config, 40 EGLContext share_list, 41 const EGLint* attrib_list) = NULL; 42 EGLBoolean (*FP_eglGetConfigAttrib)(EGLDisplay dpy, 43 EGLConfig config, 44 EGLint attribute, 45 EGLint* value) = NULL; 46 EGLSurface (*FP_eglCreateWindowSurface)(EGLDisplay dpy, 47 EGLConfig config, 48 NativeWindowType window, 49 const EGLint* attrib_list) = NULL; 50 EGLBoolean (*FP_eglMakeCurrent)(EGLDisplay dpy, 51 EGLSurface draw, 52 EGLSurface read, 53 EGLContext ctx) = NULL; 54 EGLBoolean (*FP_eglDestroyContext)(EGLDisplay dpy, EGLContext ctx) = NULL; 55 EGLBoolean (*FP_eglDestroySurface)(EGLDisplay dpy, EGLSurface surface) = NULL; 56 EGLBoolean (*FP_eglTerminate)(EGLDisplay dpy) = NULL; 57 const char* (*FP_eglQueryString)(EGLDisplay dpy, EGLint name) = NULL; 58 const GLubyte* (*FP_glGetString)(GLenum name) = NULL; 59 60 #define eglGetDisplay FP_eglGetDisplay 61 #define eglInitialize FP_eglInitialize 62 #define eglGetConfigs FP_eglGetConfigs 63 #define eglChooseConfig FP_eglChooseConfig 64 #define eglCreateContext FP_eglCreateContext 65 #define eglGetConfigAttrib FP_eglGetConfigAttrib 66 #define eglCreateWindowSurface FP_eglCreateWindowSurface 67 #define eglMakeCurrent FP_eglMakeCurrent 68 #define eglDestroyContext FP_eglDestroyContext 69 #define eglDestroySurface FP_eglDestroySurface 70 #define eglTerminate FP_eglTerminate 71 #define eglQueryString FP_eglQueryString 72 #define glGetString FP_glGetString 73 74 typedef EGLDisplay (*FT_eglGetDisplay)(NativeDisplayType); 75 typedef EGLBoolean (*FT_eglInitialize)(EGLDisplay, EGLint*, EGLint*); 76 typedef EGLBoolean (*FT_eglGetConfigs)(EGLDisplay, EGLConfig*, 77 EGLint, EGLint*); 78 typedef EGLBoolean (*FT_eglChooseConfig)(EGLDisplay, const EGLint*, 79 EGLConfig*, EGLint, EGLint*); 80 typedef EGLContext (*FT_eglCreateContext)(EGLDisplay, EGLConfig, 81 EGLContext, const EGLint*); 82 typedef EGLBoolean (*FT_eglGetConfigAttrib)(EGLDisplay, EGLConfig, 83 EGLint, EGLint*); 84 typedef EGLSurface (*FT_eglCreateWindowSurface)(EGLDisplay, EGLConfig, 85 NativeWindowType, 86 const EGLint*); 87 typedef EGLBoolean (*FT_eglMakeCurrent)(EGLDisplay, EGLSurface, 88 EGLSurface, EGLContext); 89 typedef EGLBoolean (*FT_eglDestroyContext)(EGLDisplay, EGLContext); 90 typedef EGLBoolean (*FT_eglDestroySurface)(EGLDisplay, EGLSurface); 91 typedef EGLBoolean (*FT_eglTerminate)(EGLDisplay); 92 typedef const char* (*FT_eglQueryString)(EGLDisplay, EGLint); 93 typedef const GLubyte* (*FT_glGetString)(GLenum); 94 95 bool LoadDLFunction(void** func_handle, 96 const char* func_name, 97 void* dl_handle) { 98 *func_handle = dlsym(dl_handle, func_name); 99 if (*func_handle == NULL) { 100 printf("ERROR: fail to load %s\n", func_name); 101 return false; 102 } 103 return true; 104 } 105 106 bool EntryImportGL(char* lib_gles, char* lib_egl, 107 void** handle_gles, void** handle_egl) { 108 *handle_gles = dlopen(lib_gles, RTLD_LAZY); 109 if (*handle_gles == NULL) { 110 printf("ERROR: %s\n", dlerror()); 111 return false; 112 } 113 *handle_egl = dlopen(lib_egl, RTLD_LAZY); 114 if (*handle_egl == NULL) { 115 printf("ERROR: %s\n", dlerror()); 116 return false; 117 } 118 119 bool rt = true; 120 void* tmp; 121 rt &= LoadDLFunction(&tmp, "eglGetDisplay", *handle_egl); 122 FP_eglGetDisplay = reinterpret_cast<FT_eglGetDisplay>(tmp); 123 rt &= LoadDLFunction(&tmp, "eglInitialize", *handle_egl); 124 FP_eglInitialize = reinterpret_cast<FT_eglInitialize>(tmp); 125 rt &= LoadDLFunction(&tmp, "eglGetConfigs", *handle_egl); 126 FP_eglGetConfigs = reinterpret_cast<FT_eglGetConfigs>(tmp); 127 rt &= LoadDLFunction(&tmp, "eglChooseConfig", *handle_egl); 128 FP_eglChooseConfig = reinterpret_cast<FT_eglChooseConfig>(tmp); 129 rt &= LoadDLFunction(&tmp, "eglCreateContext", *handle_egl); 130 FP_eglCreateContext = reinterpret_cast<FT_eglCreateContext>(tmp); 131 rt &= LoadDLFunction(&tmp, "eglGetConfigAttrib", *handle_egl); 132 FP_eglGetConfigAttrib = reinterpret_cast<FT_eglGetConfigAttrib>(tmp); 133 rt &= LoadDLFunction(&tmp, "eglCreateWindowSurface", *handle_egl); 134 FP_eglCreateWindowSurface = reinterpret_cast<FT_eglCreateWindowSurface>(tmp); 135 rt &= LoadDLFunction(&tmp, "eglMakeCurrent", *handle_egl); 136 FP_eglMakeCurrent = reinterpret_cast<FT_eglMakeCurrent>(tmp); 137 rt &= LoadDLFunction(&tmp, "eglDestroyContext", *handle_egl); 138 FP_eglDestroyContext = reinterpret_cast<FT_eglDestroyContext>(tmp); 139 rt &= LoadDLFunction(&tmp, "eglDestroySurface", *handle_egl); 140 FP_eglDestroySurface = reinterpret_cast<FT_eglDestroySurface>(tmp); 141 rt &= LoadDLFunction(&tmp, "eglTerminate", *handle_egl); 142 FP_eglTerminate = reinterpret_cast<FT_eglTerminate>(tmp); 143 rt &= LoadDLFunction(&tmp, "eglQueryString", *handle_egl); 144 FP_eglQueryString = reinterpret_cast<FT_eglQueryString>(tmp); 145 rt &= LoadDLFunction(&tmp, "glGetString", *handle_gles); 146 FP_glGetString = reinterpret_cast<FT_glGetString>(tmp); 147 return rt; 148 } 149 150 void ExitImportGL(void* handle_gles, void* handle_egl) { 151 if (handle_gles != NULL) 152 dlclose(handle_gles); 153 if (handle_egl != NULL) 154 dlclose(handle_egl); 155 } 156 157 #endif // OPENGL_ES_IMPORT_FUNCTIONS 158 159 bool InitGraphics(Display** display, 160 EGLDisplay* egl_display, 161 EGLContext* egl_context, 162 EGLSurface* egl_surface) { 163 const int kWindowWidth = 100; 164 const int kWindowHeight = 100; 165 const EGLint config_attribs[] = { 166 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 167 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 168 EGL_NONE 169 }; 170 const EGLint context_attribs[] = { 171 EGL_CONTEXT_CLIENT_VERSION, 2, 172 EGL_NONE 173 }; 174 175 // XWindow init. 176 *display = XOpenDisplay(NULL); 177 if (*display == NULL) { 178 printf("ERROR: XOpenDisplay failed\n"); 179 return false; 180 } 181 182 int screen = XDefaultScreen(*display); 183 Window window = XCreateSimpleWindow(*display, RootWindow(*display, screen), 184 0, 0, kWindowWidth, kWindowHeight, 185 0, 0, WhitePixel(*display, screen)); 186 XMapWindow(*display, window); 187 XSync(*display, True); 188 189 // EGL init. 190 *egl_display = eglGetDisplay((EGLNativeDisplayType)*display); 191 EGLint no_major, no_minor; 192 EGLBoolean rt_code = eglInitialize(*egl_display, &no_major, &no_minor); 193 if (rt_code == EGL_FALSE) { 194 printf("ERROR: eglInitialize failed\n"); 195 return false; 196 } 197 // Print out version info. 198 printf("EGL_VERSION = %d.%d\n", 199 static_cast<int>(no_major), 200 static_cast<int>(no_minor)); 201 // Config. 202 EGLint num_configs; 203 EGLConfig egl_config; 204 rt_code = eglChooseConfig(*egl_display, config_attribs, 205 &egl_config, 1, &num_configs); 206 if (rt_code == EGL_FALSE || num_configs != 1) { 207 printf("ERROR: eglChooseConfig failed\n"); 208 return false; 209 } 210 // Surface. 211 *egl_surface = eglCreateWindowSurface(*egl_display, egl_config, 212 (NativeWindowType)window, NULL); 213 if (*egl_surface == EGL_NO_SURFACE) { 214 printf("ERROR: eglCreateWindowSurface failed\n"); 215 return false; 216 } 217 // Context. 218 *egl_context = eglCreateContext(*egl_display, egl_config, EGL_NO_CONTEXT, 219 context_attribs); 220 if (*egl_context == EGL_NO_CONTEXT) { 221 printf("ERROR: eglCreateContext failed\n"); 222 return false; 223 } 224 // Make current. 225 rt_code = eglMakeCurrent(*egl_display, *egl_surface, 226 *egl_surface, *egl_context); 227 if (rt_code == EGL_FALSE) { 228 printf("ERROR: eglMakeCurrent failed\n"); 229 return false; 230 } 231 return true; 232 } 233 234 void ExitGraphics(EGLDisplay egl_display, 235 EGLContext egl_context, 236 EGLSurface egl_surface) { 237 if (egl_display != EGL_NO_DISPLAY) { 238 eglMakeCurrent(egl_display, NULL, NULL, NULL); 239 if (egl_context != EGL_NO_CONTEXT) 240 eglDestroyContext(egl_display, egl_context); 241 if (egl_surface != EGL_NO_SURFACE) 242 eglDestroySurface(egl_display, egl_surface); 243 eglTerminate(egl_display); 244 } 245 } 246 247 bool GetGLESVersion() { 248 const GLubyte* version_string = glGetString(GL_VERSION); 249 if (version_string == NULL) { 250 printf("ERROR: glGetString(GL_VERSION) failed\n"); 251 return false; 252 } 253 printf("GLES_VERSION = %s\n", version_string); 254 return true; 255 } 256 257 bool GetGLESExtensions() { 258 const GLubyte* ext_string = glGetString(GL_EXTENSIONS); 259 if (ext_string == NULL) { 260 printf("ERROR: glGetString(GL_EXTENSIONS) failed\n"); 261 return false; 262 } 263 printf("GLES_EXTENSIONS = %s\n", ext_string); 264 return true; 265 } 266 267 bool GetEGLExtensions(EGLDisplay egl_display) { 268 const char* ext_string = eglQueryString(egl_display, EGL_EXTENSIONS); 269 if (ext_string == NULL) { 270 printf("ERROR: eglQueryString(EGL_EXTENSIONS) failed\n"); 271 return false; 272 } 273 printf("EGL_EXTENSIONS = %s\n", ext_string); 274 return true; 275 } 276 277 bool GetXExtensions(Display* display) { 278 int ext_num; 279 char** ext_list = XListExtensions(display, &ext_num); 280 printf("X_EXTENSIONS ="); 281 for (int i = 0; i < ext_num; ++i) { 282 printf(" %s", ext_list[i]); 283 } 284 printf("\n"); 285 XFreeExtensionList(ext_list); 286 return true; 287 } 288 289 int main(int argc, char* argv[]) { 290 // Initialize graphics. 291 Display* display; 292 EGLDisplay egl_display = EGL_NO_DISPLAY; 293 EGLContext egl_context = EGL_NO_CONTEXT; 294 EGLSurface egl_surface = EGL_NO_SURFACE; 295 296 bool rt_code = true; 297 298 #ifdef OPENGL_ES_IMPORT_FUNCTIONS 299 if (argc != 3) { 300 printf("ERROR: Usage: gles_APICheck libGLESxx.so libEGLxx.so\n"); 301 return 0; 302 } 303 void* handle_gles = NULL; 304 void* handle_egl = NULL; 305 rt_code = EntryImportGL(argv[1], argv[2], &handle_gles, &handle_egl); 306 #endif // OPENGL_ES_IMPORT_FUNCTIONS 307 308 // EGL version is printed out in InitGraphics 309 if (rt_code) 310 rt_code = InitGraphics(&display, &egl_display, 311 &egl_context, &egl_surface); 312 313 // Get GLES version. 314 if (rt_code) 315 rt_code = GetGLESVersion(); 316 317 // Get GLES extentions. 318 if (rt_code) 319 rt_code = GetGLESExtensions(); 320 321 // Get EGL extentions. 322 if (rt_code) 323 rt_code = GetEGLExtensions(egl_display); 324 325 // Get X11 extensions. 326 if (rt_code) 327 rt_code = GetXExtensions(display); 328 329 ExitGraphics(egl_display, egl_context, egl_surface); 330 #ifdef OPENGL_ES_IMPORT_FUNCTIONS 331 ExitImportGL(handle_gles, handle_egl); 332 #endif // OPENGL_ES_IMPORT_FUNCTIONS 333 printf("SUCCEED: run to the end\n"); 334 return 0; 335 } 336 337