home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / OSmesa / osmesa.c
Encoding:
C/C++ Source or Header  |  1999-02-04  |  44.7 KB  |  1,606 lines

  1. /* $Id: osmesa.c,v 3.8 1998/07/26 03:11:31 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: osmesa.c,v $
  26.  * Revision 3.8  1998/07/26 03:11:31  brianp
  27.  * updated for Windows compilation per Ted jump
  28.  *
  29.  * Revision 3.7  1998/06/14 15:19:28  brianp
  30.  * fixed a few compiler warnings
  31.  *
  32.  * Revision 3.6  1998/06/14 15:16:19  brianp
  33.  * optimized RGBA span writing
  34.  *
  35.  * Revision 3.5  1998/03/28 03:59:25  brianp
  36.  * added CONST macro to fix IRIX compilation problems
  37.  *
  38.  * Revision 3.4  1998/03/28 02:03:51  brianp
  39.  * fixed G++ warnings
  40.  *
  41.  * Revision 3.3  1998/03/05 02:48:05  brianp
  42.  * call osmesa_update_state() before gl_make_current() (Lionel Ulmer)
  43.  *
  44.  * Revision 3.2  1998/03/05 02:16:55  brianp
  45.  * updated buffer clear function
  46.  *
  47.  * Revision 3.1  1998/02/05 01:10:25  brianp
  48.  * added John Stone's thread modifications
  49.  *
  50.  * Revision 3.0  1998/01/31 21:00:07  brianp
  51.  * initial rev
  52.  *
  53.  */
  54.  
  55.  
  56.  
  57. /*
  58.  * Off-Screen Mesa rendering / Rendering into client memory space
  59.  */
  60.  
  61.  
  62. #ifdef PC_HEADER
  63. #include "all.h"
  64. #else
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include "GL/osmesa.h"
  68. #include "context.h"
  69. #include "depth.h"
  70. #include "macros.h"
  71. #include "matrix.h"
  72. #include "types.h"
  73. #include "vb.h"
  74. #endif
  75.  
  76.  
  77. struct osmesa_context {
  78.    GLcontext *gl_ctx;        /* The core GL/Mesa context */
  79.    GLvisual *gl_visual;        /* Describes the buffers */
  80.    GLframebuffer *gl_buffer;    /* Depth, stencil, accum, etc buffers */
  81.    GLenum format;        /* either GL_RGBA or GL_COLOR_INDEX */
  82.    void *buffer;        /* the image buffer */
  83.    GLint width, height;        /* size of image buffer */
  84.    GLuint pixel;        /* current color index or RGBA pixel value */
  85.    GLuint clearpixel;        /* pixel for clearing the color buffer */
  86.    GLint rowlength;        /* number of pixels per row */
  87.    GLint userRowLength;        /* user-specified number of pixels per row */
  88.    GLint rshift, gshift;    /* bit shifts for RGBA formats */
  89.    GLint bshift, ashift;
  90.    GLint rind, gind, bind;    /* index offsets for RGBA formats */
  91.    void *rowaddr[MAX_HEIGHT];    /* address of first pixel in each image row */
  92.    GLboolean yup;        /* TRUE  -> Y increases upward */
  93.                 /* FALSE -> Y increases downward */
  94. };
  95.  
  96.  
  97.  
  98. #ifdef THREADS
  99.  
  100. #include "mthreads.h" /* Mesa platform independent threads interface */
  101.  
  102. static MesaTSD osmesa_ctx_tsd;
  103.  
  104. static void osmesa_ctx_thread_init() {
  105.   MesaInitTSD(&osmesa_ctx_tsd);
  106. }
  107.  
  108. static OSMesaContext osmesa_get_thread_context( void ) {
  109.   return (OSMesaContext) MesaGetTSD(&osmesa_ctx_tsd);
  110. }
  111.  
  112. static void osmesa_set_thread_context( OSMesaContext ctx ) {
  113.   MesaSetTSD(&osmesa_ctx_tsd, ctx, osmesa_ctx_thread_init);
  114. }
  115.  
  116.  
  117. #else
  118.    /* One current context for address space, all threads */
  119.    static OSMesaContext Current = NULL;
  120. #endif
  121.  
  122.  
  123.  
  124. /* A forward declaration: */
  125. static void osmesa_update_state( GLcontext *ctx );
  126.  
  127.  
  128.  
  129. /**********************************************************************/
  130. /*****                    Public Functions                        *****/
  131. /**********************************************************************/
  132.  
  133.  
  134. /*
  135.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  136.  * an RGBA vs Color-Index mode flag.
  137.  *
  138.  * Input:  format - either GL_RGBA or GL_COLOR_INDEX
  139.  *         sharelist - specifies another OSMesaContext with which to share
  140.  *                     display lists.  NULL indicates no sharing.
  141.  * Return:  an OSMesaContext or 0 if error
  142.  */
  143. WINGDIAPI OSMesaContext APIENTRY OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  144. {
  145.    OSMesaContext osmesa;
  146.    GLint rshift, gshift, bshift, ashift;
  147.    GLint rind, gind, bind;
  148.    GLint index_bits;
  149.    GLboolean rgbmode;
  150.    GLboolean swalpha;
  151.    GLuint i4 = 1;
  152.    GLubyte *i1 = (GLubyte *) &i4;
  153.    GLint little_endian = *i1;
  154.  
  155.    swalpha = GL_FALSE;
  156.    rind = gind = bind = 0;
  157.    if (format==OSMESA_COLOR_INDEX) {
  158.       index_bits = 8;
  159.       rshift = gshift = bshift = ashift = 0;
  160.       rgbmode = GL_FALSE;
  161.    }
  162.    else if (format==OSMESA_RGBA) {
  163.       index_bits = 0;
  164.       if (little_endian) {
  165.          rshift = 0;
  166.          gshift = 8;
  167.          bshift = 16;
  168.          ashift = 24;
  169.       }
  170.       else {
  171.          rshift = 24;
  172.          gshift = 16;
  173.          bshift = 8;
  174.          ashift = 0;
  175.       }
  176.       rgbmode = GL_TRUE;
  177.    }
  178.    else if (format==OSMESA_BGRA) {
  179.       index_bits = 0;
  180.       if (little_endian) {
  181.          ashift = 0;
  182.          rshift = 8;
  183.          gshift = 16;
  184.          bshift = 24;
  185.       }
  186.       else {
  187.          bshift = 24;
  188.          gshift = 16;
  189.          rshift = 8;
  190.          ashift = 0;
  191.       }
  192.       rgbmode = GL_TRUE;
  193.    }
  194.    else if (format==OSMESA_ARGB) {
  195.       index_bits = 0;
  196.       if (little_endian) {
  197.          bshift = 0;
  198.          gshift = 8;
  199.          rshift = 16;
  200.          ashift = 24;
  201.       }
  202.       else {
  203.          ashift = 24;
  204.          rshift = 16;
  205.          gshift = 8;
  206.          bshift = 0;
  207.       }
  208.       rgbmode = GL_TRUE;
  209.    }
  210.    else if (format==OSMESA_RGB) {
  211.       index_bits = 0;
  212.       bshift = 0;
  213.       gshift = 8;
  214.       rshift = 16;
  215.       ashift = 24;
  216.       bind = 2;
  217.       gind = 1;
  218.       rind = 0;
  219.       rgbmode = GL_TRUE;
  220.       swalpha = GL_TRUE;
  221.    }
  222.    else if (format==OSMESA_BGR) {
  223.       index_bits = 0;
  224.       bshift = 0;
  225.       gshift = 8;
  226.       rshift = 16;
  227.       ashift = 24;
  228.       bind = 0;
  229.       gind = 1;
  230.       rind = 2;
  231.       rgbmode = GL_TRUE;
  232.       swalpha = GL_TRUE;
  233.    }
  234.    else {
  235.       return NULL;
  236.    }
  237.  
  238.  
  239.    osmesa = (OSMesaContext) calloc( 1, sizeof(struct osmesa_context) );
  240.    if (osmesa) {
  241.       osmesa->gl_visual = gl_create_visual( rgbmode,
  242.                         swalpha,    /* software alpha */
  243.                                             GL_FALSE,    /* double buffer */
  244.                                             GL_FALSE,    /* stereo */
  245.                                             DEPTH_BITS,
  246.                                             STENCIL_BITS,
  247.                                             ACCUM_BITS,
  248.                                             index_bits,
  249.                                             8, 8, 8, 0 );
  250.       if (!osmesa->gl_visual) {
  251.          return NULL;
  252.       }
  253.  
  254.       osmesa->gl_ctx = gl_create_context( osmesa->gl_visual,
  255.                             sharelist ? sharelist->gl_ctx : (GLcontext *) NULL,
  256.                             (void *) osmesa, GL_TRUE );
  257.       if (!osmesa->gl_ctx) {
  258.          gl_destroy_visual( osmesa->gl_visual );
  259.          free(osmesa);
  260.          return NULL;
  261.       }
  262.       osmesa->gl_buffer = gl_create_framebuffer( osmesa->gl_visual );
  263.       if (!osmesa->gl_buffer) {
  264.          gl_destroy_visual( osmesa->gl_visual );
  265.          gl_destroy_context( osmesa->gl_ctx );
  266.          free(osmesa);
  267.          return NULL;
  268.       }
  269.       osmesa->format = format;
  270.       osmesa->buffer = NULL;
  271.       osmesa->width = 0;
  272.       osmesa->height = 0;
  273.       osmesa->pixel = 0;
  274.       osmesa->clearpixel = 0;
  275.       osmesa->userRowLength = 0;
  276.       osmesa->rowlength = 0;
  277.       osmesa->yup = GL_TRUE;
  278.       osmesa->rshift = rshift;
  279.       osmesa->gshift = gshift;
  280.       osmesa->bshift = bshift;
  281.       osmesa->ashift = ashift;
  282.       osmesa->rind = rind;
  283.       osmesa->gind = gind;
  284.       osmesa->bind = bind;
  285.    }
  286.    return osmesa;
  287. }
  288.  
  289.  
  290.  
  291. /*
  292.  * Destroy an Off-Screen Mesa rendering context.
  293.  *
  294.  * Input:  ctx - the context to destroy
  295.  */
  296. WINGDIAPI void APIENTRY OSMesaDestroyContext( OSMesaContext ctx )
  297. {
  298.    if (ctx) {
  299.       gl_destroy_visual( ctx->gl_visual );
  300.       gl_destroy_framebuffer( ctx->gl_buffer );
  301.       gl_destroy_context( ctx->gl_ctx );
  302.       free( ctx );
  303.    }
  304. }
  305.  
  306.  
  307.  
  308. /*
  309.  * Recompute the values of the context's rowaddr array.
  310.  */
  311. static void compute_row_addresses( OSMesaContext ctx )
  312. {
  313.    GLint i;
  314.  
  315.    if (ctx->yup) {
  316.       /* Y=0 is bottom line of window */
  317.       if (ctx->format==OSMESA_COLOR_INDEX) {
  318.          /* 1-byte CI mode */
  319.          GLubyte *origin = (GLubyte *) ctx->buffer;
  320.          for (i=0;i<MAX_HEIGHT;i++) {
  321.             ctx->rowaddr[i] = origin + i * ctx->rowlength;
  322.          }
  323.       }
  324.       else {
  325.          if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
  326.             /* 3-byte RGB mode */
  327.             GLubyte *origin = (GLubyte *) ctx->buffer;
  328.             for (i=0;i<MAX_HEIGHT;i++) {
  329.                ctx->rowaddr[i] = origin + (i * (ctx->rowlength*3));
  330.             }
  331.          } else {
  332.             /* 4-byte RGBA mode */
  333.             GLuint *origin = (GLuint *) ctx->buffer;
  334.             for (i=0;i<MAX_HEIGHT;i++) {
  335.                ctx->rowaddr[i] = origin + i * ctx->rowlength;
  336.             }
  337.          }
  338.       }
  339.    }
  340.    else {
  341.       /* Y=0 is top line of window */
  342.       if (ctx->format==OSMESA_COLOR_INDEX) {
  343.          /* 1-byte CI mode */
  344.          GLubyte *origin = (GLubyte *) ctx->buffer;
  345.          for (i=0;i<MAX_HEIGHT;i++) {
  346.             ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
  347.          }
  348.       }
  349.       else {
  350.          if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
  351.             /* 3-byte RGB mode */
  352.             GLubyte *origin = (GLubyte *) ctx->buffer;
  353.             for (i=0;i<MAX_HEIGHT;i++) {
  354.                ctx->rowaddr[i] = origin + ((ctx->height-i-1) * (ctx->rowlength*3));
  355.             }
  356.          } else {
  357.             /* 4-byte RGBA mode */
  358.             GLuint *origin = (GLuint *) ctx->buffer;
  359.             for (i=0;i<MAX_HEIGHT;i++) {
  360.                ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
  361.             }
  362.          }
  363.       }
  364.    }
  365. }
  366.  
  367.  
  368. /*
  369.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  370.  * block of memory which the client provides.  Its size must be at least
  371.  * as large as width*height*sizeof(type).  Its address should be a multiple
  372.  * of 4 if using RGBA mode.
  373.  *
  374.  * Image data is stored in the order of glDrawPixels:  row-major order
  375.  * with the lower-left image pixel stored in the first array position
  376.  * (ie. bottom-to-top).
  377.  *
  378.  * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
  379.  * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
  380.  * value.  If the context is in color indexed mode, each pixel will be
  381.  * stored as a 1-byte value.
  382.  *
  383.  * If the context's viewport hasn't been initialized yet, it will now be
  384.  * initialized to (0,0,width,height).
  385.  *
  386.  * Input:  ctx - the rendering context
  387.  *         buffer - the image buffer memory
  388.  *         type - data type for pixel components, only GL_UNSIGNED_BYTE
  389.  *                supported now
  390.  *         width, height - size of image buffer in pixels, at least 1
  391.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
  392.  *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
  393.  *          width>internal limit or height>internal limit.
  394.  */
  395. WINGDIAPI GLboolean APIENTRY OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
  396.                              GLsizei width, GLsizei height )
  397. {
  398.    if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
  399.        || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
  400.       return GL_FALSE;
  401.    }
  402.  
  403.    osmesa_update_state( ctx->gl_ctx );
  404.    gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
  405.  
  406.    ctx->buffer = buffer;
  407.    ctx->width = width;
  408.    ctx->height = height;
  409.    if (ctx->userRowLength)
  410.       ctx->rowlength = ctx->userRowLength;
  411.    else
  412.       ctx->rowlength = width;
  413.  
  414. #ifdef THREADS
  415.    /* Set current context for the calling thread */
  416.    osmesa_set_thread_context(ctx);
  417. #else
  418.    /* Set current context for the address space, all threads */
  419.    Current = ctx;
  420. #endif
  421.  
  422.    compute_row_addresses( ctx );
  423.  
  424.    /* init viewport */
  425.    if (ctx->gl_ctx->Viewport.Width==0) {
  426.       /* initialize viewport and scissor box to buffer size */
  427.       gl_Viewport( ctx->gl_ctx, 0, 0, width, height );
  428.       ctx->gl_ctx->Scissor.Width = width;
  429.       ctx->gl_ctx->Scissor.Height = height;
  430.    }
  431.  
  432.    return GL_TRUE;
  433. }
  434.  
  435.  
  436.  
  437.  
  438. WINGDIAPI OSMesaContext APIENTRY OSMesaGetCurrentContext( void )
  439. {
  440. #ifdef THREADS
  441.    /* Return current handle for the calling thread */
  442.    return osmesa_get_thread_context();
  443. #else
  444.    /* Return current handle for the address space, all threads */
  445.    return Current;
  446. #endif
  447. }
  448.  
  449.  
  450.  
  451. WINGDIAPI void APIENTRY OSMesaPixelStore( GLint pname, GLint value )
  452. {
  453.    OSMesaContext ctx = OSMesaGetCurrentContext();
  454.  
  455.    switch (pname) {
  456.       case OSMESA_ROW_LENGTH:
  457.          if (value<0) {
  458.             gl_error( ctx->gl_ctx, GL_INVALID_VALUE,
  459.                       "OSMesaPixelStore(value)" );
  460.             return;
  461.          }
  462.          ctx->userRowLength = value;
  463.          ctx->rowlength = value;
  464.          break;
  465.       case OSMESA_Y_UP:
  466.          ctx->yup = value ? GL_TRUE : GL_FALSE;
  467.          break;
  468.       default:
  469.          gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
  470.          return;
  471.    }
  472.  
  473.    compute_row_addresses( ctx );
  474. }
  475.  
  476.  
  477. WINGDIAPI void APIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
  478. {
  479.    OSMesaContext ctx = OSMesaGetCurrentContext();
  480.  
  481.    switch (pname) {
  482.       case OSMESA_WIDTH:
  483.          *value = ctx->width;
  484.          return;
  485.       case OSMESA_HEIGHT:
  486.          *value = ctx->height;
  487.          return;
  488.       case OSMESA_FORMAT:
  489.          *value = ctx->format;
  490.          return;
  491.       case OSMESA_TYPE:
  492.          *value = GL_UNSIGNED_BYTE;
  493.          return;
  494.       case OSMESA_ROW_LENGTH:
  495.          *value = ctx->rowlength;
  496.          return;
  497.       case OSMESA_Y_UP:
  498.          *value = ctx->yup;
  499.          return;
  500.       default:
  501.          gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)" );
  502.          return;
  503.    }
  504. }
  505.  
  506.  
  507.  
  508. /*
  509.  * Return the depth buffer associated with an OSMesa context.
  510.  * Input:  c - the OSMesa context
  511.  * Output:  width, height - size of buffer in pixels
  512.  *          bytesPerValue - bytes per depth value (2 or 4)
  513.  *          buffer - pointer to depth buffer values
  514.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  515.  */
  516. WINGDIAPI GLboolean APIENTRY OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
  517.                                 GLint *bytesPerValue, void **buffer )
  518. {
  519.    if ((!c->gl_buffer) || (!c->gl_buffer->Depth)) {
  520.       *width = 0;
  521.       *height = 0;
  522.       *bytesPerValue = 0;
  523.       *buffer = 0;
  524.       return GL_FALSE;
  525.    }
  526.    else {
  527.       *width = c->gl_buffer->Width;
  528.       *height = c->gl_buffer->Height;
  529.       *bytesPerValue = sizeof(GLdepth);
  530.       *buffer = c->gl_buffer->Depth;
  531.       return GL_TRUE;
  532.    }
  533. }
  534.  
  535.  
  536.  
  537.  
  538. /**********************************************************************/
  539. /*** Device Driver Functions                                        ***/
  540. /**********************************************************************/
  541.  
  542.  
  543. /*
  544.  * Useful macros:
  545.  */
  546. #define PACK_RGBA(R,G,B,A)  (  ((R) << osmesa->rshift) \
  547.                              | ((G) << osmesa->gshift) \
  548.                              | ((B) << osmesa->bshift) \
  549.                              | ((A) << osmesa->ashift) )
  550.  
  551. #define PACK_RGBA2(R,G,B,A)  (  ((R) << rshift) \
  552.                               | ((G) << gshift) \
  553.                               | ((B) << bshift) \
  554.                               | ((A) << ashift) )
  555.  
  556. #define UNPACK_RED(P)      (((P) >> osmesa->rshift) & 0xff)
  557. #define UNPACK_GREEN(P)    (((P) >> osmesa->gshift) & 0xff)
  558. #define UNPACK_BLUE(P)     (((P) >> osmesa->bshift) & 0xff)
  559. #define UNPACK_ALPHA(P)    (((P) >> osmesa->ashift) & 0xff)
  560.  
  561. #define PIXELADDR1(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + (X))
  562. #define PIXELADDR3(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
  563. #define PIXELADDR4(X,Y)  ((GLuint *)  osmesa->rowaddr[Y] + (X))
  564.  
  565.  
  566.  
  567.  
  568. static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
  569. {
  570.    (void) ctx;
  571.    if (mode==GL_FRONT) {
  572.       return GL_TRUE;
  573.    }
  574.    else {
  575.       return GL_FALSE;
  576.    }
  577. }
  578.  
  579.  
  580. static void clear_index( GLcontext *ctx, GLuint index )
  581. {
  582.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  583.    osmesa->clearpixel = index;
  584. }
  585.  
  586.  
  587.  
  588. static void clear_color( GLcontext *ctx,
  589.                          GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  590. {
  591.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  592.    osmesa->clearpixel = PACK_RGBA( r, g, b, a );
  593. }
  594.  
  595.  
  596.  
  597. static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
  598.                          GLint x, GLint y, GLint width, GLint height )
  599. {
  600.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  601.    if (mask & GL_COLOR_BUFFER_BIT) {
  602.       if (osmesa->format==OSMESA_COLOR_INDEX) {
  603.          if (all) {
  604.             /* Clear whole CI buffer */
  605.             MEMSET(osmesa->buffer, osmesa->clearpixel,
  606.                    osmesa->rowlength * osmesa->height);
  607.          }
  608.          else {
  609.             /* Clear part of CI buffer */
  610.             GLint i, j;
  611.             for (i=0;i<height;i++) {
  612.                GLubyte *ptr1 = PIXELADDR1( x, (y+i) );
  613.                for (j=0;j<width;j++) {
  614.                   *ptr1++ = osmesa->clearpixel;
  615.                }
  616.             }
  617.          }
  618.       }
  619.       else if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) {
  620.          GLubyte rval = UNPACK_RED(osmesa->clearpixel);
  621.          GLubyte gval = UNPACK_GREEN(osmesa->clearpixel);
  622.          GLubyte bval = UNPACK_BLUE(osmesa->clearpixel);
  623.          GLint   rind = osmesa->rind;
  624.          GLint   gind = osmesa->gind;
  625.          GLint   bind = osmesa->bind;
  626.          if (all) {
  627.             GLuint  i, n; 
  628.             GLubyte *ptr3 = (GLubyte *) osmesa->buffer;
  629.             /* Clear whole RGB buffer */
  630.             n = osmesa->rowlength * osmesa->height;
  631.             for (i=0;i<n;i++) {
  632.                ptr3[rind] = rval;
  633.                ptr3[gind] = gval;
  634.                ptr3[bind] = bval;
  635.                ptr3 += 3;
  636.             }
  637.          }
  638.          else {
  639.             /* Clear part of RGB buffer */
  640.             GLint i, j;
  641.             for (i=0;i<height;i++) {
  642.                GLubyte *ptr3 = PIXELADDR3( x, (y+i) );
  643.                for (j=0;j<width;j++) {
  644.                   ptr3[rind] = rval;
  645.                   ptr3[gind] = gval;
  646.                   ptr3[bind] = bval;
  647.                   ptr3 += 3;
  648.                }
  649.             }
  650.          }
  651.       }
  652.       else {
  653.          if (all) {
  654.             /* Clear whole RGBA buffer */
  655.             GLuint i, n, *ptr4;
  656.             n = osmesa->rowlength * osmesa->height;
  657.             ptr4 = (GLuint *) osmesa->buffer;
  658.             for (i=0;i<n;i++) {
  659.                *ptr4++ = osmesa->clearpixel;
  660.             }
  661.          }
  662.          else {
  663.             /* Clear part of RGBA buffer */
  664.             GLint i, j;
  665.             for (i=0;i<height;i++) {
  666.                GLuint *ptr4 = PIXELADDR4( x, (y+i) );
  667.                for (j=0;j<width;j++) {
  668.                   *ptr4++ = osmesa->clearpixel;
  669.                }
  670.             }
  671.          }
  672.       }
  673.    }
  674.    return mask & (~GL_COLOR_BUFFER_BIT);
  675. }
  676.  
  677.  
  678.  
  679. static void set_index( GLcontext *ctx, GLuint index )
  680. {
  681.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  682.    osmesa->pixel = index;
  683. }
  684.  
  685.  
  686.  
  687. static void set_color( GLcontext *ctx,
  688.                        GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  689. {
  690.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  691.    osmesa->pixel = PACK_RGBA( r, g, b, a );
  692. }
  693.  
  694.  
  695.  
  696. static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
  697. {
  698.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  699.    *width = osmesa->width;
  700.    *height = osmesa->height;
  701. }
  702.  
  703.  
  704. /**********************************************************************/
  705. /*****        Read/write spans/arrays of RGBA pixels              *****/
  706. /**********************************************************************/
  707.  
  708. /* Write RGBA pixels to an RGBA (or permuted) buffer. */
  709. static void write_rgba_span( const GLcontext *ctx,
  710.                              GLuint n, GLint x, GLint y,
  711.                              CONST GLubyte rgba[][4], const GLubyte mask[] )
  712. {
  713.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  714.    GLuint *ptr4 = PIXELADDR4( x, y );
  715.    GLuint i;
  716.    GLint rshift = osmesa->rshift;
  717.    GLint gshift = osmesa->gshift;
  718.    GLint bshift = osmesa->bshift;
  719.    GLint ashift = osmesa->ashift;
  720.    if (mask) {
  721.       for (i=0;i<n;i++,ptr4++) {
  722.          if (mask[i]) {
  723.             *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
  724.          }
  725.       }
  726.    }
  727.    else {
  728.       for (i=0;i<n;i++,ptr4++) {
  729.          *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
  730.       }
  731.    }
  732. }
  733.  
  734.  
  735. /* Write RGBA pixels to an RGBA buffer.  This is the fastest span-writer. */
  736. static void write_rgba_span_rgba( const GLcontext *ctx,
  737.                                   GLuint n, GLint x, GLint y,
  738.                                   CONST GLubyte rgba[][4],
  739.                                   const GLubyte mask[] )
  740. {
  741.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  742.    GLuint *ptr4 = PIXELADDR4( x, y );
  743.    const GLuint *rgba4 = (const GLuint *) rgba;
  744.    GLuint i;
  745.    if (mask) {
  746.       for (i=0;i<n;i++) {
  747.          if (mask[i]) {
  748.             ptr4[i] = rgba4[i];
  749.          }
  750.       }
  751.    }
  752.    else {
  753.       MEMCPY( ptr4, rgba4, n * 4 );
  754.    }
  755. }
  756.  
  757.  
  758. /* Write RGB pixels to an RGBA (or permuted) buffer. */
  759. static void write_rgb_span( const GLcontext *ctx,
  760.                             GLuint n, GLint x, GLint y,
  761.                             CONST GLubyte rgb[][3], const GLubyte mask[] )
  762. {
  763.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  764.    GLuint *ptr4 = PIXELADDR4( x, y );
  765.    GLuint i;
  766.    GLint rshift = osmesa->rshift;
  767.    GLint gshift = osmesa->gshift;
  768.    GLint bshift = osmesa->bshift;
  769.    GLint ashift = osmesa->ashift;
  770.    if (mask) {
  771.       for (i=0;i<n;i++,ptr4++) {
  772.          if (mask[i]) {
  773.             *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
  774.          }
  775.       }
  776.    }
  777.    else {
  778.       for (i=0;i<n;i++,ptr4++) {
  779.          *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
  780.       }
  781.    }
  782. }
  783.  
  784.  
  785.  
  786. static void write_monocolor_span( const GLcontext *ctx,
  787.                                   GLuint n, GLint x, GLint y,
  788.                   const GLubyte mask[] )
  789. {
  790.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  791.    GLuint *ptr4 = PIXELADDR4(x,y);
  792.    GLuint i;
  793.    for (i=0;i<n;i++,ptr4++) {
  794.       if (mask[i]) {
  795.          *ptr4 = osmesa->pixel;
  796.       }
  797.    }
  798. }
  799.  
  800.  
  801.  
  802. static void write_rgba_pixels( const GLcontext *ctx,
  803.                                GLuint n, const GLint x[], const GLint y[],
  804.                                CONST GLubyte rgba[][4], const GLubyte mask[] )
  805. {
  806.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  807.    GLuint i;
  808.    GLint rshift = osmesa->rshift;
  809.    GLint gshift = osmesa->gshift;
  810.    GLint bshift = osmesa->bshift;
  811.    GLint ashift = osmesa->ashift;
  812.    for (i=0;i<n;i++) {
  813.       if (mask[i]) {
  814.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  815.          *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
  816.       }
  817.    }
  818. }
  819.  
  820.  
  821.  
  822. static void write_monocolor_pixels( const GLcontext *ctx,
  823.                                     GLuint n, const GLint x[], const GLint y[],
  824.                     const GLubyte mask[] )
  825. {
  826.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  827.    GLuint i;
  828.    for (i=0;i<n;i++) {
  829.       if (mask[i]) {
  830.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  831.          *ptr4 = osmesa->pixel;
  832.       }
  833.    }
  834. }
  835.  
  836.  
  837. static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
  838.                              GLubyte rgba[][4] )
  839. {
  840.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  841.    GLuint i;
  842.    GLuint *ptr4 = PIXELADDR4(x,y);
  843.    for (i=0;i<n;i++) {
  844.       GLuint pixel = *ptr4++;
  845.       rgba[i][RCOMP] = UNPACK_RED(pixel);
  846.       rgba[i][GCOMP] = UNPACK_GREEN(pixel);
  847.       rgba[i][BCOMP] = UNPACK_BLUE(pixel);
  848.       rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
  849.    }
  850. }
  851.  
  852.  
  853. /* Read RGBA pixels from an RGBA buffer */
  854. static void read_rgba_span_rgba( const GLcontext *ctx,
  855.                                  GLuint n, GLint x, GLint y,
  856.                                  GLubyte rgba[][4] )
  857. {
  858.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  859.    GLuint *ptr4 = PIXELADDR4(x,y);
  860.    MEMCPY( rgba, ptr4, n * 4 * sizeof(GLubyte) );
  861. }
  862.  
  863.  
  864. static void read_rgba_pixels( const GLcontext *ctx,
  865.                                GLuint n, const GLint x[], const GLint y[],
  866.                    GLubyte rgba[][4], const GLubyte mask[] )
  867. {
  868.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  869.    GLuint i;
  870.    for (i=0;i<n;i++) {
  871.       if (mask[i]) {
  872.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  873.          GLuint pixel = *ptr4;
  874.          rgba[i][RCOMP] = UNPACK_RED(pixel);
  875.          rgba[i][GCOMP] = UNPACK_GREEN(pixel);
  876.          rgba[i][BCOMP] = UNPACK_BLUE(pixel);
  877.          rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
  878.       }
  879.    }
  880. }
  881.  
  882. /**********************************************************************/
  883. /*****                3 byte RGB pixel support funcs              *****/
  884. /**********************************************************************/
  885.  
  886. /* Write RGBA pixels to an RGB or BGR buffer. */
  887. static void write_rgba_span3( const GLcontext *ctx,
  888.                               GLuint n, GLint x, GLint y,
  889.                               CONST GLubyte rgba[][4], const GLubyte mask[] )
  890. {
  891.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  892.    GLubyte *ptr3 = PIXELADDR3( x, y);
  893.    GLuint i;
  894.    GLint rind = osmesa->rind;
  895.    GLint gind = osmesa->gind;
  896.    GLint bind = osmesa->bind;
  897.    if (mask) {
  898.       for (i=0;i<n;i++,ptr3+=3) {
  899.          if (mask[i]) {
  900.             ptr3[rind] = rgba[i][RCOMP];
  901.             ptr3[gind] = rgba[i][GCOMP];
  902.             ptr3[bind] = rgba[i][BCOMP];
  903.          }
  904.       }
  905.    }
  906.    else {
  907.       for (i=0;i<n;i++,ptr3+=3) {
  908.          ptr3[rind] = rgba[i][RCOMP];
  909.          ptr3[gind] = rgba[i][GCOMP];
  910.          ptr3[bind] = rgba[i][BCOMP];
  911.       }
  912.    }
  913. }
  914.  
  915. /* Write RGB pixels to an RGB or BGR buffer. */
  916. static void write_rgb_span3( const GLcontext *ctx,
  917.                              GLuint n, GLint x, GLint y,
  918.                              CONST GLubyte rgb[][3], const GLubyte mask[] )
  919. {
  920.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  921.    GLubyte *ptr3 = PIXELADDR3( x, y);
  922.    GLuint i;
  923.    GLint rind = osmesa->rind;
  924.    GLint gind = osmesa->gind;
  925.    GLint bind = osmesa->bind;
  926.    if (mask) {
  927.       for (i=0;i<n;i++,ptr3+=3) {
  928.          if (mask[i]) {
  929.             ptr3[rind] = rgb[i][RCOMP];
  930.             ptr3[gind] = rgb[i][GCOMP];
  931.             ptr3[bind] = rgb[i][BCOMP];
  932.          }
  933.       }
  934.    }
  935.    else {
  936.       for (i=0;i<n;i++,ptr3+=3) {
  937.          ptr3[rind] = rgb[i][RCOMP];
  938.          ptr3[gind] = rgb[i][GCOMP];
  939.          ptr3[bind] = rgb[i][BCOMP];
  940.       }
  941.    }
  942. }
  943.  
  944.  
  945. static void write_monocolor_span3( const GLcontext *ctx,
  946.                                   GLuint n, GLint x, GLint y,
  947.                   const GLubyte mask[] )
  948. {
  949.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  950.    
  951.    GLubyte rval = UNPACK_RED(osmesa->pixel);
  952.    GLubyte gval = UNPACK_GREEN(osmesa->pixel);
  953.    GLubyte bval = UNPACK_BLUE(osmesa->pixel);
  954.    GLint   rind = osmesa->rind;
  955.    GLint   gind = osmesa->gind;
  956.    GLint   bind = osmesa->bind;
  957.  
  958.  
  959.    GLubyte *ptr3 = PIXELADDR3( x, y);
  960.    GLuint i;
  961.    for (i=0;i<n;i++,ptr3+=3) {
  962.       if (mask[i]) {
  963.          ptr3[rind] = rval;
  964.          ptr3[gind] = gval;
  965.          ptr3[bind] = bval;
  966.       }
  967.    }
  968. }
  969.  
  970. static void write_rgba_pixels3( const GLcontext *ctx,
  971.                                 GLuint n, const GLint x[], const GLint y[],
  972.                                 CONST GLubyte rgba[][4], const GLubyte mask[] )
  973. {
  974.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  975.    GLuint i;
  976.    GLint rind = osmesa->rind;
  977.    GLint gind = osmesa->gind;
  978.    GLint bind = osmesa->bind;
  979.  
  980.    for (i=0;i<n;i++) {
  981.       if (mask[i]) {
  982.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  983.          ptr3[rind] = rgba[i][RCOMP];
  984.          ptr3[gind] = rgba[i][GCOMP];
  985.          ptr3[bind] = rgba[i][BCOMP];
  986.       }
  987.    }
  988. }
  989.  
  990. static void write_monocolor_pixels3( const GLcontext *ctx,
  991.                                     GLuint n, const GLint x[], const GLint y[],
  992.                     const GLubyte mask[] )
  993. {
  994.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  995.    GLuint i;
  996.    GLint rind = osmesa->rind;
  997.    GLint gind = osmesa->gind;
  998.    GLint bind = osmesa->bind;
  999.    GLubyte rval = UNPACK_RED(osmesa->pixel);
  1000.    GLubyte gval = UNPACK_GREEN(osmesa->pixel);
  1001.    GLubyte bval = UNPACK_BLUE(osmesa->pixel);
  1002.    for (i=0;i<n;i++) {
  1003.       if (mask[i]) {
  1004.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  1005.          ptr3[rind] = rval;
  1006.          ptr3[gind] = gval;
  1007.          ptr3[bind] = bval;
  1008.       }
  1009.    }
  1010. }
  1011.  
  1012. static void read_rgba_span3( const GLcontext *ctx,
  1013.                              GLuint n, GLint x, GLint y,
  1014.                              GLubyte rgba[][4] )
  1015. {
  1016.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1017.    GLuint i;
  1018.    GLint rind = osmesa->rind;
  1019.    GLint gind = osmesa->gind;
  1020.    GLint bind = osmesa->bind;
  1021.    GLubyte *ptr3 = PIXELADDR3( x, y);
  1022.    for (i=0;i<n;i++,ptr3+=3) {
  1023.       rgba[i][RCOMP] = ptr3[rind];
  1024.       rgba[i][GCOMP] = ptr3[gind];
  1025.       rgba[i][BCOMP] = ptr3[bind];
  1026.       rgba[i][ACOMP] = 0;
  1027.    }
  1028. }
  1029.  
  1030. static void read_rgba_pixels3( const GLcontext *ctx,
  1031.                                GLuint n, const GLint x[], const GLint y[],
  1032.                    GLubyte rgba[][4], const GLubyte mask[] )
  1033. {
  1034.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1035.    GLuint i;
  1036.    GLint rind = osmesa->rind;
  1037.    GLint gind = osmesa->gind;
  1038.    GLint bind = osmesa->bind;
  1039.    for (i=0;i<n;i++) {
  1040.       if (mask[i]) {
  1041.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  1042.          rgba[i][RCOMP] = ptr3[rind];
  1043.          rgba[i][GCOMP] = ptr3[gind];
  1044.          rgba[i][BCOMP] = ptr3[bind];
  1045.          rgba[i][ACOMP] = 0;
  1046.       }
  1047.    }
  1048. }
  1049.  
  1050.  
  1051. /**********************************************************************/
  1052. /*****        Read/write spans/arrays of CI pixels                *****/
  1053. /**********************************************************************/
  1054.  
  1055. /* Write 32-bit color index to buffer */
  1056. static void write_index32_span( const GLcontext *ctx,
  1057.                                 GLuint n, GLint x, GLint y,
  1058.                                 const GLuint index[], const GLubyte mask[] )
  1059. {
  1060.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1061.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1062.    GLuint i;
  1063.    if (mask) {
  1064.       for (i=0;i<n;i++,ptr1++) {
  1065.          if (mask[i]) {
  1066.             *ptr1 = (GLubyte) index[i];
  1067.          }
  1068.       }
  1069.    }
  1070.    else {
  1071.       for (i=0;i<n;i++,ptr1++) {
  1072.          *ptr1 = (GLubyte) index[i];
  1073.       }
  1074.    }
  1075. }
  1076.  
  1077.  
  1078. /* Write 8-bit color index to buffer */
  1079. static void write_index8_span( const GLcontext *ctx,
  1080.                                GLuint n, GLint x, GLint y,
  1081.                                const GLubyte index[], const GLubyte mask[] )
  1082. {
  1083.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1084.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1085.    GLuint i;
  1086.    if (mask) {
  1087.       for (i=0;i<n;i++,ptr1++) {
  1088.          if (mask[i]) {
  1089.             *ptr1 = (GLubyte) index[i];
  1090.          }
  1091.       }
  1092.    }
  1093.    else {
  1094.       MEMCPY( ptr1, index, n );
  1095.    }
  1096. }
  1097.  
  1098.  
  1099. static void write_monoindex_span( const GLcontext *ctx,
  1100.                                   GLuint n, GLint x, GLint y,
  1101.                   const GLubyte mask[] )
  1102. {
  1103.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1104.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1105.    GLuint i;
  1106.    for (i=0;i<n;i++,ptr1++) {
  1107.       if (mask[i]) {
  1108.          *ptr1 = (GLubyte) osmesa->pixel;
  1109.       }
  1110.    }
  1111. }
  1112.  
  1113.  
  1114. static void write_index_pixels( const GLcontext *ctx,
  1115.                                 GLuint n, const GLint x[], const GLint y[],
  1116.                     const GLuint index[], const GLubyte mask[] )
  1117. {
  1118.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1119.    GLuint i;
  1120.    for (i=0;i<n;i++) {
  1121.       if (mask[i]) {
  1122.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  1123.          *ptr1 = (GLubyte) index[i];
  1124.       }
  1125.    }
  1126. }
  1127.  
  1128.  
  1129. static void write_monoindex_pixels( const GLcontext *ctx,
  1130.                                     GLuint n, const GLint x[], const GLint y[],
  1131.                     const GLubyte mask[] )
  1132. {
  1133.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1134.    GLuint i;
  1135.    for (i=0;i<n;i++) {
  1136.       if (mask[i]) {
  1137.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  1138.          *ptr1 = (GLubyte) osmesa->pixel;
  1139.       }
  1140.    }
  1141. }
  1142.  
  1143.  
  1144. static void read_index_span( const GLcontext *ctx,
  1145.                              GLuint n, GLint x, GLint y, GLuint index[] )
  1146. {
  1147.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1148.    GLuint i;
  1149.    GLubyte *ptr1 = PIXELADDR1(x,y);
  1150.    for (i=0;i<n;i++,ptr1++) {
  1151.       index[i] = (GLuint) *ptr1;
  1152.    }
  1153. }
  1154.  
  1155.  
  1156. static void read_index_pixels( const GLcontext *ctx,
  1157.                                GLuint n, const GLint x[], const GLint y[],
  1158.                    GLuint index[], const GLubyte mask[] )
  1159. {
  1160.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1161.    GLuint i;
  1162.    for (i=0;i<n;i++) {
  1163.       if (mask[i] ) {
  1164.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  1165.          index[i] = (GLuint) *ptr1;
  1166.       }
  1167.    }
  1168. }
  1169.  
  1170.  
  1171.  
  1172. /**********************************************************************/
  1173. /*****                   Optimized line rendering                 *****/
  1174. /**********************************************************************/
  1175.  
  1176.  
  1177. /*
  1178.  * Draw a flat-shaded, RGB line into an osmesa buffer.
  1179.  */
  1180. static void flat_rgba_line( GLcontext *ctx,
  1181.                             GLuint vert0, GLuint vert1, GLuint pvert )
  1182. {
  1183.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1184.    GLubyte *color = ctx->VB->Color[pvert];
  1185.    unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
  1186.  
  1187. #define INTERP_XY 1
  1188. #define CLIP_HACK 1
  1189. #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
  1190.  
  1191. #ifdef WIN32
  1192. #include "..\linetemp.h"
  1193. #else
  1194. #include "linetemp.h"
  1195. #endif
  1196. }
  1197.  
  1198.  
  1199. /*
  1200.  * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
  1201.  */
  1202. static void flat_rgba_z_line( GLcontext *ctx,
  1203.                               GLuint vert0, GLuint vert1, GLuint pvert )
  1204. {
  1205.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1206.    GLubyte *color = ctx->VB->Color[pvert];
  1207.    unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
  1208.  
  1209. #define INTERP_XY 1
  1210. #define INTERP_Z 1
  1211. #define CLIP_HACK 1
  1212. #define PLOT(X,Y)                \
  1213.     if (Z < *zPtr) {            \
  1214.        GLuint *ptr4 = PIXELADDR4(X,Y);    \
  1215.        *ptr4 = pixel;            \
  1216.        *zPtr = Z;                \
  1217.     }
  1218.  
  1219. #ifdef WIN32
  1220. #include "..\linetemp.h"
  1221. #else
  1222. #include "linetemp.h"
  1223. #endif
  1224. }
  1225.  
  1226.  
  1227. /*
  1228.  * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
  1229.  */
  1230. static void flat_blend_rgba_line( GLcontext *ctx,
  1231.                                   GLuint vert0, GLuint vert1, GLuint pvert )
  1232. {
  1233.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1234.    struct vertex_buffer *VB = ctx->VB;
  1235.    GLint rshift = osmesa->rshift;
  1236.    GLint gshift = osmesa->gshift;
  1237.    GLint bshift = osmesa->bshift;
  1238.    GLint avalue = VB->Color[pvert][3];
  1239.    GLint msavalue = 255 - avalue;
  1240.    GLint rvalue = VB->Color[pvert][0]*avalue;
  1241.    GLint gvalue = VB->Color[pvert][1]*avalue;
  1242.    GLint bvalue = VB->Color[pvert][2]*avalue;
  1243.  
  1244. #define INTERP_XY 1
  1245. #define CLIP_HACK 1
  1246. #define PLOT(X,Y)                    \
  1247.    { GLuint *ptr4 = PIXELADDR4(X,Y); \
  1248.      GLuint  pixel = 0; \
  1249.      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
  1250.      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
  1251.      pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
  1252.      *ptr4 = pixel; \
  1253.    }
  1254.    
  1255. #ifdef WIN32
  1256. #include "..\linetemp.h"
  1257. #else
  1258. #include "linetemp.h"
  1259. #endif
  1260. }
  1261.  
  1262. /*
  1263.  * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
  1264.  */
  1265. static void flat_blend_rgba_z_line( GLcontext *ctx,
  1266.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  1267. {
  1268.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1269.    struct vertex_buffer *VB = ctx->VB;
  1270.    GLint rshift = osmesa->rshift;
  1271.    GLint gshift = osmesa->gshift;
  1272.    GLint bshift = osmesa->bshift;
  1273.    GLint avalue = VB->Color[pvert][3];
  1274.    GLint msavalue = 256 - avalue;
  1275.    GLint rvalue = VB->Color[pvert][0]*avalue;
  1276.    GLint gvalue = VB->Color[pvert][1]*avalue;
  1277.    GLint bvalue = VB->Color[pvert][2]*avalue;
  1278.  
  1279. #define INTERP_XY 1
  1280. #define INTERP_Z 1
  1281. #define CLIP_HACK 1
  1282. #define PLOT(X,Y)                \
  1283.     if (Z < *zPtr) {            \
  1284.    { GLuint *ptr4 = PIXELADDR4(X,Y); \
  1285.      GLuint  pixel = 0; \
  1286.      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
  1287.      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
  1288.      pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
  1289.      *ptr4 = pixel; \
  1290.    } \
  1291.     }
  1292.  
  1293. #ifdef WIN32
  1294. #include "..\linetemp.h"
  1295. #else
  1296. #include "linetemp.h"
  1297. #endif
  1298. }
  1299.  
  1300. /*
  1301.  * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
  1302.  */
  1303. static void flat_blend_rgba_z_line_write( GLcontext *ctx,
  1304.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  1305. {
  1306.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1307.    struct vertex_buffer *VB = ctx->VB;
  1308.    GLint rshift = osmesa->rshift;
  1309.    GLint gshift = osmesa->gshift;
  1310.    GLint bshift = osmesa->bshift;
  1311.    GLint avalue = VB->Color[pvert][3];
  1312.    GLint msavalue = 256 - avalue;
  1313.    GLint rvalue = VB->Color[pvert][0]*avalue;
  1314.    GLint gvalue = VB->Color[pvert][1]*avalue;
  1315.    GLint bvalue = VB->Color[pvert][2]*avalue;
  1316.  
  1317. #define INTERP_XY 1
  1318. #define INTERP_Z 1
  1319. #define CLIP_HACK 1
  1320. #define PLOT(X,Y)                \
  1321.     if (Z < *zPtr) {            \
  1322.    { GLuint *ptr4 = PIXELADDR4(X,Y); \
  1323.      GLuint  pixel = 0; \
  1324.      pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
  1325.      pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
  1326.      pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
  1327.      *ptr4 = pixel; \
  1328.    } \
  1329.        *zPtr = Z;                \
  1330.     }
  1331.  
  1332. #ifdef WIN32
  1333. #include "..\linetemp.h"
  1334. #else
  1335. #include "linetemp.h"
  1336. #endif
  1337. }
  1338.  
  1339.  
  1340. /*
  1341.  * Analyze context state to see if we can provide a fast line drawing
  1342.  * function, like those in lines.c.  Otherwise, return NULL.
  1343.  */
  1344. static line_func choose_line_function( GLcontext *ctx )
  1345. {
  1346.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1347.    
  1348.    if (ctx->Line.SmoothFlag)              return NULL;
  1349.    if (ctx->Texture.Enabled)              return NULL;
  1350.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  1351.  
  1352.    if (ctx->Line.Width==1.0F
  1353.        && ctx->Line.StippleFlag==GL_FALSE) {
  1354.  
  1355.        if (ctx->RasterMask==DEPTH_BIT
  1356.            && ctx->Depth.Func==GL_LESS
  1357.            && ctx->Depth.Mask==GL_TRUE) {
  1358.            switch(osmesa->format) {
  1359.                case OSMESA_RGBA:
  1360.                case OSMESA_BGRA:
  1361.                case OSMESA_ARGB:
  1362.                    return flat_rgba_z_line;
  1363.                default:
  1364.                    return NULL;
  1365.            }
  1366.        }
  1367.  
  1368.        if (ctx->RasterMask==0) {
  1369.            switch(osmesa->format) {
  1370.                case OSMESA_RGBA:
  1371.                case OSMESA_BGRA:
  1372.                case OSMESA_ARGB:
  1373.                    return flat_rgba_line;
  1374.                default:
  1375.                    return NULL;
  1376.            }
  1377.        }
  1378.  
  1379.        if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
  1380.            && ctx->Depth.Func==GL_LESS
  1381.            && ctx->Depth.Mask==GL_TRUE
  1382.            && ctx->Color.BlendSrc==GL_SRC_ALPHA
  1383.            && ctx->Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA
  1384.            && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  1385.            switch(osmesa->format) {
  1386.                case OSMESA_RGBA:
  1387.                case OSMESA_BGRA:
  1388.                case OSMESA_ARGB:
  1389.                    return flat_blend_rgba_z_line_write;
  1390.                default:
  1391.                    return NULL;
  1392.            }
  1393.        }
  1394.  
  1395.        if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
  1396.            && ctx->Depth.Func==GL_LESS
  1397.            && ctx->Depth.Mask==GL_FALSE
  1398.            && ctx->Color.BlendSrc==GL_SRC_ALPHA
  1399.            && ctx->Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA
  1400.            && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  1401.            switch(osmesa->format) {
  1402.                case OSMESA_RGBA:
  1403.                case OSMESA_BGRA:
  1404.                case OSMESA_ARGB:
  1405.                    return flat_blend_rgba_z_line;
  1406.                default:
  1407.                    return NULL;
  1408.            }
  1409.        }
  1410.  
  1411.        if (ctx->RasterMask==BLEND_BIT
  1412.            && ctx->Color.BlendSrc==GL_SRC_ALPHA
  1413.            && ctx->Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA
  1414.            && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
  1415.            switch(osmesa->format) {
  1416.                case OSMESA_RGBA:
  1417.                case OSMESA_BGRA:
  1418.                case OSMESA_ARGB:
  1419.                    return flat_blend_rgba_line;
  1420.                default:
  1421.                    return NULL;
  1422.            }
  1423.        }
  1424.  
  1425.    }
  1426.    return NULL;
  1427. }
  1428.  
  1429.  
  1430. /**********************************************************************/
  1431. /*****                 Optimized triangle rendering               *****/
  1432. /**********************************************************************/
  1433.  
  1434.  
  1435. /*
  1436.  * Smooth-shaded, z-less triangle, RGBA color.
  1437.  */
  1438. static void smooth_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1439.                                     GLuint v2, GLuint pv )
  1440. {
  1441.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1442.    GLint rshift = osmesa->rshift;
  1443.    GLint gshift = osmesa->gshift;
  1444.    GLint bshift = osmesa->bshift;
  1445.    GLint ashift = osmesa->ashift;
  1446.    (void) pv;
  1447. #define INTERP_Z 1
  1448. #define INTERP_RGB 1
  1449. #define INTERP_ALPHA 1
  1450. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  1451. {                                \
  1452.    GLint i, len = RIGHT-LEFT;                    \
  1453.    GLuint *img = PIXELADDR4(LEFT,Y);                   \
  1454.    for (i=0;i<len;i++,img++) {                    \
  1455.       GLdepth z = FixedToDepth(ffz);                \
  1456.       if (z < zRow[i]) {                    \
  1457.          *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg),    \
  1458.                     FixedToInt(ffb), FixedToInt(ffa) );    \
  1459.          zRow[i] = z;                        \
  1460.       }                                \
  1461.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
  1462.       ffz += fdzdx;                        \
  1463.    }                                \
  1464. }
  1465. #ifdef WIN32
  1466. #include "..\tritemp.h"
  1467. #else
  1468. #include "tritemp.h"
  1469. #endif
  1470. }
  1471.  
  1472.  
  1473.  
  1474.  
  1475. /*
  1476.  * Flat-shaded, z-less triangle, RGBA color.
  1477.  */
  1478. static void flat_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1479.                                    GLuint v2, GLuint pv )
  1480. {
  1481.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1482. #define INTERP_Z 1
  1483. #define SETUP_CODE            \
  1484.    GLubyte r = VB->Color[pv][0];    \
  1485.    GLubyte g = VB->Color[pv][1];    \
  1486.    GLubyte b = VB->Color[pv][2];    \
  1487.    GLubyte a = VB->Color[pv][3];    \
  1488.    GLuint pixel = PACK_RGBA(r,g,b,a);
  1489.  
  1490. #define INNER_LOOP( LEFT, RIGHT, Y )    \
  1491. {                    \
  1492.    GLint i, len = RIGHT-LEFT;        \
  1493.    GLuint *img = PIXELADDR4(LEFT,Y);       \
  1494.    for (i=0;i<len;i++,img++) {        \
  1495.       GLdepth z = FixedToDepth(ffz);    \
  1496.       if (z < zRow[i]) {        \
  1497.          *img = pixel;            \
  1498.          zRow[i] = z;            \
  1499.       }                    \
  1500.       ffz += fdzdx;            \
  1501.    }                    \
  1502. }
  1503. #ifdef WIN32
  1504. #include "..\tritemp.h"
  1505. #else
  1506. #include "tritemp.h"
  1507. #endif
  1508. }
  1509.  
  1510.  
  1511.  
  1512. /*
  1513.  * Return pointer to an accelerated triangle function if possible.
  1514.  */
  1515. static triangle_func choose_triangle_function( GLcontext *ctx )
  1516. {
  1517.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1518.  
  1519.    if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) return NULL;
  1520.    
  1521.    if (ctx->Polygon.SmoothFlag)     return NULL;
  1522.    if (ctx->Polygon.StippleFlag)    return NULL;
  1523.    if (ctx->Texture.Enabled)        return NULL;
  1524.  
  1525.    if (ctx->RasterMask==DEPTH_BIT
  1526.        && ctx->Depth.Func==GL_LESS
  1527.        && ctx->Depth.Mask==GL_TRUE
  1528.        && osmesa->format!=OSMESA_COLOR_INDEX) {
  1529.       if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1530.          return smooth_rgba_z_triangle;
  1531.       }
  1532.       else {
  1533.          return flat_rgba_z_triangle;
  1534.       }
  1535.    }
  1536.    return NULL;
  1537. }
  1538.  
  1539.  
  1540.  
  1541. static const char *renderer_string(void)
  1542. {
  1543.    return "OffScreen";
  1544. }
  1545.  
  1546.  
  1547. static void osmesa_update_state( GLcontext *ctx )
  1548. {
  1549.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1550.    
  1551.    ctx->Driver.RendererString = renderer_string;
  1552.    ctx->Driver.UpdateState = osmesa_update_state;
  1553.  
  1554.    ctx->Driver.SetBuffer = set_buffer;
  1555.    ctx->Driver.Color = set_color;
  1556.    ctx->Driver.Index = set_index;
  1557.    ctx->Driver.ClearIndex = clear_index;
  1558.    ctx->Driver.ClearColor = clear_color;
  1559.    ctx->Driver.Clear = clear;
  1560.  
  1561.    ctx->Driver.GetBufferSize = buffer_size;
  1562.  
  1563.    ctx->Driver.PointsFunc = NULL;
  1564.    ctx->Driver.LineFunc = choose_line_function( ctx );
  1565.    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1566.  
  1567.    /* RGB(A) span/pixel functions */
  1568.    if ((osmesa->format==OSMESA_RGB) || (osmesa->format==OSMESA_BGR)) {
  1569.       /* 3 bytes / pixel in frame buffer */
  1570.       ctx->Driver.WriteRGBASpan = write_rgba_span3;
  1571.       ctx->Driver.WriteRGBSpan = write_rgb_span3;
  1572.       ctx->Driver.WriteRGBAPixels = write_rgba_pixels3;
  1573.       ctx->Driver.WriteMonoRGBASpan = write_monocolor_span3;
  1574.       ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels3;
  1575.       ctx->Driver.ReadRGBASpan = read_rgba_span3;
  1576.       ctx->Driver.ReadRGBAPixels = read_rgba_pixels3;
  1577.    }
  1578.    else {
  1579.       /* 4 bytes / pixel in frame buffer */
  1580.       if (osmesa->format==OSMESA_RGBA
  1581.           && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
  1582.          ctx->Driver.WriteRGBASpan = write_rgba_span_rgba;
  1583.       else
  1584.          ctx->Driver.WriteRGBASpan = write_rgba_span;
  1585.       ctx->Driver.WriteRGBSpan = write_rgb_span;
  1586.       ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
  1587.       ctx->Driver.WriteMonoRGBASpan = write_monocolor_span;
  1588.       ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels;
  1589.       if (osmesa->format==OSMESA_RGBA
  1590.           && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
  1591.          ctx->Driver.ReadRGBASpan = read_rgba_span_rgba;
  1592.       else
  1593.          ctx->Driver.ReadRGBASpan = read_rgba_span;
  1594.       ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
  1595.    }
  1596.  
  1597.    /* CI span/pixel functions */
  1598.    ctx->Driver.WriteCI32Span = write_index32_span;
  1599.    ctx->Driver.WriteCI8Span = write_index8_span;
  1600.    ctx->Driver.WriteMonoCISpan = write_monoindex_span;
  1601.    ctx->Driver.WriteCI32Pixels = write_index_pixels;
  1602.    ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels;
  1603.    ctx->Driver.ReadCI32Span = read_index_span;
  1604.    ctx->Driver.ReadCI32Pixels = read_index_pixels;
  1605. }
  1606.