Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /*
  27.  * Off-Screen Mesa rendering / Rendering into client memory space
  28.  *
  29.  * Note on thread safety:  this driver is thread safe.  All
  30.  * functions are reentrant.  The notion of current context is
  31.  * managed by the core _mesa_make_current() and _mesa_get_current_context()
  32.  * functions.  Those functions are thread-safe.
  33.  */
  34.  
  35.  
  36. #include "main/glheader.h"
  37. #include "GL/osmesa.h"
  38. #include "main/api_exec.h"
  39. #include "main/context.h"
  40. #include "main/extensions.h"
  41. #include "main/formats.h"
  42. #include "main/framebuffer.h"
  43. #include "main/imports.h"
  44. #include "main/macros.h"
  45. #include "main/mipmap.h"
  46. #include "main/mtypes.h"
  47. #include "main/renderbuffer.h"
  48. #include "main/version.h"
  49. #include "main/vtxfmt.h"
  50. #include "swrast/swrast.h"
  51. #include "swrast_setup/swrast_setup.h"
  52. #include "swrast/s_context.h"
  53. #include "swrast/s_lines.h"
  54. #include "swrast/s_renderbuffer.h"
  55. #include "swrast/s_triangle.h"
  56. #include "tnl/tnl.h"
  57. #include "tnl/t_context.h"
  58. #include "tnl/t_pipeline.h"
  59. #include "drivers/common/driverfuncs.h"
  60. #include "drivers/common/meta.h"
  61. #include "vbo/vbo.h"
  62.  
  63.  
  64. #define OSMESA_RENDERBUFFER_CLASS 0x053
  65.  
  66.  
  67. /**
  68.  * OSMesa rendering context, derived from core Mesa struct gl_context.
  69.  */
  70. struct osmesa_context
  71. {
  72.    struct gl_context mesa;              /*< Base class - this must be first */
  73.    struct gl_config *gl_visual;         /*< Describes the buffers */
  74.    struct swrast_renderbuffer *srb;     /*< The user's colorbuffer */
  75.    struct gl_framebuffer *gl_buffer;    /*< The framebuffer, containing user's rb */
  76.    GLenum format;               /*< User-specified context format */
  77.    GLint userRowLength;         /*< user-specified number of pixels per row */
  78.    GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */
  79.    GLvoid *rowaddr[SWRAST_MAX_HEIGHT];  /*< address of first pixel in each image row */
  80.    GLboolean yup;               /*< TRUE  -> Y increases upward */
  81.                                 /*< FALSE -> Y increases downward */
  82.    GLenum DataType;
  83. };
  84.  
  85.  
  86. static INLINE OSMesaContext
  87. OSMESA_CONTEXT(struct gl_context *ctx)
  88. {
  89.    /* Just cast, since we're using structure containment */
  90.    return (OSMesaContext) ctx;
  91. }
  92.  
  93.  
  94. /**********************************************************************/
  95. /*** Private Device Driver Functions                                ***/
  96. /**********************************************************************/
  97.  
  98.  
  99. static const GLubyte *
  100. get_string( struct gl_context *ctx, GLenum name )
  101. {
  102.    (void) ctx;
  103.    switch (name) {
  104.       case GL_RENDERER:
  105. #if CHAN_BITS == 32
  106.          return (const GLubyte *) "Mesa OffScreen32";
  107. #elif CHAN_BITS == 16
  108.          return (const GLubyte *) "Mesa OffScreen16";
  109. #else
  110.          return (const GLubyte *) "Mesa OffScreen";
  111. #endif
  112.       default:
  113.          return NULL;
  114.    }
  115. }
  116.  
  117.  
  118. static void
  119. osmesa_update_state( struct gl_context *ctx, GLuint new_state )
  120. {
  121.    /* easy - just propogate */
  122.    _swrast_InvalidateState( ctx, new_state );
  123.    _swsetup_InvalidateState( ctx, new_state );
  124.    _tnl_InvalidateState( ctx, new_state );
  125.    _vbo_InvalidateState( ctx, new_state );
  126. }
  127.  
  128.  
  129.  
  130. /**
  131.  * Macros for optimized line/triangle rendering.
  132.  * Only for 8-bit channel, RGBA, BGRA, ARGB formats.
  133.  */
  134.  
  135. #define PACK_RGBA(DST, R, G, B, A)      \
  136. do {                                    \
  137.    (DST)[osmesa->rInd] = R;             \
  138.    (DST)[osmesa->gInd] = G;             \
  139.    (DST)[osmesa->bInd] = B;             \
  140.    (DST)[osmesa->aInd] = A;             \
  141. } while (0)
  142.  
  143. #define PIXELADDR4(X,Y)  ((GLchan *) osmesa->rowaddr[Y] + 4 * (X))
  144.  
  145.  
  146. /**
  147.  * Draw a flat-shaded, RGB line into an osmesa buffer.
  148.  */
  149. #define NAME flat_rgba_line
  150. #define CLIP_HACK 1
  151. #define SETUP_CODE                                              \
  152.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);            \
  153.    const GLchan *color = vert1->color;
  154.  
  155. #define PLOT(X, Y)                                              \
  156. do {                                                            \
  157.    GLchan *p = PIXELADDR4(X, Y);                                \
  158.    PACK_RGBA(p, color[0], color[1], color[2], color[3]);        \
  159. } while (0)
  160.  
  161. #include "swrast/s_linetemp.h"
  162.  
  163.  
  164.  
  165. /**
  166.  * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
  167.  */
  168. #define NAME flat_rgba_z_line
  169. #define CLIP_HACK 1
  170. #define INTERP_Z 1
  171. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  172. #define SETUP_CODE                                      \
  173.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);    \
  174.    const GLchan *color = vert1->color;
  175.  
  176. #define PLOT(X, Y)                                      \
  177. do {                                                    \
  178.    if (Z < *zPtr) {                                     \
  179.       GLchan *p = PIXELADDR4(X, Y);                     \
  180.       PACK_RGBA(p, color[RCOMP], color[GCOMP],          \
  181.                    color[BCOMP], color[ACOMP]);         \
  182.       *zPtr = Z;                                        \
  183.    }                                                    \
  184. } while (0)
  185.  
  186. #include "swrast/s_linetemp.h"
  187.  
  188.  
  189.  
  190. /**
  191.  * Analyze context state to see if we can provide a fast line drawing
  192.  * function.  Otherwise, return NULL.
  193.  */
  194. static swrast_line_func
  195. osmesa_choose_line_function( struct gl_context *ctx )
  196. {
  197.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  198.    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
  199.  
  200.    if (ctx->RenderMode != GL_RENDER)      return NULL;
  201.    if (ctx->Line.SmoothFlag)              return NULL;
  202.    if (ctx->Texture._EnabledUnits)        return NULL;
  203.    if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
  204.    if (ctx->Line.Width != 1.0F)           return NULL;
  205.    if (ctx->Line.StippleFlag)             return NULL;
  206.    if (ctx->Line.SmoothFlag)              return NULL;
  207.    if (osmesa->format != OSMESA_RGBA &&
  208.        osmesa->format != OSMESA_BGRA &&
  209.        osmesa->format != OSMESA_ARGB)     return NULL;
  210.  
  211.    if (swrast->_RasterMask==DEPTH_BIT
  212.        && ctx->Depth.Func==GL_LESS
  213.        && ctx->Depth.Mask==GL_TRUE
  214.        && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
  215.       return (swrast_line_func) flat_rgba_z_line;
  216.    }
  217.  
  218.    if (swrast->_RasterMask == 0) {
  219.       return (swrast_line_func) flat_rgba_line;
  220.    }
  221.  
  222.    return (swrast_line_func) NULL;
  223. }
  224.  
  225.  
  226. /**********************************************************************/
  227. /*****                 Optimized triangle rendering               *****/
  228. /**********************************************************************/
  229.  
  230.  
  231. /*
  232.  * Smooth-shaded, z-less triangle, RGBA color.
  233.  */
  234. #define NAME smooth_rgba_z_triangle
  235. #define INTERP_Z 1
  236. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  237. #define INTERP_RGB 1
  238. #define INTERP_ALPHA 1
  239. #define SETUP_CODE \
  240.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  241. #define RENDER_SPAN( span ) {                                   \
  242.    GLuint i;                                                    \
  243.    GLchan *img = PIXELADDR4(span.x, span.y);                    \
  244.    for (i = 0; i < span.end; i++, img += 4) {                   \
  245.       const GLuint z = FixedToDepth(span.z);                    \
  246.       if (z < zRow[i]) {                                        \
  247.          PACK_RGBA(img, FixedToChan(span.red),                  \
  248.             FixedToChan(span.green), FixedToChan(span.blue),    \
  249.             FixedToChan(span.alpha));                           \
  250.          zRow[i] = z;                                           \
  251.       }                                                         \
  252.       span.red += span.redStep;                                 \
  253.       span.green += span.greenStep;                             \
  254.       span.blue += span.blueStep;                               \
  255.       span.alpha += span.alphaStep;                             \
  256.       span.z += span.zStep;                                     \
  257.    }                                                            \
  258. }
  259. #include "swrast/s_tritemp.h"
  260.  
  261.  
  262.  
  263. /*
  264.  * Flat-shaded, z-less triangle, RGBA color.
  265.  */
  266. #define NAME flat_rgba_z_triangle
  267. #define INTERP_Z 1
  268. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  269. #define SETUP_CODE                                              \
  270.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);            \
  271.    GLuint pixel;                                                \
  272.    PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1],     \
  273.                                 v2->color[2], v2->color[3]);
  274.  
  275. #define RENDER_SPAN( span ) {                           \
  276.    GLuint i;                                            \
  277.    GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \
  278.    for (i = 0; i < span.end; i++) {                     \
  279.       const GLuint z = FixedToDepth(span.z);            \
  280.       if (z < zRow[i]) {                                \
  281.          img[i] = pixel;                                \
  282.          zRow[i] = z;                                   \
  283.       }                                                 \
  284.       span.z += span.zStep;                             \
  285.    }                                                    \
  286. }
  287.  
  288. #include "swrast/s_tritemp.h"
  289.  
  290.  
  291.  
  292. /**
  293.  * Return pointer to an optimized triangle function if possible.
  294.  */
  295. static swrast_tri_func
  296. osmesa_choose_triangle_function( struct gl_context *ctx )
  297. {
  298.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  299.    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
  300.  
  301.    if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
  302.    if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
  303.    if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
  304.    if (ctx->Texture._EnabledUnits)      return (swrast_tri_func) NULL;
  305.    if (osmesa->format != OSMESA_RGBA &&
  306.        osmesa->format != OSMESA_BGRA &&
  307.        osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
  308.    if (ctx->Polygon.CullFlag &&
  309.        ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
  310.                                         return (swrast_tri_func) NULL;
  311.  
  312.    if (swrast->_RasterMask == DEPTH_BIT &&
  313.        ctx->Depth.Func == GL_LESS &&
  314.        ctx->Depth.Mask == GL_TRUE &&
  315.        ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
  316.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  317.          return (swrast_tri_func) smooth_rgba_z_triangle;
  318.       }
  319.       else {
  320.          return (swrast_tri_func) flat_rgba_z_triangle;
  321.       }
  322.    }
  323.    return (swrast_tri_func) NULL;
  324. }
  325.  
  326.  
  327.  
  328. /* Override for the swrast triangle-selection function.  Try to use one
  329.  * of our internal triangle functions, otherwise fall back to the
  330.  * standard swrast functions.
  331.  */
  332. static void
  333. osmesa_choose_triangle( struct gl_context *ctx )
  334. {
  335.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  336.  
  337.    swrast->Triangle = osmesa_choose_triangle_function( ctx );
  338.    if (!swrast->Triangle)
  339.       _swrast_choose_triangle( ctx );
  340. }
  341.  
  342. static void
  343. osmesa_choose_line( struct gl_context *ctx )
  344. {
  345.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  346.  
  347.    swrast->Line = osmesa_choose_line_function( ctx );
  348.    if (!swrast->Line)
  349.       _swrast_choose_line( ctx );
  350. }
  351.  
  352.  
  353.  
  354. /**
  355.  * Recompute the values of the context's rowaddr array.
  356.  */
  357. static void
  358. compute_row_addresses( OSMesaContext osmesa )
  359. {
  360.    GLint bytesPerRow, i;
  361.    GLubyte *origin = (GLubyte *) osmesa->srb->Buffer;
  362.    GLint rowlength; /* in pixels */
  363.    GLint height = osmesa->srb->Base.Height;
  364.  
  365.    if (osmesa->userRowLength)
  366.       rowlength = osmesa->userRowLength;
  367.    else
  368.       rowlength = osmesa->srb->Base.Width;
  369.  
  370.    bytesPerRow = rowlength * _mesa_get_format_bytes(osmesa->srb->Base.Format);
  371.  
  372.    if (osmesa->yup) {
  373.       /* Y=0 is bottom line of window */
  374.       for (i = 0; i < height; i++) {
  375.          osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow);
  376.       }
  377.    }
  378.    else {
  379.       /* Y=0 is top line of window */
  380.       for (i = 0; i < height; i++) {
  381.          GLint j = height - i - 1;
  382.          osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow);
  383.       }
  384.    }
  385. }
  386.  
  387.  
  388.  
  389. /**
  390.  * Don't use _mesa_delete_renderbuffer since we can't free rb->Buffer.
  391.  */
  392. static void
  393. osmesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
  394. {
  395.    _mesa_delete_renderbuffer(ctx, rb);
  396. }
  397.  
  398.  
  399. /**
  400.  * Allocate renderbuffer storage.  We don't actually allocate any storage
  401.  * since we're using a user-provided buffer.
  402.  * Just set up all the gl_renderbuffer methods.
  403.  */
  404. static GLboolean
  405. osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  406.                             GLenum internalFormat, GLuint width, GLuint height)
  407. {
  408.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  409.  
  410.    /* Note: we can ignoring internalFormat for "window-system" renderbuffers */
  411.    (void) internalFormat;
  412.  
  413.    /* Given the user-provided format and type, figure out which MESA_FORMAT_x
  414.     * to use.
  415.     * XXX There aren't Mesa formats for all the possible combinations here!
  416.     * XXX Specifically, there's only RGBA-order 16-bit/channel and float
  417.     * XXX formats.
  418.     * XXX The 8-bit/channel formats should all be OK.
  419.     */
  420.    if (osmesa->format == OSMESA_RGBA) {
  421.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  422.          if (_mesa_little_endian())
  423.             rb->Format = MESA_FORMAT_RGBA8888_REV;
  424.          else
  425.             rb->Format = MESA_FORMAT_RGBA8888;
  426.       }
  427.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  428.          rb->Format = MESA_FORMAT_RGBA_16;
  429.       }
  430.       else {
  431.          rb->Format = MESA_FORMAT_RGBA_FLOAT32;
  432.       }
  433.    }
  434.    else if (osmesa->format == OSMESA_BGRA) {
  435.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  436.          if (_mesa_little_endian())
  437.             rb->Format = MESA_FORMAT_ARGB8888;
  438.          else
  439.             rb->Format = MESA_FORMAT_ARGB8888_REV;
  440.       }
  441.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  442.          _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLushort");
  443.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  444.       }
  445.       else {
  446.          _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLfloat");
  447.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  448.       }
  449.    }
  450.    else if (osmesa->format == OSMESA_ARGB) {
  451.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  452.          if (_mesa_little_endian())
  453.             rb->Format = MESA_FORMAT_ARGB8888_REV;
  454.          else
  455.             rb->Format = MESA_FORMAT_ARGB8888;
  456.       }
  457.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  458.          _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLushort");
  459.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  460.       }
  461.       else {
  462.          _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLfloat");
  463.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  464.       }
  465.    }
  466.    else if (osmesa->format == OSMESA_RGB) {
  467.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  468.          rb->Format = MESA_FORMAT_RGB888;
  469.       }
  470.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  471.          _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLushort");
  472.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  473.       }
  474.       else {
  475.          _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLfloat");
  476.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  477.       }
  478.    }
  479.    else if (osmesa->format == OSMESA_BGR) {
  480.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  481.          rb->Format = MESA_FORMAT_BGR888;
  482.       }
  483.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  484.          _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLushort");
  485.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  486.       }
  487.       else {
  488.          _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLfloat");
  489.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  490.       }
  491.    }
  492.    else if (osmesa->format == OSMESA_RGB_565) {
  493.       ASSERT(osmesa->DataType == GL_UNSIGNED_BYTE);
  494.       rb->Format = MESA_FORMAT_RGB565;
  495.    }
  496.    else {
  497.       _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage");
  498.    }
  499.  
  500.    rb->Width = width;
  501.    rb->Height = height;
  502.  
  503.    compute_row_addresses( osmesa );
  504.  
  505.    return GL_TRUE;
  506. }
  507.  
  508.  
  509. /**
  510.  * Allocate a new renderbuffer to describe the user-provided color buffer.
  511.  */
  512. static struct swrast_renderbuffer *
  513. new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
  514. {
  515.    const GLuint name = 0;
  516.    struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer);
  517.  
  518.    if (srb) {
  519.       _mesa_init_renderbuffer(&srb->Base, name);
  520.  
  521.       srb->Base.ClassID = OSMESA_RENDERBUFFER_CLASS;
  522.       srb->Base.RefCount = 1;
  523.       srb->Base.Delete = osmesa_delete_renderbuffer;
  524.       srb->Base.AllocStorage = osmesa_renderbuffer_storage;
  525.  
  526.       srb->Base.InternalFormat = GL_RGBA;
  527.       srb->Base._BaseFormat = GL_RGBA;
  528.  
  529.       return srb;
  530.    }
  531.    return NULL;
  532. }
  533.  
  534.  
  535.  
  536. static void
  537. osmesa_MapRenderbuffer(struct gl_context *ctx,
  538.                        struct gl_renderbuffer *rb,
  539.                        GLuint x, GLuint y, GLuint w, GLuint h,
  540.                        GLbitfield mode,
  541.                        GLubyte **mapOut, GLint *rowStrideOut)
  542. {
  543.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  544.  
  545.    if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
  546.       /* this is an OSMesa renderbuffer which wraps user memory */
  547.       struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  548.       const GLuint bpp = _mesa_get_format_bytes(rb->Format);
  549.       GLint rowStride; /* in bytes */
  550.  
  551.       if (osmesa->userRowLength)
  552.          rowStride = osmesa->userRowLength * bpp;
  553.       else
  554.          rowStride = rb->Width * bpp;
  555.  
  556.       if (!osmesa->yup) {
  557.          /* Y=0 is top line of window */
  558.          y = rb->Height - y - 1;
  559.          *rowStrideOut = -rowStride;
  560.       }
  561.       else {
  562.          *rowStrideOut = rowStride;
  563.       }
  564.  
  565.       *mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
  566.    }
  567.    else {
  568.       _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
  569.                                     mapOut, rowStrideOut);
  570.    }
  571. }
  572.  
  573.  
  574. static void
  575. osmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
  576. {
  577.    if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
  578.       /* no-op */
  579.    }
  580.    else {
  581.       _swrast_unmap_soft_renderbuffer(ctx, rb);
  582.    }
  583. }
  584.  
  585.  
  586. /**********************************************************************/
  587. /*****                    Public Functions                        *****/
  588. /**********************************************************************/
  589.  
  590.  
  591. /**
  592.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  593.  * an RGBA vs Color-Index mode flag.
  594.  *
  595.  * Input:  format - Must be GL_RGBA
  596.  *         sharelist - specifies another OSMesaContext with which to share
  597.  *                     display lists.  NULL indicates no sharing.
  598.  * Return:  an OSMesaContext or 0 if error
  599.  */
  600. GLAPI OSMesaContext GLAPIENTRY
  601. OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  602. {
  603.    return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
  604.                                  8, 0, sharelist);
  605. }
  606.  
  607.  
  608.  
  609. /**
  610.  * New in Mesa 3.5
  611.  *
  612.  * Create context and specify size of ancillary buffers.
  613.  */
  614. GLAPI OSMesaContext GLAPIENTRY
  615. OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
  616.                         GLint accumBits, OSMesaContext sharelist )
  617. {
  618.    OSMesaContext osmesa;
  619.    struct dd_function_table functions;
  620.    GLint rind, gind, bind, aind;
  621.    GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
  622.  
  623.    rind = gind = bind = aind = 0;
  624.    if (format==OSMESA_RGBA) {
  625.       redBits = CHAN_BITS;
  626.       greenBits = CHAN_BITS;
  627.       blueBits = CHAN_BITS;
  628.       alphaBits = CHAN_BITS;
  629.       rind = 0;
  630.       gind = 1;
  631.       bind = 2;
  632.       aind = 3;
  633.    }
  634.    else if (format==OSMESA_BGRA) {
  635.       redBits = CHAN_BITS;
  636.       greenBits = CHAN_BITS;
  637.       blueBits = CHAN_BITS;
  638.       alphaBits = CHAN_BITS;
  639.       bind = 0;
  640.       gind = 1;
  641.       rind = 2;
  642.       aind = 3;
  643.    }
  644.    else if (format==OSMESA_ARGB) {
  645.       redBits = CHAN_BITS;
  646.       greenBits = CHAN_BITS;
  647.       blueBits = CHAN_BITS;
  648.       alphaBits = CHAN_BITS;
  649.       aind = 0;
  650.       rind = 1;
  651.       gind = 2;
  652.       bind = 3;
  653.    }
  654.    else if (format==OSMESA_RGB) {
  655.       redBits = CHAN_BITS;
  656.       greenBits = CHAN_BITS;
  657.       blueBits = CHAN_BITS;
  658.       alphaBits = 0;
  659.       rind = 0;
  660.       gind = 1;
  661.       bind = 2;
  662.    }
  663.    else if (format==OSMESA_BGR) {
  664.       redBits = CHAN_BITS;
  665.       greenBits = CHAN_BITS;
  666.       blueBits = CHAN_BITS;
  667.       alphaBits = 0;
  668.       rind = 2;
  669.       gind = 1;
  670.       bind = 0;
  671.    }
  672. #if CHAN_TYPE == GL_UNSIGNED_BYTE
  673.    else if (format==OSMESA_RGB_565) {
  674.       redBits = 5;
  675.       greenBits = 6;
  676.       blueBits = 5;
  677.       alphaBits = 0;
  678.       rind = 0; /* not used */
  679.       gind = 0;
  680.       bind = 0;
  681.    }
  682. #endif
  683.    else {
  684.       return NULL;
  685.    }
  686.  
  687.    osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
  688.    if (osmesa) {
  689.       osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
  690.                                                GL_FALSE,    /* stereo */
  691.                                                redBits,
  692.                                                greenBits,
  693.                                                blueBits,
  694.                                                alphaBits,
  695.                                                depthBits,
  696.                                                stencilBits,
  697.                                                accumBits,
  698.                                                accumBits,
  699.                                                accumBits,
  700.                                                alphaBits ? accumBits : 0,
  701.                                                1            /* num samples */
  702.                                                );
  703.       if (!osmesa->gl_visual) {
  704.          free(osmesa);
  705.          return NULL;
  706.       }
  707.  
  708.       /* Initialize device driver function table */
  709.       _mesa_init_driver_functions(&functions);
  710.       /* override with our functions */
  711.       functions.GetString = get_string;
  712.       functions.UpdateState = osmesa_update_state;
  713.  
  714.       if (!_mesa_initialize_context(&osmesa->mesa,
  715.                                     API_OPENGL_COMPAT,
  716.                                     osmesa->gl_visual,
  717.                                     sharelist ? &sharelist->mesa
  718.                                               : (struct gl_context *) NULL,
  719.                                     &functions)) {
  720.          _mesa_destroy_visual( osmesa->gl_visual );
  721.          free(osmesa);
  722.          return NULL;
  723.       }
  724.  
  725.       _mesa_enable_sw_extensions(&(osmesa->mesa));
  726.  
  727.       osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
  728.       if (!osmesa->gl_buffer) {
  729.          _mesa_destroy_visual( osmesa->gl_visual );
  730.          _mesa_free_context_data( &osmesa->mesa );
  731.          free(osmesa);
  732.          return NULL;
  733.       }
  734.  
  735.       /* Create depth/stencil/accum buffers.  We'll create the color
  736.        * buffer later in OSMesaMakeCurrent().
  737.        */
  738.       _swrast_add_soft_renderbuffers(osmesa->gl_buffer,
  739.                                      GL_FALSE, /* color */
  740.                                      osmesa->gl_visual->haveDepthBuffer,
  741.                                      osmesa->gl_visual->haveStencilBuffer,
  742.                                      osmesa->gl_visual->haveAccumBuffer,
  743.                                      GL_FALSE, /* alpha */
  744.                                      GL_FALSE /* aux */ );
  745.  
  746.       osmesa->format = format;
  747.       osmesa->userRowLength = 0;
  748.       osmesa->yup = GL_TRUE;
  749.       osmesa->rInd = rind;
  750.       osmesa->gInd = gind;
  751.       osmesa->bInd = bind;
  752.       osmesa->aInd = aind;
  753.  
  754.       _mesa_meta_init(&osmesa->mesa);
  755.  
  756.       /* Initialize the software rasterizer and helper modules. */
  757.       {
  758.          struct gl_context *ctx = &osmesa->mesa;
  759.          SWcontext *swrast;
  760.          TNLcontext *tnl;
  761.  
  762.          if (!_swrast_CreateContext( ctx ) ||
  763.              !_vbo_CreateContext( ctx ) ||
  764.              !_tnl_CreateContext( ctx ) ||
  765.              !_swsetup_CreateContext( ctx )) {
  766.             _mesa_destroy_visual(osmesa->gl_visual);
  767.             _mesa_free_context_data(ctx);
  768.             free(osmesa);
  769.             return NULL;
  770.          }
  771.  
  772.          _swsetup_Wakeup( ctx );
  773.  
  774.          /* use default TCL pipeline */
  775.          tnl = TNL_CONTEXT(ctx);
  776.          tnl->Driver.RunPipeline = _tnl_run_pipeline;
  777.  
  778.          ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
  779.          ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;
  780.  
  781.          ctx->Driver.GenerateMipmap = _mesa_generate_mipmap;
  782.  
  783.          /* Extend the software rasterizer with our optimized line and triangle
  784.           * drawing functions.
  785.           */
  786.          swrast = SWRAST_CONTEXT( ctx );
  787.          swrast->choose_line = osmesa_choose_line;
  788.          swrast->choose_triangle = osmesa_choose_triangle;
  789.  
  790.          _mesa_compute_version(ctx);
  791.  
  792.          /* Exec table initialization requires the version to be computed */
  793.          _mesa_initialize_dispatch_tables(ctx);
  794.          _mesa_initialize_vbo_vtxfmt(ctx);
  795.       }
  796.    }
  797.    return osmesa;
  798. }
  799.  
  800.  
  801. /**
  802.  * Destroy an Off-Screen Mesa rendering context.
  803.  *
  804.  * \param osmesa  the context to destroy
  805.  */
  806. GLAPI void GLAPIENTRY
  807. OSMesaDestroyContext( OSMesaContext osmesa )
  808. {
  809.    if (osmesa) {
  810.       if (osmesa->srb)
  811.          _mesa_reference_renderbuffer((struct gl_renderbuffer **) &osmesa->srb, NULL);
  812.  
  813.       _mesa_meta_free( &osmesa->mesa );
  814.  
  815.       _swsetup_DestroyContext( &osmesa->mesa );
  816.       _tnl_DestroyContext( &osmesa->mesa );
  817.       _vbo_DestroyContext( &osmesa->mesa );
  818.       _swrast_DestroyContext( &osmesa->mesa );
  819.  
  820.       _mesa_destroy_visual( osmesa->gl_visual );
  821.       _mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
  822.  
  823.       _mesa_free_context_data( &osmesa->mesa );
  824.       free( osmesa );
  825.    }
  826. }
  827.  
  828.  
  829. /**
  830.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  831.  * block of memory which the client provides.  Its size must be at least
  832.  * as large as width*height*sizeof(type).  Its address should be a multiple
  833.  * of 4 if using RGBA mode.
  834.  *
  835.  * Image data is stored in the order of glDrawPixels:  row-major order
  836.  * with the lower-left image pixel stored in the first array position
  837.  * (ie. bottom-to-top).
  838.  *
  839.  * If the context's viewport hasn't been initialized yet, it will now be
  840.  * initialized to (0,0,width,height).
  841.  *
  842.  * Input:  osmesa - the rendering context
  843.  *         buffer - the image buffer memory
  844.  *         type - data type for pixel components
  845.  *            Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
  846.  *            are supported.  But if Mesa's been compiled with CHAN_BITS==16
  847.  *            then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.  And if
  848.  *            Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT,
  849.  *            GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.
  850.  *         width, height - size of image buffer in pixels, at least 1
  851.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid osmesa,
  852.  *          invalid buffer address, invalid type, width<1, height<1,
  853.  *          width>internal limit or height>internal limit.
  854.  */
  855. GLAPI GLboolean GLAPIENTRY
  856. OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
  857.                    GLsizei width, GLsizei height )
  858. {
  859.    if (!osmesa || !buffer ||
  860.        width < 1 || height < 1 ||
  861.        width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) {
  862.       return GL_FALSE;
  863.    }
  864.  
  865.    if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
  866.       return GL_FALSE;
  867.    }
  868.  
  869. #if 0
  870.    if (!(type == GL_UNSIGNED_BYTE ||
  871.          (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) ||
  872.          (type == GL_FLOAT && CHAN_BITS == 32))) {
  873.       /* i.e. is sizeof(type) * 8 > CHAN_BITS? */
  874.       return GL_FALSE;
  875.    }
  876. #endif
  877.  
  878.    osmesa_update_state( &osmesa->mesa, 0 );
  879.  
  880.    /* Call this periodically to detect when the user has begun using
  881.     * GL rendering from multiple threads.
  882.     */
  883.    _glapi_check_multithread();
  884.  
  885.  
  886.    /* Create a front/left color buffer which wraps the user-provided buffer.
  887.     * There is no back color buffer.
  888.     * If the user tries to use a 8, 16 or 32-bit/channel buffer that
  889.     * doesn't match what Mesa was compiled for (CHAN_BITS) the
  890.     * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer
  891.     * that converts rendering from CHAN_BITS to the user-requested channel
  892.     * size.
  893.     */
  894.    if (!osmesa->srb) {
  895.       osmesa->srb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
  896.       _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
  897.       _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
  898.                              &osmesa->srb->Base);
  899.       assert(osmesa->srb->Base.RefCount == 2);
  900.    }
  901.  
  902.    osmesa->DataType = type;
  903.  
  904.    /* Set renderbuffer fields.  Set width/height = 0 to force
  905.     * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer()
  906.     */
  907.    osmesa->srb->Buffer = buffer;
  908.    osmesa->srb->Base.Width = osmesa->srb->Base.Height = 0;
  909.  
  910.    /* Set the framebuffer's size.  This causes the
  911.     * osmesa_renderbuffer_storage() function to get called.
  912.     */
  913.    _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
  914.  
  915.    _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
  916.  
  917.    /* Remove renderbuffer attachment, then re-add.  This installs the
  918.     * renderbuffer adaptor/wrapper if needed (for bpp conversion).
  919.     */
  920.    _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
  921.    _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
  922.                           &osmesa->srb->Base);
  923.  
  924.  
  925.    /* this updates the visual's red/green/blue/alphaBits fields */
  926.    _mesa_update_framebuffer_visual(&osmesa->mesa, osmesa->gl_buffer);
  927.  
  928.    /* update the framebuffer size */
  929.    _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
  930.  
  931.    return GL_TRUE;
  932. }
  933.  
  934.  
  935.  
  936. GLAPI OSMesaContext GLAPIENTRY
  937. OSMesaGetCurrentContext( void )
  938. {
  939.    struct gl_context *ctx = _mesa_get_current_context();
  940.    if (ctx)
  941.       return (OSMesaContext) ctx;
  942.    else
  943.       return NULL;
  944. }
  945.  
  946.  
  947.  
  948. GLAPI void GLAPIENTRY
  949. OSMesaPixelStore( GLint pname, GLint value )
  950. {
  951.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  952.  
  953.    switch (pname) {
  954.       case OSMESA_ROW_LENGTH:
  955.          if (value<0) {
  956.             _mesa_error( &osmesa->mesa, GL_INVALID_VALUE,
  957.                       "OSMesaPixelStore(value)" );
  958.             return;
  959.          }
  960.          osmesa->userRowLength = value;
  961.          break;
  962.       case OSMESA_Y_UP:
  963.          osmesa->yup = value ? GL_TRUE : GL_FALSE;
  964.          break;
  965.       default:
  966.          _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
  967.          return;
  968.    }
  969.  
  970.    compute_row_addresses( osmesa );
  971. }
  972.  
  973.  
  974. GLAPI void GLAPIENTRY
  975. OSMesaGetIntegerv( GLint pname, GLint *value )
  976. {
  977.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  978.  
  979.    switch (pname) {
  980.       case OSMESA_WIDTH:
  981.          if (osmesa->gl_buffer)
  982.             *value = osmesa->gl_buffer->Width;
  983.          else
  984.             *value = 0;
  985.          return;
  986.       case OSMESA_HEIGHT:
  987.          if (osmesa->gl_buffer)
  988.             *value = osmesa->gl_buffer->Height;
  989.          else
  990.             *value = 0;
  991.          return;
  992.       case OSMESA_FORMAT:
  993.          *value = osmesa->format;
  994.          return;
  995.       case OSMESA_TYPE:
  996.          /* current color buffer's data type */
  997.          *value = osmesa->DataType;
  998.          return;
  999.       case OSMESA_ROW_LENGTH:
  1000.          *value = osmesa->userRowLength;
  1001.          return;
  1002.       case OSMESA_Y_UP:
  1003.          *value = osmesa->yup;
  1004.          return;
  1005.       case OSMESA_MAX_WIDTH:
  1006.          *value = SWRAST_MAX_WIDTH;
  1007.          return;
  1008.       case OSMESA_MAX_HEIGHT:
  1009.          *value = SWRAST_MAX_HEIGHT;
  1010.          return;
  1011.       default:
  1012.          _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
  1013.          return;
  1014.    }
  1015. }
  1016.  
  1017.  
  1018. /**
  1019.  * Return the depth buffer associated with an OSMesa context.
  1020.  * Input:  c - the OSMesa context
  1021.  * Output:  width, height - size of buffer in pixels
  1022.  *          bytesPerValue - bytes per depth value (2 or 4)
  1023.  *          buffer - pointer to depth buffer values
  1024.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1025.  */
  1026. GLAPI GLboolean GLAPIENTRY
  1027. OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
  1028.                       GLint *bytesPerValue, void **buffer )
  1029. {
  1030.    struct swrast_renderbuffer *srb = NULL;
  1031.  
  1032.    if (c->gl_buffer)
  1033.       srb = swrast_renderbuffer(c->gl_buffer->
  1034.                                 Attachment[BUFFER_DEPTH].Renderbuffer);
  1035.  
  1036.    if (!srb || !srb->Buffer) {
  1037.       *width = 0;
  1038.       *height = 0;
  1039.       *bytesPerValue = 0;
  1040.       *buffer = 0;
  1041.       return GL_FALSE;
  1042.    }
  1043.    else {
  1044.       *width = srb->Base.Width;
  1045.       *height = srb->Base.Height;
  1046.       if (c->gl_visual->depthBits <= 16)
  1047.          *bytesPerValue = sizeof(GLushort);
  1048.       else
  1049.          *bytesPerValue = sizeof(GLuint);
  1050.       *buffer = (void *) srb->Buffer;
  1051.       return GL_TRUE;
  1052.    }
  1053. }
  1054.  
  1055.  
  1056. /**
  1057.  * Return the color buffer associated with an OSMesa context.
  1058.  * Input:  c - the OSMesa context
  1059.  * Output:  width, height - size of buffer in pixels
  1060.  *          format - the pixel format (OSMESA_FORMAT)
  1061.  *          buffer - pointer to color buffer values
  1062.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1063.  */
  1064. GLAPI GLboolean GLAPIENTRY
  1065. OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width,
  1066.                       GLint *height, GLint *format, void **buffer )
  1067. {
  1068.    if (osmesa->srb && osmesa->srb->Buffer) {
  1069.       *width = osmesa->srb->Base.Width;
  1070.       *height = osmesa->srb->Base.Height;
  1071.       *format = osmesa->format;
  1072.       *buffer = (void *) osmesa->srb->Buffer;
  1073.       return GL_TRUE;
  1074.    }
  1075.    else {
  1076.       *width = 0;
  1077.       *height = 0;
  1078.       *format = 0;
  1079.       *buffer = 0;
  1080.       return GL_FALSE;
  1081.    }
  1082. }
  1083.  
  1084.  
  1085. struct name_function
  1086. {
  1087.    const char *Name;
  1088.    OSMESAproc Function;
  1089. };
  1090.  
  1091. static struct name_function functions[] = {
  1092.    { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext },
  1093.    { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt },
  1094.    { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext },
  1095.    { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent },
  1096.    { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext },
  1097.    { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore },
  1098.    { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv },
  1099.    { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer },
  1100.    { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer },
  1101.    { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress },
  1102.    { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp },
  1103.    { NULL, NULL }
  1104. };
  1105.  
  1106.  
  1107. GLAPI OSMESAproc GLAPIENTRY
  1108. OSMesaGetProcAddress( const char *funcName )
  1109. {
  1110.    int i;
  1111.    for (i = 0; functions[i].Name; i++) {
  1112.       if (strcmp(functions[i].Name, funcName) == 0)
  1113.          return functions[i].Function;
  1114.    }
  1115.    return _glapi_get_proc_address(funcName);
  1116. }
  1117.  
  1118.  
  1119. GLAPI void GLAPIENTRY
  1120. OSMesaColorClamp(GLboolean enable)
  1121. {
  1122.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  1123.  
  1124.    if (enable == GL_TRUE) {
  1125.       osmesa->mesa.Color.ClampFragmentColor = GL_TRUE;
  1126.    }
  1127.    else {
  1128.       osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
  1129.    }
  1130. }
  1131.  
  1132.  
  1133. /**
  1134.  * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in
  1135.  * libglapi.a.  We need to define them here.
  1136.  */
  1137. #ifdef GLX_INDIRECT_RENDERING
  1138.  
  1139. #define GL_GLEXT_PROTOTYPES
  1140. #include "GL/gl.h"
  1141. #include "glapi/glapi.h"
  1142. #include "glapi/glapitable.h"
  1143.  
  1144. #if defined(USE_MGL_NAMESPACE)
  1145. #define NAME(func)  mgl##func
  1146. #else
  1147. #define NAME(func)  gl##func
  1148. #endif
  1149.  
  1150. #define DISPATCH(FUNC, ARGS, MESSAGE)           \
  1151.    GET_DISPATCH()->FUNC ARGS
  1152.  
  1153. #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE)    \
  1154.    return GET_DISPATCH()->FUNC ARGS
  1155.  
  1156. /* skip normal ones */
  1157. #define _GLAPI_SKIP_NORMAL_ENTRY_POINTS
  1158. #include "glapi/glapitemp.h"
  1159.  
  1160. #endif /* GLX_INDIRECT_RENDERING */
  1161.  
  1162. int atexit(void (*func)(void))
  1163. {
  1164.     return 0;
  1165. };
  1166.