Ignore:
Timestamp:
May 23, 2000, 10:41:28 PM (25 years ago)
Author:
jeroen
Message:

* empty log message *

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/opengl/mesa/drawpix.c

    r2962 r3598  
    1 /* $Id: drawpix.c,v 1.2 2000-03-01 18:49:27 jeroen Exp $ */
     1/* $Id: drawpix.c,v 1.3 2000-05-23 20:40:31 jeroen Exp $ */
    22
    33/*
    44 * Mesa 3-D graphics library
    5  * Version:  3.1
     5 * Version:  3.3
    66 *
    77 * Copyright (C) 1999  Brian Paul   All Rights Reserved.
     
    2626
    2727
    28 
    29 
    30 
    3128#ifdef PC_HEADER
    3229#include "all.h"
    3330#else
    34 #ifndef XFree86Server
    35 #include <assert.h>
    36 #include <stdlib.h>
    37 #include <string.h>
    38 #else
    39 #include "GL/xf86glx.h"
    40 #endif
     31#include "glheader.h"
    4132#include "types.h"
    4233#include "context.h"
    4334#include "drawpix.h"
     35#include "mem.h"
    4436#include "feedback.h"
    4537#include "image.h"
     
    5042#include "stencil.h"
    5143#include "zoom.h"
     44#include "state.h"
    5245#endif
    5346
    5447
    55 
    56 /* TODO:  apply texture mapping to fragments */
    57 
    58 
    5948/*
    60  * Try to do a fast glDrawPixels.  Conditions include:
    61  *   not using a display list
    62  *   simple pixel unpacking
    63  *   no raster ops
    64  *   etc....
     49 * Given the dest position, size and skipPixels and skipRows values
     50 * for a glDrawPixels command, perform clipping of the image bounds
     51 * so the result lies withing the context's buffer bounds.
     52 * Return:  GL_TRUE if image is ready for drawing
     53 *          GL_FALSE if image was completely clipped away (draw nothing)
     54 */
     55GLboolean
     56_mesa_clip_pixelrect(const GLcontext *ctx,
     57                     GLint *destX, GLint *destY,
     58                     GLsizei *width, GLsizei *height,
     59                     GLint *skipPixels, GLint *skipRows)
     60{
     61   const GLframebuffer *buffer = ctx->DrawBuffer;
     62
     63   /* left clipping */
     64   if (*destX < buffer->Xmin) {
     65      *skipPixels += (buffer->Xmin - *destX);
     66      *width -= (buffer->Xmin - *destX);
     67      *destX = buffer->Xmin;
     68   }
     69   /* right clipping */
     70   if (*destX + *width > buffer->Xmax)
     71      *width -= (*destX + *width - buffer->Xmax - 1);
     72
     73   if (*width <= 0)
     74      return GL_FALSE;
     75
     76   /* bottom clipping */
     77   if (*destY < buffer->Ymin) {
     78      *skipRows += (buffer->Ymin - *destY);
     79      *height -= (buffer->Ymin - *destY);
     80      *destY = buffer->Ymin;
     81   }
     82   /* top clipping */
     83   if (*destY + *height > buffer->Ymax)
     84      *height -= (*destY + *height - buffer->Ymax - 1);
     85
     86   if (*height <= 0)
     87      return GL_TRUE;
     88
     89   return GL_TRUE;
     90}
     91
     92
     93
     94/*
     95 * Try to do a fast and simple RGB(a) glDrawPixels.
    6596 * Return:  GL_TRUE if success, GL_FALSE if slow path must be used instead
    6697 */
    67 GLboolean gl_direct_DrawPixels( GLcontext *ctx,
    68                                 const struct gl_pixelstore_attrib *unpack,
    69                                 GLsizei width, GLsizei height,
    70                                 GLenum format, GLenum type,
    71                                 const GLvoid *pixels )
     98static GLboolean
     99simple_DrawPixels( GLcontext *ctx, GLint x, GLint y,
     100                   GLsizei width, GLsizei height, GLenum format, GLenum type,
     101                   const GLvoid *pixels )
    72102{
     103   const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
    73104   GLubyte rgb[MAX_WIDTH][3];
    74105   GLubyte rgba[MAX_WIDTH][4];
    75106
    76107   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels",
    77                                                   GL_FALSE);
     108                                                  GL_FALSE);
    78109
    79110
     
    85116   if (ctx->NewState) {
    86117      gl_update_state(ctx);
    87    }
    88 
    89    /* see if device driver can do the drawpix */
    90    if (ctx->Driver.DrawPixels) {
    91       GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
    92       GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
    93       if ((*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
    94                                     unpack, pixels))
    95          return GL_TRUE;
    96118   }
    97119
     
    107129       && !unpack->LsbFirst) {
    108130
    109       GLint destX = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
    110       GLint destY = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
     131      GLint destX = x;
     132      GLint destY = y;
    111133      GLint drawWidth = width;           /* actual width drawn */
    112134      GLint drawHeight = height;         /* actual height drawn */
     
    128150      if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
    129151         /* horizontal clipping */
    130          if (destX < ctx->Buffer->Xmin) {
    131             skipPixels += (ctx->Buffer->Xmin - destX);
    132             drawWidth  -= (ctx->Buffer->Xmin - destX);
    133             destX = ctx->Buffer->Xmin;
    134          }
    135          if (destX + drawWidth > ctx->Buffer->Xmax)
    136             drawWidth -= (destX + drawWidth - ctx->Buffer->Xmax - 1);
     152         if (destX < ctx->DrawBuffer->Xmin) {
     153            skipPixels += (ctx->DrawBuffer->Xmin - destX);
     154            drawWidth  -= (ctx->DrawBuffer->Xmin - destX);
     155            destX = ctx->DrawBuffer->Xmin;
     156         }
     157         if (destX + drawWidth > ctx->DrawBuffer->Xmax)
     158            drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax - 1);
    137159         if (drawWidth <= 0)
    138160            return GL_TRUE;
    139161
    140162         /* vertical clipping */
    141          if (destY < ctx->Buffer->Ymin) {
    142             skipRows   += (ctx->Buffer->Ymin - destY);
    143             drawHeight -= (ctx->Buffer->Ymin - destY);
    144             destY = ctx->Buffer->Ymin;
    145          }
    146          if (destY + drawHeight > ctx->Buffer->Ymax)
    147             drawHeight -= (destY + drawHeight - ctx->Buffer->Ymax - 1);
     163         if (destY < ctx->DrawBuffer->Ymin) {
     164            skipRows   += (ctx->DrawBuffer->Ymin - destY);
     165            drawHeight -= (ctx->DrawBuffer->Ymin - destY);
     166            destY = ctx->DrawBuffer->Ymin;
     167         }
     168         if (destY + drawHeight > ctx->DrawBuffer->Ymax)
     169            drawHeight -= (destY + drawHeight - ctx->DrawBuffer->Ymax - 1);
    148170         if (drawHeight <= 0)
    149171            return GL_TRUE;
     172
     173         zoomY0 = 0;  /* not used - silence compiler warning */
    150174      }
    151175      else {
    152176         /* setup array of fragment Z value to pass to zoom function */
    153          GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
     177         GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF);
    154178         GLint i;
    155          assert(drawWidth < MAX_WIDTH);
     179         ASSERT(drawWidth < MAX_WIDTH);
    156180         for (i=0; i<drawWidth; i++)
    157181            zSpan[i] = z;
     
    179203               for (row=0; row<drawHeight; row++) {
    180204                  (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
    181                                                (const GLubyte (*)[4])src,
    182                                                NULL);
     205                                               (const GLubyte(*)[4]) src, NULL);
    183206                  src += rowLength * 4;
    184207                  destY++;
     
    190213               for (row=0; row<drawHeight; row++) {
    191214                  gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
    192                                             zSpan,
    193                                             (const GLubyte (*)[4]) src,
    194                                             zoomY0);
     215                                            zSpan, (const GLubyte(*)[4]) src, zoomY0);
    195216                  src += rowLength * 4;
    196217                  destY++;
     
    208229               for (row=0; row<drawHeight; row++) {
    209230                  (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
    210                                               (const GLubyte (*)[3]) src,
    211                                               NULL);
     231                                              (const GLubyte(*)[3]) src, NULL);
    212232                  src += rowLength * 3;
    213233                  destY++;
     
    219239               for (row=0; row<drawHeight; row++) {
    220240                  gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
    221                                            zSpan,
    222                                            (const GLubyte (*)[3]) src,
    223                                            zoomY0);
     241                                           zSpan, (const GLubyte(*)[3]) src, zoomY0);
    224242                  src += rowLength * 3;
    225243                  destY++;
     
    236254               /* no zooming */
    237255               GLint row;
    238                assert(drawWidth < MAX_WIDTH);
     256               ASSERT(drawWidth < MAX_WIDTH);
    239257               for (row=0; row<drawHeight; row++) {
    240258                  GLint i;
     
    245263                  }
    246264                  (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
    247                                               (const GLubyte (*)[3]) rgb,
    248                                               NULL);
     265                                              (const GLubyte(*)[3]) rgb, NULL);
    249266                  src += rowLength;
    250267                  destY++;
     
    254271               /* with zooming */
    255272               GLint row;
    256                assert(drawWidth < MAX_WIDTH);
     273               ASSERT(drawWidth < MAX_WIDTH);
    257274               for (row=0; row<drawHeight; row++) {
    258275                  GLint i;
     
    263280                  }
    264281                  gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
    265                                            zSpan,
    266                                            (const GLubyte (*)[3]) rgb,
    267                                            zoomY0);
     282                                           zSpan, (const GLubyte(*)[3]) rgb, zoomY0);
    268283                  src += rowLength;
    269284                  destY++;
     
    280295               /* no zooming */
    281296               GLint row;
    282                assert(drawWidth < MAX_WIDTH);
     297               ASSERT(drawWidth < MAX_WIDTH);
    283298               for (row=0; row<drawHeight; row++) {
    284299                  GLint i;
     
    291306                  }
    292307                  (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
    293                                                (const GLubyte (*)[4]) rgba,
    294                                                NULL);
     308                                               (const GLubyte (*)[4]) rgba, NULL);
    295309                  src += rowLength*2;
    296310                  destY++;
     
    300314               /* with zooming */
    301315               GLint row;
    302                assert(drawWidth < MAX_WIDTH);
     316               ASSERT(drawWidth < MAX_WIDTH);
    303317               for (row=0; row<drawHeight; row++) {
    304318                  GLubyte *ptr = src;
     
    311325                  }
    312326                  gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
    313                                             zSpan,
    314                                             (const GLubyte (*)[4]) rgba,
    315                                             zoomY0);
     327                                            zSpan, (const GLubyte (*)[4]) rgba, zoomY0);
    316328                  src += rowLength*2;
    317329                  destY++;
     
    329341               GLint row;
    330342               for (row=0; row<drawHeight; row++) {
    331                   assert(drawWidth < MAX_WIDTH);
     343                  ASSERT(drawWidth < MAX_WIDTH);
    332344                  gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
    333345                  (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
     
    343355               GLint row;
    344356               for (row=0; row<drawHeight; row++) {
    345                   assert(drawWidth < MAX_WIDTH);
     357                  ASSERT(drawWidth < MAX_WIDTH);
    346358                  gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
    347359                  gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
    348                                             zSpan,
    349                                             (const GLubyte (*)[4]) rgba,
    350                                             zoomY0);
     360                                            zSpan, (const GLubyte(*)[4]) rgba, zoomY0);
    351361                  src += rowLength;
    352362                  destY++;
     
    379389      }
    380390   }
    381    else {
    382       /* can't do direct render, have to use slow path */
    383       return GL_FALSE;
    384    }
     391
     392   /* can't do a simple draw, have to use slow path */
     393   return GL_FALSE;
    385394}
    386395
     
    390399 * Do glDrawPixels of index pixels.
    391400 */
    392 static void draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
    393                                const struct gl_image *image )
     401static void
     402draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
     403                   GLsizei width, GLsizei height,
     404                   GLenum type, const GLvoid *pixels )
    394405{
    395    GLint width, height, widthInBytes;
     406   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    396407   const GLint desty = y;
    397    GLint i, j;
     408   GLint row, drawWidth;
    398409   GLdepth zspan[MAX_WIDTH];
    399    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    400 
    401    assert(image);
    402    assert(image->Format == GL_COLOR_INDEX);
    403 
    404    width = image->Width;
    405    height = image->Height;
    406    if (image->Type == GL_BITMAP)
    407       widthInBytes = (width + 7) / 8;
    408    else
    409       widthInBytes = width;
     410
     411   drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
    410412
    411413   /* Fragment depth values */
    412414   if (ctx->Depth.Test || ctx->Fog.Enabled) {
    413       GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
    414       for (i=0;i<width;i++) {
    415          zspan[i] = zval;
    416       }
    417    }
    418 
    419    /* process the image row by row */
    420    for (i=0;i<height;i++,y++) {
    421       GLuint ispan[MAX_WIDTH];
    422 
    423       /* convert to uints */
    424       switch (image->Type) {
    425          case GL_UNSIGNED_BYTE:
    426             {
    427                GLubyte *src = (GLubyte *) image->Data + i * width;
    428                for (j=0;j<width;j++) {
    429                   ispan[j] = (GLuint) *src++;
    430                }
    431             }
    432             break;
    433          case GL_FLOAT:
    434             {
    435                GLfloat *src = (GLfloat *) image->Data + i * width;
    436                for (j=0;j<width;j++) {
    437                   ispan[j] = (GLuint) (GLint) *src++;
    438                }
    439             }
    440             break;
    441          case GL_BITMAP:
    442             {
    443                GLubyte *src = (GLubyte *) image->Data + i * widthInBytes;
    444                for (j=0;j<width;j++) {
    445                   ispan[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
    446                }
    447             }
    448             break;
    449          default:
    450             gl_problem( ctx, "draw_index_pixels type" );
    451             return;
    452       }
    453 
    454       /* apply shift and offset */
    455       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
    456          gl_shift_and_offset_ci( ctx, width, ispan );
    457       }
    458 
    459       if (ctx->Visual->RGBAflag) {
    460          /* Convert index to RGBA and write to frame buffer */
    461          GLubyte rgba[MAX_WIDTH][4];
    462          gl_map_ci_to_rgba( ctx, width, ispan, rgba );
    463          if (zoom) {
    464             gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
    465                                        (const GLubyte (*)[4])rgba, desty );
    466          }
    467          else {
    468             gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
    469          }
     415      GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF);
     416      GLint i;
     417      for (i = 0; i < drawWidth; i++) {
     418         zspan[i] = zval;
     419      }
     420   }
     421
     422   /*
     423    * General solution
     424    */
     425   for (row = 0; row < height; row++, y++) {
     426      GLuint indexes[MAX_WIDTH];
     427      const GLvoid *source = _mesa_image_address(&ctx->Unpack,
     428                    pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
     429      _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes,
     430                              type, source, &ctx->Unpack, GL_TRUE);
     431      if (zoom) {
     432         gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty);
    470433      }
    471434      else {
    472          /* optionally apply index map then write to frame buffer */
    473          if (ctx->Pixel.MapColorFlag) {
    474             gl_map_ci(ctx, width, ispan);
    475          }
    476          if (zoom) {
    477             gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty );
    478          }
    479          else {
    480             gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
    481          }
    482       }
    483    }
    484 
     435         gl_write_index_span(ctx, drawWidth, x, y, zspan, indexes, GL_BITMAP);
     436      }
     437   }
    485438}
    486439
     
    491444 * be GLubyte or GLbitmap.
    492445 */
    493 static void draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
    494                                  const struct gl_image *image )
     446static void
     447draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
     448                     GLsizei width, GLsizei height,
     449                     GLenum type, const GLvoid *pixels )
    495450{
    496    GLint widthInBytes, width, height;
     451   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    497452   const GLint desty = y;
    498    GLint i;
    499    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    500 
    501    if (image->Type != GL_BYTE &&
    502        image->Type != GL_UNSIGNED_BYTE &&
    503        image->Type != GL_SHORT &&
    504        image->Type != GL_UNSIGNED_SHORT &&
    505        image->Type != GL_INT &&
    506        image->Type != GL_UNSIGNED_INT &&
    507        image->Type != GL_FLOAT &&
    508        image->Type != GL_BITMAP) {
    509       gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels(stencil type)");
     453   GLint row, drawWidth;
     454
     455   if (type != GL_BYTE &&
     456       type != GL_UNSIGNED_BYTE &&
     457       type != GL_SHORT &&
     458       type != GL_UNSIGNED_SHORT &&
     459       type != GL_INT &&
     460       type != GL_UNSIGNED_INT &&
     461       type != GL_FLOAT &&
     462       type != GL_BITMAP) {
     463      gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)");
    510464      return;
    511465   }
    512466
    513    assert(image);
    514    assert(image->Format == GL_STENCIL_INDEX);
    515    assert(image->Type == GL_UNSIGNED_BYTE || image->Type == GL_BITMAP);
    516 
    517    if (image->Type == GL_UNSIGNED_BYTE)
    518       widthInBytes = image->Width;
    519    else
    520       widthInBytes = (image->Width + 7) / 8;
    521    width = image->Width;
    522    height = image->Height;
    523 
    524    /* process the image row by row */
    525    for (i=0;i<height;i++,y++) {
    526       GLstencil *src = (GLstencil*)image->Data + i * widthInBytes;
    527       GLstencil *stencilValues;
    528       GLstencil stencilCopy[MAX_WIDTH];
    529 
    530       if (image->Type == GL_BITMAP) {
    531          /* convert bitmap data to GLubyte (0 or 1) data */
    532          GLint j;
    533          for (j = 0; j < width; j++) {
    534             stencilCopy[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
    535          }
    536          src = stencilCopy;
    537       }
    538 
    539       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift
    540           || ctx->Pixel.MapStencilFlag) {
    541 
    542          /* make copy of stencil values */
    543          if (src != stencilCopy)
    544             MEMCPY( stencilCopy, src, width * sizeof(GLstencil));
    545 
    546          /* apply shift and offset */
    547          if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
    548             gl_shift_and_offset_stencil( ctx, width, stencilCopy );
    549          }
    550 
    551          /* mapping */
    552          if (ctx->Pixel.MapStencilFlag) {
    553             gl_map_stencil( ctx, width, stencilCopy );
    554          }
    555 
    556          stencilValues = stencilCopy;
     467   drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
     468
     469   for (row = 0; row < height; row++, y++) {
     470      GLstencil values[MAX_WIDTH];
     471      GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
     472                      ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
     473      const GLvoid *source = _mesa_image_address(&ctx->Unpack,
     474                    pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
     475      _mesa_unpack_index_span(ctx, drawWidth, destType, values,
     476                              type, source, &ctx->Unpack, GL_TRUE);
     477
     478      if (zoom) {
     479         gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y,
     480                                       values, desty );
    557481      }
    558482      else {
    559          /* use stencil values in-place */
    560          stencilValues = src;
    561       }
    562 
    563       /* write stencil values to stencil buffer */
    564       if (zoom) {
    565          gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y,
    566                                        stencilValues, desty );
    567       }
    568       else {
    569          gl_write_stencil_span( ctx, (GLuint) width, x, y, stencilValues );
     483         gl_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values );
    570484      }
    571485   }
     
    577491 * Do a glDrawPixels of depth values.
    578492 */
    579 static void draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
    580                                const struct gl_image *image )
     493static void
     494draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
     495                   GLsizei width, GLsizei height,
     496                   GLenum type, const GLvoid *pixels )
    581497{
    582    GLint width, height;
     498   const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
     499   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    583500   const GLint desty = y;
    584501   GLubyte rgba[MAX_WIDTH][4];
    585502   GLuint ispan[MAX_WIDTH];
    586    const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
    587    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    588 
    589    assert(image);
    590    assert(image->Format == GL_DEPTH_COMPONENT);
    591 
    592    width = image->Width;
    593    height = image->Height;
    594 
    595    /* Color or index */
     503   GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
     504
     505   if (type != GL_UNSIGNED_BYTE
     506       && type != GL_UNSIGNED_BYTE
     507       && type != GL_UNSIGNED_SHORT
     508       && type != GL_UNSIGNED_SHORT
     509       && type != GL_UNSIGNED_INT
     510       && type != GL_UNSIGNED_INT
     511       && type != GL_FLOAT) {
     512      gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)");
     513      return;
     514   }
     515
     516   /* Colors or indexes */
    596517   if (ctx->Visual->RGBAflag) {
    597518      GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
     
    600521      GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
    601522      GLint i;
    602       for (i=0; i<width; i++) {
     523      for (i = 0; i < drawWidth; i++) {
    603524         rgba[i][RCOMP] = r;
    604525         rgba[i][GCOMP] = g;
     
    609530   else {
    610531      GLint i;
    611       for (i=0;i<width;i++) {
    612         ispan[i] = ctx->Current.RasterIndex;
    613       }
    614    }
    615 
    616    if (image->Type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
     532      for (i = 0; i < drawWidth; i++) {
     533        ispan[i] = ctx->Current.RasterIndex;
     534      }
     535   }
     536
     537   if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
    617538       && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
    618539      /* Special case: directly write 16-bit depth values */
    619       GLint j;
    620       for (j=0;j<height;j++,y++) {
    621          GLdepth *zptr = (GLdepth *) image->Data + j * width;
    622          gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP );
    623       }
    624    }
    625    else if (image->Type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
     540      GLint row;
     541      for (row = 0; row < height; row++, y++) {
     542         GLdepth zspan[MAX_WIDTH];
     543         const GLushort *zptr = (const GLushort *)_mesa_image_address(&ctx->Unpack,
     544                pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
     545         GLint i;
     546         for (i = 0; i < width; i++)
     547            zspan[i] = zptr[i];
     548         gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
     549      }
     550   }
     551   else if (type==GL_UNSIGNED_INT && ctx->Visual->DepthBits == 32
    626552       && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
    627553      /* Special case: directly write 32-bit depth values */
    628       GLint i, j;
    629       /* Compute shift value to scale 32-bit uints down to depth values. */
    630       GLuint shift = 0;
    631       GLuint max = MAX_DEPTH;
    632       while ((max&0x80000000)==0) {
    633          max = max << 1;
    634          shift++;
    635       }
    636       for (j=0;j<height;j++,y++) {
     554      GLint row;
     555      for (row = 0; row < height; row++, y++) {
     556         const GLuint *zptr = (GLuint *)_mesa_image_address(&ctx->Unpack,
     557                pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
     558         gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP );
     559      }
     560   }
     561   else {
     562      /* General case */
     563      GLint row;
     564      for (row = 0; row < height; row++, y++) {
    637565         GLdepth zspan[MAX_WIDTH];
    638          GLuint *zptr = (GLuint *) image->Data + j * width;
    639          for (i=0;i<width;i++) {
    640             zspan[i] = zptr[i] >> shift;
    641          }
    642          gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
    643       }
    644    }
    645    else {
    646       /* General case (slower) */
    647       GLint i, j;
    648 
    649       /* process image row by row */
    650       for (i=0;i<height;i++,y++) {
    651          GLfloat depth[MAX_WIDTH];
    652          GLdepth zspan[MAX_WIDTH];
    653 
    654          switch (image->Type) {
    655             case GL_UNSIGNED_SHORT:
    656                {
    657                   GLushort *src = (GLushort *) image->Data + i * width;
    658                   for (j=0;j<width;j++) {
    659                      depth[j] = USHORT_TO_FLOAT( *src++ );
    660                   }
    661                }
    662                break;
    663             case GL_UNSIGNED_INT:
    664                {
    665                   GLuint *src = (GLuint *) image->Data + i * width;
    666                   for (j=0;j<width;j++) {
    667                      depth[j] = UINT_TO_FLOAT( *src++ );
    668                   }
    669                }
    670                break;
    671             case GL_FLOAT:
    672                {
    673                   GLfloat *src = (GLfloat *) image->Data + i * width;
    674                   for (j=0;j<width;j++) {
    675                      depth[j] = *src++;
    676                   }
    677                }
    678                break;
    679             default:
    680                gl_problem(ctx, "Bad type in draw_depth_pixels");
    681                return;
    682          }
    683 
    684          /* apply depth scale and bias */
    685          if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) {
    686             for (j=0;j<width;j++) {
    687                depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
    688             }
    689          }
    690 
    691          /* clamp depth values to [0,1] and convert from floats to integers */
    692          for (j=0;j<width;j++) {
    693             zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
    694          }
    695 
     566         const GLvoid *src = _mesa_image_address(&ctx->Unpack,
     567                pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
     568         _mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src,
     569                                  &ctx->Unpack, GL_TRUE );
    696570         if (ctx->Visual->RGBAflag) {
    697571            if (zoom) {
    698                gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
    699                                           (const GLubyte (*)[4])rgba, desty );
     572               gl_write_zoomed_rgba_span(ctx, width, x, y, zspan,
     573                                         (const GLubyte (*)[4])rgba, desty);
    700574            }
    701575            else {
    702                gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
     576               gl_write_rgba_span(ctx, width, x, y, zspan, rgba, GL_BITMAP);
    703577            }
    704578         }
    705579         else {
    706580            if (zoom) {
    707                gl_write_zoomed_index_span( ctx, width, x, y, zspan,
    708                                            ispan, GL_BITMAP );
     581               gl_write_zoomed_index_span(ctx, width, x, y, zspan,
     582                                          ispan, GL_BITMAP);
    709583            }
    710584            else {
    711                gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
     585               gl_write_index_span(ctx, width, x, y, zspan, ispan, GL_BITMAP);
    712586            }
    713587         }
     
    716590   }
    717591}
    718 
    719 
    720 
    721 /* Simple unpacking parameters: */
    722 static struct gl_pixelstore_attrib NoUnpack = {
    723    1,            /* Alignment */
    724    0,            /* RowLength */
    725    0,            /* SkipPixels */
    726    0,            /* SkipRows */
    727    0,            /* ImageHeight */
    728    0,            /* SkipImages */
    729    GL_FALSE,     /* SwapBytes */
    730    GL_FALSE      /* LsbFirst */
    731 };
    732592
    733593
     
    735595 * Do glDrawPixels of RGBA pixels.
    736596 */
    737 static void draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
    738                               const struct gl_image *image )
     597static void
     598draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
     599                  GLsizei width, GLsizei height,
     600                  GLenum format, GLenum type, const GLvoid *pixels )
    739601{
    740    GLint width, height;
    741    GLint i, j;
     602   const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
     603   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    742604   const GLint desty = y;
    743605   GLdepth zspan[MAX_WIDTH];
    744606   GLboolean quickDraw;
    745    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    746 
    747    assert(image);
    748607
    749608   /* Try an optimized glDrawPixels first */
    750    if (gl_direct_DrawPixels(ctx, &NoUnpack, image->Width, image->Height,
    751                             image->Format, image->Type, image->Data ))
     609   if (simple_DrawPixels(ctx, x, y, width, height, format, type, pixels))
    752610      return;
    753 
    754    width = image->Width;
    755    height = image->Height;
    756611
    757612   /* Fragment depth values */
    758613   if (ctx->Depth.Test || ctx->Fog.Enabled) {
    759614      /* fill in array of z values */
    760       GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
     615      GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF);
     616      GLint i;
    761617      for (i=0;i<width;i++) {
    762          zspan[i] = z;
    763       }
    764    }
    765 
    766    if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
    767        && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
     618         zspan[i] = z;
     619      }
     620   }
     621
     622
     623   if (ctx->RasterMask == 0 && !zoom
     624       && x >= 0 && y >= 0
     625       && x + width <= ctx->DrawBuffer->Width
     626       && y + height <= ctx->DrawBuffer->Height) {
    768627      quickDraw = GL_TRUE;
    769628   }
     
    772631   }
    773632
     633   /*
     634    * General solution
     635    */
    774636   {
    775       /* General solution */
    776       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
    777       GLuint components;
    778637      GLubyte rgba[MAX_WIDTH][4];
    779       GLfloat  rf[MAX_WIDTH];
    780       GLfloat  gf[MAX_WIDTH];
    781       GLfloat  bf[MAX_WIDTH];
    782       DEFARRAY(GLfloat,af,MAX_WIDTH);
    783       CHECKARRAY(af,return);
    784 
    785       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
    786       switch (image->Format) {
    787          case GL_RED:
    788             r_flag = GL_TRUE;
    789             components = 1;
    790             break;
    791          case GL_GREEN:
    792             g_flag = GL_TRUE;
    793             components = 1;
    794             break;
    795          case GL_BLUE:
    796             b_flag = GL_TRUE;
    797             components = 1;
    798             break;
    799          case GL_ALPHA:
    800             a_flag = GL_TRUE;
    801             components = 1;
    802             break;
    803          case GL_RGB:
    804             r_flag = g_flag = b_flag = GL_TRUE;
    805             components = 3;
    806             break;
    807          case GL_LUMINANCE:
    808             l_flag = GL_TRUE;
    809             components = 1;
    810             break;
    811          case GL_LUMINANCE_ALPHA:
    812             l_flag = a_flag = GL_TRUE;
    813             components = 2;
    814             break;
    815          case GL_RGBA:
    816             r_flag = g_flag = b_flag = a_flag = GL_TRUE;
    817             components = 4;
    818             break;
    819          default:
    820             gl_problem(ctx, "Bad type in draw_rgba_pixels");
    821             goto cleanup;
    822       }
    823 
    824       /* process the image row by row */
    825       for (i=0;i<height;i++,y++) {
    826          /* convert to floats */
    827          switch (image->Type) {
    828             case GL_UNSIGNED_BYTE:
    829                {
    830                   GLubyte *src = (GLubyte *) image->Data + i * width * components;
    831                   for (j=0;j<width;j++) {
    832                      if (l_flag) {
    833                         rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
    834                      }
    835                      else {
    836                         rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
    837                         gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
    838                         bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
    839                      }
    840                      af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
    841                   }
    842                }
    843                break;
    844             case GL_FLOAT:
    845                {
    846                   GLfloat *src = (GLfloat *) image->Data + i * width * components;
    847                   for (j=0;j<width;j++) {
    848                      if (l_flag) {
    849                         rf[j] = gf[j] = bf[j] = *src++;
    850                      }
    851                      else {
    852                         rf[j] = r_flag ? *src++ : 0.0;
    853                         gf[j] = g_flag ? *src++ : 0.0;
    854                         bf[j] = b_flag ? *src++ : 0.0;
    855                      }
    856                      af[j] = a_flag ? *src++ : 1.0;
    857                   }
    858                }
    859                break;
    860             default:
    861                gl_problem( ctx, "draw_rgba_pixels type" );
    862                goto cleanup;
    863          }
    864 
    865          /* apply scale and bias */
    866          if (ctx->Pixel.ScaleOrBiasRGBA) {
    867             gl_scale_and_bias_color(ctx, width, rf, gf, bf, af);
    868          }
    869 
    870          /* apply pixel mappings */
    871          if (ctx->Pixel.MapColorFlag) {
    872             gl_map_color(ctx, width, rf, gf, bf, af);
    873          }
    874 
    875          /* convert to integers */
    876          for (j=0;j<width;j++) {
    877             rgba[j][RCOMP] = (GLint) (rf[j] * 255.0F);
    878             rgba[j][GCOMP] = (GLint) (gf[j] * 255.0F);
    879             rgba[j][BCOMP] = (GLint) (bf[j] * 255.0F);
    880             rgba[j][ACOMP] = (GLint) (af[j] * 255.0F);
    881          }
    882 
    883          /* write to frame buffer */
     638      GLint row;
     639      if (width > MAX_WIDTH)
     640         width = MAX_WIDTH;
     641      for (row = 0; row < height; row++, y++) {
     642         const GLvoid *source = _mesa_image_address(unpack,
     643                  pixels, width, height, format, type, 0, row, 0);
     644         _mesa_unpack_ubyte_color_span(ctx, width, GL_RGBA, (GLubyte *) rgba,
     645                   format, type, source, unpack, GL_TRUE);
     646
    884647         if (quickDraw) {
    885648            (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y,
    886                                           (const GLubyte (*)[4])rgba, NULL);
     649                                          (CONST GLubyte (*)[4]) rgba, NULL);
    887650         }
    888651         else if (zoom) {
    889652            gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
    890                                        (const GLubyte (*)[4])rgba, desty );
     653                                       (CONST GLubyte (*)[4]) rgba, desty );
    891654         }
    892655         else {
     
    894657         }
    895658      }
    896 cleanup:
    897       UNDEFARRAY(af);
    898659   }
    899660}
     
    904665 * Execute glDrawPixels
    905666 */
    906 void gl_DrawPixels( GLcontext* ctx, struct gl_image *image )
     667void
     668_mesa_DrawPixels( GLsizei width, GLsizei height,
     669                  GLenum format, GLenum type, const GLvoid *pixels )
    907670{
     671   GET_CURRENT_CONTEXT(ctx);
    908672   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels");
    909 
    910 
    911    if (gl_image_error_test( ctx, image, "glDrawPixels" ))
    912       return;
    913673
    914674   if (ctx->RenderMode==GL_RENDER) {
    915675      GLint x, y;
    916       if (!ctx->Current.RasterPosValid) {
    917         return;
     676      if (!pixels || !ctx->Current.RasterPosValid) {
     677        return;
    918678      }
    919679
     
    921681      y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
    922682
    923       switch (image->Format) {
    924          case GL_COLOR_INDEX:
    925             draw_index_pixels( ctx, x, y, image );
    926             break;
    927          case GL_STENCIL_INDEX:
    928             draw_stencil_pixels( ctx, x, y, image );
    929             break;
    930          case GL_DEPTH_COMPONENT:
    931             draw_depth_pixels( ctx, x, y, image );
    932             break;
    933          case GL_RED:
    934          case GL_GREEN:
    935          case GL_BLUE:
    936          case GL_ALPHA:
    937          case GL_RGB:
    938          case GL_LUMINANCE:
    939          case GL_LUMINANCE_ALPHA:
    940          case GL_RGBA:
    941             draw_rgba_pixels( ctx, x, y, image );
    942             break;
    943          default:
    944             gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
     683      /* see if device driver can do the drawpix */
     684      if (ctx->Driver.DrawPixels
     685          && (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
     686                                       &ctx->Unpack, pixels)) {
     687         return;
     688      }
     689
     690      switch (format) {
     691         case GL_STENCIL_INDEX:
     692            draw_stencil_pixels( ctx, x, y, width, height, type, pixels );
     693            break;
     694         case GL_DEPTH_COMPONENT:
     695            draw_depth_pixels( ctx, x, y, width, height, type, pixels );
     696            break;
     697         case GL_COLOR_INDEX:
     698            if (ctx->Visual->RGBAflag)
     699               draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels);
     700            else
     701               draw_index_pixels(ctx, x, y, width, height, type, pixels);
     702            break;
     703         case GL_RED:
     704         case GL_GREEN:
     705         case GL_BLUE:
     706         case GL_ALPHA:
     707         case GL_LUMINANCE:
     708         case GL_LUMINANCE_ALPHA:
     709         case GL_RGB:
     710         case GL_BGR:
     711         case GL_RGBA:
     712         case GL_BGRA:
     713         case GL_ABGR_EXT:
     714            draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels);
     715            break;
     716         default:
     717            gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" );
    945718            return;
    946719      }
     
    949722      if (ctx->Current.RasterPosValid) {
    950723         GLfloat color[4];
    951         GLfloat texcoord[4], invq;
    952         UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor);
     724        GLfloat texcoord[4], invq;
     725        UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor);
    953726         invq = 1.0F / ctx->Current.Texcoord[0][3];
    954727         texcoord[0] = ctx->Current.Texcoord[0][0] * invq;
Note: See TracChangeset for help on using the changeset viewer.