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 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;
const GLfloat * params
#define SDLCALL
Definition: SDL_internal.h:45

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; \
}
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:134
const GLfloat * params
#define SDLCALL
Definition: SDL_internal.h:45

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); \
}
GLuint const GLchar * name
#define SDL_Log
#define SDL_PRINTF_FORMAT_STRING
Definition: SDL_stdinc.h:300
#define SDLCALL
Definition: SDL_internal.h:45

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

◆ 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 }
SDL_bool retval
#define NULL
Definition: begin_code.h:164
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 local 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

◆ 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 }
GLenum GLsizei GLenum GLenum const void * table
#define SDL_DYNAPI_VERSION
Definition: SDL_dynapi.c:49
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:134

◆ 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 }
GLenum GLsizei GLenum GLenum const void * table
static Sint32 initialize_jumptable(Uint32 apiver, void *table, Uint32 tablesize)
Definition: SDL_dynapi.c:174

◆ SDL_InitDynamicAPI()

static void SDL_InitDynamicAPI ( void  )
static

Definition at line 297 of file SDL_dynapi.c.

298 {
299  /* So the theory is that every function in the jump table defaults to
300  * calling this function, and then replaces itself with a version that
301  * doesn't call this function anymore. But it's possible that, in an
302  * extreme corner case, you can have a second thread hit this function
303  * while the jump table is being initialized by the first.
304  * In this case, a spinlock is really painful compared to what spinlocks
305  * _should_ be used for, but this would only happen once, and should be
306  * insanely rare, as you would have to spin a thread outside of SDL (as
307  * SDL_CreateThread() would also call this function before building the
308  * new thread).
309  */
310  static SDL_bool already_initialized = SDL_FALSE;
311 
312  /* SDL_AtomicLock calls SDL mutex functions to emulate if
313  SDL_ATOMIC_DISABLED, which we can't do here, so in such a
314  configuration, you're on your own. */
315  #if !SDL_ATOMIC_DISABLED
316  static SDL_SpinLock lock = 0;
317  SDL_AtomicLock_REAL(&lock);
318  #endif
319 
320  if (!already_initialized) {
322  already_initialized = SDL_TRUE;
323  }
324 
325  #if !SDL_ATOMIC_DISABLED
326  SDL_AtomicUnlock_REAL(&lock);
327  #endif
328 }
static void SDL_InitDynamicAPILocked(void)
Definition: SDL_dynapi.c:268
SDL_bool
Definition: SDL_stdinc.h:161
SDL_mutex * lock
Definition: SDL_events.c:78
int SDL_SpinLock
Definition: SDL_atomic.h:89

◆ SDL_InitDynamicAPILocked()

static void SDL_InitDynamicAPILocked ( void  )
static

Definition at line 268 of file SDL_dynapi.c.

269 {
270  const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API");
271  SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
272 
273  if (libname) {
274  entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry");
275  if (!entry) {
276  /* !!! FIXME: fail to startup here instead? */
277  /* !!! FIXME: definitely warn user. */
278  /* Just fill in the function pointers from this library. */
279  }
280  }
281 
282  if (!entry || (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0)) {
283  /* !!! FIXME: fail to startup here instead? */
284  /* !!! FIXME: definitely warn user. */
285  /* Just fill in the function pointers from this library. */
286  if (!entry) {
288  /* !!! FIXME: now we're screwed. Should definitely abort now. */
289  }
290  }
291  }
292 
293  /* we intentionally never close the newly-loaded lib, of course. */
294 }
static SDL_INLINE void * get_sdlapi_entry(const char *fname, const char *sym)
Definition: SDL_dynapi.c:220
Sint32(* SDL_DYNAPI_ENTRYFN)(Uint32 apiver, void *table, Uint32 tablesize)
Definition: SDL_dynapi.c:203
#define SDL_DYNAPI_VERSION
Definition: SDL_dynapi.c:49
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:134
#define NULL
Definition: begin_code.h:164
static Sint32 initialize_jumptable(Uint32 apiver, void *table, Uint32 tablesize)
Definition: SDL_dynapi.c:174

Variable Documentation

◆ jump_table

SDL_DYNAPI_jump_table jump_table
static

Definition at line 134 of file SDL_dynapi.c.