Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  6.5.3
  4.  *
  5.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR 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/context.h"
  39. #include "main/extensions.h"
  40. #include "main/formats.h"
  41. #include "main/framebuffer.h"
  42. #include "main/imports.h"
  43. #include "main/mtypes.h"
  44. #include "main/renderbuffer.h"
  45. #include "swrast/swrast.h"
  46. #include "swrast_setup/swrast_setup.h"
  47. #include "swrast/s_context.h"
  48. #include "swrast/s_lines.h"
  49. #include "swrast/s_triangle.h"
  50. #include "tnl/tnl.h"
  51. #include "tnl/t_context.h"
  52. #include "tnl/t_pipeline.h"
  53. #include "drivers/common/driverfuncs.h"
  54. #include "drivers/common/meta.h"
  55. #include "vbo/vbo.h"
  56.  
  57.  
  58.  
  59. /**
  60.  * OSMesa rendering context, derived from core Mesa struct gl_context.
  61.  */
  62. struct osmesa_context
  63. {
  64.    struct gl_context mesa;              /*< Base class - this must be first */
  65.    struct gl_config *gl_visual;         /*< Describes the buffers */
  66.    struct gl_renderbuffer *rb;  /*< The user's colorbuffer */
  67.    struct gl_framebuffer *gl_buffer;    /*< The framebuffer, containing user's rb */
  68.    GLenum format;               /*< User-specified context format */
  69.    GLint userRowLength;         /*< user-specified number of pixels per row */
  70.    GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */
  71.    GLvoid *rowaddr[MAX_HEIGHT]; /*< address of first pixel in each image row */
  72.    GLboolean yup;               /*< TRUE  -> Y increases upward */
  73.                                 /*< FALSE -> Y increases downward */
  74. };
  75.  
  76.  
  77. static INLINE OSMesaContext
  78. OSMESA_CONTEXT(struct gl_context *ctx)
  79. {
  80.    /* Just cast, since we're using structure containment */
  81.    return (OSMesaContext) ctx;
  82. }
  83.  
  84.  
  85. /**********************************************************************/
  86. /*** Private Device Driver Functions                                ***/
  87. /**********************************************************************/
  88.  
  89.  
  90. static const GLubyte *
  91. get_string( struct gl_context *ctx, GLenum name )
  92. {
  93.    (void) ctx;
  94.    switch (name) {
  95.       case GL_RENDERER:
  96. #if CHAN_BITS == 32
  97.          return (const GLubyte *) "Mesa OffScreen32";
  98. #elif CHAN_BITS == 16
  99.          return (const GLubyte *) "Mesa OffScreen16";
  100. #else
  101.          return (const GLubyte *) "Mesa OffScreen";
  102. #endif
  103.       default:
  104.          return NULL;
  105.    }
  106. }
  107.  
  108.  
  109. static void
  110. osmesa_update_state( struct gl_context *ctx, GLuint new_state )
  111. {
  112.    /* easy - just propogate */
  113.    _swrast_InvalidateState( ctx, new_state );
  114.    _swsetup_InvalidateState( ctx, new_state );
  115.    _tnl_InvalidateState( ctx, new_state );
  116.    _vbo_InvalidateState( ctx, new_state );
  117. }
  118.  
  119.  
  120.  
  121. /**********************************************************************/
  122. /*****        Read/write spans/arrays of pixels                   *****/
  123. /**********************************************************************/
  124.  
  125. /* 8-bit RGBA */
  126. #define NAME(PREFIX) PREFIX##_RGBA8
  127. #define RB_TYPE GLubyte
  128. #define SPAN_VARS \
  129.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  130. #define INIT_PIXEL_PTR(P, X, Y) \
  131.    GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X)
  132. #define INC_PIXEL_PTR(P) P += 4
  133. #define STORE_PIXEL(DST, X, Y, VALUE) \
  134.    DST[0] = VALUE[RCOMP];  \
  135.    DST[1] = VALUE[GCOMP];  \
  136.    DST[2] = VALUE[BCOMP];  \
  137.    DST[3] = VALUE[ACOMP]
  138. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  139.    DST[0] = VALUE[RCOMP];  \
  140.    DST[1] = VALUE[GCOMP];  \
  141.    DST[2] = VALUE[BCOMP];  \
  142.    DST[3] = 255
  143. #define FETCH_PIXEL(DST, SRC) \
  144.    DST[RCOMP] = SRC[0];  \
  145.    DST[GCOMP] = SRC[1];  \
  146.    DST[BCOMP] = SRC[2];  \
  147.    DST[ACOMP] = SRC[3]
  148. #include "swrast/s_spantemp.h"
  149.  
  150. /* 16-bit RGBA */
  151. #define NAME(PREFIX) PREFIX##_RGBA16
  152. #define RB_TYPE GLushort
  153. #define SPAN_VARS \
  154.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  155. #define INIT_PIXEL_PTR(P, X, Y) \
  156.    GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X)
  157. #define INC_PIXEL_PTR(P) P += 4
  158. #define STORE_PIXEL(DST, X, Y, VALUE) \
  159.    DST[0] = VALUE[RCOMP];  \
  160.    DST[1] = VALUE[GCOMP];  \
  161.    DST[2] = VALUE[BCOMP];  \
  162.    DST[3] = VALUE[ACOMP]
  163. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  164.    DST[0] = VALUE[RCOMP];  \
  165.    DST[1] = VALUE[GCOMP];  \
  166.    DST[2] = VALUE[BCOMP];  \
  167.    DST[3] = 65535
  168. #define FETCH_PIXEL(DST, SRC) \
  169.    DST[RCOMP] = SRC[0];  \
  170.    DST[GCOMP] = SRC[1];  \
  171.    DST[BCOMP] = SRC[2];  \
  172.    DST[ACOMP] = SRC[3]
  173. #include "swrast/s_spantemp.h"
  174.  
  175. /* 32-bit RGBA */
  176. #define NAME(PREFIX) PREFIX##_RGBA32
  177. #define RB_TYPE GLfloat
  178. #define SPAN_VARS \
  179.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  180. #define INIT_PIXEL_PTR(P, X, Y) \
  181.    GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X)
  182. #define INC_PIXEL_PTR(P) P += 4
  183. #define STORE_PIXEL(DST, X, Y, VALUE) \
  184.    DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \
  185.    DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \
  186.    DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \
  187.    DST[3] = CLAMP((VALUE[ACOMP]), 0.0F, 1.0F)
  188. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  189.    DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \
  190.    DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \
  191.    DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \
  192.    DST[3] = 1.0F
  193. #define FETCH_PIXEL(DST, SRC) \
  194.    DST[RCOMP] = SRC[0];  \
  195.    DST[GCOMP] = SRC[1];  \
  196.    DST[BCOMP] = SRC[2];  \
  197.    DST[ACOMP] = SRC[3]
  198. #include "swrast/s_spantemp.h"
  199.  
  200.  
  201. /* 8-bit BGRA */
  202. #define NAME(PREFIX) PREFIX##_BGRA8
  203. #define RB_TYPE GLubyte
  204. #define SPAN_VARS \
  205.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  206. #define INIT_PIXEL_PTR(P, X, Y) \
  207.    GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X)
  208. #define INC_PIXEL_PTR(P) P += 4
  209. #define STORE_PIXEL(DST, X, Y, VALUE) \
  210.    DST[2] = VALUE[RCOMP];  \
  211.    DST[1] = VALUE[GCOMP];  \
  212.    DST[0] = VALUE[BCOMP];  \
  213.    DST[3] = VALUE[ACOMP]
  214. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  215.    DST[2] = VALUE[RCOMP];  \
  216.    DST[1] = VALUE[GCOMP];  \
  217.    DST[0] = VALUE[BCOMP];  \
  218.    DST[3] = 255
  219. #define FETCH_PIXEL(DST, SRC) \
  220.    DST[RCOMP] = SRC[2];  \
  221.    DST[GCOMP] = SRC[1];  \
  222.    DST[BCOMP] = SRC[0];  \
  223.    DST[ACOMP] = SRC[3]
  224. #include "swrast/s_spantemp.h"
  225.  
  226. /* 16-bit BGRA */
  227. #define NAME(PREFIX) PREFIX##_BGRA16
  228. #define RB_TYPE GLushort
  229. #define SPAN_VARS \
  230.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  231. #define INIT_PIXEL_PTR(P, X, Y) \
  232.    GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X)
  233. #define INC_PIXEL_PTR(P) P += 4
  234. #define STORE_PIXEL(DST, X, Y, VALUE) \
  235.    DST[2] = VALUE[RCOMP];  \
  236.    DST[1] = VALUE[GCOMP];  \
  237.    DST[0] = VALUE[BCOMP];  \
  238.    DST[3] = VALUE[ACOMP]
  239. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  240.    DST[2] = VALUE[RCOMP];  \
  241.    DST[1] = VALUE[GCOMP];  \
  242.    DST[0] = VALUE[BCOMP];  \
  243.    DST[3] = 65535
  244. #define FETCH_PIXEL(DST, SRC) \
  245.    DST[RCOMP] = SRC[2];  \
  246.    DST[GCOMP] = SRC[1];  \
  247.    DST[BCOMP] = SRC[0];  \
  248.    DST[ACOMP] = SRC[3]
  249. #include "swrast/s_spantemp.h"
  250.  
  251. /* 32-bit BGRA */
  252. #define NAME(PREFIX) PREFIX##_BGRA32
  253. #define RB_TYPE GLfloat
  254. #define SPAN_VARS \
  255.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  256. #define INIT_PIXEL_PTR(P, X, Y) \
  257.    GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X)
  258. #define INC_PIXEL_PTR(P) P += 4
  259. #define STORE_PIXEL(DST, X, Y, VALUE) \
  260.    DST[2] = VALUE[RCOMP];  \
  261.    DST[1] = VALUE[GCOMP];  \
  262.    DST[0] = VALUE[BCOMP];  \
  263.    DST[3] = VALUE[ACOMP]
  264. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  265.    DST[2] = VALUE[RCOMP];  \
  266.    DST[1] = VALUE[GCOMP];  \
  267.    DST[0] = VALUE[BCOMP];  \
  268.    DST[3] = 1.0F
  269. #define FETCH_PIXEL(DST, SRC) \
  270.    DST[RCOMP] = SRC[2];  \
  271.    DST[GCOMP] = SRC[1];  \
  272.    DST[BCOMP] = SRC[0];  \
  273.    DST[ACOMP] = SRC[3]
  274. #include "swrast/s_spantemp.h"
  275.  
  276.  
  277. /* 8-bit ARGB */
  278. #define NAME(PREFIX) PREFIX##_ARGB8
  279. #define RB_TYPE GLubyte
  280. #define SPAN_VARS \
  281.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  282. #define INIT_PIXEL_PTR(P, X, Y) \
  283.    GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X)
  284. #define INC_PIXEL_PTR(P) P += 4
  285. #define STORE_PIXEL(DST, X, Y, VALUE) \
  286.    DST[1] = VALUE[RCOMP];  \
  287.    DST[2] = VALUE[GCOMP];  \
  288.    DST[3] = VALUE[BCOMP];  \
  289.    DST[0] = VALUE[ACOMP]
  290. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  291.    DST[1] = VALUE[RCOMP];  \
  292.    DST[2] = VALUE[GCOMP];  \
  293.    DST[3] = VALUE[BCOMP];  \
  294.    DST[0] = 255
  295. #define FETCH_PIXEL(DST, SRC) \
  296.    DST[RCOMP] = SRC[1];  \
  297.    DST[GCOMP] = SRC[2];  \
  298.    DST[BCOMP] = SRC[3];  \
  299.    DST[ACOMP] = SRC[0]
  300. #include "swrast/s_spantemp.h"
  301.  
  302. /* 16-bit ARGB */
  303. #define NAME(PREFIX) PREFIX##_ARGB16
  304. #define RB_TYPE GLushort
  305. #define SPAN_VARS \
  306.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  307. #define INIT_PIXEL_PTR(P, X, Y) \
  308.    GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X)
  309. #define INC_PIXEL_PTR(P) P += 4
  310. #define STORE_PIXEL(DST, X, Y, VALUE) \
  311.    DST[1] = VALUE[RCOMP];  \
  312.    DST[2] = VALUE[GCOMP];  \
  313.    DST[3] = VALUE[BCOMP];  \
  314.    DST[0] = VALUE[ACOMP]
  315. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  316.    DST[1] = VALUE[RCOMP];  \
  317.    DST[2] = VALUE[GCOMP];  \
  318.    DST[3] = VALUE[BCOMP];  \
  319.    DST[0] = 65535
  320. #define FETCH_PIXEL(DST, SRC) \
  321.    DST[RCOMP] = SRC[1];  \
  322.    DST[GCOMP] = SRC[2];  \
  323.    DST[BCOMP] = SRC[3];  \
  324.    DST[ACOMP] = SRC[0]
  325. #include "swrast/s_spantemp.h"
  326.  
  327. /* 32-bit ARGB */
  328. #define NAME(PREFIX) PREFIX##_ARGB32
  329. #define RB_TYPE GLfloat
  330. #define SPAN_VARS \
  331.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  332. #define INIT_PIXEL_PTR(P, X, Y) \
  333.    GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X)
  334. #define INC_PIXEL_PTR(P) P += 4
  335. #define STORE_PIXEL(DST, X, Y, VALUE) \
  336.    DST[1] = VALUE[RCOMP];  \
  337.    DST[2] = VALUE[GCOMP];  \
  338.    DST[3] = VALUE[BCOMP];  \
  339.    DST[0] = VALUE[ACOMP]
  340. #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
  341.    DST[1] = VALUE[RCOMP];  \
  342.    DST[2] = VALUE[GCOMP];  \
  343.    DST[3] = VALUE[BCOMP];  \
  344.    DST[0] = 1.0F
  345. #define FETCH_PIXEL(DST, SRC) \
  346.    DST[RCOMP] = SRC[1];  \
  347.    DST[GCOMP] = SRC[2];  \
  348.    DST[BCOMP] = SRC[3];  \
  349.    DST[ACOMP] = SRC[0]
  350. #include "swrast/s_spantemp.h"
  351.  
  352.  
  353. /* 8-bit RGB */
  354. #define NAME(PREFIX) PREFIX##_RGB8
  355. #define RB_TYPE GLubyte
  356. #define SPAN_VARS \
  357.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  358. #define INIT_PIXEL_PTR(P, X, Y) \
  359.    GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 3 * (X)
  360. #define INC_PIXEL_PTR(P) P += 3
  361. #define STORE_PIXEL(DST, X, Y, VALUE) \
  362.    DST[0] = VALUE[RCOMP];  \
  363.    DST[1] = VALUE[GCOMP];  \
  364.    DST[2] = VALUE[BCOMP]
  365. #define FETCH_PIXEL(DST, SRC) \
  366.    DST[RCOMP] = SRC[0];  \
  367.    DST[GCOMP] = SRC[1];  \
  368.    DST[BCOMP] = SRC[2];  \
  369.    DST[ACOMP] = 255
  370. #include "swrast/s_spantemp.h"
  371.  
  372. /* 16-bit RGB */
  373. #define NAME(PREFIX) PREFIX##_RGB16
  374. #define RB_TYPE GLushort
  375. #define SPAN_VARS \
  376.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  377. #define INIT_PIXEL_PTR(P, X, Y) \
  378.    GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 3 * (X)
  379. #define INC_PIXEL_PTR(P) P += 3
  380. #define STORE_PIXEL(DST, X, Y, VALUE) \
  381.    DST[0] = VALUE[RCOMP];  \
  382.    DST[1] = VALUE[GCOMP];  \
  383.    DST[2] = VALUE[BCOMP]
  384. #define FETCH_PIXEL(DST, SRC) \
  385.    DST[RCOMP] = SRC[0];  \
  386.    DST[GCOMP] = SRC[1];  \
  387.    DST[BCOMP] = SRC[2];  \
  388.    DST[ACOMP] = 65535U
  389. #include "swrast/s_spantemp.h"
  390.  
  391. /* 32-bit RGB */
  392. #define NAME(PREFIX) PREFIX##_RGB32
  393. #define RB_TYPE GLfloat
  394. #define SPAN_VARS \
  395.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  396. #define INIT_PIXEL_PTR(P, X, Y) \
  397.    GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 3 * (X)
  398. #define INC_PIXEL_PTR(P) P += 3
  399. #define STORE_PIXEL(DST, X, Y, VALUE) \
  400.    DST[0] = VALUE[RCOMP];  \
  401.    DST[1] = VALUE[GCOMP];  \
  402.    DST[2] = VALUE[BCOMP]
  403. #define FETCH_PIXEL(DST, SRC) \
  404.    DST[RCOMP] = SRC[0];  \
  405.    DST[GCOMP] = SRC[1];  \
  406.    DST[BCOMP] = SRC[2];  \
  407.    DST[ACOMP] = 1.0F
  408. #include "swrast/s_spantemp.h"
  409.  
  410.  
  411. /* 8-bit BGR */
  412. #define NAME(PREFIX) PREFIX##_BGR8
  413. #define RB_TYPE GLubyte
  414. #define SPAN_VARS \
  415.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  416. #define INIT_PIXEL_PTR(P, X, Y) \
  417.    GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 3 * (X)
  418. #define INC_PIXEL_PTR(P) P += 3
  419. #define STORE_PIXEL(DST, X, Y, VALUE) \
  420.    DST[2] = VALUE[RCOMP];  \
  421.    DST[1] = VALUE[GCOMP];  \
  422.    DST[0] = VALUE[BCOMP]
  423. #define FETCH_PIXEL(DST, SRC) \
  424.    DST[RCOMP] = SRC[2];  \
  425.    DST[GCOMP] = SRC[1];  \
  426.    DST[BCOMP] = SRC[0];  \
  427.    DST[ACOMP] = 255
  428. #include "swrast/s_spantemp.h"
  429.  
  430. /* 16-bit BGR */
  431. #define NAME(PREFIX) PREFIX##_BGR16
  432. #define RB_TYPE GLushort
  433. #define SPAN_VARS \
  434.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  435. #define INIT_PIXEL_PTR(P, X, Y) \
  436.    GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 3 * (X)
  437. #define INC_PIXEL_PTR(P) P += 3
  438. #define STORE_PIXEL(DST, X, Y, VALUE) \
  439.    DST[2] = VALUE[RCOMP];  \
  440.    DST[1] = VALUE[GCOMP];  \
  441.    DST[0] = VALUE[BCOMP]
  442. #define FETCH_PIXEL(DST, SRC) \
  443.    DST[RCOMP] = SRC[2];  \
  444.    DST[GCOMP] = SRC[1];  \
  445.    DST[BCOMP] = SRC[0];  \
  446.    DST[ACOMP] = 65535
  447. #include "swrast/s_spantemp.h"
  448.  
  449. /* 32-bit BGR */
  450. #define NAME(PREFIX) PREFIX##_BGR32
  451. #define RB_TYPE GLfloat
  452. #define SPAN_VARS \
  453.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  454. #define INIT_PIXEL_PTR(P, X, Y) \
  455.    GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 3 * (X)
  456. #define INC_PIXEL_PTR(P) P += 3
  457. #define STORE_PIXEL(DST, X, Y, VALUE) \
  458.    DST[2] = VALUE[RCOMP];  \
  459.    DST[1] = VALUE[GCOMP];  \
  460.    DST[0] = VALUE[BCOMP]
  461. #define FETCH_PIXEL(DST, SRC) \
  462.    DST[RCOMP] = SRC[2];  \
  463.    DST[GCOMP] = SRC[1];  \
  464.    DST[BCOMP] = SRC[0];  \
  465.    DST[ACOMP] = 1.0F
  466. #include "swrast/s_spantemp.h"
  467.  
  468.  
  469. /* 16-bit 5/6/5 RGB */
  470. #define NAME(PREFIX) PREFIX##_RGB_565
  471. #define RB_TYPE GLubyte
  472. #define SPAN_VARS \
  473.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  474. #define INIT_PIXEL_PTR(P, X, Y) \
  475.    GLushort *P = (GLushort *) osmesa->rowaddr[Y] + (X)
  476. #define INC_PIXEL_PTR(P) P += 1
  477. #define STORE_PIXEL(DST, X, Y, VALUE) \
  478.    *DST = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
  479. #define FETCH_PIXEL(DST, SRC) \
  480.    DST[RCOMP] = ( (((*SRC) >> 8) & 0xf8) | (((*SRC) >> 11) & 0x7) ); \
  481.    DST[GCOMP] = ( (((*SRC) >> 3) & 0xfc) | (((*SRC) >>  5) & 0x3) ); \
  482.    DST[BCOMP] = ( (((*SRC) << 3) & 0xf8) | (((*SRC)      ) & 0x7) ); \
  483.    DST[ACOMP] = CHAN_MAX
  484. #include "swrast/s_spantemp.h"
  485.  
  486.  
  487. /**
  488.  * Macros for optimized line/triangle rendering.
  489.  * Only for 8-bit channel, RGBA, BGRA, ARGB formats.
  490.  */
  491.  
  492. #define PACK_RGBA(DST, R, G, B, A)      \
  493. do {                                    \
  494.    (DST)[osmesa->rInd] = R;             \
  495.    (DST)[osmesa->gInd] = G;             \
  496.    (DST)[osmesa->bInd] = B;             \
  497.    (DST)[osmesa->aInd] = A;             \
  498. } while (0)
  499.  
  500. #define PIXELADDR4(X,Y)  ((GLchan *) osmesa->rowaddr[Y] + 4 * (X))
  501.  
  502.  
  503. /**
  504.  * Draw a flat-shaded, RGB line into an osmesa buffer.
  505.  */
  506. #define NAME flat_rgba_line
  507. #define CLIP_HACK 1
  508. #define SETUP_CODE                                              \
  509.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);            \
  510.    const GLchan *color = vert1->color;
  511.  
  512. #define PLOT(X, Y)                                              \
  513. do {                                                            \
  514.    GLchan *p = PIXELADDR4(X, Y);                                \
  515.    PACK_RGBA(p, color[0], color[1], color[2], color[3]);        \
  516. } while (0)
  517.  
  518. #ifdef WIN32
  519. #include "..\swrast\s_linetemp.h"
  520. #else
  521. #include "swrast/s_linetemp.h"
  522. #endif
  523.  
  524.  
  525.  
  526. /**
  527.  * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
  528.  */
  529. #define NAME flat_rgba_z_line
  530. #define CLIP_HACK 1
  531. #define INTERP_Z 1
  532. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  533. #define SETUP_CODE                                      \
  534.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);    \
  535.    const GLchan *color = vert1->color;
  536.  
  537. #define PLOT(X, Y)                                      \
  538. do {                                                    \
  539.    if (Z < *zPtr) {                                     \
  540.       GLchan *p = PIXELADDR4(X, Y);                     \
  541.       PACK_RGBA(p, color[RCOMP], color[GCOMP],          \
  542.                    color[BCOMP], color[ACOMP]);         \
  543.       *zPtr = Z;                                        \
  544.    }                                                    \
  545. } while (0)
  546.  
  547. #ifdef WIN32
  548. #include "..\swrast\s_linetemp.h"
  549. #else
  550. #include "swrast/s_linetemp.h"
  551. #endif
  552.  
  553.  
  554.  
  555. /**
  556.  * Analyze context state to see if we can provide a fast line drawing
  557.  * function.  Otherwise, return NULL.
  558.  */
  559. static swrast_line_func
  560. osmesa_choose_line_function( struct gl_context *ctx )
  561. {
  562.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  563.    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
  564.  
  565.    if (osmesa->rb->DataType != GL_UNSIGNED_BYTE)
  566.       return NULL;
  567.  
  568.    if (ctx->RenderMode != GL_RENDER)      return NULL;
  569.    if (ctx->Line.SmoothFlag)              return NULL;
  570.    if (ctx->Texture._EnabledUnits)        return NULL;
  571.    if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
  572.    if (ctx->Line.Width != 1.0F)           return NULL;
  573.    if (ctx->Line.StippleFlag)             return NULL;
  574.    if (ctx->Line.SmoothFlag)              return NULL;
  575.    if (osmesa->format != OSMESA_RGBA &&
  576.        osmesa->format != OSMESA_BGRA &&
  577.        osmesa->format != OSMESA_ARGB)     return NULL;
  578.  
  579.    if (swrast->_RasterMask==DEPTH_BIT
  580.        && ctx->Depth.Func==GL_LESS
  581.        && ctx->Depth.Mask==GL_TRUE
  582.        && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
  583.       return (swrast_line_func) flat_rgba_z_line;
  584.    }
  585.  
  586.    if (swrast->_RasterMask == 0) {
  587.       return (swrast_line_func) flat_rgba_line;
  588.    }
  589.  
  590.    return (swrast_line_func) NULL;
  591. }
  592.  
  593.  
  594. /**********************************************************************/
  595. /*****                 Optimized triangle rendering               *****/
  596. /**********************************************************************/
  597.  
  598.  
  599. /*
  600.  * Smooth-shaded, z-less triangle, RGBA color.
  601.  */
  602. #define NAME smooth_rgba_z_triangle
  603. #define INTERP_Z 1
  604. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  605. #define INTERP_RGB 1
  606. #define INTERP_ALPHA 1
  607. #define SETUP_CODE \
  608.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  609. #define RENDER_SPAN( span ) {                                   \
  610.    GLuint i;                                                    \
  611.    GLchan *img = PIXELADDR4(span.x, span.y);                    \
  612.    for (i = 0; i < span.end; i++, img += 4) {                   \
  613.       const GLuint z = FixedToDepth(span.z);                    \
  614.       if (z < zRow[i]) {                                        \
  615.          PACK_RGBA(img, FixedToChan(span.red),                  \
  616.             FixedToChan(span.green), FixedToChan(span.blue),    \
  617.             FixedToChan(span.alpha));                           \
  618.          zRow[i] = z;                                           \
  619.       }                                                         \
  620.       span.red += span.redStep;                                 \
  621.       span.green += span.greenStep;                             \
  622.       span.blue += span.blueStep;                               \
  623.       span.alpha += span.alphaStep;                             \
  624.       span.z += span.zStep;                                     \
  625.    }                                                            \
  626. }
  627. #ifdef WIN32
  628. #include "..\swrast\s_tritemp.h"
  629. #else
  630. #include "swrast/s_tritemp.h"
  631. #endif
  632.  
  633.  
  634.  
  635. /*
  636.  * Flat-shaded, z-less triangle, RGBA color.
  637.  */
  638. #define NAME flat_rgba_z_triangle
  639. #define INTERP_Z 1
  640. #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
  641. #define SETUP_CODE                                              \
  642.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);            \
  643.    GLuint pixel;                                                \
  644.    PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1],     \
  645.                                 v2->color[2], v2->color[3]);
  646.  
  647. #define RENDER_SPAN( span ) {                           \
  648.    GLuint i;                                            \
  649.    GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \
  650.    for (i = 0; i < span.end; i++) {                     \
  651.       const GLuint z = FixedToDepth(span.z);            \
  652.       if (z < zRow[i]) {                                \
  653.          img[i] = pixel;                                \
  654.          zRow[i] = z;                                   \
  655.       }                                                 \
  656.       span.z += span.zStep;                             \
  657.    }                                                    \
  658. }
  659. #ifdef WIN32
  660. #include "..\swrast\s_tritemp.h"
  661. #else
  662. #include "swrast/s_tritemp.h"
  663. #endif
  664.  
  665.  
  666.  
  667. /**
  668.  * Return pointer to an optimized triangle function if possible.
  669.  */
  670. static swrast_tri_func
  671. osmesa_choose_triangle_function( struct gl_context *ctx )
  672. {
  673.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  674.    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
  675.  
  676.    if (osmesa->rb->DataType != GL_UNSIGNED_BYTE)
  677.       return (swrast_tri_func) NULL;
  678.  
  679.    if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
  680.    if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
  681.    if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
  682.    if (ctx->Texture._EnabledUnits)      return (swrast_tri_func) NULL;
  683.    if (osmesa->format != OSMESA_RGBA &&
  684.        osmesa->format != OSMESA_BGRA &&
  685.        osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
  686.    if (ctx->Polygon.CullFlag &&
  687.        ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
  688.                                         return (swrast_tri_func) NULL;
  689.  
  690.    if (swrast->_RasterMask == DEPTH_BIT &&
  691.        ctx->Depth.Func == GL_LESS &&
  692.        ctx->Depth.Mask == GL_TRUE &&
  693.        ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
  694.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  695.          return (swrast_tri_func) smooth_rgba_z_triangle;
  696.       }
  697.       else {
  698.          return (swrast_tri_func) flat_rgba_z_triangle;
  699.       }
  700.    }
  701.    return (swrast_tri_func) NULL;
  702. }
  703.  
  704.  
  705.  
  706. /* Override for the swrast triangle-selection function.  Try to use one
  707.  * of our internal triangle functions, otherwise fall back to the
  708.  * standard swrast functions.
  709.  */
  710. static void
  711. osmesa_choose_triangle( struct gl_context *ctx )
  712. {
  713.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  714.  
  715.    swrast->Triangle = osmesa_choose_triangle_function( ctx );
  716.    if (!swrast->Triangle)
  717.       _swrast_choose_triangle( ctx );
  718. }
  719.  
  720. static void
  721. osmesa_choose_line( struct gl_context *ctx )
  722. {
  723.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  724.  
  725.    swrast->Line = osmesa_choose_line_function( ctx );
  726.    if (!swrast->Line)
  727.       _swrast_choose_line( ctx );
  728. }
  729.  
  730.  
  731.  
  732. /**
  733.  * Recompute the values of the context's rowaddr array.
  734.  */
  735. static void
  736. compute_row_addresses( OSMesaContext osmesa )
  737. {
  738.    GLint bytesPerPixel, bytesPerRow, i;
  739.    GLubyte *origin = (GLubyte *) osmesa->rb->Data;
  740.    GLint bpc; /* bytes per channel */
  741.    GLint rowlength; /* in pixels */
  742.    GLint height = osmesa->rb->Height;
  743.  
  744.    if (osmesa->userRowLength)
  745.       rowlength = osmesa->userRowLength;
  746.    else
  747.       rowlength = osmesa->rb->Width;
  748.  
  749.    if (osmesa->rb->DataType == GL_UNSIGNED_BYTE)
  750.       bpc = 1;
  751.    else if (osmesa->rb->DataType == GL_UNSIGNED_SHORT)
  752.       bpc = 2;
  753.    else if (osmesa->rb->DataType == GL_FLOAT)
  754.       bpc = 4;
  755.    else {
  756.       _mesa_problem(&osmesa->mesa,
  757.                     "Unexpected datatype in osmesa::compute_row_addresses");
  758.       return;
  759.    }
  760.  
  761.    if ((osmesa->format == OSMESA_RGB) || (osmesa->format == OSMESA_BGR)) {
  762.       /* RGB mode */
  763.       bytesPerPixel = 3 * bpc;
  764.    }
  765.    else if (osmesa->format == OSMESA_RGB_565) {
  766.       /* 5/6/5 RGB pixel in 16 bits */
  767.       bytesPerPixel = 2;
  768.    }
  769.    else {
  770.       /* RGBA mode */
  771.       bytesPerPixel = 4 * bpc;
  772.    }
  773.  
  774.    bytesPerRow = rowlength * bytesPerPixel;
  775.  
  776.    if (osmesa->yup) {
  777.       /* Y=0 is bottom line of window */
  778.       for (i = 0; i < height; i++) {
  779.          osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow);
  780.       }
  781.    }
  782.    else {
  783.       /* Y=0 is top line of window */
  784.       for (i = 0; i < height; i++) {
  785.          GLint j = height - i - 1;
  786.          osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow);
  787.       }
  788.    }
  789. }
  790.  
  791.  
  792.  
  793. /**
  794.  * Don't use _mesa_delete_renderbuffer since we can't free rb->Data.
  795.  */
  796. static void
  797. osmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
  798. {
  799.    free(rb);
  800. }
  801.  
  802.  
  803. /**
  804.  * Allocate renderbuffer storage.  We don't actually allocate any storage
  805.  * since we're using a user-provided buffer.
  806.  * Just set up all the gl_renderbuffer methods.
  807.  */
  808. static GLboolean
  809. osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  810.                             GLenum internalFormat, GLuint width, GLuint height)
  811. {
  812.    const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
  813.    GLint bpc; /* bits per channel */
  814.  
  815.    if (rb->DataType == GL_UNSIGNED_BYTE)
  816.       bpc = 8;
  817.    else if (rb->DataType == GL_UNSIGNED_SHORT)
  818.       bpc = 16;
  819.    else
  820.       bpc = 32;
  821.  
  822.    /* Note: we can ignoring internalFormat for "window-system" renderbuffers */
  823.    (void) internalFormat;
  824.  
  825.    if (osmesa->format == OSMESA_RGBA) {
  826.       if (rb->DataType == GL_UNSIGNED_BYTE) {
  827.          rb->GetRow = get_row_RGBA8;
  828.          rb->GetValues = get_values_RGBA8;
  829.          rb->PutRow = put_row_RGBA8;
  830.          rb->PutRowRGB = put_row_rgb_RGBA8;
  831.          rb->PutMonoRow = put_mono_row_RGBA8;
  832.          rb->PutValues = put_values_RGBA8;
  833.          rb->PutMonoValues = put_mono_values_RGBA8;
  834.       }
  835.       else if (rb->DataType == GL_UNSIGNED_SHORT) {
  836.          rb->GetRow = get_row_RGBA16;
  837.          rb->GetValues = get_values_RGBA16;
  838.          rb->PutRow = put_row_RGBA16;
  839.          rb->PutRowRGB = put_row_rgb_RGBA16;
  840.          rb->PutMonoRow = put_mono_row_RGBA16;
  841.          rb->PutValues = put_values_RGBA16;
  842.          rb->PutMonoValues = put_mono_values_RGBA16;
  843.       }
  844.       else {
  845.          rb->GetRow = get_row_RGBA32;
  846.          rb->GetValues = get_values_RGBA32;
  847.          rb->PutRow = put_row_RGBA32;
  848.          rb->PutRowRGB = put_row_rgb_RGBA32;
  849.          rb->PutMonoRow = put_mono_row_RGBA32;
  850.          rb->PutValues = put_values_RGBA32;
  851.          rb->PutMonoValues = put_mono_values_RGBA32;
  852.       }
  853.    }
  854.    else if (osmesa->format == OSMESA_BGRA) {
  855.       if (rb->DataType == GL_UNSIGNED_BYTE) {
  856.          rb->GetRow = get_row_BGRA8;
  857.          rb->GetValues = get_values_BGRA8;
  858.          rb->PutRow = put_row_BGRA8;
  859.          rb->PutRowRGB = put_row_rgb_BGRA8;
  860.          rb->PutMonoRow = put_mono_row_BGRA8;
  861.          rb->PutValues = put_values_BGRA8;
  862.          rb->PutMonoValues = put_mono_values_BGRA8;
  863.       }
  864.       else if (rb->DataType == GL_UNSIGNED_SHORT) {
  865.          rb->GetRow = get_row_BGRA16;
  866.          rb->GetValues = get_values_BGRA16;
  867.          rb->PutRow = put_row_BGRA16;
  868.          rb->PutRowRGB = put_row_rgb_BGRA16;
  869.          rb->PutMonoRow = put_mono_row_BGRA16;
  870.          rb->PutValues = put_values_BGRA16;
  871.          rb->PutMonoValues = put_mono_values_BGRA16;
  872.       }
  873.       else {
  874.          rb->GetRow = get_row_BGRA32;
  875.          rb->GetValues = get_values_BGRA32;
  876.          rb->PutRow = put_row_BGRA32;
  877.          rb->PutRowRGB = put_row_rgb_BGRA32;
  878.          rb->PutMonoRow = put_mono_row_BGRA32;
  879.          rb->PutValues = put_values_BGRA32;
  880.          rb->PutMonoValues = put_mono_values_BGRA32;
  881.       }
  882.    }
  883.    else if (osmesa->format == OSMESA_ARGB) {
  884.       if (rb->DataType == GL_UNSIGNED_BYTE) {
  885.          rb->GetRow = get_row_ARGB8;
  886.          rb->GetValues = get_values_ARGB8;
  887.          rb->PutRow = put_row_ARGB8;
  888.          rb->PutRowRGB = put_row_rgb_ARGB8;
  889.          rb->PutMonoRow = put_mono_row_ARGB8;
  890.          rb->PutValues = put_values_ARGB8;
  891.          rb->PutMonoValues = put_mono_values_ARGB8;
  892.       }
  893.       else if (rb->DataType == GL_UNSIGNED_SHORT) {
  894.          rb->GetRow = get_row_ARGB16;
  895.          rb->GetValues = get_values_ARGB16;
  896.          rb->PutRow = put_row_ARGB16;
  897.          rb->PutRowRGB = put_row_rgb_ARGB16;
  898.          rb->PutMonoRow = put_mono_row_ARGB16;
  899.          rb->PutValues = put_values_ARGB16;
  900.          rb->PutMonoValues = put_mono_values_ARGB16;
  901.       }
  902.       else {
  903.          rb->GetRow = get_row_ARGB32;
  904.          rb->GetValues = get_values_ARGB32;
  905.          rb->PutRow = put_row_ARGB32;
  906.          rb->PutRowRGB = put_row_rgb_ARGB32;
  907.          rb->PutMonoRow = put_mono_row_ARGB32;
  908.          rb->PutValues = put_values_ARGB32;
  909.          rb->PutMonoValues = put_mono_values_ARGB32;
  910.       }
  911.    }
  912.    else if (osmesa->format == OSMESA_RGB) {
  913.       if (rb->DataType == GL_UNSIGNED_BYTE) {
  914.          rb->GetRow = get_row_RGB8;
  915.          rb->GetValues = get_values_RGB8;
  916.          rb->PutRow = put_row_RGB8;
  917.          rb->PutRowRGB = put_row_rgb_RGB8;
  918.          rb->PutMonoRow = put_mono_row_RGB8;
  919.          rb->PutValues = put_values_RGB8;
  920.          rb->PutMonoValues = put_mono_values_RGB8;
  921.       }
  922.       else if (rb->DataType == GL_UNSIGNED_SHORT) {
  923.          rb->GetRow = get_row_RGB16;
  924.          rb->GetValues = get_values_RGB16;
  925.          rb->PutRow = put_row_RGB16;
  926.          rb->PutRowRGB = put_row_rgb_RGB16;
  927.          rb->PutMonoRow = put_mono_row_RGB16;
  928.          rb->PutValues = put_values_RGB16;
  929.          rb->PutMonoValues = put_mono_values_RGB16;
  930.       }
  931.       else {
  932.          rb->GetRow = get_row_RGB32;
  933.          rb->GetValues = get_values_RGB32;
  934.          rb->PutRow = put_row_RGB32;
  935.          rb->PutRowRGB = put_row_rgb_RGB32;
  936.          rb->PutMonoRow = put_mono_row_RGB32;
  937.          rb->PutValues = put_values_RGB32;
  938.          rb->PutMonoValues = put_mono_values_RGB32;
  939.       }
  940.    }
  941.    else if (osmesa->format == OSMESA_BGR) {
  942.       if (rb->DataType == GL_UNSIGNED_BYTE) {
  943.          rb->GetRow = get_row_BGR8;
  944.          rb->GetValues = get_values_BGR8;
  945.          rb->PutRow = put_row_BGR8;
  946.          rb->PutRowRGB = put_row_rgb_BGR8;
  947.          rb->PutMonoRow = put_mono_row_BGR8;
  948.          rb->PutValues = put_values_BGR8;
  949.          rb->PutMonoValues = put_mono_values_BGR8;
  950.       }
  951.       else if (rb->DataType == GL_UNSIGNED_SHORT) {
  952.          rb->GetRow = get_row_BGR16;
  953.          rb->GetValues = get_values_BGR16;
  954.          rb->PutRow = put_row_BGR16;
  955.          rb->PutRowRGB = put_row_rgb_BGR16;
  956.          rb->PutMonoRow = put_mono_row_BGR16;
  957.          rb->PutValues = put_values_BGR16;
  958.          rb->PutMonoValues = put_mono_values_BGR16;
  959.       }
  960.       else {
  961.          rb->GetRow = get_row_BGR32;
  962.          rb->GetValues = get_values_BGR32;
  963.          rb->PutRow = put_row_BGR32;
  964.          rb->PutRowRGB = put_row_rgb_BGR32;
  965.          rb->PutMonoRow = put_mono_row_BGR32;
  966.          rb->PutValues = put_values_BGR32;
  967.          rb->PutMonoValues = put_mono_values_BGR32;
  968.       }
  969.    }
  970.    else if (osmesa->format == OSMESA_RGB_565) {
  971.       ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
  972.       rb->GetRow = get_row_RGB_565;
  973.       rb->GetValues = get_values_RGB_565;
  974.       rb->PutRow = put_row_RGB_565;
  975.       rb->PutRowRGB = put_row_rgb_RGB_565;
  976.       rb->PutMonoRow = put_mono_row_RGB_565;
  977.       rb->PutValues = put_values_RGB_565;
  978.       rb->PutMonoValues = put_mono_values_RGB_565;
  979.    }
  980.    else {
  981.       _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage");
  982.    }
  983.  
  984.    rb->Width = width;
  985.    rb->Height = height;
  986.  
  987.    compute_row_addresses( osmesa );
  988.  
  989.    return GL_TRUE;
  990. }
  991.  
  992.  
  993. /**
  994.  * Allocate a new renderbuffer to describe the user-provided color buffer.
  995.  */
  996. static struct gl_renderbuffer *
  997. new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
  998. {
  999.    const GLuint name = 0;
  1000.    struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
  1001.    if (rb) {
  1002.       rb->RefCount = 1;
  1003.       rb->Delete = osmesa_delete_renderbuffer;
  1004.       rb->AllocStorage = osmesa_renderbuffer_storage;
  1005.  
  1006.       rb->InternalFormat = GL_RGBA;
  1007.       switch (type) {
  1008.       case GL_UNSIGNED_BYTE:
  1009.          rb->Format = MESA_FORMAT_RGBA8888;
  1010.          break;
  1011.       case GL_UNSIGNED_SHORT:
  1012.          rb->Format = MESA_FORMAT_RGBA_16;
  1013.          break;
  1014.       case GL_FLOAT:
  1015.          rb->Format = MESA_FORMAT_RGBA_FLOAT32;
  1016.          break;
  1017.       default:
  1018.          assert(0 && "Unexpected type in new_osmesa_renderbuffer()");
  1019.          rb->Format = MESA_FORMAT_RGBA8888;
  1020.       }
  1021.       rb->_BaseFormat = GL_RGBA;
  1022.       rb->DataType = type;
  1023.    }
  1024.    return rb;
  1025. }
  1026.  
  1027.  
  1028. /**********************************************************************/
  1029. /*****                    Public Functions                        *****/
  1030. /**********************************************************************/
  1031.  
  1032.  
  1033. /**
  1034.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  1035.  * an RGBA vs Color-Index mode flag.
  1036.  *
  1037.  * Input:  format - Must be GL_RGBA
  1038.  *         sharelist - specifies another OSMesaContext with which to share
  1039.  *                     display lists.  NULL indicates no sharing.
  1040.  * Return:  an OSMesaContext or 0 if error
  1041.  */
  1042. GLAPI OSMesaContext GLAPIENTRY
  1043. OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  1044. {
  1045.    return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
  1046.                                  8, 0, sharelist);
  1047. }
  1048.  
  1049.  
  1050.  
  1051. /**
  1052.  * New in Mesa 3.5
  1053.  *
  1054.  * Create context and specify size of ancillary buffers.
  1055.  */
  1056. GLAPI OSMesaContext GLAPIENTRY
  1057. OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
  1058.                         GLint accumBits, OSMesaContext sharelist )
  1059. {
  1060.    OSMesaContext osmesa;
  1061.    struct dd_function_table functions;
  1062.    GLint rind, gind, bind, aind;
  1063.    GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
  1064.  
  1065.    rind = gind = bind = aind = 0;
  1066.    if (format==OSMESA_RGBA) {
  1067.       redBits = CHAN_BITS;
  1068.       greenBits = CHAN_BITS;
  1069.       blueBits = CHAN_BITS;
  1070.       alphaBits = CHAN_BITS;
  1071.       rind = 0;
  1072.       gind = 1;
  1073.       bind = 2;
  1074.       aind = 3;
  1075.    }
  1076.    else if (format==OSMESA_BGRA) {
  1077.       redBits = CHAN_BITS;
  1078.       greenBits = CHAN_BITS;
  1079.       blueBits = CHAN_BITS;
  1080.       alphaBits = CHAN_BITS;
  1081.       bind = 0;
  1082.       gind = 1;
  1083.       rind = 2;
  1084.       aind = 3;
  1085.    }
  1086.    else if (format==OSMESA_ARGB) {
  1087.       redBits = CHAN_BITS;
  1088.       greenBits = CHAN_BITS;
  1089.       blueBits = CHAN_BITS;
  1090.       alphaBits = CHAN_BITS;
  1091.       aind = 0;
  1092.       rind = 1;
  1093.       gind = 2;
  1094.       bind = 3;
  1095.    }
  1096.    else if (format==OSMESA_RGB) {
  1097.       redBits = CHAN_BITS;
  1098.       greenBits = CHAN_BITS;
  1099.       blueBits = CHAN_BITS;
  1100.       alphaBits = 0;
  1101.       rind = 0;
  1102.       gind = 1;
  1103.       bind = 2;
  1104.    }
  1105.    else if (format==OSMESA_BGR) {
  1106.       redBits = CHAN_BITS;
  1107.       greenBits = CHAN_BITS;
  1108.       blueBits = CHAN_BITS;
  1109.       alphaBits = 0;
  1110.       rind = 2;
  1111.       gind = 1;
  1112.       bind = 0;
  1113.    }
  1114. #if CHAN_TYPE == GL_UNSIGNED_BYTE
  1115.    else if (format==OSMESA_RGB_565) {
  1116.       redBits = 5;
  1117.       greenBits = 6;
  1118.       blueBits = 5;
  1119.       alphaBits = 0;
  1120.       rind = 0; /* not used */
  1121.       gind = 0;
  1122.       bind = 0;
  1123.    }
  1124. #endif
  1125.    else {
  1126.       return NULL;
  1127.    }
  1128.  
  1129.    osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
  1130.    if (osmesa) {
  1131.       osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
  1132.                                                GL_FALSE,    /* stereo */
  1133.                                                redBits,
  1134.                                                greenBits,
  1135.                                                blueBits,
  1136.                                                alphaBits,
  1137.                                                depthBits,
  1138.                                                stencilBits,
  1139.                                                accumBits,
  1140.                                                accumBits,
  1141.                                                accumBits,
  1142.                                                alphaBits ? accumBits : 0,
  1143.                                                1            /* num samples */
  1144.                                                );
  1145.       if (!osmesa->gl_visual) {
  1146.          free(osmesa);
  1147.          return NULL;
  1148.       }
  1149.  
  1150.       /* Initialize device driver function table */
  1151.       _mesa_init_driver_functions(&functions);
  1152.       /* override with our functions */
  1153.       functions.GetString = get_string;
  1154.       functions.UpdateState = osmesa_update_state;
  1155.       functions.GetBufferSize = NULL;
  1156.  
  1157.       if (!_mesa_initialize_context(&osmesa->mesa,
  1158.                                     osmesa->gl_visual,
  1159.                                     sharelist ? &sharelist->mesa
  1160.                                               : (struct gl_context *) NULL,
  1161.                                     &functions, (void *) osmesa)) {
  1162.          _mesa_destroy_visual( osmesa->gl_visual );
  1163.          free(osmesa);
  1164.          return NULL;
  1165.       }
  1166.  
  1167.       _mesa_enable_sw_extensions(&(osmesa->mesa));
  1168.       _mesa_enable_1_3_extensions(&(osmesa->mesa));
  1169.       _mesa_enable_1_4_extensions(&(osmesa->mesa));
  1170.       _mesa_enable_1_5_extensions(&(osmesa->mesa));
  1171.       _mesa_enable_2_0_extensions(&(osmesa->mesa));
  1172.       _mesa_enable_2_1_extensions(&(osmesa->mesa));
  1173.  
  1174.       osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
  1175.       if (!osmesa->gl_buffer) {
  1176.          _mesa_destroy_visual( osmesa->gl_visual );
  1177.          _mesa_free_context_data( &osmesa->mesa );
  1178.          free(osmesa);
  1179.          return NULL;
  1180.       }
  1181.  
  1182.       /* Create depth/stencil/accum buffers.  We'll create the color
  1183.        * buffer later in OSMesaMakeCurrent().
  1184.        */
  1185.       _mesa_add_soft_renderbuffers(osmesa->gl_buffer,
  1186.                                    GL_FALSE, /* color */
  1187.                                    osmesa->gl_visual->haveDepthBuffer,
  1188.                                    osmesa->gl_visual->haveStencilBuffer,
  1189.                                    osmesa->gl_visual->haveAccumBuffer,
  1190.                                    GL_FALSE, /* alpha */
  1191.                                    GL_FALSE /* aux */ );
  1192.  
  1193.       osmesa->format = format;
  1194.       osmesa->userRowLength = 0;
  1195.       osmesa->yup = GL_TRUE;
  1196.       osmesa->rInd = rind;
  1197.       osmesa->gInd = gind;
  1198.       osmesa->bInd = bind;
  1199.       osmesa->aInd = aind;
  1200.  
  1201.       _mesa_meta_init(&osmesa->mesa);
  1202.  
  1203.       /* Initialize the software rasterizer and helper modules. */
  1204.       {
  1205.          struct gl_context *ctx = &osmesa->mesa;
  1206.          SWcontext *swrast;
  1207.          TNLcontext *tnl;
  1208.  
  1209.          if (!_swrast_CreateContext( ctx ) ||
  1210.              !_vbo_CreateContext( ctx ) ||
  1211.              !_tnl_CreateContext( ctx ) ||
  1212.              !_swsetup_CreateContext( ctx )) {
  1213.             _mesa_destroy_visual(osmesa->gl_visual);
  1214.             _mesa_free_context_data(ctx);
  1215.             free(osmesa);
  1216.             return NULL;
  1217.          }
  1218.  
  1219.          _swsetup_Wakeup( ctx );
  1220.  
  1221.          /* use default TCL pipeline */
  1222.          tnl = TNL_CONTEXT(ctx);
  1223.          tnl->Driver.RunPipeline = _tnl_run_pipeline;
  1224.  
  1225.          /* Extend the software rasterizer with our optimized line and triangle
  1226.           * drawing functions.
  1227.           */
  1228.          swrast = SWRAST_CONTEXT( ctx );
  1229.          swrast->choose_line = osmesa_choose_line;
  1230.          swrast->choose_triangle = osmesa_choose_triangle;
  1231.       }
  1232.    }
  1233.    return osmesa;
  1234. }
  1235.  
  1236.  
  1237. /**
  1238.  * Destroy an Off-Screen Mesa rendering context.
  1239.  *
  1240.  * \param osmesa  the context to destroy
  1241.  */
  1242. GLAPI void GLAPIENTRY
  1243. OSMesaDestroyContext( OSMesaContext osmesa )
  1244. {
  1245.    if (osmesa) {
  1246.       if (osmesa->rb)
  1247.          _mesa_reference_renderbuffer(&osmesa->rb, NULL);
  1248.  
  1249.       _mesa_meta_free( &osmesa->mesa );
  1250.  
  1251.       _swsetup_DestroyContext( &osmesa->mesa );
  1252.       _tnl_DestroyContext( &osmesa->mesa );
  1253.       _vbo_DestroyContext( &osmesa->mesa );
  1254.       _swrast_DestroyContext( &osmesa->mesa );
  1255.  
  1256.       _mesa_destroy_visual( osmesa->gl_visual );
  1257.       _mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
  1258.  
  1259.       _mesa_free_context_data( &osmesa->mesa );
  1260.       free( osmesa );
  1261.    }
  1262. }
  1263.  
  1264.  
  1265. /**
  1266.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  1267.  * block of memory which the client provides.  Its size must be at least
  1268.  * as large as width*height*sizeof(type).  Its address should be a multiple
  1269.  * of 4 if using RGBA mode.
  1270.  *
  1271.  * Image data is stored in the order of glDrawPixels:  row-major order
  1272.  * with the lower-left image pixel stored in the first array position
  1273.  * (ie. bottom-to-top).
  1274.  *
  1275.  * If the context's viewport hasn't been initialized yet, it will now be
  1276.  * initialized to (0,0,width,height).
  1277.  *
  1278.  * Input:  osmesa - the rendering context
  1279.  *         buffer - the image buffer memory
  1280.  *         type - data type for pixel components
  1281.  *            Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
  1282.  *            are supported.  But if Mesa's been compiled with CHAN_BITS==16
  1283.  *            then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.  And if
  1284.  *            Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT,
  1285.  *            GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.
  1286.  *         width, height - size of image buffer in pixels, at least 1
  1287.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid osmesa,
  1288.  *          invalid buffer address, invalid type, width<1, height<1,
  1289.  *          width>internal limit or height>internal limit.
  1290.  */
  1291. GLAPI GLboolean GLAPIENTRY
  1292. OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
  1293.                    GLsizei width, GLsizei height )
  1294. {
  1295.    if (!osmesa || !buffer ||
  1296.        width < 1 || height < 1 ||
  1297.        width > MAX_WIDTH || height > MAX_HEIGHT) {
  1298.       return GL_FALSE;
  1299.    }
  1300.  
  1301.    if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
  1302.       return GL_FALSE;
  1303.    }
  1304.  
  1305. #if 0
  1306.    if (!(type == GL_UNSIGNED_BYTE ||
  1307.          (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) ||
  1308.          (type == GL_FLOAT && CHAN_BITS == 32))) {
  1309.       /* i.e. is sizeof(type) * 8 > CHAN_BITS? */
  1310.       return GL_FALSE;
  1311.    }
  1312. #endif
  1313.  
  1314.    osmesa_update_state( &osmesa->mesa, 0 );
  1315.  
  1316.    /* Call this periodically to detect when the user has begun using
  1317.     * GL rendering from multiple threads.
  1318.     */
  1319.    _glapi_check_multithread();
  1320.  
  1321.  
  1322.    /* Create a front/left color buffer which wraps the user-provided buffer.
  1323.     * There is no back color buffer.
  1324.     * If the user tries to use a 8, 16 or 32-bit/channel buffer that
  1325.     * doesn't match what Mesa was compiled for (CHAN_BITS) the
  1326.     * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer
  1327.     * that converts rendering from CHAN_BITS to the user-requested channel
  1328.     * size.
  1329.     */
  1330.    if (!osmesa->rb) {
  1331.       osmesa->rb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
  1332.       _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
  1333.       _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb);
  1334.       assert(osmesa->rb->RefCount == 2);
  1335.    }
  1336.  
  1337.    /* Set renderbuffer fields.  Set width/height = 0 to force
  1338.     * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer()
  1339.     */
  1340.    osmesa->rb->Data = buffer;
  1341.    osmesa->rb->Width = osmesa->rb->Height = 0;
  1342.  
  1343.    /* Set the framebuffer's size.  This causes the
  1344.     * osmesa_renderbuffer_storage() function to get called.
  1345.     */
  1346.    _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
  1347.    osmesa->gl_buffer->Initialized = GL_TRUE; /* XXX TEMPORARY? */
  1348.  
  1349.    _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
  1350.  
  1351.    /* Remove renderbuffer attachment, then re-add.  This installs the
  1352.     * renderbuffer adaptor/wrapper if needed (for bpp conversion).
  1353.     */
  1354.    _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
  1355.    _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb);
  1356.  
  1357.  
  1358.    /* this updates the visual's red/green/blue/alphaBits fields */
  1359.    _mesa_update_framebuffer_visual(osmesa->gl_buffer);
  1360.  
  1361.    /* update the framebuffer size */
  1362.    _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
  1363.  
  1364.    return GL_TRUE;
  1365. }
  1366.  
  1367.  
  1368.  
  1369. GLAPI OSMesaContext GLAPIENTRY
  1370. OSMesaGetCurrentContext( void )
  1371. {
  1372.    struct gl_context *ctx = _mesa_get_current_context();
  1373.    if (ctx)
  1374.       return (OSMesaContext) ctx;
  1375.    else
  1376.       return NULL;
  1377. }
  1378.  
  1379.  
  1380.  
  1381. GLAPI void GLAPIENTRY
  1382. OSMesaPixelStore( GLint pname, GLint value )
  1383. {
  1384.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  1385.  
  1386.    switch (pname) {
  1387.       case OSMESA_ROW_LENGTH:
  1388.          if (value<0) {
  1389.             _mesa_error( &osmesa->mesa, GL_INVALID_VALUE,
  1390.                       "OSMesaPixelStore(value)" );
  1391.             return;
  1392.          }
  1393.          osmesa->userRowLength = value;
  1394.          break;
  1395.       case OSMESA_Y_UP:
  1396.          osmesa->yup = value ? GL_TRUE : GL_FALSE;
  1397.          break;
  1398.       default:
  1399.          _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
  1400.          return;
  1401.    }
  1402.  
  1403.    compute_row_addresses( osmesa );
  1404. }
  1405.  
  1406.  
  1407. GLAPI void GLAPIENTRY
  1408. OSMesaGetIntegerv( GLint pname, GLint *value )
  1409. {
  1410.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  1411.  
  1412.    switch (pname) {
  1413.       case OSMESA_WIDTH:
  1414.          if (osmesa->gl_buffer)
  1415.             *value = osmesa->gl_buffer->Width;
  1416.          else
  1417.             *value = 0;
  1418.          return;
  1419.       case OSMESA_HEIGHT:
  1420.          if (osmesa->gl_buffer)
  1421.             *value = osmesa->gl_buffer->Height;
  1422.          else
  1423.             *value = 0;
  1424.          return;
  1425.       case OSMESA_FORMAT:
  1426.          *value = osmesa->format;
  1427.          return;
  1428.       case OSMESA_TYPE:
  1429.          /* current color buffer's data type */
  1430.          if (osmesa->rb) {
  1431.             *value = osmesa->rb->DataType;
  1432.          }
  1433.          else {
  1434.             *value = 0;
  1435.          }
  1436.          return;
  1437.       case OSMESA_ROW_LENGTH:
  1438.          *value = osmesa->userRowLength;
  1439.          return;
  1440.       case OSMESA_Y_UP:
  1441.          *value = osmesa->yup;
  1442.          return;
  1443.       case OSMESA_MAX_WIDTH:
  1444.          *value = MAX_WIDTH;
  1445.          return;
  1446.       case OSMESA_MAX_HEIGHT:
  1447.          *value = MAX_HEIGHT;
  1448.          return;
  1449.       default:
  1450.          _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
  1451.          return;
  1452.    }
  1453. }
  1454.  
  1455.  
  1456. /**
  1457.  * Return the depth buffer associated with an OSMesa context.
  1458.  * Input:  c - the OSMesa context
  1459.  * Output:  width, height - size of buffer in pixels
  1460.  *          bytesPerValue - bytes per depth value (2 or 4)
  1461.  *          buffer - pointer to depth buffer values
  1462.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1463.  */
  1464. GLAPI GLboolean GLAPIENTRY
  1465. OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
  1466.                       GLint *bytesPerValue, void **buffer )
  1467. {
  1468.    struct gl_renderbuffer *rb = NULL;
  1469.  
  1470.    if (c->gl_buffer)
  1471.       rb = c->gl_buffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  1472.  
  1473.    if (!rb || !rb->Data) {
  1474.       *width = 0;
  1475.       *height = 0;
  1476.       *bytesPerValue = 0;
  1477.       *buffer = 0;
  1478.       return GL_FALSE;
  1479.    }
  1480.    else {
  1481.       *width = rb->Width;
  1482.       *height = rb->Height;
  1483.       if (c->gl_visual->depthBits <= 16)
  1484.          *bytesPerValue = sizeof(GLushort);
  1485.       else
  1486.          *bytesPerValue = sizeof(GLuint);
  1487.       *buffer = rb->Data;
  1488.       return GL_TRUE;
  1489.    }
  1490. }
  1491.  
  1492.  
  1493. /**
  1494.  * Return the color buffer associated with an OSMesa context.
  1495.  * Input:  c - the OSMesa context
  1496.  * Output:  width, height - size of buffer in pixels
  1497.  *          format - the pixel format (OSMESA_FORMAT)
  1498.  *          buffer - pointer to color buffer values
  1499.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1500.  */
  1501. GLAPI GLboolean GLAPIENTRY
  1502. OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width,
  1503.                       GLint *height, GLint *format, void **buffer )
  1504. {
  1505.    if (osmesa->rb && osmesa->rb->Data) {
  1506.       *width = osmesa->rb->Width;
  1507.       *height = osmesa->rb->Height;
  1508.       *format = osmesa->format;
  1509.       *buffer = osmesa->rb->Data;
  1510.       return GL_TRUE;
  1511.    }
  1512.    else {
  1513.       *width = 0;
  1514.       *height = 0;
  1515.       *format = 0;
  1516.       *buffer = 0;
  1517.       return GL_FALSE;
  1518.    }
  1519. }
  1520.  
  1521.  
  1522. struct name_function
  1523. {
  1524.    const char *Name;
  1525.    OSMESAproc Function;
  1526. };
  1527.  
  1528. static struct name_function functions[] = {
  1529.    { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext },
  1530.    { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt },
  1531.    { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext },
  1532.    { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent },
  1533.    { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext },
  1534.    { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore },
  1535.    { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv },
  1536.    { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer },
  1537.    { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer },
  1538.    { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress },
  1539.    { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp },
  1540.    { NULL, NULL }
  1541. };
  1542.  
  1543. /*
  1544. GLAPI OSMESAproc GLAPIENTRY
  1545. OSMesaGetProcAddress( const char *funcName )
  1546. {
  1547.    int i;
  1548.    for (i = 0; functions[i].Name; i++) {
  1549.       if (strcmp(functions[i].Name, funcName) == 0)
  1550.          return functions[i].Function;
  1551.    }
  1552.    return _glapi_get_proc_address(funcName);
  1553. }
  1554. */
  1555.  
  1556. GLAPI void GLAPIENTRY
  1557. OSMesaColorClamp(GLboolean enable)
  1558. {
  1559.    OSMesaContext osmesa = OSMesaGetCurrentContext();
  1560.  
  1561.    if (enable == GL_TRUE) {
  1562.       osmesa->mesa.Color.ClampFragmentColor = GL_TRUE;
  1563.    }
  1564.    else {
  1565.       osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
  1566.    }
  1567. }
  1568.  
  1569.  
  1570.