Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.0.3
  4.  *
  5.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. #include "main/glheader.h"
  27. #include "main/bufferobj.h"
  28. #include "main/colormac.h"
  29. #include "main/feedback.h"
  30. #include "main/formats.h"
  31. #include "main/image.h"
  32. #include "main/imports.h"
  33. #include "main/macros.h"
  34. #include "main/pack.h"
  35. #include "main/state.h"
  36.  
  37. #include "s_context.h"
  38. #include "s_depth.h"
  39. #include "s_span.h"
  40. #include "s_stencil.h"
  41.  
  42.  
  43. /**
  44.  * Read pixels for format=GL_DEPTH_COMPONENT.
  45.  */
  46. static void
  47. read_depth_pixels( struct gl_context *ctx,
  48.                    GLint x, GLint y,
  49.                    GLsizei width, GLsizei height,
  50.                    GLenum type, GLvoid *pixels,
  51.                    const struct gl_pixelstore_attrib *packing )
  52. {
  53.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  54.    struct gl_renderbuffer *rb = fb->_DepthBuffer;
  55.    const GLboolean biasOrScale
  56.       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
  57.  
  58.    if (!rb)
  59.       return;
  60.  
  61.    /* clipping should have been done already */
  62.    ASSERT(x >= 0);
  63.    ASSERT(y >= 0);
  64.    ASSERT(x + width <= (GLint) rb->Width);
  65.    ASSERT(y + height <= (GLint) rb->Height);
  66.    /* width should never be > MAX_WIDTH since we did clipping earlier */
  67.    ASSERT(width <= MAX_WIDTH);
  68.  
  69.    if (type == GL_UNSIGNED_SHORT && fb->Visual.depthBits == 16
  70.        && !biasOrScale && !packing->SwapBytes) {
  71.       /* Special case: directly read 16-bit unsigned depth values. */
  72.       GLint j;
  73.       ASSERT(rb->Format == MESA_FORMAT_Z16);
  74.       ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
  75.       for (j = 0; j < height; j++, y++) {
  76.          void *dest =_mesa_image_address2d(packing, pixels, width, height,
  77.                                            GL_DEPTH_COMPONENT, type, j, 0);
  78.          rb->GetRow(ctx, rb, width, x, y, dest);
  79.       }
  80.    }
  81.    else if (type == GL_UNSIGNED_INT && fb->Visual.depthBits == 24
  82.             && !biasOrScale && !packing->SwapBytes) {
  83.       /* Special case: directly read 24-bit unsigned depth values. */
  84.       GLint j;
  85.       ASSERT(rb->Format == MESA_FORMAT_X8_Z24 ||
  86.              rb->Format == MESA_FORMAT_S8_Z24 ||
  87.              rb->Format == MESA_FORMAT_Z24_X8 ||
  88.              rb->Format == MESA_FORMAT_Z24_S8);
  89.       ASSERT(rb->DataType == GL_UNSIGNED_INT ||
  90.              rb->DataType == GL_UNSIGNED_INT_24_8);
  91.       for (j = 0; j < height; j++, y++) {
  92.          GLuint *dest = (GLuint *)
  93.             _mesa_image_address2d(packing, pixels, width, height,
  94.                                   GL_DEPTH_COMPONENT, type, j, 0);
  95.          GLint k;
  96.          rb->GetRow(ctx, rb, width, x, y, dest);
  97.          /* convert range from 24-bit to 32-bit */
  98.          if (rb->Format == MESA_FORMAT_X8_Z24 ||
  99.              rb->Format == MESA_FORMAT_S8_Z24) {
  100.             for (k = 0; k < width; k++) {
  101.                /* Note: put MSByte of 24-bit value into LSByte */
  102.                dest[k] = (dest[k] << 8) | ((dest[k] >> 16) & 0xff);
  103.             }
  104.          }
  105.          else {
  106.             for (k = 0; k < width; k++) {
  107.                /* Note: fill in LSByte by replication */
  108.                dest[k] = dest[k] | ((dest[k] >> 8) & 0xff);
  109.             }
  110.          }
  111.       }
  112.    }
  113.    else if (type == GL_UNSIGNED_INT && fb->Visual.depthBits == 32
  114.             && !biasOrScale && !packing->SwapBytes) {
  115.       /* Special case: directly read 32-bit unsigned depth values. */
  116.       GLint j;
  117.       ASSERT(rb->Format == MESA_FORMAT_Z32);
  118.       ASSERT(rb->DataType == GL_UNSIGNED_INT);
  119.       for (j = 0; j < height; j++, y++) {
  120.          void *dest = _mesa_image_address2d(packing, pixels, width, height,
  121.                                             GL_DEPTH_COMPONENT, type, j, 0);
  122.          rb->GetRow(ctx, rb, width, x, y, dest);
  123.       }
  124.    }
  125.    else {
  126.       /* General case (slower) */
  127.       GLint j;
  128.       for (j = 0; j < height; j++, y++) {
  129.          GLfloat depthValues[MAX_WIDTH];
  130.          GLvoid *dest = _mesa_image_address2d(packing, pixels, width, height,
  131.                                               GL_DEPTH_COMPONENT, type, j, 0);
  132.          _swrast_read_depth_span_float(ctx, rb, width, x, y, depthValues);
  133.          _mesa_pack_depth_span(ctx, width, dest, type, depthValues, packing);
  134.       }
  135.    }
  136. }
  137.  
  138.  
  139. /**
  140.  * Read pixels for format=GL_STENCIL_INDEX.
  141.  */
  142. static void
  143. read_stencil_pixels( struct gl_context *ctx,
  144.                      GLint x, GLint y,
  145.                      GLsizei width, GLsizei height,
  146.                      GLenum type, GLvoid *pixels,
  147.                      const struct gl_pixelstore_attrib *packing )
  148. {
  149.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  150.    struct gl_renderbuffer *rb = fb->_StencilBuffer;
  151.    GLint j;
  152.  
  153.    if (!rb)
  154.       return;
  155.  
  156.    /* width should never be > MAX_WIDTH since we did clipping earlier */
  157.    ASSERT(width <= MAX_WIDTH);
  158.  
  159.    /* process image row by row */
  160.    for (j=0;j<height;j++,y++) {
  161.       GLvoid *dest;
  162.       GLstencil stencil[MAX_WIDTH];
  163.  
  164.       _swrast_read_stencil_span(ctx, rb, width, x, y, stencil);
  165.  
  166.       dest = _mesa_image_address2d(packing, pixels, width, height,
  167.                                    GL_STENCIL_INDEX, type, j, 0);
  168.  
  169.       _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
  170.    }
  171. }
  172.  
  173.  
  174.  
  175. /**
  176.  * Optimized glReadPixels for particular pixel formats when pixel
  177.  * scaling, biasing, mapping, etc. are disabled.
  178.  * \return GL_TRUE if success, GL_FALSE if unable to do the readpixels
  179.  */
  180. static GLboolean
  181. fast_read_rgba_pixels( struct gl_context *ctx,
  182.                        GLint x, GLint y,
  183.                        GLsizei width, GLsizei height,
  184.                        GLenum format, GLenum type,
  185.                        GLvoid *pixels,
  186.                        const struct gl_pixelstore_attrib *packing,
  187.                        GLbitfield transferOps)
  188. {
  189.    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
  190.  
  191.    if (!rb)
  192.       return GL_FALSE;
  193.  
  194.    ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB ||
  195.           rb->_BaseFormat == GL_ALPHA);
  196.  
  197.    /* clipping should have already been done */
  198.    ASSERT(x + width <= (GLint) rb->Width);
  199.    ASSERT(y + height <= (GLint) rb->Height);
  200.  
  201.    /* check for things we can't handle here */
  202.    if (transferOps ||
  203.        packing->SwapBytes ||
  204.        packing->LsbFirst) {
  205.       return GL_FALSE;
  206.    }
  207.  
  208.    if (format == GL_RGBA && rb->DataType == type) {
  209.       const GLint dstStride = _mesa_image_row_stride(packing, width,
  210.                                                      format, type);
  211.       GLubyte *dest
  212.          = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  213.                                              format, type, 0, 0);
  214.       GLint row;
  215.       ASSERT(rb->GetRow);
  216.       for (row = 0; row < height; row++) {
  217.          rb->GetRow(ctx, rb, width, x, y + row, dest);
  218.          dest += dstStride;
  219.       }
  220.       return GL_TRUE;
  221.    }
  222.  
  223.    if (format == GL_RGB &&
  224.        rb->DataType == GL_UNSIGNED_BYTE &&
  225.        type == GL_UNSIGNED_BYTE) {
  226.       const GLint dstStride = _mesa_image_row_stride(packing, width,
  227.                                                      format, type);
  228.       GLubyte *dest
  229.          = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  230.                                              format, type, 0, 0);
  231.       GLint row;
  232.       ASSERT(rb->GetRow);
  233.       for (row = 0; row < height; row++) {
  234.          GLubyte tempRow[MAX_WIDTH][4];
  235.          GLint col;
  236.          rb->GetRow(ctx, rb, width, x, y + row, tempRow);
  237.          /* convert RGBA to RGB */
  238.          for (col = 0; col < width; col++) {
  239.             dest[col * 3 + 0] = tempRow[col][0];
  240.             dest[col * 3 + 1] = tempRow[col][1];
  241.             dest[col * 3 + 2] = tempRow[col][2];
  242.          }
  243.          dest += dstStride;
  244.       }
  245.       return GL_TRUE;
  246.    }
  247.  
  248.    /* not handled */
  249.    return GL_FALSE;
  250. }
  251.  
  252.  
  253. /**
  254.  * When we're using a low-precision color buffer (like 16-bit 5/6/5)
  255.  * we have to adjust our color values a bit to pass conformance.
  256.  * The problem is when a 5 or 6-bit color value is converted to an 8-bit
  257.  * value and then a floating point value, the floating point values don't
  258.  * increment uniformly as the 5 or 6-bit value is incremented.
  259.  *
  260.  * This function adjusts floating point values to compensate.
  261.  */
  262. static void
  263. adjust_colors(const struct gl_framebuffer *fb, GLuint n, GLfloat rgba[][4])
  264. {
  265.    const GLuint rShift = 8 - fb->Visual.redBits;
  266.    const GLuint gShift = 8 - fb->Visual.greenBits;
  267.    const GLuint bShift = 8 - fb->Visual.blueBits;
  268.    GLfloat rScale = 1.0F / (GLfloat) ((1 << fb->Visual.redBits  ) - 1);
  269.    GLfloat gScale = 1.0F / (GLfloat) ((1 << fb->Visual.greenBits) - 1);
  270.    GLfloat bScale = 1.0F / (GLfloat) ((1 << fb->Visual.blueBits ) - 1);
  271.    GLuint i;
  272.  
  273.    if (fb->Visual.redBits == 0)
  274.       rScale = 0;
  275.    if (fb->Visual.greenBits == 0)
  276.       gScale = 0;
  277.    if (fb->Visual.blueBits == 0)
  278.       bScale = 0;
  279.  
  280.    for (i = 0; i < n; i++) {
  281.       GLint r, g, b;
  282.       /* convert float back to ubyte */
  283.       CLAMPED_FLOAT_TO_UBYTE(r, rgba[i][RCOMP]);
  284.       CLAMPED_FLOAT_TO_UBYTE(g, rgba[i][GCOMP]);
  285.       CLAMPED_FLOAT_TO_UBYTE(b, rgba[i][BCOMP]);
  286.       /* using only the N most significant bits of the ubyte value, convert to
  287.        * float in [0,1].
  288.        */
  289.       rgba[i][RCOMP] = (GLfloat) (r >> rShift) * rScale;
  290.       rgba[i][GCOMP] = (GLfloat) (g >> gShift) * gScale;
  291.       rgba[i][BCOMP] = (GLfloat) (b >> bShift) * bScale;
  292.    }
  293. }
  294.  
  295.  
  296.  
  297. /*
  298.  * Read R, G, B, A, RGB, L, or LA pixels.
  299.  */
  300. static void
  301. read_rgba_pixels( struct gl_context *ctx,
  302.                   GLint x, GLint y,
  303.                   GLsizei width, GLsizei height,
  304.                   GLenum format, GLenum type, GLvoid *pixels,
  305.                   const struct gl_pixelstore_attrib *packing )
  306. {
  307.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  308.    GLbitfield transferOps = ctx->_ImageTransferState;
  309.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  310.    struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
  311.  
  312.    if (!rb)
  313.       return;
  314.  
  315.    if (type == GL_FLOAT && ((ctx->Color.ClampReadColor == GL_TRUE) ||
  316.                             (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
  317.                              rb->DataType != GL_FLOAT)))
  318.       transferOps |= IMAGE_CLAMP_BIT;
  319.  
  320.    /* Try optimized path first */
  321.    if (fast_read_rgba_pixels(ctx, x, y, width, height,
  322.                              format, type, pixels, packing, transferOps)) {
  323.       return; /* done! */
  324.    }
  325.  
  326.    /* width should never be > MAX_WIDTH since we did clipping earlier */
  327.    ASSERT(width <= MAX_WIDTH);
  328.  
  329.    do {
  330.       const GLint dstStride
  331.          = _mesa_image_row_stride(packing, width, format, type);
  332.       GLfloat (*rgba)[4] = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];
  333.       GLint row;
  334.       GLubyte *dst
  335.          = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  336.                                              format, type, 0, 0);
  337.  
  338.       for (row = 0; row < height; row++, y++) {
  339.  
  340.          /* Get float rgba pixels */
  341.          _swrast_read_rgba_span(ctx, rb, width, x, y, GL_FLOAT, rgba);
  342.  
  343.          /* apply fudge factor for shallow color buffers */
  344.          if (fb->Visual.redBits < 8 ||
  345.              fb->Visual.greenBits < 8 ||
  346.              fb->Visual.blueBits < 8) {
  347.             adjust_colors(fb, width, rgba);
  348.          }
  349.  
  350.          /* pack the row of RGBA pixels into user's buffer */
  351.          _mesa_pack_rgba_span_float(ctx, width, rgba, format, type, dst,
  352.                                     packing, transferOps);
  353.  
  354.          dst += dstStride;
  355.       }
  356.    } while (0);
  357. }
  358.  
  359.  
  360. /**
  361.  * Read combined depth/stencil values.
  362.  * We'll have already done error checking to be sure the expected
  363.  * depth and stencil buffers really exist.
  364.  */
  365. static void
  366. read_depth_stencil_pixels(struct gl_context *ctx,
  367.                           GLint x, GLint y,
  368.                           GLsizei width, GLsizei height,
  369.                           GLenum type, GLvoid *pixels,
  370.                           const struct gl_pixelstore_attrib *packing )
  371. {
  372.    const GLboolean scaleOrBias
  373.       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
  374.    const GLboolean stencilTransfer = ctx->Pixel.IndexShift
  375.       || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
  376.    struct gl_renderbuffer *depthRb, *stencilRb;
  377.  
  378.    depthRb = ctx->ReadBuffer->_DepthBuffer;
  379.    stencilRb = ctx->ReadBuffer->_StencilBuffer;
  380.  
  381.    if (!depthRb || !stencilRb)
  382.       return;
  383.  
  384.    depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  385.    stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
  386.  
  387.    if (depthRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&
  388.        stencilRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&
  389.        depthRb == stencilRb &&
  390.        !scaleOrBias &&
  391.        !stencilTransfer) {
  392.       /* This is the ideal case.
  393.        * Reading GL_DEPTH_STENCIL pixels from combined depth/stencil buffer.
  394.        * Plus, no pixel transfer ops to worry about!
  395.        */
  396.       GLint i;
  397.       GLint dstStride = _mesa_image_row_stride(packing, width,
  398.                                                GL_DEPTH_STENCIL_EXT, type);
  399.       GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
  400.                                                        width, height,
  401.                                                        GL_DEPTH_STENCIL_EXT,
  402.                                                        type, 0, 0);
  403.       for (i = 0; i < height; i++) {
  404.          depthRb->GetRow(ctx, depthRb, width, x, y + i, dst);
  405.          dst += dstStride;
  406.       }
  407.    }
  408.    else {
  409.       /* Reading GL_DEPTH_STENCIL pixels from separate depth/stencil buffers,
  410.        * or we need pixel transfer.
  411.        */
  412.       GLint i;
  413.       depthRb = ctx->ReadBuffer->_DepthBuffer;
  414.       stencilRb = ctx->ReadBuffer->_StencilBuffer;
  415.  
  416.       for (i = 0; i < height; i++) {
  417.          GLstencil stencilVals[MAX_WIDTH];
  418.  
  419.          GLuint *depthStencilDst = (GLuint *)
  420.             _mesa_image_address2d(packing, pixels, width, height,
  421.                                   GL_DEPTH_STENCIL_EXT, type, i, 0);
  422.  
  423.          _swrast_read_stencil_span(ctx, stencilRb, width,
  424.                                    x, y + i, stencilVals);
  425.  
  426.          if (!scaleOrBias && !stencilTransfer
  427.              && ctx->ReadBuffer->Visual.depthBits == 24) {
  428.             /* ideal case */
  429.             GLuint zVals[MAX_WIDTH]; /* 24-bit values! */
  430.             GLint j;
  431.             ASSERT(depthRb->DataType == GL_UNSIGNED_INT);
  432.             /* note, we've already been clipped */
  433.             depthRb->GetRow(ctx, depthRb, width, x, y + i, zVals);
  434.             for (j = 0; j < width; j++) {
  435.                depthStencilDst[j] = (zVals[j] << 8) | (stencilVals[j] & 0xff);
  436.             }
  437.          }
  438.          else {
  439.             /* general case */
  440.             GLfloat depthVals[MAX_WIDTH];
  441.             _swrast_read_depth_span_float(ctx, depthRb, width, x, y + i,
  442.                                           depthVals);
  443.             _mesa_pack_depth_stencil_span(ctx, width, depthStencilDst,
  444.                                           depthVals, stencilVals, packing);
  445.          }
  446.       }
  447.    }
  448. }
  449.  
  450.  
  451.  
  452. /**
  453.  * Software fallback routine for ctx->Driver.ReadPixels().
  454.  * By time we get here, all error checking will have been done.
  455.  */
  456. void
  457. _swrast_ReadPixels( struct gl_context *ctx,
  458.                     GLint x, GLint y, GLsizei width, GLsizei height,
  459.                     GLenum format, GLenum type,
  460.                     const struct gl_pixelstore_attrib *packing,
  461.                     GLvoid *pixels )
  462. {
  463.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  464.    struct gl_pixelstore_attrib clippedPacking = *packing;
  465.  
  466.    if (ctx->NewState)
  467.       _mesa_update_state(ctx);
  468.  
  469.    /* Need to do swrast_render_start() before clipping or anything else
  470.     * since this is where a driver may grab the hw lock and get an updated
  471.     * window size.
  472.     */
  473.    swrast_render_start(ctx);
  474.  
  475.    if (swrast->NewState)
  476.       _swrast_validate_derived( ctx );
  477.  
  478.    /* Do all needed clipping here, so that we can forget about it later */
  479.    if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
  480.  
  481.       pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
  482.  
  483.       if (pixels) {
  484.          switch (format) {
  485.          case GL_STENCIL_INDEX:
  486.             read_stencil_pixels(ctx, x, y, width, height, type, pixels,
  487.                                 &clippedPacking);
  488.             break;
  489.          case GL_DEPTH_COMPONENT:
  490.             read_depth_pixels(ctx, x, y, width, height, type, pixels,
  491.                               &clippedPacking);
  492.             break;
  493.          case GL_DEPTH_STENCIL_EXT:
  494.             read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
  495.                                       &clippedPacking);
  496.             break;
  497.          default:
  498.             /* all other formats should be color formats */
  499.             read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
  500.                              &clippedPacking);
  501.          }
  502.  
  503.          _mesa_unmap_pbo_dest(ctx, &clippedPacking);
  504.       }
  505.    }
  506.  
  507.    swrast_render_finish(ctx);
  508. }
  509.