1 /* 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * an EGL library wrapper 28 * 29 * The why of this GL/EGL library wrapper: 30 * Vendors provide very different versions of the libraries, and linking 31 * directly with those libraries introduces a loader depenancy chain. 32 * But using this wrapper allows us to avoid this at the code of loading 33 * all the symbols needed at runtime and one level of indirection. 34 * 35 * to use, simply link this file, as well as the provided stub versions of -lEGL -lGLESv2 36 * call openNativeFramebuffer() to get the NativeDisplayType and the NativeWindowType 37 * that match the platform. 38 * 39 */ 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <linux/fb.h> 44 #include <fcntl.h> 45 #ifndef __USE_GNU // required for dladdr() & Dl_info 46 #define __USE_GNU 47 #endif 48 #include <dlfcn.h> 49 #include <sys/ioctl.h> 50 51 #include <string.h> 52 #include <strings.h> 53 54 #define WRAPPEDAPI 55 #include "eglWrapper.h" 56 57 int load_wrapped_gles_symbols(void); 58 void *libglesv2; 59 void *libegl; 60 int done_loading_symbols = 0; 61 62 /***************************** UTILITY ********************************/ 63 64 #ifdef ANDROID_NDK 65 66 static EGLDisplay(*_eglGetDisplay)(EGLNativeDisplayType display_id); 67 static EGLNativeWindowType(*_ANDROID_getNativeWindow)(); 68 69 #else 70 71 PrismNativePort prismPort; 72 73 #endif 74 75 int load_wrapped_gles_symbols() { 76 if (done_loading_symbols) { 77 return 0; 78 } 79 done_loading_symbols = 1; 80 81 #ifdef ANDROID_NDK 82 libegl = dlopen("libEGL.so", RTLD_LAZY | RTLD_GLOBAL); 83 if (!libegl) { 84 fprintf(stderr, "Did not find libEGL.so %s\n", dlerror()); 85 return 0; 86 } 87 88 _eglGetDisplay = dlsym(libegl, "eglGetDisplay"); 89 90 libglesv2 = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL); 91 if (!libglesv2) { 92 fprintf(stderr, "Did not find libGLESv2.so %s\n", dlerror()); 93 return 0; 94 } 95 #else 96 97 Dl_info dlinfo; 98 if (dladdr(&load_wrapped_gles_symbols, &dlinfo)) { 99 100 size_t rslash = (size_t)rindex(dlinfo.dli_fname,'/'); 101 if (rslash) { 102 char *b = (char *) alloca(strlen(dlinfo.dli_fname)+20); 103 rslash = rslash + 1 - (size_t)dlinfo.dli_fname; 104 strncpy(b, dlinfo.dli_fname,rslash); 105 strcpy(b + rslash, LENSPORT_LIBRARY_NAME); 106 107 jboolean (*prism_platform_init)(PrismNativePort*) = 0; 108 109 void *dlhand = dlopen(b,RTLD_NOW); 110 if (dlhand) { 111 prism_platform_init = dlsym(dlhand, "prism_platform_initialize"); 112 if (!prism_platform_init) { 113 fprintf(stderr,"prism_platform_initialize missing in %s\n",LENSPORT_LIBRARY_NAME); 114 exit(-1); 115 } 116 } else { 117 fprintf(stderr,"Prism FAILED TO OPEN %s\n",b); 118 fprintf(stderr,"dlopen reports %s\n",dlerror()); 119 exit(-1); 120 } 121 prismPort.version = NATIVE_PRISM_PORT_VERSION; 122 123 if (!(*prism_platform_init)(&prismPort)) { 124 fprintf(stderr,"prism_platform_initialize failed\n"); 125 exit(-1); 126 } 127 } 128 } else { 129 printf("Did not get DLINFO\n"); 130 exit(-1); 131 } 132 133 #endif 134 return 1; 135 } 136 137 EGLNativeDisplayType getNativeDisplayType() { 138 if (!done_loading_symbols) { 139 load_wrapped_gles_symbols(); 140 } 141 #ifdef ANDROID_NDK 142 return (EGLNativeDisplayType) NULL; 143 #else 144 return (EGLNativeDisplayType) (*prismPort.getNativeDisplayType)(); 145 #endif 146 147 } 148 149 EGLNativeWindowType getNativeWindowType() { 150 if (!done_loading_symbols) { 151 load_wrapped_gles_symbols(); 152 } 153 154 #ifdef ANDROID_NDK 155 #ifdef DALVIK_VM 156 #define ANDROID_LIB "libactivity.so" 157 #define GET_NATIVE_WINDOW "android_getNativeWindow" 158 #else 159 #define ANDROID_LIB "libglass_lens_android.so" 160 #define GET_NATIVE_WINDOW "ANDROID_getNativeWindow" 161 #endif 162 //don't cache for Android! 163 printf("Using %s\n", ANDROID_LIB); 164 void *libglass_android = dlopen(ANDROID_LIB, RTLD_LAZY | RTLD_GLOBAL); 165 if (!libglass_android) { 166 fprintf(stderr, "Did not find %s %s\n", ANDROID_LIB, dlerror()); 167 return NULL; 168 } 169 _ANDROID_getNativeWindow = dlsym(libglass_android, GET_NATIVE_WINDOW); 170 if (!_ANDROID_getNativeWindow) { 171 fprintf(stderr, "Did not find symbol \"%s\" %s\n", GET_NATIVE_WINDOW, dlerror()); 172 return NULL; 173 } 174 return (*_ANDROID_getNativeWindow)(); 175 #else 176 return (EGLNativeWindowType) (*prismPort.getNativeWindowType)(); 177 #endif 178 } 179 180 EGLDisplay wr_eglGetDisplay(EGLNativeDisplayType display_id) { 181 #ifdef ANDROID_NDK 182 return (*_eglGetDisplay)(display_id); 183 #else 184 return (EGLDisplay) (*prismPort.wr_eglGetDisplay)((void*)display_id); 185 #endif 186 } 187 188 void * getLibGLEShandle() { 189 #ifdef ANDROID_NDK 190 return libglesv2; 191 #else 192 return (*prismPort.getLibGLEShandle)(); 193 #endif 194 } 195