| 103 | |
| 104 | |
| 105 | static void *loadGLSymbol(const char *name, bool optional) |
| 106 | { |
| 107 | char *err = NULL; |
| 108 | |
| 109 | if(!__glXGetProcAddress) |
| 110 | { |
| 111 | if(strlen(fconfig.gllib) > 0) |
| 112 | { |
| 113 | dlerror(); // Clear error state |
| 114 | void *dllhnd = _vgl_dlopen(fconfig.gllib, RTLD_LAZY); |
| 115 | err = dlerror(); |
| 116 | if(!dllhnd) |
| 117 | { |
| 118 | vglout.print("[VGL] ERROR: Could not open %s\n", fconfig.gllib); |
| 119 | if(err) vglout.print("[VGL] %s\n", err); |
| 120 | return NULL; |
| 121 | } |
| 122 | gldllhnd = dllhnd; |
| 123 | } |
| 124 | else gldllhnd = RTLD_NEXT; |
| 125 | |
| 126 | dlerror(); // Clear error state |
| 127 | FIND_GLXGETPROCADDRESS(glXGetProcAddress) |
| 128 | if(!__glXGetProcAddress) |
| 129 | FIND_GLXGETPROCADDRESS(glXGetProcAddressARB) |
| 130 | err = dlerror(); |
| 131 | |
| 132 | if(!__glXGetProcAddress) |
| 133 | { |
| 134 | vglout.print("[VGL] ERROR: Could not load GLX/OpenGL functions"); |
| 135 | if(strlen(fconfig.gllib) > 0) |
| 136 | vglout.print(" from %s", fconfig.gllib); |
| 137 | vglout.print("\n"); |
| 138 | if(err) vglout.print("[VGL] %s\n", err); |
| 139 | return NULL; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | void *sym = NULL; |
| 144 | if(!strcmp(name, "glXGetProcAddress") |
| 145 | || !strcmp(name, "glXGetProcAddressARB")) |
| 146 | sym = (void *)__glXGetProcAddress; |
| 147 | else |
| 148 | { |
| 149 | // For whatever reason, on Solaris, if a function doesn't exist in libGL, |
| 150 | // glXGetProcAddress() will return the address of VGL's interposed |
| 151 | // version, which causes an infinite loop until the program blows its stack |
| 152 | // and segfaults. Thus, we use the old reliable dlsym() method by default. |
| 153 | // On Linux and FreeBSD, we use glXGetProcAddress[ARB]() by default, to |
| 154 | // work around issues with certain drivers, but because Steam's |
| 155 | // gameoverlayrenderer.so interposer causes a similar problem to the |
| 156 | // aforementioned issue on Solaris, we allow the GL symbol loading method |
| 157 | // to be controlled at run time using an environment variable (VGL_DLSYM). |
| 158 | if(fconfig.dlsymloader) |
| 159 | { |
| 160 | dlerror(); // Clear error state |
| 161 | sym = dlsym(gldllhnd, (char *)name); |
| 162 | err = dlerror(); |
no test coverage detected