Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
CROSS-PLATFORM PORTABILITY GUIDELINES FOR GALLIUM3D
2
 
3
 
4
= General Considerations =
5
 
6
The state tracker and winsys driver support a rather limited number of
7
platforms. However, the pipe drivers are meant to run in a wide number of
8
platforms. Hence the pipe drivers, the auxiliary modules, and all public
9
headers in general, should strictly follow these guidelines to ensure
10
 
11
 
12
= Compiler Support =
13
 
14
* Include the p_compiler.h.
15
 
16
* Don't use the 'inline' keyword, use the INLINE macro in p_compiler.h instead.
17
 
18
* Cast explicitly when converting to integer types of smaller sizes.
19
 
20
* Cast explicitly when converting between float, double and integral types.
21
 
22
* Don't use named struct initializers.
23
 
24
* Don't use variable number of macro arguments. Use static inline functions
25
instead.
26
 
27
* Don't use C99 features.
28
 
29
= Standard Library =
30
 
31
* Avoid including standard library headers. Most standard library functions are
32
not available in Windows Kernel Mode. Use the appropriate p_*.h include.
33
 
34
== Memory Allocation ==
35
 
36
* Use MALLOC, CALLOC, FREE instead of the malloc, calloc, free functions.
37
 
38
* Use align_pointer() function defined in u_memory.h for aligning pointers
39
 in a portable way.
40
 
41
== Debugging ==
42
 
43
* Use the functions/macros in p_debug.h.
44
 
45
* Don't include assert.h, call abort, printf, etc.
46
 
47
 
48
= Code Style =
49
 
50
== Inherantice in C ==
51
 
52
The main thing we do is mimic inheritance by structure containment.
53
 
54
Here's a silly made-up example:
55
 
56
/* base class */
57
struct buffer
58
{
59
  int size;
60
  void (*validate)(struct buffer *buf);
61
};
62
 
63
/* sub-class of bufffer */
64
struct texture_buffer
65
{
66
  struct buffer base;  /* the base class, MUST COME FIRST! */
67
  int format;
68
  int width, height;
69
};
70
 
71
 
72
Then, we'll typically have cast-wrapper functions to convert base-class
73
pointers to sub-class pointers where needed:
74
 
75
static inline struct vertex_buffer *vertex_buffer(struct buffer *buf)
76
{
77
  return (struct vertex_buffer *) buf;
78
}
79
 
80
 
81
To create/init a sub-classed object:
82
 
83
struct buffer *create_texture_buffer(int w, int h, int format)
84
{
85
  struct texture_buffer *t = malloc(sizeof(*t));
86
  t->format = format;
87
  t->width = w;
88
  t->height = h;
89
  t->base.size = w * h;
90
  t->base.validate = tex_validate;
91
  return &t->base;
92
}
93
 
94
Example sub-class method:
95
 
96
void tex_validate(struct buffer *buf)
97
{
98
  struct texture_buffer *tb = texture_buffer(buf);
99
  assert(tb->format);
100
  assert(tb->width);
101
  assert(tb->height);
102
}
103
 
104
 
105
Note that we typically do not use typedefs to make "class names"; we use
106
'struct whatever' everywhere.
107
 
108
Gallium's pipe_context and the subclassed psb_context, etc are prime examples
109
of this.  There's also many examples in Mesa and the Mesa state tracker.