/* * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * an EGL library wrapper * * The why of this GL/EGL library wrapper: * Vendors provide very different versions of the libraries, and linking * directly with those libraries introduces a loader depenancy chain. * But using this wrapper allows us to avoid this at the code of loading * all the symbols needed at runtime and one level of indirection. * * to use, simply link this file, as well as the provided stub versions of -lEGL -lGLESv2 * call openNativeFramebuffer() to get the NativeDisplayType and the NativeWindowType * that match the platform. * */ #include #include #include #include #ifndef __USE_GNU // required for dladdr() & Dl_info #define __USE_GNU #endif #include #include #include #include #define WRAPPEDAPI #include "eglWrapper.h" int load_wrapped_gles_symbols(void); void *libglesv2; void *libegl; int done_loading_symbols = 0; /***************************** UTILITY ********************************/ #ifdef ANDROID_NDK static EGLDisplay(*_eglGetDisplay)(EGLNativeDisplayType display_id); static EGLNativeWindowType(*_ANDROID_getNativeWindow)(); #else PrismNativePort prismPort; #endif int load_wrapped_gles_symbols() { if (done_loading_symbols) { return 0; } done_loading_symbols = 1; #ifdef ANDROID_NDK libegl = dlopen("libEGL.so", RTLD_LAZY | RTLD_GLOBAL); if (!libegl) { fprintf(stderr, "Did not find libEGL.so %s\n", dlerror()); return 0; } _eglGetDisplay = dlsym(libegl, "eglGetDisplay"); libglesv2 = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL); if (!libglesv2) { fprintf(stderr, "Did not find libGLESv2.so %s\n", dlerror()); return 0; } #else Dl_info dlinfo; if (dladdr(&load_wrapped_gles_symbols, &dlinfo)) { size_t rslash = (size_t)rindex(dlinfo.dli_fname,'/'); if (rslash) { char *b = (char *) alloca(strlen(dlinfo.dli_fname)+20); rslash = rslash + 1 - (size_t)dlinfo.dli_fname; strncpy(b, dlinfo.dli_fname,rslash); strcpy(b + rslash, LENSPORT_LIBRARY_NAME); jboolean (*prism_platform_init)(PrismNativePort*) = 0; void *dlhand = dlopen(b,RTLD_NOW); if (dlhand) { prism_platform_init = dlsym(dlhand, "prism_platform_initialize"); if (!prism_platform_init) { fprintf(stderr,"prism_platform_initialize missing in %s\n",LENSPORT_LIBRARY_NAME); exit(-1); } } else { fprintf(stderr,"Prism FAILED TO OPEN %s\n",b); fprintf(stderr,"dlopen reports %s\n",dlerror()); exit(-1); } prismPort.version = NATIVE_PRISM_PORT_VERSION; if (!(*prism_platform_init)(&prismPort)) { fprintf(stderr,"prism_platform_initialize failed\n"); exit(-1); } } } else { printf("Did not get DLINFO\n"); exit(-1); } #endif return 1; } EGLNativeDisplayType getNativeDisplayType() { if (!done_loading_symbols) { load_wrapped_gles_symbols(); } #ifdef ANDROID_NDK return (EGLNativeDisplayType) NULL; #else return (EGLNativeDisplayType) (*prismPort.getNativeDisplayType)(); #endif } EGLNativeWindowType getNativeWindowType() { if (!done_loading_symbols) { load_wrapped_gles_symbols(); } #ifdef ANDROID_NDK #ifdef DALVIK_VM #define ANDROID_LIB "libactivity.so" #define GET_NATIVE_WINDOW "android_getNativeWindow" #else #define ANDROID_LIB "libglass_lens_android.so" #define GET_NATIVE_WINDOW "ANDROID_getNativeWindow" #endif //don't cache for Android! printf("Using %s\n", ANDROID_LIB); void *libglass_android = dlopen(ANDROID_LIB, RTLD_LAZY | RTLD_GLOBAL); if (!libglass_android) { fprintf(stderr, "Did not find %s %s\n", ANDROID_LIB, dlerror()); return NULL; } _ANDROID_getNativeWindow = dlsym(libglass_android, GET_NATIVE_WINDOW); if (!_ANDROID_getNativeWindow) { fprintf(stderr, "Did not find symbol \"%s\" %s\n", GET_NATIVE_WINDOW, dlerror()); return NULL; } return (*_ANDROID_getNativeWindow)(); #else return (EGLNativeWindowType) (*prismPort.getNativeWindowType)(); #endif } EGLDisplay wr_eglGetDisplay(EGLNativeDisplayType display_id) { #ifdef ANDROID_NDK return (*_eglGetDisplay)(display_id); #else return (EGLDisplay) (*prismPort.wr_eglGetDisplay)((void*)display_id); #endif } void * getLibGLEShandle() { #ifdef ANDROID_NDK return libglesv2; #else return (*prismPort.getLibGLEShandle)(); #endif }