Subversion Repositories Kolibri OS

Rev

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