1 // Copyright Danny Arends 2020. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See: http://www.boost.org/LICENSE_1_0.txt) 4 5 module bindbc.gles.egl; 6 7 import bindbc.loader; 8 public import bindbc.gles.config, 9 bindbc.gles.egltypes; 10 11 enum EGLNativeDisplayType EGL_DEFAULT_DISPLAY = cast(EGLNativeDisplayType)0; 12 enum EGLContext EGL_NO_CONTEXT = null; 13 enum EGLDisplay EGL_NO_DISPLAY = null; 14 struct ANativeWindow; 15 struct egl_native_pixmap_t; 16 17 alias EGLNativeWindowType = ANativeWindow*; 18 alias EGLNativePixmapType = egl_native_pixmap_t*; 19 alias EGLNativeDisplayType = void*; 20 21 private { 22 SharedLib lib; 23 EGLSupport contextVersion = EGLSupport.noContext; 24 EGLSupport loadedVersion = EGLSupport.noContext; 25 EGLint major; 26 EGLint minor; 27 } 28 29 @nogc nothrow: 30 31 void unloadEGL() 32 { 33 if(lib != invalidHandle) { 34 lib.unload(); 35 contextVersion = loadedVersion = EGLSupport.noContext; 36 } 37 } 38 39 EGLSupport loadEGL() 40 { 41 version(Windows) { 42 const(char)[][1] libNames = ["libegl.dll"]; 43 } 44 else version(Posix) { 45 const(char)[][2] libNames = [ 46 "libEGL.so.1", 47 "libEGL.so" 48 ]; 49 } 50 else static assert(0, "bindbc-gles is not yet supported on this platform"); 51 52 EGLSupport ret; 53 foreach(name; libNames) { 54 ret = loadEGL(name.ptr); 55 if(ret != EGLSupport.noLibrary) break; 56 } 57 return ret; 58 } 59 60 EGLSupport loadEGL(const(char)* libName) 61 { 62 // If the library isn't yet loaded, load it now. 63 if(lib == invalidHandle) { 64 lib = load(libName); 65 if(lib == invalidHandle) { 66 return EGLSupport.noLibrary; 67 } 68 } 69 if(!lib.loadEGL()) return EGLSupport.badLibrary; 70 return loadedVersion; 71 } 72 73 extern(System) @nogc nothrow { 74 // V1.0 75 alias peglGetError = void function( ); 76 alias peglGetDisplay = EGLDisplay function( EGLNativeDisplayType ); 77 alias peglInitialize = EGLBoolean function( EGLDisplay, EGLint*, EGLint* ); 78 alias peglTerminate = EGLBoolean function( EGLDisplay ); 79 alias peglQueryString = const( char )* function( EGLDisplay, EGLint ); 80 alias peglGetConfigs = EGLBoolean function( EGLDisplay, EGLConfig*, EGLint, EGLint* ); 81 alias peglChooseConfig = EGLBoolean function( EGLDisplay, const( EGLint )*, EGLConfig*, EGLint, EGLint* ); 82 alias peglGetConfigAttrib = EGLBoolean function( EGLDisplay, EGLConfig, EGLint, EGLint* ); 83 alias peglCreateWindowSurface = EGLSurface function( EGLDisplay, EGLConfig, EGLNativeWindowType, const( EGLint )* ); 84 alias peglCreatePbufferSurface = EGLSurface function( EGLDisplay, EGLConfig, const( EGLint )* ); 85 alias peglCreatePixmapSurface = EGLSurface function( EGLDisplay, EGLConfig, EGLNativePixmapType, const( EGLint )* ); 86 alias peglDestroySurface = EGLBoolean function( EGLDisplay, EGLSurface ); 87 alias peglQuerySurface = EGLBoolean function( EGLDisplay, EGLSurface, EGLint, EGLint* ); 88 alias peglCreateContext = EGLContext function( EGLDisplay, EGLConfig, EGLContext, const( EGLint )* ); 89 alias peglDestroyContext = EGLBoolean function( EGLDisplay, EGLContext ); 90 alias peglMakeCurrent = EGLBoolean function( EGLDisplay, EGLSurface, EGLSurface, EGLContext ); 91 alias peglGetCurrentSurface = EGLSurface function( EGLint ); 92 alias peglGetCurrentDisplay = EGLDisplay function( ); 93 alias peglQueryContext = EGLBoolean function( EGLDisplay, EGLContext, EGLint, EGLint* ); 94 alias peglWaitGL = EGLBoolean function( ); 95 alias peglWaitNative = EGLBoolean function( EGLint ); 96 alias peglSwapBuffers = EGLBoolean function( EGLDisplay, EGLSurface ); 97 alias peglCopyBuffers = EGLBoolean function( EGLDisplay, EGLSurface, EGLNativePixmapType ); 98 /* This is a generic function pointer type, whose name indicates it must be cast to the proper type *and calling convention* before use. */ 99 alias __eglMustCastToProperFunctionPointerType = void function( ); 100 /* Now, define eglGetProcAddress using the generic function ptr. type */ 101 alias peglGetProcAddress = __eglMustCastToProperFunctionPointerType function( const( char )* ); 102 103 //V1.1 104 alias peglSurfaceAttrib = EGLBoolean function( EGLDisplay, EGLSurface, EGLint, EGLint ); 105 alias peglBindTexImage = EGLBoolean function( EGLDisplay, EGLSurface, EGLint ); 106 alias peglReleaseTexImage = EGLBoolean function( EGLDisplay, EGLSurface, EGLint ); 107 alias peglSwapInterval = EGLBoolean function( EGLDisplay, EGLint ); 108 109 //V1.2 110 alias peglBindAPI = EGLBoolean function( EGLenum ); 111 alias peglQueryAPI = EGLenum function( ); 112 alias peglWaitClient = EGLBoolean function( ); 113 alias peglReleaseThread = EGLBoolean function( ); 114 alias peglCreatePbufferFromClientBuffer = EGLSurface function( EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const( EGLint )* ); 115 116 //V1.4 117 alias peglGetCurrentContext = EGLContext function( ); 118 119 //V1.5 120 alias peglCreateSync = EGLSync function ( EGLDisplay, EGLenum, const( EGLAttrib )* ); 121 alias peglDestroySync = EGLBoolean function ( EGLDisplay, EGLSync ); 122 alias peglClientWaitSync = EGLint function ( EGLDisplay, EGLSync, EGLint, EGLTime ); 123 alias peglGetSyncAttrib = EGLBoolean function ( EGLDisplay, EGLSync, EGLint, EGLAttrib* ); 124 alias peglGetPlatformDisplay = EGLDisplay function ( EGLenum, void*, const( EGLAttrib )* ); 125 alias peglCreatePlatformWindowSurface = EGLSurface function ( EGLDisplay, EGLConfig, void*, const( EGLAttrib )* ); 126 alias peglCreatePlatformPixmapSurface = EGLSurface function ( EGLDisplay, EGLConfig, void*, const( EGLAttrib )* ); 127 alias peglWaitSync = EGLBoolean function ( EGLDisplay, EGLSync, EGLint ); 128 } 129 130 __gshared { 131 peglGetError eglGetError; 132 peglGetDisplay eglGetDisplay; 133 peglInitialize eglInitialize; 134 peglTerminate eglTerminate; 135 136 peglQueryString eglQueryString; 137 peglGetConfigs eglGetConfigs; 138 peglChooseConfig eglChooseConfig; 139 peglGetConfigAttrib eglGetConfigAttrib; 140 peglCreateWindowSurface eglCreateWindowSurface; 141 peglCreatePbufferSurface eglCreatePbufferSurface; 142 peglCreatePixmapSurface eglCreatePixmapSurface; 143 peglDestroySurface eglDestroySurface; 144 peglQuerySurface eglQuerySurface; 145 peglCreateContext eglCreateContext; 146 peglDestroyContext eglDestroyContext; 147 peglMakeCurrent eglMakeCurrent; 148 peglGetCurrentSurface eglGetCurrentSurface; 149 peglGetCurrentDisplay eglGetCurrentDisplay; 150 peglQueryContext eglQueryContext; 151 peglWaitGL eglWaitGL; 152 peglWaitNative eglWaitNative; 153 peglSwapBuffers eglSwapBuffers; 154 peglCopyBuffers eglCopyBuffers; 155 peglGetProcAddress eglGetProcAddress; 156 157 peglSurfaceAttrib eglSurfaceAttrib; 158 peglBindTexImage eglBindTexImage; 159 peglReleaseTexImage eglReleaseTexImage; 160 peglSwapInterval eglSwapInterval; 161 162 peglBindAPI eglBindAPI; 163 peglQueryAPI eglQueryAPI; 164 peglWaitClient eglWaitClient; 165 peglReleaseThread eglReleaseThread; 166 peglCreatePbufferFromClientBuffer eglCreatePbufferFromClientBuffer; 167 168 peglGetCurrentContext eglGetCurrentContext; 169 170 peglCreateSync eglCreateSync; 171 peglDestroySync eglDestroySync; 172 peglClientWaitSync eglClientWaitSync; 173 peglGetSyncAttrib eglGetSyncAttrib; 174 peglGetPlatformDisplay eglGetPlatformDisplay; 175 peglCreatePlatformWindowSurface eglCreatePlatformWindowSurface; 176 peglCreatePlatformPixmapSurface eglCreatePlatformPixmapSurface; 177 peglWaitSync eglWaitSync; 178 } 179 180 package(bindbc.gles) @nogc nothrow 181 bool loadEGL(SharedLib lib){ 182 auto startErrorCount = errorCount(); 183 lib.bindSymbol( cast( void** )&eglGetError, "eglGetError" ); 184 lib.bindSymbol( cast( void** )&eglGetDisplay, "eglGetDisplay" ); 185 lib.bindSymbol( cast( void** )&eglInitialize, "eglInitialize" ); 186 lib.bindSymbol( cast( void** )&eglTerminate, "eglTerminate" ); 187 188 EGLDisplay disp = eglGetDisplay( EGL_DEFAULT_DISPLAY ); 189 if( disp == EGL_NO_DISPLAY ) { 190 assert(0, "Unable to get a display for EGL"); 191 } 192 193 if( eglInitialize( disp, &major, &minor ) == EGL_FALSE ) { 194 //assert( "Failed to initialize the EGL display: " ~ to!string( eglGetError( ) ) ); 195 } 196 if( major != 1 ) { 197 eglTerminate( disp ); 198 //assert( "The EGL version is not recognized: " ~ to!string( eglGetError( ) ) ); 199 } 200 201 if( minor >= 0 ) { 202 lib.bindSymbol( cast( void** )&eglQueryString, "eglQueryString" ); 203 lib.bindSymbol( cast( void** )&eglGetConfigs, "eglGetConfigs" ); 204 lib.bindSymbol( cast( void** )&eglChooseConfig, "eglChooseConfig" ); 205 lib.bindSymbol( cast( void** )&eglGetConfigAttrib, "eglGetConfigAttrib" ); 206 lib.bindSymbol( cast( void** )&eglCreateWindowSurface, "eglCreateWindowSurface" ); 207 lib.bindSymbol( cast( void** )&eglCreatePbufferSurface, "eglCreatePbufferSurface" ); 208 lib.bindSymbol( cast( void** )&eglCreatePixmapSurface, "eglCreatePixmapSurface" ); 209 lib.bindSymbol( cast( void** )&eglDestroySurface, "eglDestroySurface" ); 210 lib.bindSymbol( cast( void** )&eglQuerySurface, "eglQuerySurface" ); 211 lib.bindSymbol( cast( void** )&eglCreateContext, "eglCreateContext" ); 212 lib.bindSymbol( cast( void** )&eglDestroyContext, "eglDestroyContext" ); 213 lib.bindSymbol( cast( void** )&eglMakeCurrent, "eglMakeCurrent" ); 214 lib.bindSymbol( cast( void** )&eglGetCurrentSurface, "eglGetCurrentSurface" ); 215 lib.bindSymbol( cast( void** )&eglGetCurrentDisplay, "eglGetCurrentDisplay" ); 216 lib.bindSymbol( cast( void** )&eglQueryContext, "eglQueryContext" ); 217 lib.bindSymbol( cast( void** )&eglWaitGL, "eglWaitGL" ); 218 lib.bindSymbol( cast( void** )&eglWaitNative, "eglWaitNative" ); 219 lib.bindSymbol( cast( void** )&eglSwapBuffers, "eglSwapBuffers" ); 220 lib.bindSymbol( cast( void** )&eglCopyBuffers, "eglCopyBuffers" ); 221 lib.bindSymbol( cast( void** )&eglGetProcAddress, "eglGetProcAddress" ); 222 loadedVersion = EGLSupport.EGL10; 223 } 224 if( minor >= 1 ) { 225 lib.bindSymbol( cast( void** )&eglSurfaceAttrib, "eglSurfaceAttrib" ); 226 lib.bindSymbol( cast( void** )&eglBindTexImage, "eglBindTexImage" ); 227 lib.bindSymbol( cast( void** )&eglReleaseTexImage, "eglReleaseTexImage" ); 228 lib.bindSymbol( cast( void** )&eglSwapInterval, "eglSwapInterval" ); 229 loadedVersion = EGLSupport.EGL11; 230 } 231 if( minor >= 2 ) { 232 lib.bindSymbol( cast( void** )&eglBindAPI, "eglBindAPI" ); 233 lib.bindSymbol( cast( void** )&eglQueryAPI, "eglQueryAPI" ); 234 lib.bindSymbol( cast( void** )&eglWaitClient, "eglWaitClient" ); 235 lib.bindSymbol( cast( void** )&eglReleaseThread, "eglReleaseThread" ); 236 lib.bindSymbol( cast( void** )&eglCreatePbufferFromClientBuffer, "eglCreatePbufferFromClientBuffer" ); 237 loadedVersion = EGLSupport.EGL12; 238 } 239 if( minor >= 3 ) { 240 loadedVersion = EGLSupport.EGL13; 241 } 242 if( minor >= 4 ) { 243 lib.bindSymbol( cast( void** )&eglGetCurrentContext, "eglGetCurrentContext" ); 244 loadedVersion = EGLSupport.EGL14; 245 } 246 if( minor >= 5 ) { 247 lib.bindSymbol( cast( void** )&eglCreateSync, "eglCreateSync" ); 248 lib.bindSymbol( cast( void** )&eglDestroySync, "eglDestroySync" ); 249 lib.bindSymbol( cast( void** )&eglClientWaitSync, "eglClientWaitSync" ); 250 lib.bindSymbol( cast( void** )&eglGetSyncAttrib, "eglGetSyncAttrib" ); 251 lib.bindSymbol( cast( void** )&eglGetPlatformDisplay, "eglGetPlatformDisplay" ); 252 lib.bindSymbol( cast( void** )&eglCreatePlatformWindowSurface, "eglCreatePlatformWindowSurface" ); 253 lib.bindSymbol( cast( void** )&eglCreatePlatformPixmapSurface, "eglCreatePlatformPixmapSurface" ); 254 lib.bindSymbol( cast( void** )&eglWaitSync, "eglWaitSync" ); 255 loadedVersion = EGLSupport.EGL14; 256 } 257 return(errorCount() == startErrorCount); 258 } 259 EGLint EGLversionMajor() { return major; } 260 EGLint EGLversionMinor() { return minor; } 261 262 package: 263 SharedLib libGLES() { return lib; }