glimp_dlopen.cpp.m4 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "idlib/precompiled.h"
  2. #include "renderer/tr_local.h"
  3. #include "sys/linux/local.h"
  4. #include "glimp_local.h"
  5. #include <dlfcn.h>
  6. dnl =====================================================
  7. dnl utils
  8. dnl =====================================================
  9. define(`forloop',
  10. `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
  11. define(`_forloop',
  12. `$4`'ifelse($1, `$3', ,
  13. `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
  14. dnl =====================================================
  15. dnl the gl wgl glX definitions
  16. dnl =====================================================
  17. include(../gllog/gl_def.m4)
  18. dnl =====================================================
  19. dnl qgl function ptrs
  20. dnl =====================================================
  21. define(`instance_funcptr', ``$1' ( APIENTRY * qgl`$2' )(`$3');')
  22. forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
  23. ')
  24. dnl =====================================================
  25. dnl glX function ptrs
  26. dnl =====================================================
  27. define(`instance_funcptr', ``$1' ( * qglX`$2' )(`$3');')
  28. forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
  29. ')
  30. dnl =====================================================
  31. dnl dll ptrs
  32. dnl those are the actual dlsym'ed pointers
  33. dnl logging configuration redirects qgl / qglX to either log or dll versions
  34. dnl =====================================================
  35. define(`instance_funcptr', ``$1' ( * dll`$2' )(`$3');')
  36. forloop(`i', gl_start, gl_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
  37. ')
  38. forloop(`i', glX_start, glX_end, `instance_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
  39. ')
  40. dnl =====================================================
  41. dnl code
  42. dnl =====================================================
  43. /*
  44. ======================
  45. GLimp_BindNative
  46. ======================
  47. */
  48. void GLimp_BindNative() {
  49. define(`assign_funcptr', `qgl`$1' = dll`$1';')
  50. forloop(`i', gl_start, gl_end, `assign_funcptr(indir(`f'i`_name'))
  51. ')
  52. define(`assign_funcptr', `qglX`$1' = dll`$1';')
  53. forloop(`i', glX_start, glX_end, `assign_funcptr(indir(`f'i`_name'))
  54. ')
  55. }
  56. static void *glHandle = NULL;
  57. /*
  58. ======================
  59. GLimp_dlsym_failed
  60. ======================
  61. */
  62. void GLimp_dlsym_failed(const char *name) {
  63. common->DPrintf("dlsym(%s) failed: %s\n", name, dlerror());
  64. }
  65. /*
  66. ======================
  67. GLimp_dlopen
  68. ======================
  69. */
  70. bool GLimp_dlopen() {
  71. const char *driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "libGL.so.1";
  72. common->Printf("dlopen(%s)\n", driverName);
  73. if ( !( glHandle = dlopen( driverName, RTLD_NOW | RTLD_GLOBAL ) ) ) {
  74. common->DPrintf("dlopen(%s) failed: %s\n", driverName, dlerror());
  75. return false;
  76. }
  77. // dlsym the symbols
  78. define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "gl`$2'" );')
  79. define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3')
  80. if (!dll`$2') { GLimp_dlsym_failed("gl`$2'"); return false; }')
  81. forloop(`i', gl_start, gl_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
  82. ')
  83. define(`dlsym_funcptr', `dll`$2' = ( `$1' ( APIENTRY *)(`$3') ) dlsym( glHandle, "glX`$2'" );')
  84. define(`safe_dlsym_funcptr', `dlsym_funcptr(`$1', `$2', `$3')
  85. if (!dll`$2') { GLimp_dlsym_failed("glX`$2'"); return false; }')
  86. forloop(`i', glX_start, glX_end, `safe_dlsym_funcptr(indir(`f'i`_ret'), indir(`f'i`_name'), indir(`f'i`_params'))
  87. ')
  88. // make the initial binding
  89. GLimp_BindNative();
  90. return true;
  91. }
  92. /*
  93. ======================
  94. GLimp_dlclose
  95. ======================
  96. */
  97. void GLimp_dlclose() {
  98. if ( !glHandle ) {
  99. common->DPrintf("dlclose: GL handle is NULL\n");
  100. } else {
  101. dlclose( glHandle );
  102. glHandle = NULL;
  103. }
  104. define(`reset_funcptr', `qgl`$1' = NULL;')
  105. forloop(`i', gl_start, gl_end, `reset_funcptr(indir(`f'i`_name'))
  106. ')
  107. define(`reset_funcptr', `qglX`$1' = NULL;')
  108. forloop(`i', glX_start, glX_end, `reset_funcptr(indir(`f'i`_name'))
  109. ')
  110. }