1 /************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * Copyright 2009-2010 Chia-I Wu <olvaffe (at) gmail.com> 5 * Copyright 2010-2011 LunarG, Inc. 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sub license, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial portions 18 * of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 * 28 **************************************************************************/ 29 30 31 /** 32 * Small/misc EGL functions 33 */ 34 35 36 #include <assert.h> 37 #include <string.h> 38 #include "eglcurrent.h" 39 #include "eglmisc.h" 40 #include "egldisplay.h" 41 #include "egldriver.h" 42 #include "eglstring.h" 43 44 45 /** 46 * Copy the extension into the string and update the string pointer. 47 */ 48 static EGLint 49 _eglAppendExtension(char **str, const char *ext) 50 { 51 char *s = *str; 52 size_t len = strlen(ext); 53 54 if (s) { 55 memcpy(s, ext, len); 56 s[len++] = ' '; 57 s[len] = '\0'; 58 59 *str += len; 60 } 61 else { 62 len++; 63 } 64 65 return (EGLint) len; 66 } 67 68 69 /** 70 * Examine the individual extension enable/disable flags and recompute 71 * the driver's Extensions string. 72 */ 73 static void 74 _eglUpdateExtensionsString(_EGLDisplay *dpy) 75 { 76 #define _EGL_CHECK_EXTENSION(ext) \ 77 do { \ 78 if (dpy->Extensions.ext) { \ 79 _eglAppendExtension(&exts, "EGL_" #ext); \ 80 assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \ 81 } \ 82 } while (0) 83 84 char *exts = dpy->ExtensionsString; 85 86 if (exts[0]) 87 return; 88 89 _EGL_CHECK_EXTENSION(MESA_screen_surface); 90 _EGL_CHECK_EXTENSION(MESA_copy_context); 91 _EGL_CHECK_EXTENSION(MESA_drm_display); 92 _EGL_CHECK_EXTENSION(MESA_drm_image); 93 94 _EGL_CHECK_EXTENSION(WL_bind_wayland_display); 95 96 _EGL_CHECK_EXTENSION(KHR_image_base); 97 _EGL_CHECK_EXTENSION(KHR_image_pixmap); 98 if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap) 99 _eglAppendExtension(&exts, "EGL_KHR_image"); 100 101 _EGL_CHECK_EXTENSION(KHR_vg_parent_image); 102 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image); 103 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image); 104 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image); 105 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); 106 107 _EGL_CHECK_EXTENSION(KHR_reusable_sync); 108 _EGL_CHECK_EXTENSION(KHR_fence_sync); 109 110 _EGL_CHECK_EXTENSION(KHR_surfaceless_context); 111 _EGL_CHECK_EXTENSION(KHR_create_context); 112 113 _EGL_CHECK_EXTENSION(NOK_swap_region); 114 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap); 115 116 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer); 117 118 _EGL_CHECK_EXTENSION(EXT_create_context_robustness); 119 120 _EGL_CHECK_EXTENSION(NV_post_sub_buffer); 121 #undef _EGL_CHECK_EXTENSION 122 } 123 124 125 static void 126 _eglUpdateAPIsString(_EGLDisplay *dpy) 127 { 128 char *apis = dpy->ClientAPIsString; 129 130 if (apis[0] || !dpy->ClientAPIs) 131 return; 132 133 if (dpy->ClientAPIs & EGL_OPENGL_BIT) 134 strcat(apis, "OpenGL "); 135 136 if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT) 137 strcat(apis, "OpenGL_ES "); 138 139 if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT) 140 strcat(apis, "OpenGL_ES2 "); 141 142 if (dpy->ClientAPIs & EGL_OPENVG_BIT) 143 strcat(apis, "OpenVG "); 144 145 assert(strlen(apis) < sizeof(dpy->ClientAPIsString)); 146 } 147 148 149 const char * 150 _eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name) 151 { 152 (void) drv; 153 154 switch (name) { 155 case EGL_VENDOR: 156 return _EGL_VENDOR_STRING; 157 case EGL_VERSION: 158 _eglsnprintf(dpy->VersionString, sizeof(dpy->VersionString), 159 "%d.%d (%s)", dpy->VersionMajor, dpy->VersionMinor, 160 dpy->Driver->Name); 161 return dpy->VersionString; 162 case EGL_EXTENSIONS: 163 _eglUpdateExtensionsString(dpy); 164 return dpy->ExtensionsString; 165 case EGL_CLIENT_APIS: 166 _eglUpdateAPIsString(dpy); 167 return dpy->ClientAPIsString; 168 default: 169 _eglError(EGL_BAD_PARAMETER, "eglQueryString"); 170 return NULL; 171 } 172 } 173