ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

s_drawpix.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00026 #include "main/glheader.h"
00027 #include "main/bufferobj.h"
00028 #include "main/context.h"
00029 #include "main/convolve.h"
00030 #include "main/image.h"
00031 #include "main/macros.h"
00032 #include "main/imports.h"
00033 #include "main/pixel.h"
00034 #include "main/state.h"
00035 
00036 #include "s_context.h"
00037 #include "s_span.h"
00038 #include "s_stencil.h"
00039 #include "s_zoom.h"
00040 
00041 
00042 
00047 static GLboolean
00048 fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
00049                       GLsizei width, GLsizei height,
00050                       GLenum format, GLenum type,
00051                       const struct gl_pixelstore_attrib *userUnpack,
00052                       const GLvoid *pixels)
00053 {
00054    const GLint imgX = x, imgY = y;
00055    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
00056    GLenum rbType;
00057    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00058    SWspan span;
00059    GLboolean simpleZoom;
00060    GLint yStep;  /* +1 or -1 */
00061    struct gl_pixelstore_attrib unpack;
00062    GLint destX, destY, drawWidth, drawHeight; /* post clipping */
00063 
00064    if (!rb)
00065       return GL_TRUE; /* no-op */
00066 
00067    rbType = rb->DataType;
00068 
00069    if ((swrast->_RasterMask & ~CLIP_BIT) ||
00070        ctx->Texture._EnabledCoordUnits ||
00071        userUnpack->SwapBytes ||
00072        ctx->_ImageTransferState) {
00073       /* can't handle any of those conditions */
00074       return GL_FALSE;
00075    }
00076 
00077    INIT_SPAN(span, GL_BITMAP);
00078    span.arrayMask = SPAN_RGBA;
00079    span.arrayAttribs = FRAG_BIT_COL0;
00080    _swrast_span_default_attribs(ctx, &span);
00081 
00082    /* copy input params since clipping may change them */
00083    unpack = *userUnpack;
00084    destX = x;
00085    destY = y;
00086    drawWidth = width;
00087    drawHeight = height;
00088 
00089    /* check for simple zooming and clipping */
00090    if (ctx->Pixel.ZoomX == 1.0F &&
00091        (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)) {
00092       if (!_mesa_clip_drawpixels(ctx, &destX, &destY,
00093                                  &drawWidth, &drawHeight, &unpack)) {
00094          /* image was completely clipped: no-op, all done */
00095          return GL_TRUE;
00096       }
00097       simpleZoom = GL_TRUE;
00098       yStep = (GLint) ctx->Pixel.ZoomY;
00099       ASSERT(yStep == 1 || yStep == -1);
00100    }
00101    else {
00102       /* non-simple zooming */
00103       simpleZoom = GL_FALSE;
00104       yStep = 1;
00105       if (unpack.RowLength == 0)
00106          unpack.RowLength = width;
00107    }
00108 
00109    /*
00110     * Ready to draw!
00111     */
00112 
00113    if (format == GL_RGBA && type == rbType) {
00114       const GLubyte *src
00115          = (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width,
00116                                                    height, format, type, 0, 0);
00117       const GLint srcStride = _mesa_image_row_stride(&unpack, width,
00118                                                      format, type);
00119       if (simpleZoom) {
00120          GLint row;
00121          for (row = 0; row < drawHeight; row++) {
00122             rb->PutRow(ctx, rb, drawWidth, destX, destY, src, NULL);
00123             src += srcStride;
00124             destY += yStep;
00125          }
00126       }
00127       else {
00128          /* with zooming */
00129          GLint row;
00130          for (row = 0; row < drawHeight; row++) {
00131             span.x = destX;
00132             span.y = destY + row;
00133             span.end = drawWidth;
00134             span.array->ChanType = rbType;
00135             _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, src);
00136             src += srcStride;
00137          }
00138          span.array->ChanType = CHAN_TYPE;
00139       }
00140       return GL_TRUE;
00141    }
00142 
00143    if (format == GL_RGB && type == rbType) {
00144       const GLubyte *src
00145          = (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width,
00146                                                    height, format, type, 0, 0);
00147       const GLint srcStride = _mesa_image_row_stride(&unpack, width,
00148                                                      format, type);
00149       if (simpleZoom) {
00150          GLint row;
00151          for (row = 0; row < drawHeight; row++) {
00152             rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, src, NULL);
00153             src += srcStride;
00154             destY += yStep;
00155          }
00156       }
00157       else {
00158          /* with zooming */
00159          GLint row;
00160          for (row = 0; row < drawHeight; row++) {
00161             span.x = destX;
00162             span.y = destY;
00163             span.end = drawWidth;
00164             span.array->ChanType = rbType;
00165             _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, src);
00166             src += srcStride;
00167             destY++;
00168          }
00169          span.array->ChanType = CHAN_TYPE;
00170       }
00171       return GL_TRUE;
00172    }
00173 
00174    /* Remaining cases haven't been tested with alignment != 1 */
00175    if (userUnpack->Alignment != 1)
00176       return GL_FALSE;
00177 
00178    if (format == GL_LUMINANCE && type == CHAN_TYPE && rbType == CHAN_TYPE) {
00179       const GLchan *src = (const GLchan *) pixels
00180          + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels);
00181       if (simpleZoom) {
00182          /* no zooming */
00183          GLint row;
00184          ASSERT(drawWidth <= MAX_WIDTH);
00185          for (row = 0; row < drawHeight; row++) {
00186             GLchan rgb[MAX_WIDTH][3];
00187             GLint i;
00188             for (i = 0;i<drawWidth;i++) {
00189                rgb[i][0] = src[i];
00190                rgb[i][1] = src[i];
00191                rgb[i][2] = src[i];
00192             }
00193             rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, rgb, NULL);
00194             src += unpack.RowLength;
00195             destY += yStep;
00196          }
00197       }
00198       else {
00199          /* with zooming */
00200          GLint row;
00201          ASSERT(drawWidth <= MAX_WIDTH);
00202          for (row = 0; row < drawHeight; row++) {
00203             GLchan rgb[MAX_WIDTH][3];
00204             GLint i;
00205             for (i = 0;i<drawWidth;i++) {
00206                rgb[i][0] = src[i];
00207                rgb[i][1] = src[i];
00208                rgb[i][2] = src[i];
00209             }
00210             span.x = destX;
00211             span.y = destY;
00212             span.end = drawWidth;
00213             _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, rgb);
00214             src += unpack.RowLength;
00215             destY++;
00216          }
00217       }
00218       return GL_TRUE;
00219    }
00220 
00221    if (format == GL_LUMINANCE_ALPHA && type == CHAN_TYPE && rbType == CHAN_TYPE) {
00222       const GLchan *src = (const GLchan *) pixels
00223          + (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels)*2;
00224       if (simpleZoom) {
00225          GLint row;
00226          ASSERT(drawWidth <= MAX_WIDTH);
00227          for (row = 0; row < drawHeight; row++) {
00228             GLint i;
00229             const GLchan *ptr = src;
00230             for (i = 0;i<drawWidth;i++) {
00231                span.array->rgba[i][0] = *ptr;
00232                span.array->rgba[i][1] = *ptr;
00233                span.array->rgba[i][2] = *ptr++;
00234                span.array->rgba[i][3] = *ptr++;
00235             }
00236             rb->PutRow(ctx, rb, drawWidth, destX, destY,
00237                        span.array->rgba, NULL);
00238             src += unpack.RowLength*2;
00239             destY += yStep;
00240          }
00241       }
00242       else {
00243          /* with zooming */
00244          GLint row;
00245          ASSERT(drawWidth <= MAX_WIDTH);
00246          for (row = 0; row < drawHeight; row++) {
00247             const GLchan *ptr = src;
00248             GLint i;
00249             for (i = 0;i<drawWidth;i++) {
00250                span.array->rgba[i][0] = *ptr;
00251                span.array->rgba[i][1] = *ptr;
00252                span.array->rgba[i][2] = *ptr++;
00253                span.array->rgba[i][3] = *ptr++;
00254             }
00255             span.x = destX;
00256             span.y = destY;
00257             span.end = drawWidth;
00258             _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
00259                                            span.array->rgba);
00260             src += unpack.RowLength*2;
00261             destY++;
00262          }
00263       }
00264       return GL_TRUE;
00265    }
00266 
00267    if (format == GL_COLOR_INDEX && type == GL_UNSIGNED_BYTE) {
00268       const GLubyte *src = (const GLubyte *) pixels
00269          + unpack.SkipRows * unpack.RowLength + unpack.SkipPixels;
00270       if (ctx->Visual.rgbMode && rbType == GL_UNSIGNED_BYTE) {
00271          /* convert ubyte/CI data to ubyte/RGBA */
00272          if (simpleZoom) {
00273             GLint row;
00274             for (row = 0; row < drawHeight; row++) {
00275                ASSERT(drawWidth <= MAX_WIDTH);
00276                _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
00277                                       span.array->rgba8);
00278                rb->PutRow(ctx, rb, drawWidth, destX, destY,
00279                           span.array->rgba8, NULL);
00280                src += unpack.RowLength;
00281                destY += yStep;
00282             }
00283          }
00284          else {
00285             /* ubyte/CI to ubyte/RGBA with zooming */
00286             GLint row;
00287             for (row = 0; row < drawHeight; row++) {
00288                ASSERT(drawWidth <= MAX_WIDTH);
00289                _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
00290                                       span.array->rgba8);
00291                span.x = destX;
00292                span.y = destY;
00293                span.end = drawWidth;
00294                _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
00295                                               span.array->rgba8);
00296                src += unpack.RowLength;
00297                destY++;
00298             }
00299          }
00300          return GL_TRUE;
00301       }
00302       else if (!ctx->Visual.rgbMode && rbType == GL_UNSIGNED_INT) {
00303          /* write CI data to CI frame buffer */
00304          GLint row;
00305          if (simpleZoom) {
00306             for (row = 0; row < drawHeight; row++) {
00307                GLuint index32[MAX_WIDTH];
00308                GLint col;
00309                for (col = 0; col < drawWidth; col++)
00310                   index32[col] = src[col];
00311                rb->PutRow(ctx, rb, drawWidth, destX, destY, index32, NULL);
00312                src += unpack.RowLength;
00313                destY += yStep;
00314             }
00315             return GL_TRUE;
00316          }
00317       }
00318    }
00319 
00320    /* can't handle this pixel format and/or data type */
00321    return GL_FALSE;
00322 }
00323 
00324 
00325 
00326 /*
00327  * Draw color index image.
00328  */
00329 static void
00330 draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
00331                    GLsizei width, GLsizei height,
00332                    GLenum type,
00333                    const struct gl_pixelstore_attrib *unpack,
00334                    const GLvoid *pixels )
00335 {
00336    const GLint imgX = x, imgY = y;
00337    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
00338    GLint row, skipPixels;
00339    SWspan span;
00340 
00341    INIT_SPAN(span, GL_BITMAP);
00342    span.arrayMask = SPAN_INDEX;
00343    _swrast_span_default_attribs(ctx, &span);
00344 
00345    /*
00346     * General solution
00347     */
00348    skipPixels = 0;
00349    while (skipPixels < width) {
00350       const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
00351       ASSERT(spanWidth <= MAX_WIDTH);
00352       for (row = 0; row < height; row++) {
00353          const GLvoid *source = _mesa_image_address2d(unpack, pixels,
00354                                                       width, height,
00355                                                       GL_COLOR_INDEX, type,
00356                                                       row, skipPixels);
00357          _mesa_unpack_index_span(ctx, spanWidth, GL_UNSIGNED_INT,
00358                                  span.array->index, type, source, unpack,
00359                                  ctx->_ImageTransferState);
00360 
00361          /* These may get changed during writing/clipping */
00362          span.x = x + skipPixels;
00363          span.y = y + row;
00364          span.end = spanWidth;
00365          
00366          if (zoom)
00367             _swrast_write_zoomed_index_span(ctx, imgX, imgY, &span);
00368          else
00369             _swrast_write_index_span(ctx, &span);
00370       }
00371       skipPixels += spanWidth;
00372    }
00373 }
00374 
00375 
00376 
00377 /*
00378  * Draw stencil image.
00379  */
00380 static void
00381 draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
00382                      GLsizei width, GLsizei height,
00383                      GLenum type,
00384                      const struct gl_pixelstore_attrib *unpack,
00385                      const GLvoid *pixels )
00386 {
00387    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
00388    GLint skipPixels;
00389 
00390    /* if width > MAX_WIDTH, have to process image in chunks */
00391    skipPixels = 0;
00392    while (skipPixels < width) {
00393       const GLint spanX = x + skipPixels;
00394       const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
00395       GLint row;
00396       for (row = 0; row < height; row++) {
00397          const GLint spanY = y + row;
00398          GLstencil values[MAX_WIDTH];
00399          GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
00400                          ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
00401          const GLvoid *source = _mesa_image_address2d(unpack, pixels,
00402                                                       width, height,
00403                                                       GL_COLOR_INDEX, type,
00404                                                       row, skipPixels);
00405          _mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
00406                                    type, source, unpack,
00407                                    ctx->_ImageTransferState);
00408          if (zoom) {
00409             _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
00410                                               spanX, spanY, values);
00411          }
00412          else {
00413             _swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values);
00414          }
00415       }
00416       skipPixels += spanWidth;
00417    }
00418 }
00419 
00420 
00421 /*
00422  * Draw depth image.
00423  */
00424 static void
00425 draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
00426                    GLsizei width, GLsizei height,
00427                    GLenum type,
00428                    const struct gl_pixelstore_attrib *unpack,
00429                    const GLvoid *pixels )
00430 {
00431    const GLboolean scaleOrBias
00432       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
00433    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
00434    SWspan span;
00435 
00436    INIT_SPAN(span, GL_BITMAP);
00437    span.arrayMask = SPAN_Z;
00438    _swrast_span_default_attribs(ctx, &span);
00439 
00440    if (type == GL_UNSIGNED_SHORT
00441        && ctx->DrawBuffer->Visual.depthBits == 16
00442        && !scaleOrBias
00443        && !zoom
00444        && ctx->Visual.rgbMode
00445        && width <= MAX_WIDTH
00446        && !unpack->SwapBytes) {
00447       /* Special case: directly write 16-bit depth values */
00448       GLint row;
00449       for (row = 0; row < height; row++) {
00450          const GLushort *zSrc = (const GLushort *)
00451             _mesa_image_address2d(unpack, pixels, width, height,
00452                                   GL_DEPTH_COMPONENT, type, row, 0);
00453          GLint i;
00454          for (i = 0; i < width; i++)
00455             span.array->z[i] = zSrc[i];
00456          span.x = x;
00457          span.y = y + row;
00458          span.end = width;
00459          _swrast_write_rgba_span(ctx, &span);
00460       }
00461    }
00462    else if (type == GL_UNSIGNED_INT
00463             && !scaleOrBias
00464             && !zoom
00465             && ctx->Visual.rgbMode
00466             && width <= MAX_WIDTH
00467             && !unpack->SwapBytes) {
00468       /* Special case: shift 32-bit values down to Visual.depthBits */
00469       const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits;
00470       GLint row;
00471       for (row = 0; row < height; row++) {
00472          const GLuint *zSrc = (const GLuint *)
00473             _mesa_image_address2d(unpack, pixels, width, height,
00474                                   GL_DEPTH_COMPONENT, type, row, 0);
00475          if (shift == 0) {
00476             _mesa_memcpy(span.array->z, zSrc, width * sizeof(GLuint));
00477          }
00478          else {
00479             GLint col;
00480             for (col = 0; col < width; col++)
00481                span.array->z[col] = zSrc[col] >> shift;
00482          }
00483          span.x = x;
00484          span.y = y + row;
00485          span.end = width;
00486          _swrast_write_rgba_span(ctx, &span);
00487       }
00488    }
00489    else {
00490       /* General case */
00491       const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
00492       GLint skipPixels = 0;
00493 
00494       /* in case width > MAX_WIDTH do the copy in chunks */
00495       while (skipPixels < width) {
00496          const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
00497          GLint row;
00498          ASSERT(span.end <= MAX_WIDTH);
00499          for (row = 0; row < height; row++) {
00500             const GLvoid *zSrc = _mesa_image_address2d(unpack,
00501                                                       pixels, width, height,
00502                                                       GL_DEPTH_COMPONENT, type,
00503                                                       row, skipPixels);
00504 
00505             /* Set these for each row since the _swrast_write_* function may
00506              * change them while clipping.
00507              */
00508             span.x = x + skipPixels;
00509             span.y = y + row;
00510             span.end = spanWidth;
00511 
00512             _mesa_unpack_depth_span(ctx, spanWidth,
00513                                     GL_UNSIGNED_INT, span.array->z, depthMax,
00514                                     type, zSrc, unpack);
00515             if (zoom) {
00516                _swrast_write_zoomed_depth_span(ctx, x, y, &span);
00517             }
00518             else if (ctx->Visual.rgbMode) {
00519                _swrast_write_rgba_span(ctx, &span);
00520             }
00521             else {
00522                _swrast_write_index_span(ctx, &span);
00523             }
00524          }
00525          skipPixels += spanWidth;
00526       }
00527    }
00528 }
00529 
00530 
00531 
00535 static void
00536 draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
00537                   GLsizei width, GLsizei height,
00538                   GLenum format, GLenum type,
00539                   const struct gl_pixelstore_attrib *unpack,
00540                   const GLvoid *pixels )
00541 {
00542    const GLint imgX = x, imgY = y;
00543    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
00544    GLfloat *convImage = NULL;
00545    GLbitfield transferOps = ctx->_ImageTransferState;
00546    SWspan span;
00547 
00548    /* Try an optimized glDrawPixels first */
00549    if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type,
00550                              unpack, pixels)) {
00551       return;
00552    }
00553 
00554    INIT_SPAN(span, GL_BITMAP);
00555    _swrast_span_default_attribs(ctx, &span);
00556    span.arrayMask = SPAN_RGBA;
00557    span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */
00558 
00559    if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
00560       /* Convolution has to be handled specially.  We'll create an
00561        * intermediate image, applying all pixel transfer operations
00562        * up to convolution.  Then we'll convolve the image.  Then
00563        * we'll proceed with the rest of the transfer operations and
00564        * rasterize the image.
00565        */
00566       GLint row;
00567       GLfloat *dest, *tmpImage;
00568 
00569       tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
00570       if (!tmpImage) {
00571          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
00572          return;
00573       }
00574       convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
00575       if (!convImage) {
00576          _mesa_free(tmpImage);
00577          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
00578          return;
00579       }
00580 
00581       /* Unpack the image and apply transfer ops up to convolution */
00582       dest = tmpImage;
00583       for (row = 0; row < height; row++) {
00584          const GLvoid *source = _mesa_image_address2d(unpack,
00585                                   pixels, width, height, format, type, row, 0);
00586          _mesa_unpack_color_span_float(ctx, width, GL_RGBA, (GLfloat *) dest,
00587                                      format, type, source, unpack,
00588                                      transferOps & IMAGE_PRE_CONVOLUTION_BITS);
00589          dest += width * 4;
00590       }
00591 
00592       /* do convolution */
00593       if (ctx->Pixel.Convolution2DEnabled) {
00594          _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
00595       }
00596       else {
00597          ASSERT(ctx->Pixel.Separable2DEnabled);
00598          _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
00599       }
00600       _mesa_free(tmpImage);
00601 
00602       /* continue transfer ops and draw the convolved image */
00603       unpack = &ctx->DefaultPacking;
00604       pixels = convImage;
00605       format = GL_RGBA;
00606       type = GL_FLOAT;
00607       transferOps &= IMAGE_POST_CONVOLUTION_BITS;
00608    }
00609    else if (ctx->Pixel.Convolution1DEnabled) {
00610       /* we only want to apply 1D convolution to glTexImage1D */
00611       transferOps &= ~(IMAGE_CONVOLUTION_BIT |
00612                        IMAGE_POST_CONVOLUTION_SCALE_BIAS);
00613    }
00614 
00615    if (ctx->DrawBuffer->_NumColorDrawBuffers > 0 &&
00616        ctx->DrawBuffer->_ColorDrawBuffers[0]->DataType != GL_FLOAT &&
00617        ctx->Color.ClampFragmentColor != GL_FALSE) {
00618       /* need to clamp colors before applying fragment ops */
00619       transferOps |= IMAGE_CLAMP_BIT;
00620    }
00621 
00622    /*
00623     * General solution
00624     */
00625    {
00626       const GLboolean sink = (ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink)
00627          || (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink);
00628       const GLbitfield interpMask = span.interpMask;
00629       const GLbitfield arrayMask = span.arrayMask;
00630       const GLint srcStride
00631          = _mesa_image_row_stride(unpack, width, format, type);
00632       GLint skipPixels = 0;
00633       /* use span array for temp color storage */
00634       GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0];
00635 
00636       /* if the span is wider than MAX_WIDTH we have to do it in chunks */
00637       while (skipPixels < width) {
00638          const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
00639          const GLubyte *source
00640             = (const GLubyte *) _mesa_image_address2d(unpack, pixels,
00641                                                       width, height, format,
00642                                                       type, 0, skipPixels);
00643          GLint row;
00644 
00645          for (row = 0; row < height; row++) {
00646             /* get image row as float/RGBA */
00647             _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba,
00648                                      format, type, source, unpack,
00649                                      transferOps);
00650             /* draw the span */
00651             if (!sink) {
00652                /* Set these for each row since the _swrast_write_* functions
00653                 * may change them while clipping/rendering.
00654                 */
00655                span.array->ChanType = GL_FLOAT;
00656                span.x = x + skipPixels;
00657                span.y = y + row;
00658                span.end = spanWidth;
00659                span.arrayMask = arrayMask;
00660                span.interpMask = interpMask;
00661                if (zoom) {
00662                   _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba);
00663                }
00664                else {
00665                   _swrast_write_rgba_span(ctx, &span);
00666                }
00667             }
00668 
00669             source += srcStride;
00670          } /* for row */
00671 
00672          skipPixels += spanWidth;
00673       } /* while skipPixels < width */
00674 
00675       /* XXX this is ugly/temporary, to undo above change */
00676       span.array->ChanType = CHAN_TYPE;
00677    }
00678 
00679    if (convImage) {
00680       _mesa_free(convImage);
00681    }
00682 }
00683 
00684 
00693 static void
00694 draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
00695                           GLsizei width, GLsizei height, GLenum type,
00696                           const struct gl_pixelstore_attrib *unpack,
00697                           const GLvoid *pixels)
00698 {
00699    const GLint imgX = x, imgY = y;
00700    const GLboolean scaleOrBias
00701       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
00702    const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
00703    const GLuint stencilMask = ctx->Stencil.WriteMask[0];
00704    const GLuint stencilType = (STENCIL_BITS == 8) ? 
00705       GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
00706    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
00707    struct gl_renderbuffer *depthRb, *stencilRb;
00708    struct gl_pixelstore_attrib clippedUnpack = *unpack;
00709 
00710    if (!zoom) {
00711       if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
00712                                  &clippedUnpack)) {
00713          /* totally clipped */
00714          return;
00715       }
00716    }
00717    
00718    depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
00719    stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
00720    ASSERT(depthRb);
00721    ASSERT(stencilRb);
00722 
00723    if (depthRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&
00724        stencilRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&
00725        depthRb == stencilRb &&
00726        !scaleOrBias &&
00727        !zoom &&
00728        ctx->Depth.Mask &&
00729        (stencilMask & 0xff) == 0xff) {
00730       /* This is the ideal case.
00731        * Drawing GL_DEPTH_STENCIL pixels into a combined depth/stencil buffer.
00732        * Plus, no pixel transfer ops, zooming, or masking needed.
00733        */
00734       GLint i;
00735       for (i = 0; i < height; i++) {
00736          const GLuint *src = (const GLuint *) 
00737             _mesa_image_address2d(&clippedUnpack, pixels, width, height,
00738                                   GL_DEPTH_STENCIL_EXT, type, i, 0);
00739          depthRb->PutRow(ctx, depthRb, width, x, y + i, src, NULL);
00740       }
00741    }
00742    else {
00743       /* sub-optimal cases:
00744        * Separate depth/stencil buffers, or pixel transfer ops required.
00745        */
00746       /* XXX need to handle very wide images (skippixels) */
00747       GLint i;
00748 
00749       depthRb = ctx->DrawBuffer->_DepthBuffer;
00750       stencilRb = ctx->DrawBuffer->_StencilBuffer;
00751 
00752       for (i = 0; i < height; i++) {
00753          const GLuint *depthStencilSrc = (const GLuint *)
00754             _mesa_image_address2d(&clippedUnpack, pixels, width, height,
00755                                   GL_DEPTH_STENCIL_EXT, type, i, 0);
00756 
00757          if (ctx->Depth.Mask) {
00758             if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24) {
00759                /* fast path 24-bit zbuffer */
00760                GLuint zValues[MAX_WIDTH];
00761                GLint j;
00762                ASSERT(depthRb->DataType == GL_UNSIGNED_INT);
00763                for (j = 0; j < width; j++) {
00764                   zValues[j] = depthStencilSrc[j] >> 8;
00765                }
00766                if (zoom)
00767                   _swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
00768                                               x, y + i, zValues);
00769                else
00770                   depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
00771             }
00772             else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16) {
00773                /* fast path 16-bit zbuffer */
00774                GLushort zValues[MAX_WIDTH];
00775                GLint j;
00776                ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT);
00777                for (j = 0; j < width; j++) {
00778                   zValues[j] = depthStencilSrc[j] >> 16;
00779                }
00780                if (zoom)
00781                   _swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
00782                                               x, y + i, zValues);
00783                else
00784                   depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
00785             }
00786             else {
00787                /* general case */
00788                GLuint zValues[MAX_WIDTH];  /* 16 or 32-bit Z value storage */
00789                _mesa_unpack_depth_span(ctx, width,
00790                                        depthRb->DataType, zValues, depthMax,
00791                                        type, depthStencilSrc, &clippedUnpack);
00792                if (zoom) {
00793                   _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
00794                                               y + i, zValues);
00795                }
00796                else {
00797                   depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
00798                }
00799             }
00800          }
00801 
00802          if (stencilMask != 0x0) {
00803             GLstencil stencilValues[MAX_WIDTH];
00804             /* get stencil values, with shift/offset/mapping */
00805             _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues,
00806                                       type, depthStencilSrc, &clippedUnpack,
00807                                       ctx->_ImageTransferState);
00808             if (zoom)
00809                _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
00810                                                   x, y + i, stencilValues);
00811             else
00812                _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
00813          }
00814       }
00815    }
00816 }
00817 
00818 
00823 void
00824 _swrast_DrawPixels( GLcontext *ctx,
00825             GLint x, GLint y,
00826             GLsizei width, GLsizei height,
00827             GLenum format, GLenum type,
00828             const struct gl_pixelstore_attrib *unpack,
00829             const GLvoid *pixels )
00830 {
00831    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00832 
00833    RENDER_START(swrast,ctx);
00834 
00835    if (ctx->NewState)
00836       _mesa_update_state(ctx);
00837 
00838    if (swrast->NewState)
00839       _swrast_validate_derived( ctx );
00840 
00841     pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
00842     if (!pixels) {
00843        RENDER_FINISH(swrast,ctx);
00844        return;
00845     }
00846 
00847    switch (format) {
00848    case GL_STENCIL_INDEX:
00849       draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels );
00850       break;
00851    case GL_DEPTH_COMPONENT:
00852       draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels );
00853       break;
00854    case GL_COLOR_INDEX:
00855       if (ctx->Visual.rgbMode)
00856      draw_rgba_pixels(ctx, x,y, width, height, format, type, unpack, pixels);
00857       else
00858      draw_index_pixels(ctx, x, y, width, height, type, unpack, pixels);
00859       break;
00860    case GL_RED:
00861    case GL_GREEN:
00862    case GL_BLUE:
00863    case GL_ALPHA:
00864    case GL_LUMINANCE:
00865    case GL_LUMINANCE_ALPHA:
00866    case GL_RGB:
00867    case GL_BGR:
00868    case GL_RGBA:
00869    case GL_BGRA:
00870    case GL_ABGR_EXT:
00871       draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
00872       break;
00873    case GL_DEPTH_STENCIL_EXT:
00874       draw_depth_stencil_pixels(ctx, x, y, width, height,
00875                                 type, unpack, pixels);
00876       break;
00877    default:
00878       _mesa_problem(ctx, "unexpected format in _swrast_DrawPixels");
00879       /* don't return yet, clean-up */
00880    }
00881 
00882    RENDER_FINISH(swrast,ctx);
00883 
00884    _mesa_unmap_drapix_pbo(ctx, unpack);
00885 }
00886 
00887 
00888 
00889 #if 0  /* experimental */
00890 /*
00891  * Execute glDrawDepthPixelsMESA().
00892  */
00893 void
00894 _swrast_DrawDepthPixelsMESA( GLcontext *ctx,
00895                              GLint x, GLint y,
00896                              GLsizei width, GLsizei height,
00897                              GLenum colorFormat, GLenum colorType,
00898                              const GLvoid *colors,
00899                              GLenum depthType, const GLvoid *depths,
00900                              const struct gl_pixelstore_attrib *unpack )
00901 {
00902    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00903 
00904    if (swrast->NewState)
00905       _swrast_validate_derived( ctx );
00906 
00907    RENDER_START(swrast,ctx);
00908 
00909    switch (colorFormat) {
00910    case GL_COLOR_INDEX:
00911       if (ctx->Visual.rgbMode)
00912      draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType,
00913                           unpack, colors);
00914       else
00915      draw_index_pixels(ctx, x, y, width, height, colorType,
00916                            unpack, colors);
00917       break;
00918    case GL_RED:
00919    case GL_GREEN:
00920    case GL_BLUE:
00921    case GL_ALPHA:
00922    case GL_LUMINANCE:
00923    case GL_LUMINANCE_ALPHA:
00924    case GL_RGB:
00925    case GL_BGR:
00926    case GL_RGBA:
00927    case GL_BGRA:
00928    case GL_ABGR_EXT:
00929       draw_rgba_pixels(ctx, x, y, width, height, colorFormat, colorType,
00930                        unpack, colors);
00931       break;
00932    default:
00933       _mesa_problem(ctx, "unexpected format in glDrawDepthPixelsMESA");
00934    }
00935 
00936    RENDER_FINISH(swrast,ctx);
00937 }
00938 #endif

Generated on Sat May 26 2012 04:19:32 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.