Subversion Repositories Kolibri OS

Rev

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

  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.
  110.