glx_obs.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stddef.h>
  4. #include "glx_obs.h"
  5. #if defined(__APPLE__)
  6. #include <dlfcn.h>
  7. static void* AppleGLGetProcAddress (const const char *name)
  8. {
  9. static void* image = NULL;
  10. if (NULL == image)
  11. image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
  12. return (image ? dlsym(image, name) : NULL);
  13. }
  14. #define IntGetProcAddress(name) AppleGLGetProcAddress(name)
  15. #endif /* __APPLE__ */
  16. #if defined(_WIN32)
  17. #ifdef _MSC_VER
  18. #pragma warning(disable: 4055)
  19. #pragma warning(disable: 4054)
  20. #pragma warning(disable: 4996)
  21. #endif
  22. static PROC WinGetProcAddress(const char *name)
  23. {
  24. static HMODULE glMod = NULL;
  25. PROC pFunc = wglGetProcAddress((LPCSTR)name);
  26. if (pFunc) return pFunc;
  27. if (NULL == glMod)
  28. glMod = GetModuleHandleA("OpenGL32.dll");
  29. return (PROC)GetProcAddress(glMod, (LPCSTR)name);
  30. }
  31. #define IntGetProcAddress(name) WinGetProcAddress(name)
  32. #endif
  33. /* Linux, FreeBSD, other */
  34. #ifndef IntGetProcAddress
  35. #ifndef GLX_ARB_get_proc_address
  36. #define GLX_ARB_get_proc_address 1
  37. typedef void (*__GLXextFuncPtr)(void);
  38. extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *);
  39. #endif /* GLX_ARB_get_proc_address */
  40. #define IntGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name)
  41. #endif
  42. int glx_ext_ARB_create_context = glx_LOAD_FAILED;
  43. int glx_ext_ARB_create_context_profile = glx_LOAD_FAILED;
  44. int glx_ext_ARB_create_context_robustness = glx_LOAD_FAILED;
  45. int glx_ext_ARB_fbconfig_float = glx_LOAD_FAILED;
  46. int glx_ext_ARB_framebuffer_sRGB = glx_LOAD_FAILED;
  47. int glx_ext_ARB_multisample = glx_LOAD_FAILED;
  48. int glx_ext_EXT_create_context_es2_profile = glx_LOAD_FAILED;
  49. int glx_ext_EXT_fbconfig_packed_float = glx_LOAD_FAILED;
  50. int glx_ext_EXT_framebuffer_sRGB = glx_LOAD_FAILED;
  51. int glx_ext_EXT_import_context = glx_LOAD_FAILED;
  52. int glx_ext_EXT_swap_control = glx_LOAD_FAILED;
  53. int glx_ext_EXT_swap_control_tear = glx_LOAD_FAILED;
  54. GLXContext (CODEGEN_FUNCPTR *_ptrc_glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *) = NULL;
  55. static int Load_ARB_create_context()
  56. {
  57. int numFailed = 0;
  58. _ptrc_glXCreateContextAttribsARB = (GLXContext (CODEGEN_FUNCPTR *)(Display *, GLXFBConfig, GLXContext, Bool, const int *))IntGetProcAddress("glXCreateContextAttribsARB");
  59. if(!_ptrc_glXCreateContextAttribsARB) numFailed++;
  60. return numFailed;
  61. }
  62. void (CODEGEN_FUNCPTR *_ptrc_glXFreeContextEXT)(Display *, GLXContext) = NULL;
  63. GLXContextID (CODEGEN_FUNCPTR *_ptrc_glXGetContextIDEXT)(const GLXContext) = NULL;
  64. Display * (CODEGEN_FUNCPTR *_ptrc_glXGetCurrentDisplayEXT)() = NULL;
  65. GLXContext (CODEGEN_FUNCPTR *_ptrc_glXImportContextEXT)(Display *, GLXContextID) = NULL;
  66. int (CODEGEN_FUNCPTR *_ptrc_glXQueryContextInfoEXT)(Display *, GLXContext, int, int *) = NULL;
  67. static int Load_EXT_import_context()
  68. {
  69. int numFailed = 0;
  70. _ptrc_glXFreeContextEXT = (void (CODEGEN_FUNCPTR *)(Display *, GLXContext))IntGetProcAddress("glXFreeContextEXT");
  71. if(!_ptrc_glXFreeContextEXT) numFailed++;
  72. _ptrc_glXGetContextIDEXT = (GLXContextID (CODEGEN_FUNCPTR *)(const GLXContext))IntGetProcAddress("glXGetContextIDEXT");
  73. if(!_ptrc_glXGetContextIDEXT) numFailed++;
  74. _ptrc_glXGetCurrentDisplayEXT = (Display * (CODEGEN_FUNCPTR *)())IntGetProcAddress("glXGetCurrentDisplayEXT");
  75. if(!_ptrc_glXGetCurrentDisplayEXT) numFailed++;
  76. _ptrc_glXImportContextEXT = (GLXContext (CODEGEN_FUNCPTR *)(Display *, GLXContextID))IntGetProcAddress("glXImportContextEXT");
  77. if(!_ptrc_glXImportContextEXT) numFailed++;
  78. _ptrc_glXQueryContextInfoEXT = (int (CODEGEN_FUNCPTR *)(Display *, GLXContext, int, int *))IntGetProcAddress("glXQueryContextInfoEXT");
  79. if(!_ptrc_glXQueryContextInfoEXT) numFailed++;
  80. return numFailed;
  81. }
  82. void (CODEGEN_FUNCPTR *_ptrc_glXSwapIntervalEXT)(Display *, GLXDrawable, int) = NULL;
  83. static int Load_EXT_swap_control()
  84. {
  85. int numFailed = 0;
  86. _ptrc_glXSwapIntervalEXT = (void (CODEGEN_FUNCPTR *)(Display *, GLXDrawable, int))IntGetProcAddress("glXSwapIntervalEXT");
  87. if(!_ptrc_glXSwapIntervalEXT) numFailed++;
  88. return numFailed;
  89. }
  90. typedef int (*PFN_LOADFUNCPOINTERS)();
  91. typedef struct glx_StrToExtMap_s
  92. {
  93. char *extensionName;
  94. int *extensionVariable;
  95. PFN_LOADFUNCPOINTERS LoadExtension;
  96. } glx_StrToExtMap;
  97. static glx_StrToExtMap ExtensionMap[12] = {
  98. {"GLX_ARB_create_context", &glx_ext_ARB_create_context, Load_ARB_create_context},
  99. {"GLX_ARB_create_context_profile", &glx_ext_ARB_create_context_profile, NULL},
  100. {"GLX_ARB_create_context_robustness", &glx_ext_ARB_create_context_robustness, NULL},
  101. {"GLX_ARB_fbconfig_float", &glx_ext_ARB_fbconfig_float, NULL},
  102. {"GLX_ARB_framebuffer_sRGB", &glx_ext_ARB_framebuffer_sRGB, NULL},
  103. {"GLX_ARB_multisample", &glx_ext_ARB_multisample, NULL},
  104. {"GLX_EXT_create_context_es2_profile", &glx_ext_EXT_create_context_es2_profile, NULL},
  105. {"GLX_EXT_fbconfig_packed_float", &glx_ext_EXT_fbconfig_packed_float, NULL},
  106. {"GLX_EXT_framebuffer_sRGB", &glx_ext_EXT_framebuffer_sRGB, NULL},
  107. {"GLX_EXT_import_context", &glx_ext_EXT_import_context, Load_EXT_import_context},
  108. {"GLX_EXT_swap_control", &glx_ext_EXT_swap_control, Load_EXT_swap_control},
  109. {"GLX_EXT_swap_control_tear", &glx_ext_EXT_swap_control_tear, NULL},
  110. };
  111. static int g_extensionMapSize = 12;
  112. static glx_StrToExtMap *FindExtEntry(const char *extensionName)
  113. {
  114. int loop;
  115. glx_StrToExtMap *currLoc = ExtensionMap;
  116. for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
  117. {
  118. if(strcmp(extensionName, currLoc->extensionName) == 0)
  119. return currLoc;
  120. }
  121. return NULL;
  122. }
  123. static void ClearExtensionVars()
  124. {
  125. glx_ext_ARB_create_context = glx_LOAD_FAILED;
  126. glx_ext_ARB_create_context_profile = glx_LOAD_FAILED;
  127. glx_ext_ARB_create_context_robustness = glx_LOAD_FAILED;
  128. glx_ext_ARB_fbconfig_float = glx_LOAD_FAILED;
  129. glx_ext_ARB_framebuffer_sRGB = glx_LOAD_FAILED;
  130. glx_ext_ARB_multisample = glx_LOAD_FAILED;
  131. glx_ext_EXT_create_context_es2_profile = glx_LOAD_FAILED;
  132. glx_ext_EXT_fbconfig_packed_float = glx_LOAD_FAILED;
  133. glx_ext_EXT_framebuffer_sRGB = glx_LOAD_FAILED;
  134. glx_ext_EXT_import_context = glx_LOAD_FAILED;
  135. glx_ext_EXT_swap_control = glx_LOAD_FAILED;
  136. glx_ext_EXT_swap_control_tear = glx_LOAD_FAILED;
  137. }
  138. static void LoadExtByName(const char *extensionName)
  139. {
  140. glx_StrToExtMap *entry = NULL;
  141. entry = FindExtEntry(extensionName);
  142. if(entry)
  143. {
  144. if(entry->LoadExtension)
  145. {
  146. int numFailed = entry->LoadExtension();
  147. if(numFailed == 0)
  148. {
  149. *(entry->extensionVariable) = glx_LOAD_SUCCEEDED;
  150. }
  151. else
  152. {
  153. *(entry->extensionVariable) = glx_LOAD_SUCCEEDED + numFailed;
  154. }
  155. }
  156. else
  157. {
  158. *(entry->extensionVariable) = glx_LOAD_SUCCEEDED;
  159. }
  160. }
  161. }
  162. static void ProcExtsFromExtString(const char *strExtList)
  163. {
  164. size_t iExtListLen = strlen(strExtList);
  165. const char *strExtListEnd = strExtList + iExtListLen;
  166. const char *strCurrPos = strExtList;
  167. char strWorkBuff[256];
  168. while(*strCurrPos)
  169. {
  170. /*Get the extension at our position.*/
  171. int iStrLen = 0;
  172. const char *strEndStr = strchr(strCurrPos, ' ');
  173. int iStop = 0;
  174. if(strEndStr == NULL)
  175. {
  176. strEndStr = strExtListEnd;
  177. iStop = 1;
  178. }
  179. iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos);
  180. if(iStrLen > 255)
  181. return;
  182. strncpy(strWorkBuff, strCurrPos, iStrLen);
  183. strWorkBuff[iStrLen] = '\0';
  184. LoadExtByName(strWorkBuff);
  185. strCurrPos = strEndStr + 1;
  186. if(iStop) break;
  187. }
  188. }
  189. int glx_LoadFunctions(Display *display, int screen)
  190. {
  191. ClearExtensionVars();
  192. ProcExtsFromExtString((const char *)glXQueryExtensionsString(display, screen));
  193. return glx_LOAD_SUCCEEDED;
  194. }