SDL  2.0
SDL_dynapi.c File Reference
#include "SDL_config.h"
#include "SDL_dynapi.h"
#include "SDL.h"
#include "SDL_syswm.h"
#include "SDL_vulkan.h"
#include "SDL_dynapi_procs.h"
#include <windows.h>
+ Include dependency graph for SDL_dynapi.c:

Go to the source code of this file.

Data Structures

struct  SDL_DYNAPI_jump_table
 

Macros

#define SDL_DYNAPI_VERSION   1
 
#define DISABLE_JUMP_MAGIC   1
 
#define SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, logname, prio)
 
#define SDL_DYNAPI_VARARGS(_static, name, initcall)
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   SDL_DYNAPIFN_##fn fn;
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   static rc SDLCALL fn##_DEFAULT params;
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   fn##_DEFAULT,
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)
 
#define SDL_DYNAPI_PROC_NO_VARARGS   1
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   rc SDLCALL fn params { ret jump_table.fn args; }
 
#define SDL_DYNAPI_PROC_NO_VARARGS   1
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   jump_table.fn = fn##_REAL;
 
#define WIN32_LEAN_AND_MEAN   1
 

Typedefs

typedef Sint32(* SDL_DYNAPI_ENTRYFN) (Uint32 apiver, void *table, Uint32 tablesize)
 

Functions

static void SDL_InitDynamicAPI (void)
 
static Sint32 initialize_jumptable (Uint32 apiver, void *table, Uint32 tablesize)
 
Sint32 SDL_DYNAPI_entry (Uint32, void *, Uint32)
 
static SDL_INLINE voidget_sdlapi_entry (const char *fname, const char *sym)
 
static void dynapi_warn (const char *msg)
 
SDL_NORETURN void SDL_ExitProcess (int exitcode)
 
static void SDL_InitDynamicAPILocked (void)
 

Variables

static SDL_DYNAPI_jump_table jump_table
 

Macro Definition Documentation

◆ DISABLE_JUMP_MAGIC

#define DISABLE_JUMP_MAGIC   1

Definition at line 61 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [1/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)
Value:
typedef rc (SDLCALL *SDL_DYNAPIFN_##fn) params; \
static rc SDLCALL fn##_DEFAULT params; \
extern rc SDLCALL fn##_REAL params;

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [2/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    SDL_DYNAPIFN_##fn fn;

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [3/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    static rc SDLCALL fn##_DEFAULT params;

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [4/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    fn##_DEFAULT,

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [5/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)
Value:
static rc SDLCALL fn##_DEFAULT params { \
SDL_InitDynamicAPI(); \
ret jump_table.fn args; \
}

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [6/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    rc SDLCALL fn params { ret jump_table.fn args; }

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [7/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    jump_table.fn = fn##_REAL;

Definition at line 159 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC_NO_VARARGS [1/2]

#define SDL_DYNAPI_PROC_NO_VARARGS   1

Definition at line 161 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC_NO_VARARGS [2/2]

#define SDL_DYNAPI_PROC_NO_VARARGS   1

Definition at line 161 of file SDL_dynapi.c.

◆ SDL_DYNAPI_VARARGS

#define SDL_DYNAPI_VARARGS (   _static,
  name,
  initcall 
)

Definition at line 72 of file SDL_dynapi.c.

◆ SDL_DYNAPI_VARARGS_LOGFN

#define SDL_DYNAPI_VARARGS_LOGFN (   _static,
  name,
  initcall,
  logname,
  prio 
)
Value:
_static void SDLCALL SDL_Log##logname##name(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
va_list ap; initcall; va_start(ap, fmt); \
jump_table.SDL_LogMessageV(category, SDL_LOG_PRIORITY_##prio, fmt, ap); \
va_end(ap); \
}

Definition at line 65 of file SDL_dynapi.c.

◆ SDL_DYNAPI_VERSION

#define SDL_DYNAPI_VERSION   1

Definition at line 49 of file SDL_dynapi.c.

◆ WIN32_LEAN_AND_MEAN

#define WIN32_LEAN_AND_MEAN   1

Definition at line 217 of file SDL_dynapi.c.

Typedef Documentation

◆ SDL_DYNAPI_ENTRYFN

typedef Sint32( * SDL_DYNAPI_ENTRYFN) (Uint32 apiver, void *table, Uint32 tablesize)

Definition at line 203 of file SDL_dynapi.c.

Function Documentation

◆ dynapi_warn()

static void dynapi_warn ( const char *  msg)
static

Definition at line 267 of file SDL_dynapi.c.

268 {
269  const char *caption = "SDL Dynamic API Failure!";
270  /* SDL_ShowSimpleMessageBox() is a too heavy for here. */
271  #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
272  MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR);
273  #else
274  fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg);
275  fflush(stderr);
276  #endif
277 }

References NULL.

Referenced by SDL_InitDynamicAPILocked().

◆ get_sdlapi_entry()

static SDL_INLINE void* get_sdlapi_entry ( const char *  fname,
const char *  sym 
)
static

Definition at line 220 of file SDL_dynapi.c.

221 {
222  HANDLE lib = LoadLibraryA(fname);
223  void *retval = NULL;
224  if (lib) {
225  retval = GetProcAddress(lib, sym);
226  if (retval == NULL) {
227  FreeLibrary(lib);
228  }
229  }
230  return retval;
231 }

References fname, NULL, and retval.

Referenced by SDL_InitDynamicAPILocked().

◆ initialize_jumptable()

static Sint32 initialize_jumptable ( Uint32  apiver,
void table,
Uint32  tablesize 
)
static

Definition at line 174 of file SDL_dynapi.c.

175 {
176  SDL_DYNAPI_jump_table *output_jump_table = (SDL_DYNAPI_jump_table *) table;
177 
178  if (apiver != SDL_DYNAPI_VERSION) {
179  /* !!! FIXME: can maybe handle older versions? */
180  return -1; /* not compatible. */
181  } else if (tablesize > sizeof (jump_table)) {
182  return -1; /* newer version of SDL with functions we can't provide. */
183  }
184 
185  /* Init our jump table first. */
186  #define SDL_DYNAPI_PROC(rc,fn,params,args,ret) jump_table.fn = fn##_REAL;
187  #include "SDL_dynapi_procs.h"
188  #undef SDL_DYNAPI_PROC
189 
190  /* Then the external table... */
191  if (output_jump_table != &jump_table) {
192  jump_table.SDL_memcpy(output_jump_table, &jump_table, tablesize);
193  }
194 
195  /* Safe to call SDL functions now; jump table is initialized! */
196 
197  return 0; /* success! */
198 }

References jump_table, and SDL_DYNAPI_VERSION.

Referenced by SDL_DYNAPI_entry(), and SDL_InitDynamicAPILocked().

◆ SDL_DYNAPI_entry()

Sint32 SDL_DYNAPI_entry ( Uint32  apiver,
void table,
Uint32  tablesize 
)

Definition at line 207 of file SDL_dynapi.c.

208 {
209  return initialize_jumptable(apiver, table, tablesize);
210 }

References initialize_jumptable().

◆ SDL_ExitProcess()

SDL_NORETURN void SDL_ExitProcess ( int  exitcode)

Definition at line 60 of file SDL.c.

61 {
62 #ifdef __WIN32__
63  /* "if you do not know the state of all threads in your process, it is
64  better to call TerminateProcess than ExitProcess"
65  https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
66  TerminateProcess(GetCurrentProcess(), exitcode);
67  /* MingW doesn't have TerminateProcess marked as noreturn, so add an
68  ExitProcess here that will never be reached but make MingW happy. */
69  ExitProcess(exitcode);
70 #elif defined(__EMSCRIPTEN__)
71  emscripten_cancel_main_loop(); /* this should "kill" the app. */
72  emscripten_force_exit(exitcode); /* this should "kill" the app. */
73  exit(exitcode);
74 #elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
75  _exit(exitcode);
76 #elif defined(HAVE__EXIT) /* Upper case _Exit() */
77  _Exit(exitcode);
78 #else
79  _exit(exitcode);
80 #endif
81 }

Referenced by SDL_InitDynamicAPILocked().

◆ SDL_InitDynamicAPI()

static void SDL_InitDynamicAPI ( void  )
static

Definition at line 326 of file SDL_dynapi.c.

327 {
328  /* So the theory is that every function in the jump table defaults to
329  * calling this function, and then replaces itself with a version that
330  * doesn't call this function anymore. But it's possible that, in an
331  * extreme corner case, you can have a second thread hit this function
332  * while the jump table is being initialized by the first.
333  * In this case, a spinlock is really painful compared to what spinlocks
334  * _should_ be used for, but this would only happen once, and should be
335  * insanely rare, as you would have to spin a thread outside of SDL (as
336  * SDL_CreateThread() would also call this function before building the
337  * new thread).
338  */
339  static SDL_bool already_initialized = SDL_FALSE;
340 
341  /* SDL_AtomicLock calls SDL mutex functions to emulate if
342  SDL_ATOMIC_DISABLED, which we can't do here, so in such a
343  configuration, you're on your own. */
344  #if !SDL_ATOMIC_DISABLED
345  static SDL_SpinLock lock = 0;
346  SDL_AtomicLock_REAL(&lock);
347  #endif
348 
349  if (!already_initialized) {
351  already_initialized = SDL_TRUE;
352  }
353 
354  #if !SDL_ATOMIC_DISABLED
355  SDL_AtomicUnlock_REAL(&lock);
356  #endif
357 }

References lock, SDL_FALSE, SDL_InitDynamicAPILocked(), and SDL_TRUE.

◆ SDL_InitDynamicAPILocked()

static void SDL_InitDynamicAPILocked ( void  )
static

Definition at line 290 of file SDL_dynapi.c.

291 {
292  const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API");
293  SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
294  SDL_bool use_internal = SDL_TRUE;
295 
296  if (libname) {
297  entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry");
298  if (!entry) {
299  dynapi_warn("Couldn't load overriding SDL library. Please fix or remove the SDL_DYNAMIC_API environment variable. Using the default SDL.");
300  /* Just fill in the function pointers from this library, later. */
301  }
302  }
303 
304  if (entry) {
305  if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) {
306  dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the SDL_DYNAMIC_API environment variable. Using the default SDL.");
307  /* Just fill in the function pointers from this library, later. */
308  } else {
309  use_internal = SDL_FALSE; /* We overrode SDL! Don't use the internal version! */
310  }
311  }
312 
313  /* Just fill in the function pointers from this library. */
314  if (use_internal) {
316  /* Now we're screwed. Should definitely abort now. */
317  dynapi_warn("Failed to initialize internal SDL dynapi. As this would otherwise crash, we have to abort now.");
318  SDL_ExitProcess(86);
319  }
320  }
321 
322  /* we intentionally never close the newly-loaded lib, of course. */
323 }

References dynapi_warn(), get_sdlapi_entry(), initialize_jumptable(), jump_table, NULL, SDL_DYNAPI_VERSION, SDL_ExitProcess(), SDL_FALSE, and SDL_TRUE.

Referenced by SDL_InitDynamicAPI().

Variable Documentation

◆ jump_table

SDL_DYNAPI_jump_table jump_table
static
Initial value:
= {
#define SDL_DYNAPI_PROC(rc,fn,params,args,ret)
}

Definition at line 134 of file SDL_dynapi.c.

Referenced by initialize_jumptable(), and SDL_InitDynamicAPILocked().

SDL_ExitProcess
SDL_NORETURN void SDL_ExitProcess(int exitcode)
Definition: SDL.c:60
SDL_PRINTF_FORMAT_STRING
#define SDL_PRINTF_FORMAT_STRING
Definition: SDL_stdinc.h:300
fname
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld fname[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
Definition: pixman-arm-neon-asm.h:617
NULL
#define NULL
Definition: begin_code.h:167
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:49
SDL_dynapi_procs.h
params
const GLfloat * params
Definition: SDL_opengl_glext.h:374
get_sdlapi_entry
static SDL_INLINE void * get_sdlapi_entry(const char *fname, const char *sym)
Definition: SDL_dynapi.c:220
initialize_jumptable
static Sint32 initialize_jumptable(Uint32 apiver, void *table, Uint32 tablesize)
Definition: SDL_dynapi.c:174
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
retval
SDL_bool retval
Definition: testgamecontroller.c:65
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:31
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:663
jump_table
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:134
SDL_SpinLock
int SDL_SpinLock
Definition: SDL_atomic.h:89
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_InitDynamicAPILocked
static void SDL_InitDynamicAPILocked(void)
Definition: SDL_dynapi.c:290
SDL_DYNAPI_jump_table
Definition: SDL_dynapi.c:122
SDL_DYNAPI_ENTRYFN
Sint32(* SDL_DYNAPI_ENTRYFN)(Uint32 apiver, void *table, Uint32 tablesize)
Definition: SDL_dynapi.c:203
SDL_DYNAPI_VERSION
#define SDL_DYNAPI_VERSION
Definition: SDL_dynapi.c:49
dynapi_warn
static void dynapi_warn(const char *msg)
Definition: SDL_dynapi.c:267
table
GLenum GLsizei GLenum GLenum const void * table
Definition: SDL_opengl_glext.h:3121
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
lock
SDL_mutex * lock
Definition: SDL_events.c:83