Subversion Repositories Kolibri OS

Rev

Rev 4401 | 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->DrawBuffer &&
  201.        ctx->DrawBuffer->Visual.redBits == 32) {
  202.       /* the special-case line functions in this file don't work
  203.        * for float color channels.
  204.        */
  205.       return NULL;
  206.    }
  207.  
  208.    if (ctx->RenderMode != GL_RENDER)      return NULL;
  209.    if (ctx->Line.SmoothFlag)              return NULL;
  210.    if (ctx->Texture._EnabledUnits)        return NULL;
  211.    if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
  212.    if (ctx->Line.Width != 1.0F)           return NULL;
  213.    if (ctx->Line.StippleFlag)             return NULL;
  214.    if (ctx->Line.SmoothFlag)              return NULL;
  215.    if (osmesa->format != OSMESA_RGBA &&
  216.        osmesa->format != OSMESA_BGRA &&
  217.        osmesa->format != OSMESA_ARGB)     return NULL;
  218.  
  219.    if (swrast->_RasterMask==DEPTH_BIT
  220.        && ctx->Depth.Func==GL_LESS
  221.        && ctx->Depth.Mask==GL_TRUE
  222.        && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
  223.       return (swrast_line_func) flat_rgba_z_line;
  224.    }
  225.  
  226.    if (swrast->_RasterMask == 0) {
  227.       return (swrast_line_func) flat_rgba_line;
  228.    }
  229.  
  230.    return (swrast_line_func) NULL;
  231. }
  232.  
  233.  
  234. /**********************************************************************/
  235. /*****                 Optimized triangle rendering               *****/
  236. /**********************************************************************/
  237.  
  238.  
  239. /*
  240.  * Smooth-shaded, z-less triangle, RGBA color.
  241.  */
  242. #define NAME smooth_rgba_z_triangle
  243. #define INTERP_Z 1
  244. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  245. #define INTERP_RGB 1
  246. #define INTERP_ALPHA 1
  247. #define SETUP_CODE \
  248.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  249. #define RENDER_SPAN( span ) {                                   \
  250.    GLuint i;                                                    \
  251.    GLchan *img = PIXELADDR4(span.x, span.y);                    \
  252.    for (i = 0; i < span.end; i++, img += 4) {                   \
  253.       const GLuint z = FixedToDepth(span.z);                    \
  254.       if (z < zRow[i]) {                                        \
  255.          PACK_RGBA(img, FixedToChan(span.red),                  \
  256.             FixedToChan(span.green), FixedToChan(span.blue),    \
  257.             FixedToChan(span.alpha));                           \
  258.          zRow[i] = z;                                           \
  259.       }                                                         \
  260.       span.red += span.redStep;                                 \
  261.       span.green += span.greenStep;                             \
  262.       span.blue += span.blueStep;                               \
  263.       span.alpha += span.alphaStep;                             \
  264.       span.z += span.zStep;                                     \
  265.    }                                                            \
  266. }
  267. #include "swrast/s_tritemp.h"
  268.  
  269.  
  270.  
  271. /*
  272.  * Flat-shaded, z-less triangle, RGBA color.
  273.  */
  274. #define NAME flat_rgba_z_triangle
  275. #define INTERP_Z 1
  276. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  277. #define SETUP_CODE                                              \
  278.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);            \
  279.    GLuint pixel;                                                \
  280.    PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1],     \
  281.                                 v2->color[2], v2->color[3]);
  282.  
  283. #define RENDER_SPAN( span ) {                           \
  284.    GLuint i;                                            \
  285.    GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \
  286.    for (i = 0; i < span.end; i++) {                     \
  287.       const GLuint z = FixedToDepth(span.z);            \
  288.       if (z < zRow[i]) {                                \
  289.          img[i] = pixel;                                \
  290.          zRow[i] = z;                                   \
  291.       }                                                 \
  292.       span.z += span.zStep;                             \
  293.    }                                                    \
  294. }
  295.  
  296. #include "swrast/s_tritemp.h"
  297.  
  298.  
  299.  
  300. /**
  301.  * Return pointer to an optimized triangle function if possible.
  302.  */
  303. static swrast_tri_func
  304. osmesa_choose_triangle_function( struct gl_context *ctx )
  305. {
  306.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  307.    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
  308.  
  309.    if (ctx->DrawBuffer &&
  310.        ctx->DrawBuffer->Visual.redBits == 32) {
  311.       /* the special-case triangle functions in this file don't work
  312.        * for float color channels.
  313.        */
  314.       return (swrast_tri_func) NULL;
  315.    }
  316.  
  317.    if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
  318.    if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
  319.    if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
  320.    if (ctx->Texture._EnabledUnits)      return (swrast_tri_func) NULL;
  321.    if (osmesa->format != OSMESA_RGBA &&
  322.        osmesa->format != OSMESA_BGRA &&
  323.        osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
  324.    if (ctx->Polygon.CullFlag &&
  325.        ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
  326.                                         return (swrast_tri_func) NULL;
  327.  
  328.    if (swrast->_RasterMask == DEPTH_BIT &&
  329.        ctx->Depth.Func == GL_LESS &&
  330.        ctx->Depth.Mask == GL_TRUE &&
  331.        ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
  332.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  333.          return (swrast_tri_func) smooth_rgba_z_triangle;
  334.       }
  335.       else {
  336.          return (swrast_tri_func) flat_rgba_z_triangle;
  337.       }
  338.    }
  339.    return (swrast_tri_func) NULL;
  340. }
  341.  
  342.  
  343.  
  344. /* Override for the swrast triangle-selection function.  Try to use one
  345.  * of our internal triangle functions, otherwise fall back to the
  346.  * standard swrast functions.
  347.  */
  348. static void
  349. osmesa_choose_triangle( struct gl_context *ctx )
  350. {
  351.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  352.  
  353.    swrast->Triangle = osmesa_choose_triangle_function( ctx );
  354.    if (!swrast->Triangle)
  355.       _swrast_choose_triangle( ctx );
  356. }
  357.  
  358. static void
  359. osmesa_choose_line( struct gl_context *ctx )
  360. {
  361.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  362.  
  363.    swrast->Line = osmesa_choose_line_function( ctx );
  364.    if (!swrast->Line)
  365.       _swrast_choose_line( ctx );
  366. }
  367.  
  368.  
  369.  
  370. /**
  371.  * Recompute the values of the context's rowaddr array.
  372.  */
  373. static void
  374. compute_row_addresses( OSMesaContext osmesa )
  375. {
  376.    GLint bytesPerRow, i;
  377.    GLubyte *origin = (GLubyte *) osmesa->srb->Buffer;
  378.    GLint rowlength; /* in pixels */
  379.    GLint height = osmesa->srb->Base.Height;
  380.  
  381.    if (osmesa->userRowLength)
  382.       rowlength = osmesa->userRowLength;
  383.    else
  384.       rowlength = osmesa->srb->Base.Width;
  385.  
  386.    bytesPerRow = rowlength * _mesa_get_format_bytes(osmesa->srb->Base.Format);
  387.  
  388.    if (osmesa->yup) {
  389.       /* Y=0 is bottom line of window */
  390.       for (i = 0; i < height; i++) {
  391.          osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow);
  392.       }
  393.    }
  394.    else {
  395.       /* Y=0 is top line of window */
  396.       for (i = 0; i < height; i++) {
  397.          GLint j = height - i - 1;
  398.          osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow);
  399.       }
  400.    }
  401. }
  402.  
  403.  
  404.  
  405. /**
  406.  * Don't use _mesa_delete_renderbuffer since we can't free rb->Buffer.
  407.  */
  408. static void
  409. osmesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
  410. {
  411.    _mesa_delete_renderbuffer(ctx, rb);
  412. }
  413.  
  414.  
  415. /**
  416.  * Allocate renderbuffer storage.  We don't actually allocate any storage
  417.  * since we're using a user-provided buffer.
  418.  * Just set up all the gl_renderbuffer methods.
  419.  */
  420. static GLboolean
  421. osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  422.                             GLenum internalFormat, GLuint width, GLuint height)
  423. {
  424.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  425.  
  426.    /* Note: we can ignoring internalFormat for "window-system" renderbuffers */
  427.    (void) internalFormat;
  428.  
  429.    /* Given the user-provided format and type, figure out which MESA_FORMAT_x
  430.     * to use.
  431.     * XXX There aren't Mesa formats for all the possible combinations here!
  432.     * XXX Specifically, there's only RGBA-order 16-bit/channel and float
  433.     * XXX formats.
  434.     * XXX The 8-bit/channel formats should all be OK.
  435.     */
  436.    if (osmesa->format == OSMESA_RGBA) {
  437.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  438.          if (_mesa_little_endian())
  439.             rb->Format = MESA_FORMAT_RGBA8888_REV;
  440.          else
  441.             rb->Format = MESA_FORMAT_RGBA8888;
  442.       }
  443.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  444.          rb->Format = MESA_FORMAT_RGBA_16;
  445.       }
  446.       else {
  447.          rb->Format = MESA_FORMAT_RGBA_FLOAT32;
  448.       }
  449.    }
  450.    else if (osmesa->format == OSMESA_BGRA) {
  451.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  452.          if (_mesa_little_endian())
  453.             rb->Format = MESA_FORMAT_ARGB8888;
  454.          else
  455.             rb->Format = MESA_FORMAT_ARGB8888_REV;
  456.       }
  457.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  458.          _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLushort");
  459.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  460.       }
  461.       else {
  462.          _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLfloat");
  463.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  464.       }
  465.    }
  466.    else if (osmesa->format == OSMESA_ARGB) {
  467.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  468.          if (_mesa_little_endian())
  469.             rb->Format = MESA_FORMAT_ARGB8888_REV;
  470.          else
  471.             rb->Format = MESA_FORMAT_ARGB8888;
  472.       }
  473.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  474.          _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLushort");
  475.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  476.       }
  477.       else {
  478.          _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLfloat");
  479.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  480.       }
  481.    }
  482.    else if (osmesa->format == OSMESA_RGB) {
  483.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  484.          rb->Format = MESA_FORMAT_RGB888;
  485.       }
  486.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  487.          _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLushort");
  488.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  489.       }
  490.       else {
  491.          _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLfloat");
  492.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  493.       }
  494.    }
  495.    else if (osmesa->format == OSMESA_BGR) {
  496.       if (osmesa->DataType == GL_UNSIGNED_BYTE) {
  497.          rb->Format = MESA_FORMAT_BGR888;
  498.       }
  499.       else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
  500.          _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLushort");
  501.          rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
  502.       }
  503.       else {
  504.          _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLfloat");
  505.          rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
  506.       }
  507.    }
  508.    else if (osmesa->format == OSMESA_RGB_565) {
  509.       ASSERT(osmesa->DataType == GL_UNSIGNED_BYTE);
  510.       rb->Format = MESA_FORMAT_RGB565;
  511.    }
  512.    else {
  513.       _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage");
  514.    }
  515.  
  516.    rb->Width = width;
  517.    rb->Height = height;
  518.  
  519.    compute_row_addresses( osmesa );
  520.  
  521.    return GL_TRUE;
  522. }
  523.  
  524.  
  525. /**
  526.  * Allocate a new renderbuffer to describe the user-provided color buffer.
  527.  */
  528. static struct swrast_renderbuffer *
  529. new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
  530. {
  531.    const GLuint name = 0;
  532.    struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer);
  533.  
  534.    if (srb) {
  535.       _mesa_init_renderbuffer(&srb->Base, name);
  536.  
  537.       srb->Base.ClassID = OSMESA_RENDERBUFFER_CLASS;
  538.       srb->Base.RefCount = 1;
  539.       srb->Base.Delete = osmesa_delete_renderbuffer;
  540.       srb->Base.AllocStorage = osmesa_renderbuffer_storage;
  541.  
  542.       srb->Base.InternalFormat = GL_RGBA;
  543.       srb->Base._BaseFormat = GL_RGBA;
  544.  
  545.       return srb;
  546.    }
  547.    return NULL;
  548. }
  549.  
  550.  
  551.  
  552. static void
  553. osmesa_MapRenderbuffer(struct gl_context *ctx,
  554.                        struct gl_renderbuffer *rb,
  555.                        GLuint x, GLuint y, GLuint w, GLuint h,
  556.                        GLbitfield mode,
  557.                        GLubyte **mapOut, GLint *rowStrideOut)
  558. {
  559.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  560.  
  561.    if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
  562.       /* this is an OSMesa renderbuffer which wraps user memory */
  563.       struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  564.       const GLuint bpp = _mesa_get_format_bytes(rb->Format);
  565.       GLint rowStride; /* in bytes */
  566.  
  567.       if (osmesa->userRowLength)
  568.          rowStride = osmesa->userRowLength * bpp;
  569.       else
  570.          rowStride = rb->Width * bpp;
  571.  
  572.       if (!osmesa->yup) {
  573.          /* Y=0 is top line of window */
  574.          y = rb->Height - y - 1;
  575.          *rowStrideOut = -rowStride;
  576.       }
  577.       else {
  578.          *rowStrideOut = rowStride;
  579.       }
  580.  
  581.       *mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
  582.    }
  583.    else {
  584.       _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
  585.                                     mapOut, rowStrideOut);
  586.    }
  587. }
  588.  
  589.  
  590. static void
  591. osmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
  592. {
  593.    if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
  594.       /* no-op */
  595.    }
  596.    else {
  597.       _swrast_unmap_soft_renderbuffer(ctx, rb);
  598.    }
  599. }
  600.  
  601.  
  602. /**********************************************************************/
  603. /*****                    Public Functions                        *****/
  604. /**********************************************************************/
  605.  
  606.  
  607. /**
  608.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  609.  * an RGBA vs Color-Index mode flag.
  610.  *
  611.  * Input:  format - Must be GL_RGBA
  612.  *         sharelist - specifies another OSMesaContext with which to share
  613.  *                     display lists.  NULL indicates no sharing.
  614.  * Return:  an OSMesaContext or 0 if error
  615.  */
  616. GLAPI OSMesaContext GLAPIENTRY
  617. OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  618. {
  619.    return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
  620.                                  8, 0, sharelist);
  621. }
  622.  
  623.  
  624.  
  625. /**
  626.  * New in Mesa 3.5
  627.  *
  628.  * Create context and specify size of ancillary buffers.
  629.  */
  630. GLAPI OSMesaContext GLAPIENTRY
  631. OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
  632.                         GLint accumBits, OSMesaContext sharelist )
  633. {
  634.    OSMesaContext osmesa;
  635.    struct dd_function_table functions;
  636.    GLint rind, gind, bind, aind;
  637.    GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
  638.  
  639.    rind = gind = bind = aind = 0;
  640.    if (format==OSMESA_RGBA) {
  641.       redBits = CHAN_BITS;
  642.       greenBits = CHAN_BITS;
  643.       blueBits = CHAN_BITS;
  644.       alphaBits = CHAN_BITS;
  645.       rind = 0;
  646.       gind = 1;
  647.       bind = 2;
  648.       aind = 3;
  649.    }
  650.    else if (format==OSMESA_BGRA) {
  651.       redBits = CHAN_BITS;
  652.       greenBits = CHAN_BITS;
  653.       blueBits = CHAN_BITS;
  654.       alphaBits = CHAN_BITS;
  655.       bind = 0;
  656.       gind = 1;
  657.       rind = 2;
  658.       aind = 3;
  659.    }
  660.    else if (format==OSMESA_ARGB) {
  661.       redBits = CHAN_BITS;
  662.       greenBits = CHAN_BITS;
  663.       blueBits = CHAN_BITS;
  664.       alphaBits = CHAN_BITS;
  665.       aind = 0;
  666.       rind = 1;
  667.       gind = 2;
  668.       bind = 3;
  669.    }
  670.    else if (format==OSMESA_RGB) {
  671.       redBits = CHAN_BITS;
  672.       greenBits = CHAN_BITS;
  673.       blueBits = CHAN_BITS;
  674.       alphaBits = 0;
  675.       rind = 0;
  676.       gind = 1;
  677.       bind = 2;
  678.    }
  679.    else if (format==OSMESA_BGR) {
  680.       redBits = CHAN_BITS;
  681.       greenBits = CHAN_BITS;
  682.       blueBits = CHAN_BITS;
  683.       alphaBits = 0;
  684.       rind = 2;
  685.       gind = 1;
  686.       bind = 0;
  687.    }
  688. #if CHAN_TYPE == GL_UNSIGNED_BYTE
  689.    else if (format==OSMESA_RGB_565) {
  690.       redBits = 5;
  691.       greenBits = 6;
  692.       blueBits = 5;
  693.       alphaBits = 0;
  694.       rind = 0; /* not used */
  695.       gind = 0;
  696.       bind = 0;
  697.    }
  698. #endif
  699.    else {
  700.       return NULL;
  701.    }
  702.  
  703.    osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
  704.    if (osmesa) {
  705.       osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
  706.                                                GL_FALSE,    /* stereo */
  707.                                                redBits,
  708.                                                greenBits,
  709.                                                blueBits,
  710.                                                alphaBits,
  711.                                                depthBits,
  712.                                                stencilBits,
  713.                                                accumBits,
  714.                                                accumBits,
  715.                                                accumBits,
  716.                                                alphaBits ? accumBits : 0,
  717.                                                1            /* num samples */
  718.                                                );
  719.       if (!osmesa->gl_visual) {
  720.          free(osmesa);
  721.          return NULL;
  722.       }
  723.  
  724.       /* Initialize device driver function table */
  725.       _mesa_init_driver_functions(&functions);
  726.       /* override with our functions */
  727.       functions.GetString = get_string;
  728.       functions.UpdateState = osmesa_update_state;
  729.  
  730.       if (!_mesa_initialize_context(&osmesa->mesa,
  731.                                     API_OPENGL_COMPAT,
  732.                                     osmesa->gl_visual,
  733.                                     sharelist ? &sharelist->mesa
  734.                                               : (struct gl_context *) NULL,
  735.                                     &functions)) {
  736.          _mesa_destroy_visual( osmesa->gl_visual );
  737.          free(osmesa);
  738.          return NULL;
  739.       }
  740.  
  741.       _mesa_enable_sw_extensions(&(osmesa->mesa));
  742.  
  743.       osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
  744.       if (!osmesa->gl_buffer) {
  745.          _mesa_destroy_visual( osmesa->gl_visual );
  746.          _mesa_free_context_data( &osmesa->mesa );
  747.          free(osmesa);
  748.          return NULL;
  749.       }
  750.  
  751.       /* Create depth/stencil/accum buffers.  We'll create the color
  752.        * buffer later in OSMesaMakeCurrent().
  753.        */
  754.       _swrast_add_soft_renderbuffers(osmesa->gl_buffer,
  755.                                      GL_FALSE, /* color */
  756.                                      osmesa->gl_visual->haveDepthBuffer,
  757.                                      osmesa->gl_visual->haveStencilBuffer,
  758.                                      osmesa->gl_visual->haveAccumBuffer,
  759.                                      GL_FALSE, /* alpha */
  760.                                      GL_FALSE /* aux */ );
  761.  
  762.       osmesa->format = format;
  763.       osmesa->userRowLength = 0;
  764.       osmesa->yup = GL_TRUE;
  765.       osmesa->rInd = rind;
  766.       osmesa->gInd = gind;
  767.       osmesa->bInd = bind;
  768.       osmesa->aInd = aind;
  769.  
  770.       _mesa_meta_init(&osmesa->mesa);
  771.  
  772.       /* Initialize the software rasterizer and helper modules. */
  773.       {
  774.          struct gl_context *ctx = &osmesa->mesa;
  775.          SWcontext *swrast;
  776.          TNLcontext *tnl;
  777.  
  778.          if (!_swrast_CreateContext( ctx ) ||
  779.              !_vbo_CreateContext( ctx ) ||
  780.              !_tnl_CreateContext( ctx ) ||
  781.              !_swsetup_CreateContext( ctx )) {
  782.             _mesa_destroy_visual(osmesa->gl_visual);
  783.             _mesa_free_context_data(ctx);
  784.             free(osmesa);
  785.             return NULL;
  786.          }
  787.  
  788.          _swsetup_Wakeup( ctx );
  789.  
  790.          /* use default TCL pipeline */
  791.          tnl = TNL_CONTEXT(ctx);
  792.          tnl->Driver.RunPipeline = _tnl_run_pipeline;
  793.  
  794.          ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
  795.          ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;
  796.  
  797.          ctx->Driver.GenerateMipmap = _mesa_generate_mipmap;
  798.  
  799.          /* Extend the software rasterizer with our optimized line and triangle
  800.           * drawing functions.
  801.           */
  802.          swrast = SWRAST_CONTEXT( ctx );
  803.          swrast->choose_line = osmesa_choose_line;
  804.          swrast->choose_triangle = osmesa_choose_triangle;
  805.  
  806.          _mesa_compute_version(ctx);
  807.  
  808.          /* Exec table initialization requires the version to be computed */
  809.          _mesa_initialize_dispatch_tables(ctx);
  810.          _mesa_initialize_vbo_vtxfmt(ctx);
  811.       }
  812.    }
  813.    return osmesa;
  814. }
  815.  
  816.  
  817. /**
  818.  * Destroy an Off-Screen Mesa rendering context.
  819.  *
  820.  * \param osmesa  the context to destroy
  821.  */
  822. GLAPI void GLAPIENTRY
  823. OSMesaDestroyContext( OSMesaContext osmesa )
  824. {
  825.    if (osmesa) {
  826.       if (osmesa->srb)
  827.          _mesa_reference_renderbuffer((struct gl_renderbuffer **) &osmesa->srb, NULL);
  828.  
  829.       _mesa_meta_free( &osmesa->mesa );
  830.  
  831.       _swsetup_DestroyContext( &osmesa->mesa );
  832.       _tnl_DestroyContext( &osmesa->mesa );
  833.       _vbo_DestroyContext( &osmesa->mesa );
  834.       _swrast_DestroyContext( &osmesa->mesa );
  835.  
  836.       _mesa_destroy_visual( osmesa->gl_visual );
  837.       _mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
  838.  
  839.       _mesa_free_context_data( &osmesa->mesa );
  840.       free( osmesa );
  841.    }
  842. }
  843.  
  844.  
  845. /**
  846.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  847.  * block of memory which the client provides.  Its size must be at least
  848.  * as large as width*height*sizeof(type).  Its address should be a multiple
  849.  * of 4 if using RGBA mode.
  850.  *
  851.  * Image data is stored in the order of glDrawPixels:  row-major order
  852.  * with the lower-left image pixel stored in the first array position
  853.  * (ie. bottom-to-top).
  854.  *
  855.  * If the context's viewport hasn't been initialized yet, it will now be
  856.  * initialized to (0,0,width,height).
  857.  *
  858.  * Input:  osmesa - the rendering context
  859.  *         buffer - the image buffer memory
  860.  *         type - data type for pixel components
  861.  *            Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
  862.  *            are supported.  But if Mesa's been compiled with CHAN_BITS==16
  863.  *            then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.  And if
  864.  *            Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT,
  865.  *            GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.
  866.  *         width, height - size of image buffer in pixels, at least 1
  867.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid osmesa,
  868.  *          invalid buffer address, invalid type, width<1, height<1,
  869.  *          width>internal limit or height>internal limit.
  870.  */
  871. GLAPI GLboolean GLAPIENTRY
  872. OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
  873.                    GLsizei width, GLsizei height )
  874. {
  875.    if (!osmesa || !buffer ||
  876.        width < 1 || height < 1 ||
  877.        width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) {
  878.       return GL_FALSE;
  879.    }
  880.  
  881.    if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
  882.       return GL_FALSE;
  883.    }
  884.  
  885. #if 0
  886.    if (!(type == GL_UNSIGNED_BYTE ||
  887.          (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) ||
  888.          (type == GL_FLOAT && CHAN_BITS == 32))) {
  889.       /* i.e. is sizeof(type) * 8 > CHAN_BITS? */
  890.       return GL_FALSE;
  891.    }
  892. #endif
  893.  
  894.    osmesa_update_state( &osmesa->mesa, 0 );
  895.  
  896.    /* Call this periodically to detect when the user has begun using
  897.     * GL rendering from multiple threads.
  898.     */
  899.    _glapi_check_multithread();
  900.  
  901.  
  902.    /* Create a front/left color buffer which wraps the user-provided buffer.
  903.     * There is no back color buffer.
  904.     * If the user tries to use a 8, 16 or 32-bit/channel buffer that
  905.     * doesn't match what Mesa was compiled for (CHAN_BITS) the
  906.     * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer
  907.     * that converts rendering from CHAN_BITS to the user-requested channel
  908.     * size.
  909.     */
  910.    if (!osmesa->srb) {
  911.       osmesa->srb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
  912.       _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
  913.       _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
  914.                              &osmesa->srb->Base);
  915.       assert(osmesa->srb->Base.RefCount == 2);
  916.    }
  917.  
  918.    osmesa->DataType = type;
  919.  
  920.    /* Set renderbuffer fields.  Set width/height = 0 to force
  921.     * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer()
  922.     */
  923.    osmesa->srb->Buffer = buffer;
  924.    osmesa->srb->Base.Width = osmesa->srb->Base.Height = 0;
  925.  
  926.    /* Set the framebuffer's size.  This causes the
  927.     * osmesa_renderbuffer_storage() function to get called.
  928.     */
  929.    _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
  930.  
  931.    _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
  932.  
  933.    /* Remove renderbuffer attachment, then re-add.  This installs the
  934.     * renderbuffer adaptor/wrapper if needed (for bpp conversion).
  935.     */
  936.    _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
  937.    _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
  938.                           &osmesa->srb->Base);
  939.  
  940.  
  941.    /* this updates the visual's red/green/blue/alphaBits fields */
  942.    _mesa_update_framebuffer_visual(&osmesa->mesa, osmesa->gl_buffer);
  943.  
  944.    /* update the framebuffer size */
  945.    _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
  946.  
  947.    return GL_TRUE;
  948. }
  949.  
  950.  
  951.  
  952. GLAPI OSMesaContext GLAPIENTRY
  953. OSMesaGetCurrentContext( void )
  954. {
  955.    struct gl_context *ctx = _mesa_get_current_context();
  956.    if (ctx)
  957.       return (OSMesaContext) ctx;
  958.    else
  959.       return NULL;
  960. }
  961.  
  962.  
  963.  
  964. GLAPI void GLAPIENTRY
  965. OSMesaPixelStore( GLint pname, GLint value )
  966. {
  967.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  968.  
  969.    switch (pname) {
  970.       case OSMESA_ROW_LENGTH:
  971.          if (value<0) {
  972.             _mesa_error( &osmesa->mesa, GL_INVALID_VALUE,
  973.                       "OSMesaPixelStore(value)" );
  974.             return;
  975.          }
  976.          osmesa->userRowLength = value;
  977.          break;
  978.       case OSMESA_Y_UP:
  979.          osmesa->yup = value ? GL_TRUE : GL_FALSE;
  980.          break;
  981.       default:
  982.          _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
  983.          return;
  984.    }
  985.  
  986.    compute_row_addresses( osmesa );
  987. }
  988.  
  989.  
  990. GLAPI void GLAPIENTRY
  991. OSMesaGetIntegerv( GLint pname, GLint *value )
  992. {
  993.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  994.  
  995.    switch (pname) {
  996.       case OSMESA_WIDTH:
  997.          if (osmesa->gl_buffer)
  998.             *value = osmesa->gl_buffer->Width;
  999.          else
  1000.             *value = 0;
  1001.          return;
  1002.       case OSMESA_HEIGHT:
  1003.          if (osmesa->gl_buffer)
  1004.             *value = osmesa->gl_buffer->Height;
  1005.          else
  1006.             *value = 0;
  1007.          return;
  1008.       case OSMESA_FORMAT:
  1009.          *value = osmesa->format;
  1010.          return;
  1011.       case OSMESA_TYPE:
  1012.          /* current color buffer's data type */
  1013.          *value = osmesa->DataType;
  1014.          return;
  1015.       case OSMESA_ROW_LENGTH:
  1016.          *value = osmesa->userRowLength;
  1017.          return;
  1018.       case OSMESA_Y_UP:
  1019.          *value = osmesa->yup;
  1020.          return;
  1021.       case OSMESA_MAX_WIDTH:
  1022.          *value = SWRAST_MAX_WIDTH;
  1023.          return;
  1024.       case OSMESA_MAX_HEIGHT:
  1025.          *value = SWRAST_MAX_HEIGHT;
  1026.          return;
  1027.       default:
  1028.          _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
  1029.          return;
  1030.    }
  1031. }
  1032.  
  1033.  
  1034. /**
  1035.  * Return the depth buffer associated with an OSMesa context.
  1036.  * Input:  c - the OSMesa context
  1037.  * Output:  width, height - size of buffer in pixels
  1038.  *          bytesPerValue - bytes per depth value (2 or 4)
  1039.  *          buffer - pointer to depth buffer values
  1040.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1041.  */
  1042. GLAPI GLboolean GLAPIENTRY
  1043. OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
  1044.                       GLint *bytesPerValue, void **buffer )
  1045. {
  1046.    struct swrast_renderbuffer *srb = NULL;
  1047.  
  1048.    if (c->gl_buffer)
  1049.       srb = swrast_renderbuffer(c->gl_buffer->
  1050.                                 Attachment[BUFFER_DEPTH].Renderbuffer);
  1051.  
  1052.    if (!srb || !srb->Buffer) {
  1053.       *width = 0;
  1054.       *height = 0;
  1055.       *bytesPerValue = 0;
  1056.       *buffer = 0;
  1057.       return GL_FALSE;
  1058.    }
  1059.    else {
  1060.       *width = srb->Base.Width;
  1061.       *height = srb->Base.Height;
  1062.       if (c->gl_visual->depthBits <= 16)
  1063.          *bytesPerValue = sizeof(GLushort);
  1064.       else
  1065.          *bytesPerValue = sizeof(GLuint);
  1066.       *buffer = (void *) srb->Buffer;
  1067.       return GL_TRUE;
  1068.    }
  1069. }
  1070.  
  1071.  
  1072. /**
  1073.  * Return the color buffer associated with an OSMesa context.
  1074.  * Input:  c - the OSMesa context
  1075.  * Output:  width, height - size of buffer in pixels
  1076.  *          format - the pixel format (OSMESA_FORMAT)
  1077.  *          buffer - pointer to color buffer values
  1078.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1079.  */
  1080. GLAPI GLboolean GLAPIENTRY
  1081. OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width,
  1082.                       GLint *height, GLint *format, void **buffer )
  1083. {
  1084.    if (osmesa->srb && osmesa->srb->Buffer) {
  1085.       *width = osmesa->srb->Base.Width;
  1086.       *height = osmesa->srb->Base.Height;
  1087.       *format = osmesa->format;
  1088.       *buffer = (void *) osmesa->srb->Buffer;
  1089.       return GL_TRUE;
  1090.    }
  1091.    else {
  1092.       *width = 0;
  1093.       *height = 0;
  1094.       *format = 0;
  1095.       *buffer = 0;
  1096.       return GL_FALSE;
  1097.    }
  1098. }
  1099.  
  1100.  
  1101. struct name_function
  1102. {
  1103.    const char *Name;
  1104.    OSMESAproc Function;
  1105. };
  1106.  
  1107. static struct name_function functions[] = {
  1108.    { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext },
  1109.    { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt },
  1110.    { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext },
  1111.    { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent },
  1112.    { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext },
  1113.    { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore },
  1114.    { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv },
  1115.    { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer },
  1116.    { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer },
  1117.    { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress },
  1118.    { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp },
  1119.    { NULL, NULL }
  1120. };
  1121.  
  1122.  
  1123. GLAPI OSMESAproc GLAPIENTRY
  1124. OSMesaGetProcAddress( const char *funcName )
  1125. {
  1126.    int i;
  1127.    for (i = 0; functions[i].Name; i++) {
  1128.       if (strcmp(functions[i].Name, funcName) == 0)
  1129.          return functions[i].Function;
  1130.    }
  1131.    return _glapi_get_proc_address(funcName);
  1132. }
  1133.  
  1134.  
  1135. GLAPI void GLAPIENTRY
  1136. OSMesaColorClamp(GLboolean enable)
  1137. {
  1138.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  1139.  
  1140.    if (enable == GL_TRUE) {
  1141.       osmesa->mesa.Color.ClampFragmentColor = GL_TRUE;
  1142.    }
  1143.    else {
  1144.       osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
  1145.    }
  1146. }
  1147.  
  1148.  
  1149. /**
  1150.  * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in
  1151.  * libglapi.a.  We need to define them here.
  1152.  */
  1153. #ifdef GLX_INDIRECT_RENDERING
  1154.  
  1155. #define GL_GLEXT_PROTOTYPES
  1156. #include "GL/gl.h"
  1157. #include "glapi/glapi.h"
  1158. #include "glapi/glapitable.h"
  1159.  
  1160. #if defined(USE_MGL_NAMESPACE)
  1161. #define NAME(func)  mgl##func
  1162. #else
  1163. #define NAME(func)  gl##func
  1164. #endif
  1165.  
  1166. #define DISPATCH(FUNC, ARGS, MESSAGE)           \
  1167.    GET_DISPATCH()->FUNC ARGS
  1168.  
  1169. #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE)    \
  1170.    return GET_DISPATCH()->FUNC ARGS
  1171.  
  1172. /* skip normal ones */
  1173. #define _GLAPI_SKIP_NORMAL_ENTRY_POINTS
  1174. #include "glapi/glapitemp.h"
  1175.  
  1176. #endif /* GLX_INDIRECT_RENDERING */
  1177.