Home | History | Annotate | Download | only in src
      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