Subversion Repositories shark

Rev

Rev 118 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
685 giacomo 1
/* $Id: imports.c,v 1.6 2004-05-26 10:36:50 giacomo Exp $ */
55 pj 2
 
3
/*
4
 * Mesa 3-D graphics library
5
 * Version:  5.0
6
 *
7
 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a
10
 * copy of this software and associated documentation files (the "Software"),
11
 * to deal in the Software without restriction, including without limitation
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
 * and/or sell copies of the Software, and to permit persons to whom the
14
 * Software is furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included
17
 * in all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
 
27
 
28
/*
29
 * Imports are services which the device driver or window system or
30
 * operating system provides to the core renderer.  The core renderer (Mesa)
31
 * will call these functions in order to do memory allocation, simple I/O,
32
 * etc.
33
 *
34
 * Some drivers will want to override/replace this file with something
35
 * specialized, but that'll be rare.
36
 *
37
 * Eventually, I want to move roll the glheader.h file into this.
38
 *
39
 * The OpenGL SI's __GLimports structure allows per-context specification of
40
 * replacements for the standard C lib functions.  In practice that's probably
41
 * never needed; compile-time replacements are far more likely.
42
 *
43
 * The _mesa_foo() functions defined here don't in general take a context
44
 * parameter.  I guess we can change that someday, if need be.
45
 * So for now, the __GLimports stuff really isn't used.
46
 */
47
 
48
 
49
#include "glheader.h"
50
#include "mtypes.h"
51
#include "context.h"
52
#include "imports.h"
53
 
54
 
55
#define MAXSTRING 4000  /* for vsnprintf() */
56
 
57
#ifdef WIN32
58
#define vsnprintf _vsnprintf
59
#endif
60
 
61
 
62
/**********************************************************************/
63
/* Wrappers for standard C library functions                          */
64
/**********************************************************************/
65
 
66
/*
67
 * Functions still needed:
68
 * scanf
69
 * qsort
70
 * bsearch
71
 * rand and RAND_MAX
72
 */
73
 
74
void *
75
_mesa_malloc(size_t bytes)
76
{
77
#if defined(XFree86LOADER) && defined(IN_MODULE)
78
   return xf86malloc(bytes);
79
#else
80
   return malloc(bytes);
81
#endif
82
}
83
 
84
 
85
void *
86
_mesa_calloc(size_t bytes)
87
{
88
#if defined(XFree86LOADER) && defined(IN_MODULE)
89
   return xf86calloc(1, bytes);
90
#else
91
   return calloc(1, bytes);
92
#endif
93
}
94
 
95
 
96
void
97
_mesa_free(void *ptr)
98
{
99
#if defined(XFree86LOADER) && defined(IN_MODULE)
100
   xf86free(ptr);
101
#else
102
   free(ptr);
103
#endif
104
}
105
 
106
 
107
void *
108
_mesa_align_malloc(size_t bytes, unsigned long alignment)
109
{
110
   unsigned long ptr, buf;
111
 
112
   ASSERT( alignment > 0 );
113
 
114
   /* Allocate extra memory to accomodate rounding up the address for
115
    * alignment and to record the real malloc address.
116
    */
117
   ptr = (unsigned long) _mesa_malloc(bytes + alignment + sizeof(void *));
118
   if (!ptr)
119
      return NULL;
120
 
121
   buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment - 1);
122
   *(unsigned long *)(buf - sizeof(void *)) = ptr;
123
 
124
#ifdef DEBUG
125
   /* mark the non-aligned area */
126
   while ( ptr < buf - sizeof(void *) ) {
127
      *(unsigned long *)ptr = 0xcdcdcdcd;
128
      ptr += sizeof(unsigned long);
129
   }
130
#endif
131
 
132
   return (void *) buf;
133
}
134
 
135
 
136
void *
137
_mesa_align_calloc(size_t bytes, unsigned long alignment)
138
{
139
   unsigned long ptr, buf;
140
 
141
   ASSERT( alignment > 0 );
142
 
143
   ptr = (unsigned long) _mesa_calloc(bytes + alignment + sizeof(void *));
144
   if (!ptr)
145
      return NULL;
146
 
147
   buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment - 1);
148
   *(unsigned long *)(buf - sizeof(void *)) = ptr;
149
 
150
#ifdef DEBUG
151
   /* mark the non-aligned area */
152
   while ( ptr < buf - sizeof(void *) ) {
153
      *(unsigned long *)ptr = 0xcdcdcdcd;
154
      ptr += sizeof(unsigned long);
155
   }
156
#endif
157
 
158
   return (void *)buf;
159
}
160
 
161
 
162
void
163
_mesa_align_free(void *ptr)
164
{
165
#if 0
166
   _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr - sizeof(void *))) );
167
#else
168
   /* The actuall address to free is stuffed in the word immediately
169
    * before the address the client sees.
170
    */
171
   void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
172
   void *realAddr = *cubbyHole;
173
   _mesa_free(realAddr);
174
#endif
175
}
176
 
177
 
178
void *
179
_mesa_memcpy(void *dest, const void *src, size_t n)
180
{
181
#if defined(XFree86LOADER) && defined(IN_MODULE)
182
   return xf86memcpy(dest, src, n);
183
#elif defined(SUNOS4)
184
   return memcpy((char *) dest, (char *) src, (int) n);
185
#else
186
   return memcpy(dest, src, n);
187
#endif
188
}
189
 
190
 
191
void
192
_mesa_memset( void *dst, int val, size_t n )
193
{
194
#if defined(XFree86LOADER) && defined(IN_MODULE)
195
   xf86memset( dst, val, n );
196
#elif defined(SUNOS4)
197
   memset( (char *) dst, (int) val, (int) n );
198
#else
199
   memset(dst, val, n);
200
#endif
201
}
202
 
203
 
204
void
205
_mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
206
{
207
   while (n-- > 0)
208
      *dst++ = val;
209
}
210
 
211
 
212
void
213
_mesa_bzero( void *dst, size_t n )
214
{
215
#if defined(XFree86LOADER) && defined(IN_MODULE)
216
   xf86memset( dst, 0, n );
217
#elif defined(__FreeBSD__)
218
   bzero( dst, n );
219
#else
220
   memset( dst, 0, n );
221
#endif
222
}
223
 
224
 
225
double
226
_mesa_sin(double a)
227
{
228
#if defined(XFree86LOADER) && defined(IN_MODULE)
229
   return xf86sin(a);
230
#else
231
   return sin(a);
232
#endif
233
}
234
 
235
 
236
double
237
_mesa_cos(double a)
238
{
239
#if defined(XFree86LOADER) && defined(IN_MODULE)
240
   return xf86cos(a);
241
#else
242
   return cos(a);
243
#endif
244
}
245
 
246
 
247
double
248
_mesa_sqrt(double x)
249
{
250
#if defined(XFree86LOADER) && defined(IN_MODULE)
251
   return xf86sqrt(x);
252
#else
253
   return sqrt(x);
254
#endif
255
}
256
 
257
 
258
double
259
_mesa_pow(double x, double y)
260
{
261
#if defined(XFree86LOADER) && defined(IN_MODULE)
262
   return xf86pow(x, y);
263
#else
264
   return pow(x, y);
265
#endif
266
}
267
 
268
 
269
char *
270
_mesa_getenv( const char *var )
271
{
272
#if defined(XFree86LOADER) && defined(IN_MODULE)
273
   return xf86getenv(var);
274
#else
275
   return getenv(var);
276
#endif
277
}
278
 
279
 
280
char *
281
_mesa_strstr( const char *haystack, const char *needle )
282
{
283
#if defined(XFree86LOADER) && defined(IN_MODULE)
284
   return xf86strstr(haystack, needle);
285
#else
286
   return strstr(haystack, needle);
287
#endif
288
}
289
 
290
 
291
char *
292
_mesa_strncat( char *dest, const char *src, size_t n )
293
{
294
#if defined(XFree86LOADER) && defined(IN_MODULE)
295
   return xf86strncat(dest, src, n);
296
#else
297
   return strncat(dest, src, n);
298
#endif
299
}
300
 
301
 
302
char *
303
_mesa_strcpy( char *dest, const char *src )
304
{
305
#if defined(XFree86LOADER) && defined(IN_MODULE)
306
   return xf86strcpy(dest, src);
307
#else
308
   return strcpy(dest, src);
309
#endif
310
}
311
 
312
 
313
char *
314
_mesa_strncpy( char *dest, const char *src, size_t n )
315
{
316
#if defined(XFree86LOADER) && defined(IN_MODULE)
317
   return xf86strncpy(dest, src, n);
318
#else
319
   return strncpy(dest, src, n);
320
#endif
321
}
322
 
323
 
324
size_t
325
_mesa_strlen( const char *s )
326
{
327
#if defined(XFree86LOADER) && defined(IN_MODULE)
328
   return xf86strlen(s);
329
#else
330
   return strlen(s);
331
#endif
332
}
333
 
334
 
335
int
336
_mesa_strcmp( const char *s1, const char *s2 )
337
{
338
#if defined(XFree86LOADER) && defined(IN_MODULE)
339
   return xf86strcmp(s1, s2);
340
#else
341
   return strcmp(s1, s2);
342
#endif
343
}
344
 
345
 
346
int
347
_mesa_strncmp( const char *s1, const char *s2, size_t n )
348
{
349
#if defined(XFree86LOADER) && defined(IN_MODULE)
350
   return xf86strncmp(s1, s2, n);
351
#else
352
   return strncmp(s1, s2, n);
353
#endif
354
}
355
 
356
 
357
int
358
_mesa_atoi(const char *s)
359
{
360
#if defined(XFree86LOADER) && defined(IN_MODULE)
361
   return xf86atoi(s);
362
#else
87 giacomo 363
   return (int)atoi((char *)s);
55 pj 364
#endif
365
}
366
 
86 giacomo 367
 
55 pj 368
int
369
_mesa_sprintf( char *str, const char *fmt, ... )
370
{
371
   int r;
685 giacomo 372
   va_list parms;
373
   va_start(parms,fmt);
374
   r = vsprintf(str,fmt,parms);
375
   va_end(parms);  
55 pj 376
   return r;
377
}
378
 
86 giacomo 379
 
55 pj 380
void
381
_mesa_printf( const char *fmtString, ... )
382
{
383
   char s[MAXSTRING];
685 giacomo 384
   va_list parms;
385
   int r;
386
 
387
   va_start(parms,fmtString);
388
   r = vsprintf(s,fmtString,parms);
389
   va_end(parms);
390
 
55 pj 391
#if defined(XFree86LOADER) && defined(IN_MODULE)
392
   xf86printf("%s", s);
393
#else
118 giacomo 394
   cprintf("%s\n", s);
55 pj 395
#endif
396
}
397
 
398
 
399
void
400
_mesa_warning( GLcontext *ctx, const char *fmtString, ... )
401
{
402
   GLboolean debug;
403
   char str[MAXSTRING];
685 giacomo 404
   va_list parms;
405
   int r;
406
 
407
   va_start(parms,fmtString);
408
   r = vsprintf(str,fmtString,parms);
409
   va_end(parms);
55 pj 410
#ifdef DEBUG
411
   debug = GL_TRUE; /* always print warning */
412
#else
413
   debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
414
#endif
415
   if (debug) {
416
#if defined(XFree86LOADER) && defined(IN_MODULE)
417
      xf86fprintf(stderr, "Mesa warning: %s\n", str);
418
#else
86 giacomo 419
      cprintf("Mesa warning: %s\n", str);
55 pj 420
#endif
421
   }
422
}
423
 
424
 
425
/*
426
 * This function is called when the Mesa user has stumbled into a code
427
 * path which may not be implemented fully or correctly.
428
 */
429
void
430
_mesa_problem( const GLcontext *ctx, const char *s )
431
{
432
   (void) ctx;
433
#if defined(XFree86LOADER) && defined(IN_MODULE)
434
   xf86fprintf(stderr, "Mesa implementation error: %s\n", s);
435
   xf86fprintf(stderr, "Please report to the DRI project at dri.sourceforge.net\n");
436
#else
72 giacomo 437
   cprintf("Mesa implementation error: %s\n", s);
438
   cprintf("Please report to the Mesa bug database at www.mesa3d.org\n" );
55 pj 439
#endif
440
}
441
 
442
 
443
/*
444
 * If in debug mode, print error message to stdout.
445
 * Also, record the error code by calling _mesa_record_error().
446
 * Input:  ctx - the GL context
447
 *         error - the error value
448
 *         fmtString - printf-style format string, followed by optional args
449
 */
450
void
451
_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
452
{
453
   const char *debugEnv;
454
   GLboolean debug;
455
 
456
   debugEnv = _mesa_getenv("MESA_DEBUG");
457
 
458
#ifdef DEBUG
86 giacomo 459
   if (debugEnv && _mesa_strstr(debugEnv, "silent"))
460
      debug = GL_FALSE;
461
   else
55 pj 462
      debug = GL_TRUE;
463
#else
464
   if (debugEnv)
465
      debug = GL_TRUE;
466
   else
467
      debug = GL_FALSE;
468
#endif
469
 
470
   if (debug) {
471
      va_list args;
86 giacomo 472
      char where[MAXSTRING];
55 pj 473
      const char *errstr;
86 giacomo 474
 
55 pj 475
      va_start( args, fmtString );  
685 giacomo 476
      vsprintf( where, fmtString, args );
55 pj 477
      va_end( args );
86 giacomo 478
 
55 pj 479
      switch (error) {
480
         case GL_NO_ERROR:
481
            errstr = "GL_NO_ERROR";
482
            break;
483
         case GL_INVALID_VALUE:
484
            errstr = "GL_INVALID_VALUE";
485
            break;
486
         case GL_INVALID_ENUM:
487
            errstr = "GL_INVALID_ENUM";
488
            break;
489
         case GL_INVALID_OPERATION:
490
            errstr = "GL_INVALID_OPERATION";
491
            break;
492
         case GL_STACK_OVERFLOW:
493
            errstr = "GL_STACK_OVERFLOW";
494
            break;
495
         case GL_STACK_UNDERFLOW:
496
            errstr = "GL_STACK_UNDERFLOW";
497
            break;
498
         case GL_OUT_OF_MEMORY:
499
            errstr = "GL_OUT_OF_MEMORY";
500
            break;
501
         case GL_TABLE_TOO_LARGE:
502
            errstr = "GL_TABLE_TOO_LARGE";
503
            break;
504
         default:
505
            errstr = "unknown";
506
            break;
507
      }
86 giacomo 508
      _mesa_debug(ctx, "Mesa user error: %s in %s\n", errstr, where);
55 pj 509
   }
510
 
511
   _mesa_record_error(ctx, error);
512
}  
513
 
514
 
515
/*
516
 * Call this to report debug information.  Uses stderr.
517
 */
518
void
519
_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
520
{
521
   char s[MAXSTRING];
522
   va_list args;
523
   va_start(args, fmtString);
685 giacomo 524
   vsprintf(s, fmtString, args);
86 giacomo 525
   va_end(args);
55 pj 526
#if defined(XFree86LOADER) && defined(IN_MODULE)
527
   xf86fprintf(stderr, "Mesa: %s", s);
528
#else
118 giacomo 529
   cprintf("Mesa: %s\n", s);
55 pj 530
#endif
531
}
532
 
533
 
534
 
535
/**********************************************************************/
536
/* Default Imports Wrapper                                            */
537
/**********************************************************************/
538
 
539
static void *
540
default_malloc(__GLcontext *gc, size_t size)
541
{
542
   return _mesa_malloc(size);
543
}
544
 
545
static void *
546
default_calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
547
{
548
   return _mesa_calloc(numElem * elemSize);
549
}
550
 
551
static void *
552
default_realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
553
{
554
#if defined(XFree86LOADER) && defined(IN_MODULE)
555
   return xf86realloc(oldAddr, newSize);
556
#else
557
   return realloc(oldAddr, newSize);
558
#endif
559
}
560
 
561
static void
562
default_free(__GLcontext *gc, void *addr)
563
{
564
   _mesa_free(addr);
565
}
566
 
567
static char * CAPI
568
default_getenv( __GLcontext *gc, const char *var )
569
{
570
   return _mesa_getenv(var);
571
}
572
 
573
static void
574
default_warning(__GLcontext *gc, char *str)
575
{
576
   _mesa_warning(gc, str);
577
}
578
 
579
static void
580
default_fatal(__GLcontext *gc, char *str)
581
{
582
   _mesa_problem(gc, str);
583
}
584
 
585
static int CAPI
586
default_atoi(__GLcontext *gc, const char *str)
587
{
87 giacomo 588
   return (int)atoi((char *)str);
55 pj 589
}
590
 
591
static int CAPI
592
default_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
593
{
594
   int r;
86 giacomo 595
   va_list args;
596
   va_start( args, fmt );  
685 giacomo 597
   r = vsprintf( str, fmt, args );
86 giacomo 598
   va_end( args );
55 pj 599
   return r;
600
}
601
 
602
static void * CAPI
603
default_fopen(__GLcontext *gc, const char *path, const char *mode)
604
{
685 giacomo 605
   return NULL;
55 pj 606
}
607
 
608
static int CAPI
609
default_fclose(__GLcontext *gc, void *stream)
610
{
685 giacomo 611
   return 0;
55 pj 612
}
613
 
614
static int CAPI
615
default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
616
{
685 giacomo 617
   return 0;
55 pj 618
}
619
 
620
/* XXX this really is driver-specific and can't be here */
621
static __GLdrawablePrivate *
622
default_GetDrawablePrivate(__GLcontext *gc)
623
{
624
   return NULL;
625
}
626
 
627
 
628
 
629
 
630
/*
631
 * Initialize a __GLimports object to point to the functions in
632
 * this file.  This is to be called from device drivers.
633
 * Input:  imports - the object to init
634
 *         driverCtx - pointer to device driver-specific data
635
 */
636
void
637
_mesa_init_default_imports(__GLimports *imports, void *driverCtx)
638
{
639
   imports->malloc = default_malloc;
640
   imports->calloc = default_calloc;
641
   imports->realloc = default_realloc;
642
   imports->free = default_free;
643
   imports->warning = default_warning;
644
   imports->fatal = default_fatal;
645
   imports->getenv = default_getenv; /* not used for now */
646
   imports->atoi = default_atoi;
647
   imports->sprintf = default_sprintf;
648
   imports->fopen = default_fopen;
649
   imports->fclose = default_fclose;
650
   imports->fprintf = default_fprintf;
651
   imports->getDrawablePrivate = default_GetDrawablePrivate;
652
   imports->other = driverCtx;
653
}