📄 imports.c
字号:
/** * \file imports.c * Standard C library function wrappers. * * Imports are services which the device driver or window system or * operating system provides to the core renderer. The core renderer (Mesa) * will call these functions in order to do memory allocation, simple I/O, * etc. * * Some drivers will want to override/replace this file with something * specialized, but that'll be rare. * * Eventually, I want to move roll the glheader.h file into this. * * The OpenGL SI's __GLimports structure allows per-context specification of * replacements for the standard C lib functions. In practice that's probably * never needed; compile-time replacements are far more likely. * * The _mesa_*() functions defined here don't in general take a context * parameter. I guess we can change that someday, if need be. * So for now, the __GLimports stuff really isn't used. * * \todo Functions still needed: * - scanf * - qsort * - rand and RAND_MAX * * \note When compiled into a XFree86 module these functions wrap around * XFree86 own wrappers. *//* * Mesa 3-D graphics library * Version: 6.5 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "imports.h"#include "context.h"#include "version.h"#define MAXSTRING 4000 /* for vsnprintf() */#ifdef WIN32#define vsnprintf _vsnprintf#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);#ifdef __VMS#include "vsnprintf.c"#endif#endif/* If we don't actually want to use the libcwrapper junk (even though we're * building an Xorg server module), then just undef IN_MODULE to signal that to * the following code. It's left around for now to allow compiling of newish * Mesa with older servers, but this whole mess should go away at some point. */#ifdef NO_LIBCWRAPPER#undef IN_MODULE#endif/**********************************************************************//** \name Memory *//*@{*//** Wrapper around either malloc() or xf86malloc() */void *_mesa_malloc(size_t bytes){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86malloc(bytes);#else return malloc(bytes);#endif}/** Wrapper around either calloc() or xf86calloc() */void *_mesa_calloc(size_t bytes){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86calloc(1, bytes);#else return calloc(1, bytes);#endif}/** Wrapper around either free() or xf86free() */void_mesa_free(void *ptr){#if defined(XFree86LOADER) && defined(IN_MODULE) xf86free(ptr);#else free(ptr);#endif}/** * Allocate aligned memory. * * \param bytes number of bytes to allocate. * \param alignment alignment (must be greater than zero). * * Allocates extra memory to accommodate rounding up the address for * alignment and to record the real malloc address. * * \sa _mesa_align_free(). */void *_mesa_align_malloc(size_t bytes, unsigned long alignment){ uintptr_t ptr, buf; ASSERT( alignment > 0 ); ptr = (uintptr_t) _mesa_malloc(bytes + alignment + sizeof(void *)); if (!ptr) return NULL; buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); *(uintptr_t *)(buf - sizeof(void *)) = ptr;#ifdef DEBUG /* mark the non-aligned area */ while ( ptr < buf - sizeof(void *) ) { *(unsigned long *)ptr = 0xcdcdcdcd; ptr += sizeof(unsigned long); }#endif return (void *) buf;}/** * Same as _mesa_align_malloc(), but using _mesa_calloc() instead of * _mesa_malloc() */void *_mesa_align_calloc(size_t bytes, unsigned long alignment){ uintptr_t ptr, buf; ASSERT( alignment > 0 ); ptr = (uintptr_t) _mesa_calloc(bytes + alignment + sizeof(void *)); if (!ptr) return NULL; buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); *(uintptr_t *)(buf - sizeof(void *)) = ptr;#ifdef DEBUG /* mark the non-aligned area */ while ( ptr < buf - sizeof(void *) ) { *(unsigned long *)ptr = 0xcdcdcdcd; ptr += sizeof(unsigned long); }#endif return (void *)buf;}/** * Free memory which was allocated with either _mesa_align_malloc() * or _mesa_align_calloc(). * \param ptr pointer to the memory to be freed. * The actual address to free is stored in the word immediately before the * address the client sees. */void_mesa_align_free(void *ptr){#if 0 _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr - sizeof(void *))) );#else void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); void *realAddr = *cubbyHole; _mesa_free(realAddr);#endif}/** Reallocate memory */void *_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize){ const size_t copySize = (oldSize < newSize) ? oldSize : newSize; void *newBuffer = _mesa_malloc(newSize); if (newBuffer && oldBuffer && copySize > 0) _mesa_memcpy(newBuffer, oldBuffer, copySize); if (oldBuffer) _mesa_free(oldBuffer); return newBuffer;}/** memcpy wrapper */void *_mesa_memcpy(void *dest, const void *src, size_t n){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86memcpy(dest, src, n);#elif defined(SUNOS4) return memcpy((char *) dest, (char *) src, (int) n);#else return memcpy(dest, src, n);#endif}/** Wrapper around either memset() or xf86memset() */void_mesa_memset( void *dst, int val, size_t n ){#if defined(XFree86LOADER) && defined(IN_MODULE) xf86memset( dst, val, n );#elif defined(SUNOS4) memset( (char *) dst, (int) val, (int) n );#else memset(dst, val, n);#endif}/** * Fill memory with a constant 16bit word. * \param dst destination pointer. * \param val value. * \param n number of words. */void_mesa_memset16( unsigned short *dst, unsigned short val, size_t n ){ while (n-- > 0) *dst++ = val;}/** Wrapper around either memcpy() or xf86memcpy() or bzero() */void_mesa_bzero( void *dst, size_t n ){#if defined(XFree86LOADER) && defined(IN_MODULE) xf86memset( dst, 0, n );#elif defined(__FreeBSD__) bzero( dst, n );#else memset( dst, 0, n );#endif}/** Wrapper around either memcmp() or xf86memcmp() */int_mesa_memcmp( const void *s1, const void *s2, size_t n ){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86memcmp( s1, s2, n );#elif defined(SUNOS4) return memcmp( (char *) s1, (char *) s2, (int) n );#else return memcmp(s1, s2, n);#endif}/*@}*//**********************************************************************//** \name Math *//*@{*//** Wrapper around either sin() or xf86sin() */double_mesa_sin(double a){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86sin(a);#else return sin(a);#endif}
/** Single precision wrapper around either sin() or xf86sin() */
float
_mesa_sinf(float a)
{
#if defined(XFree86LOADER) && defined(IN_MODULE)
return (float) xf86sin((double) a);
#else
return (float) sin((double) a);
#endif
}/** Wrapper around either cos() or xf86cos() */double_mesa_cos(double a){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86cos(a);#else return cos(a);#endif}/** Single precision wrapper around either asin() or xf86asin() */float_mesa_asinf(float x){#if defined(XFree86LOADER) && defined(IN_MODULE) return (float) xf86asin((double) x);#else return (float) asin((double) x);#endif}/** Single precision wrapper around either atan() or xf86atan() */float_mesa_atanf(float x){#if defined(XFree86LOADER) && defined(IN_MODULE) return (float) xf86atan((double) x);#else return (float) atan((double) x);#endif}/** Wrapper around either sqrt() or xf86sqrt() */double_mesa_sqrtd(double x){#if defined(XFree86LOADER) && defined(IN_MODULE) return xf86sqrt(x);#else return sqrt(x);#endif}/* * A High Speed, Low Precision Square Root * by Paul Lalonde and Robert Dawson * from "Graphics Gems", Academic Press, 1990 * * SPARC implementation of a fast square root by table * lookup. * SPARC floating point format is as follows: * * BIT 31 30 23 22 0 * sign exponent mantissa */static short sqrttab[0x100]; /* declare table of square roots */static void init_sqrt_table(void){#if defined(USE_IEEE) && !defined(DEBUG) unsigned short i; fi_type fi; /* to access the bits of a float in C quickly */ /* we use a union defined in glheader.h */ for(i=0; i<= 0x7f; i++) { fi.i = 0; /* * Build a float with the bit pattern i as mantissa * and an exponent of 0, stored as 127 */ fi.i = (i << 16) | (127 << 23); fi.f = _mesa_sqrtd(fi.f); /* * Take the square root then strip the first 7 bits of * the mantissa into the table */ sqrttab[i] = (fi.i & 0x7fffff) >> 16; /* * Repeat the process, this time with an exponent of * 1, stored as 128 */ fi.i = 0; fi.i = (i << 16) | (128 << 23); fi.f = sqrt(fi.f); sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16; }#else (void) sqrttab; /* silence compiler warnings */#endif /*HAVE_FAST_MATH*/}/** * Single precision square root. */float_mesa_sqrtf( float x ){#if defined(USE_IEEE) && !defined(DEBUG) fi_type num; /* to access the bits of a float in C * we use a union from glheader.h */ short e; /* the exponent */ if (x == 0.0F) return 0.0F; /* check for square root of 0 */ num.f = x; e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */ /* exponent is stored with 127 added */ num.i &= 0x7fffff; /* leave only the mantissa */ if (e & 0x01) num.i |= 0x800000; /* the exponent is odd so we have to */ /* look it up in the second half of */ /* the lookup table, so we set the */ /* high bit */ e >>= 1; /* divide the exponent by two */ /* note that in C the shift */ /* operators are sign preserving */ /* for signed operands */ /* Do the table lookup, based on the quaternary mantissa, * then reconstruct the result back into a float */ num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23); return num.f;#else return (float) _mesa_sqrtd((double) x);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -