Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include "glheader.h"
  26. #include "imports.h"
  27. #include "blend.h"
  28. #include "bufferobj.h"
  29. #include "context.h"
  30. #include "enums.h"
  31. #include "readpix.h"
  32. #include "framebuffer.h"
  33. #include "formats.h"
  34. #include "format_unpack.h"
  35. #include "image.h"
  36. #include "mtypes.h"
  37. #include "pack.h"
  38. #include "pbo.h"
  39. #include "state.h"
  40. #include "glformats.h"
  41. #include "fbobject.h"
  42.  
  43.  
  44. /**
  45.  * Return true if the conversion L=R+G+B is needed.
  46.  */
  47. static GLboolean
  48. need_rgb_to_luminance_conversion(gl_format texFormat, GLenum format)
  49. {
  50.    GLenum baseTexFormat = _mesa_get_format_base_format(texFormat);
  51.  
  52.    return (baseTexFormat == GL_RG ||
  53.            baseTexFormat == GL_RGB ||
  54.            baseTexFormat == GL_RGBA) &&
  55.           (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA);
  56. }
  57.  
  58.  
  59. /**
  60.  * Return transfer op flags for this ReadPixels operation.
  61.  */
  62. static GLbitfield
  63. get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat,
  64.                             GLenum format, GLenum type, GLboolean uses_blit)
  65. {
  66.    GLbitfield transferOps = ctx->_ImageTransferState;
  67.  
  68.    if (format == GL_DEPTH_COMPONENT ||
  69.        format == GL_DEPTH_STENCIL ||
  70.        format == GL_STENCIL_INDEX) {
  71.       return 0;
  72.    }
  73.  
  74.    /* Pixel transfer ops (scale, bias, table lookup) do not apply
  75.     * to integer formats.
  76.     */
  77.    if (_mesa_is_enum_format_integer(format)) {
  78.       return 0;
  79.    }
  80.  
  81.    if (uses_blit) {
  82.       /* For blit-based ReadPixels packing, the clamping is done automatically
  83.        * unless the type is float. */
  84.       if (_mesa_get_clamp_read_color(ctx) &&
  85.           (type == GL_FLOAT || type == GL_HALF_FLOAT)) {
  86.          transferOps |= IMAGE_CLAMP_BIT;
  87.       }
  88.    }
  89.    else {
  90.       /* For CPU-based ReadPixels packing, the clamping must always be done
  91.        * for non-float types, */
  92.       if (_mesa_get_clamp_read_color(ctx) ||
  93.           (type != GL_FLOAT && type != GL_HALF_FLOAT)) {
  94.          transferOps |= IMAGE_CLAMP_BIT;
  95.       }
  96.    }
  97.  
  98.    /* If the format is unsigned normalized, we can ignore clamping
  99.     * because the values are already in the range [0,1] so it won't
  100.     * have any effect anyway.
  101.     */
  102.    if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
  103.        !need_rgb_to_luminance_conversion(texFormat, format)) {
  104.       transferOps &= ~IMAGE_CLAMP_BIT;
  105.    }
  106.  
  107.    return transferOps;
  108. }
  109.  
  110.  
  111. /**
  112.  * Return true if memcpy cannot be used for ReadPixels.
  113.  *
  114.  * If uses_blit is true, the function returns true if a simple 3D engine blit
  115.  * cannot be used for ReadPixels packing.
  116.  *
  117.  * NOTE: This doesn't take swizzling and format conversions between
  118.  *       the readbuffer and the pixel pack buffer into account.
  119.  */
  120. GLboolean
  121. _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
  122.                                  GLenum type, GLboolean uses_blit)
  123. {
  124.    struct gl_renderbuffer *rb =
  125.          _mesa_get_read_renderbuffer_for_format(ctx, format);
  126.    GLenum srcType;
  127.  
  128.    ASSERT(rb);
  129.  
  130.    /* There are different rules depending on the base format. */
  131.    switch (format) {
  132.    case GL_DEPTH_STENCIL:
  133.       return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
  134.              ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
  135.              ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
  136.              ctx->Pixel.MapStencilFlag;
  137.  
  138.    case GL_DEPTH_COMPONENT:
  139.       return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
  140.  
  141.    case GL_STENCIL_INDEX:
  142.       return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
  143.              ctx->Pixel.MapStencilFlag;
  144.  
  145.    default:
  146.       /* Color formats. */
  147.       if (need_rgb_to_luminance_conversion(rb->Format, format)) {
  148.          return GL_TRUE;
  149.       }
  150.  
  151.       /* Conversion between signed and unsigned integers needs masking
  152.        * (it isn't just memcpy). */
  153.       srcType = _mesa_get_format_datatype(rb->Format);
  154.  
  155.       if ((srcType == GL_INT &&
  156.            (type == GL_UNSIGNED_INT ||
  157.             type == GL_UNSIGNED_SHORT ||
  158.             type == GL_UNSIGNED_BYTE)) ||
  159.           (srcType == GL_UNSIGNED_INT &&
  160.            (type == GL_INT ||
  161.             type == GL_SHORT ||
  162.             type == GL_BYTE))) {
  163.          return GL_TRUE;
  164.       }
  165.  
  166.       /* And finally, see if there are any transfer ops. */
  167.       return get_readpixels_transfer_ops(ctx, rb->Format, format, type,
  168.                                          uses_blit) != 0;
  169.    }
  170.    return GL_FALSE;
  171. }
  172.  
  173.  
  174. static GLboolean
  175. readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
  176.                           const struct gl_pixelstore_attrib *packing)
  177. {
  178.    struct gl_renderbuffer *rb =
  179.          _mesa_get_read_renderbuffer_for_format(ctx, format);
  180.  
  181.    ASSERT(rb);
  182.  
  183.    if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
  184.       return GL_FALSE;
  185.    }
  186.  
  187.    /* The base internal format and the base Mesa format must match. */
  188.    if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
  189.       return GL_FALSE;
  190.    }
  191.  
  192.    /* The Mesa format must match the input format and type. */
  193.    if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
  194.                                              packing->SwapBytes)) {
  195.       return GL_FALSE;
  196.    }
  197.  
  198.    return GL_TRUE;
  199. }
  200.  
  201.  
  202. static GLboolean
  203. readpixels_memcpy(struct gl_context *ctx,
  204.                   GLint x, GLint y,
  205.                   GLsizei width, GLsizei height,
  206.                   GLenum format, GLenum type,
  207.                   GLvoid *pixels,
  208.                   const struct gl_pixelstore_attrib *packing)
  209. {
  210.    struct gl_renderbuffer *rb =
  211.          _mesa_get_read_renderbuffer_for_format(ctx, format);
  212.    GLubyte *dst, *map;
  213.    int dstStride, stride, j, texelBytes;
  214.  
  215.    /* Fail if memcpy cannot be used. */
  216.    if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
  217.       return GL_FALSE;
  218.    }
  219.  
  220.    dstStride = _mesa_image_row_stride(packing, width, format, type);
  221.    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  222.                                            format, type, 0, 0);
  223.  
  224.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  225.                                &map, &stride);
  226.    if (!map) {
  227.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  228.       return GL_TRUE;  /* don't bother trying the slow path */
  229.    }
  230.  
  231.    texelBytes = _mesa_get_format_bytes(rb->Format);
  232.  
  233.    /* memcpy*/
  234.    for (j = 0; j < height; j++) {
  235.       memcpy(dst, map, width * texelBytes);
  236.       dst += dstStride;
  237.       map += stride;
  238.    }
  239.  
  240.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  241.    return GL_TRUE;
  242. }
  243.  
  244.  
  245. /**
  246.  * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
  247.  * GL_UNSIGNED_INT.
  248.  */
  249. static GLboolean
  250. read_uint_depth_pixels( struct gl_context *ctx,
  251.                         GLint x, GLint y,
  252.                         GLsizei width, GLsizei height,
  253.                         GLenum type, GLvoid *pixels,
  254.                         const struct gl_pixelstore_attrib *packing )
  255. {
  256.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  257.    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  258.    GLubyte *map, *dst;
  259.    int stride, dstStride, j;
  260.  
  261.    if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0)
  262.       return GL_FALSE;
  263.  
  264.    if (packing->SwapBytes)
  265.       return GL_FALSE;
  266.  
  267.    if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
  268.       return GL_FALSE;
  269.  
  270.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  271.                                &map, &stride);
  272.  
  273.    if (!map) {
  274.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  275.       return GL_TRUE;  /* don't bother trying the slow path */
  276.    }
  277.  
  278.    dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
  279.    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  280.                                            GL_DEPTH_COMPONENT, type, 0, 0);
  281.  
  282.    for (j = 0; j < height; j++) {
  283.       _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
  284.  
  285.       map += stride;
  286.       dst += dstStride;
  287.    }
  288.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  289.  
  290.    return GL_TRUE;
  291. }
  292.  
  293. /**
  294.  * Read pixels for format=GL_DEPTH_COMPONENT.
  295.  */
  296. static void
  297. read_depth_pixels( struct gl_context *ctx,
  298.                    GLint x, GLint y,
  299.                    GLsizei width, GLsizei height,
  300.                    GLenum type, GLvoid *pixels,
  301.                    const struct gl_pixelstore_attrib *packing )
  302. {
  303.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  304.    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  305.    GLint j;
  306.    GLubyte *dst, *map;
  307.    int dstStride, stride;
  308.    GLfloat *depthValues;
  309.  
  310.    if (!rb)
  311.       return;
  312.  
  313.    /* clipping should have been done already */
  314.    ASSERT(x >= 0);
  315.    ASSERT(y >= 0);
  316.    ASSERT(x + width <= (GLint) rb->Width);
  317.    ASSERT(y + height <= (GLint) rb->Height);
  318.  
  319.    if (type == GL_UNSIGNED_INT &&
  320.        read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
  321.       return;
  322.    }
  323.  
  324.    dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
  325.    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  326.                                            GL_DEPTH_COMPONENT, type, 0, 0);
  327.  
  328.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  329.                                &map, &stride);
  330.    if (!map) {
  331.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  332.       return;
  333.    }
  334.  
  335.    depthValues = malloc(width * sizeof(GLfloat));
  336.  
  337.    if (depthValues) {
  338.       /* General case (slower) */
  339.       for (j = 0; j < height; j++, y++) {
  340.          _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
  341.          _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
  342.  
  343.          dst += dstStride;
  344.          map += stride;
  345.       }
  346.    }
  347.    else {
  348.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  349.    }
  350.  
  351.    free(depthValues);
  352.  
  353.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  354. }
  355.  
  356.  
  357. /**
  358.  * Read pixels for format=GL_STENCIL_INDEX.
  359.  */
  360. static void
  361. read_stencil_pixels( struct gl_context *ctx,
  362.                      GLint x, GLint y,
  363.                      GLsizei width, GLsizei height,
  364.                      GLenum type, GLvoid *pixels,
  365.                      const struct gl_pixelstore_attrib *packing )
  366. {
  367.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  368.    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  369.    GLint j;
  370.    GLubyte *map, *stencil;
  371.    GLint stride;
  372.  
  373.    if (!rb)
  374.       return;
  375.  
  376.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  377.                                &map, &stride);
  378.    if (!map) {
  379.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  380.       return;
  381.    }
  382.  
  383.    stencil = malloc(width * sizeof(GLubyte));
  384.  
  385.    if (stencil) {
  386.       /* process image row by row */
  387.       for (j = 0; j < height; j++) {
  388.          GLvoid *dest;
  389.  
  390.          _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
  391.          dest = _mesa_image_address2d(packing, pixels, width, height,
  392.                                       GL_STENCIL_INDEX, type, j, 0);
  393.  
  394.          _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
  395.  
  396.          map += stride;
  397.       }
  398.    }
  399.    else {
  400.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  401.    }
  402.  
  403.    free(stencil);
  404.  
  405.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  406. }
  407.  
  408.  
  409. /**
  410.  * Try to do glReadPixels of RGBA data using swizzle.
  411.  * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
  412.  */
  413. static GLboolean
  414. read_rgba_pixels_swizzle(struct gl_context *ctx,
  415.                          GLint x, GLint y,
  416.                          GLsizei width, GLsizei height,
  417.                          GLenum format, GLenum type,
  418.                          GLvoid *pixels,
  419.                          const struct gl_pixelstore_attrib *packing)
  420. {
  421.    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
  422.    GLubyte *dst, *map;
  423.    int dstStride, stride, j;
  424.    GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE;
  425.  
  426.    /* XXX we could check for other swizzle/special cases here as needed */
  427.    if (rb->Format == MESA_FORMAT_RGBA8888_REV &&
  428.        format == GL_BGRA &&
  429.        type == GL_UNSIGNED_INT_8_8_8_8_REV &&
  430.        !ctx->Pack.SwapBytes) {
  431.       swizzle_rb = GL_TRUE;
  432.    }
  433.    else if (rb->Format == MESA_FORMAT_XRGB8888 &&
  434.        format == GL_BGRA &&
  435.        type == GL_UNSIGNED_INT_8_8_8_8_REV &&
  436.        !ctx->Pack.SwapBytes) {
  437.       copy_xrgb = GL_TRUE;
  438.    }
  439.    else {
  440.       return GL_FALSE;
  441.    }
  442.  
  443.    dstStride = _mesa_image_row_stride(packing, width, format, type);
  444.    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  445.                                            format, type, 0, 0);
  446.  
  447.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  448.                                &map, &stride);
  449.    if (!map) {
  450.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  451.       return GL_TRUE;  /* don't bother trying the slow path */
  452.    }
  453.  
  454.    if (swizzle_rb) {
  455.       /* swap R/B */
  456.       for (j = 0; j < height; j++) {
  457.          int i;
  458.          for (i = 0; i < width; i++) {
  459.             GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
  460.             GLuint pixel = map4[i];
  461.             dst4[i] = (pixel & 0xff00ff00)
  462.                    | ((pixel & 0x00ff0000) >> 16)
  463.                    | ((pixel & 0x000000ff) << 16);
  464.          }
  465.          dst += dstStride;
  466.          map += stride;
  467.       }
  468.    } else if (copy_xrgb) {
  469.       /* convert xrgb -> argb */
  470.       for (j = 0; j < height; j++) {
  471.          GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
  472.          int i;
  473.          for (i = 0; i < width; i++) {
  474.             dst4[i] = map4[i] | 0xff000000;  /* set A=0xff */
  475.          }
  476.          dst += dstStride;
  477.          map += stride;
  478.       }
  479.    }
  480.  
  481.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  482.  
  483.    return GL_TRUE;
  484. }
  485.  
  486. static void
  487. slow_read_rgba_pixels( struct gl_context *ctx,
  488.                        GLint x, GLint y,
  489.                        GLsizei width, GLsizei height,
  490.                        GLenum format, GLenum type,
  491.                        GLvoid *pixels,
  492.                        const struct gl_pixelstore_attrib *packing,
  493.                        GLbitfield transferOps )
  494. {
  495.    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
  496.    const gl_format rbFormat = _mesa_get_srgb_format_linear(rb->Format);
  497.    void *rgba;
  498.    GLubyte *dst, *map;
  499.    int dstStride, stride, j;
  500.    GLboolean dst_is_integer = _mesa_is_enum_format_integer(format);
  501.    GLboolean dst_is_uint = _mesa_is_format_unsigned(rbFormat);
  502.  
  503.    dstStride = _mesa_image_row_stride(packing, width, format, type);
  504.    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
  505.                                            format, type, 0, 0);
  506.  
  507.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  508.                                &map, &stride);
  509.    if (!map) {
  510.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  511.       return;
  512.    }
  513.  
  514.    rgba = malloc(width * MAX_PIXEL_BYTES);
  515.    if (!rgba)
  516.       goto done;
  517.  
  518.    for (j = 0; j < height; j++) {
  519.       if (dst_is_integer) {
  520.          _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba);
  521.          _mesa_rebase_rgba_uint(width, (GLuint (*)[4]) rgba,
  522.                                 rb->_BaseFormat);
  523.          if (dst_is_uint) {
  524.             _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format,
  525.                                             type, dst);
  526.          } else {
  527.             _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format,
  528.                                            type, dst);
  529.          }
  530.       } else {
  531.          _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba);
  532.          _mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba,
  533.                                  rb->_BaseFormat);
  534.          _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
  535.                                     type, dst, packing, transferOps);
  536.       }
  537.       dst += dstStride;
  538.       map += stride;
  539.    }
  540.  
  541.    free(rgba);
  542.  
  543. done:
  544.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  545. }
  546.  
  547. /*
  548.  * Read R, G, B, A, RGB, L, or LA pixels.
  549.  */
  550. static void
  551. read_rgba_pixels( struct gl_context *ctx,
  552.                   GLint x, GLint y,
  553.                   GLsizei width, GLsizei height,
  554.                   GLenum format, GLenum type, GLvoid *pixels,
  555.                   const struct gl_pixelstore_attrib *packing )
  556. {
  557.    GLbitfield transferOps;
  558.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  559.    struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
  560.  
  561.    if (!rb)
  562.       return;
  563.  
  564.    transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type,
  565.                                              GL_FALSE);
  566.  
  567.    /* Try the optimized paths first. */
  568.    if (!transferOps &&
  569.        read_rgba_pixels_swizzle(ctx, x, y, width, height,
  570.                                     format, type, pixels, packing)) {
  571.       return;
  572.    }
  573.  
  574.    slow_read_rgba_pixels(ctx, x, y, width, height,
  575.                          format, type, pixels, packing, transferOps);
  576. }
  577.  
  578. /**
  579.  * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
  580.  * data (possibly swapping 8/24 vs 24/8 as we go).
  581.  */
  582. static GLboolean
  583. fast_read_depth_stencil_pixels(struct gl_context *ctx,
  584.                                GLint x, GLint y,
  585.                                GLsizei width, GLsizei height,
  586.                                GLubyte *dst, int dstStride)
  587. {
  588.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  589.    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  590.    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  591.    GLubyte *map;
  592.    int stride, i;
  593.  
  594.    if (rb != stencilRb)
  595.       return GL_FALSE;
  596.  
  597.    if (rb->Format != MESA_FORMAT_Z24_S8 &&
  598.        rb->Format != MESA_FORMAT_S8_Z24)
  599.       return GL_FALSE;
  600.  
  601.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
  602.                                &map, &stride);
  603.    if (!map) {
  604.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  605.       return GL_TRUE;  /* don't bother trying the slow path */
  606.    }
  607.  
  608.    for (i = 0; i < height; i++) {
  609.       _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
  610.                                                map, (GLuint *)dst);
  611.       map += stride;
  612.       dst += dstStride;
  613.    }
  614.  
  615.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  616.  
  617.    return GL_TRUE;
  618. }
  619.  
  620.  
  621. /**
  622.  * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
  623.  * copy the integer data directly instead of converting depth to float and
  624.  * re-packing.
  625.  */
  626. static GLboolean
  627. fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
  628.                                         GLint x, GLint y,
  629.                                         GLsizei width, GLsizei height,
  630.                                         uint32_t *dst, int dstStride)
  631. {
  632.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  633.    struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  634.    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  635.    GLubyte *depthMap, *stencilMap, *stencilVals;
  636.    int depthStride, stencilStride, i, j;
  637.  
  638.    if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
  639.       return GL_FALSE;
  640.  
  641.    ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
  642.                                GL_MAP_READ_BIT, &depthMap, &depthStride);
  643.    if (!depthMap) {
  644.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  645.       return GL_TRUE;  /* don't bother trying the slow path */
  646.    }
  647.  
  648.    ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
  649.                                GL_MAP_READ_BIT, &stencilMap, &stencilStride);
  650.    if (!stencilMap) {
  651.       ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
  652.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  653.       return GL_TRUE;  /* don't bother trying the slow path */
  654.    }
  655.  
  656.    stencilVals = malloc(width * sizeof(GLubyte));
  657.  
  658.    if (stencilVals) {
  659.       for (j = 0; j < height; j++) {
  660.          _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
  661.          _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
  662.                                         stencilMap, stencilVals);
  663.  
  664.          for (i = 0; i < width; i++) {
  665.             dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
  666.          }
  667.  
  668.          depthMap += depthStride;
  669.          stencilMap += stencilStride;
  670.          dst += dstStride / 4;
  671.       }
  672.    }
  673.    else {
  674.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  675.    }
  676.  
  677.    free(stencilVals);
  678.  
  679.    ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
  680.    ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
  681.  
  682.    return GL_TRUE;
  683. }
  684.  
  685. static void
  686. slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
  687.                                         GLint x, GLint y,
  688.                                         GLsizei width, GLsizei height,
  689.                                         GLenum type,
  690.                                         const struct gl_pixelstore_attrib *packing,
  691.                                         GLubyte *dst, int dstStride)
  692. {
  693.    struct gl_framebuffer *fb = ctx->ReadBuffer;
  694.    struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  695.    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  696.    GLubyte *depthMap, *stencilMap;
  697.    int depthStride, stencilStride, j;
  698.    GLubyte *stencilVals;
  699.    GLfloat *depthVals;
  700.  
  701.  
  702.    /* The depth and stencil buffers might be separate, or a single buffer.
  703.     * If one buffer, only map it once.
  704.     */
  705.    ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
  706.                                GL_MAP_READ_BIT, &depthMap, &depthStride);
  707.    if (!depthMap) {
  708.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  709.       return;
  710.    }
  711.  
  712.    if (stencilRb != depthRb) {
  713.       ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
  714.                                   GL_MAP_READ_BIT, &stencilMap,
  715.                                   &stencilStride);
  716.       if (!stencilMap) {
  717.          ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
  718.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  719.          return;
  720.       }
  721.    }
  722.    else {
  723.       stencilMap = depthMap;
  724.       stencilStride = depthStride;
  725.    }
  726.  
  727.    stencilVals = malloc(width * sizeof(GLubyte));
  728.    depthVals = malloc(width * sizeof(GLfloat));
  729.  
  730.    if (stencilVals && depthVals) {
  731.       for (j = 0; j < height; j++) {
  732.          _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
  733.          _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
  734.                                         stencilMap, stencilVals);
  735.  
  736.          _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
  737.                                        depthVals, stencilVals, packing);
  738.  
  739.          depthMap += depthStride;
  740.          stencilMap += stencilStride;
  741.          dst += dstStride;
  742.       }
  743.    }
  744.    else {
  745.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
  746.    }
  747.  
  748.    free(stencilVals);
  749.    free(depthVals);
  750.  
  751.    ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
  752.    if (stencilRb != depthRb) {
  753.       ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
  754.    }
  755. }
  756.  
  757.  
  758. /**
  759.  * Read combined depth/stencil values.
  760.  * We'll have already done error checking to be sure the expected
  761.  * depth and stencil buffers really exist.
  762.  */
  763. static void
  764. read_depth_stencil_pixels(struct gl_context *ctx,
  765.                           GLint x, GLint y,
  766.                           GLsizei width, GLsizei height,
  767.                           GLenum type, GLvoid *pixels,
  768.                           const struct gl_pixelstore_attrib *packing )
  769. {
  770.    const GLboolean scaleOrBias
  771.       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
  772.    const GLboolean stencilTransfer = ctx->Pixel.IndexShift
  773.       || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
  774.    GLubyte *dst;
  775.    int dstStride;
  776.  
  777.    dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
  778.                                            width, height,
  779.                                            GL_DEPTH_STENCIL_EXT,
  780.                                            type, 0, 0);
  781.    dstStride = _mesa_image_row_stride(packing, width,
  782.                                       GL_DEPTH_STENCIL_EXT, type);
  783.  
  784.    /* Fast 24/8 reads. */
  785.    if (type == GL_UNSIGNED_INT_24_8 &&
  786.        !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
  787.       if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
  788.                                          dst, dstStride))
  789.          return;
  790.  
  791.       if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
  792.                                                   (uint32_t *)dst, dstStride))
  793.          return;
  794.    }
  795.  
  796.    slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
  797.                                            type, packing,
  798.                                            dst, dstStride);
  799. }
  800.  
  801.  
  802.  
  803. /**
  804.  * Software fallback routine for ctx->Driver.ReadPixels().
  805.  * By time we get here, all error checking will have been done.
  806.  */
  807. void
  808. _mesa_readpixels(struct gl_context *ctx,
  809.                  GLint x, GLint y, GLsizei width, GLsizei height,
  810.                  GLenum format, GLenum type,
  811.                  const struct gl_pixelstore_attrib *packing,
  812.                  GLvoid *pixels)
  813. {
  814.    struct gl_pixelstore_attrib clippedPacking = *packing;
  815.  
  816.    if (ctx->NewState)
  817.       _mesa_update_state(ctx);
  818.  
  819.    /* Do all needed clipping here, so that we can forget about it later */
  820.    if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
  821.  
  822.       pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
  823.  
  824.       if (pixels) {
  825.          /* Try memcpy first. */
  826.          if (readpixels_memcpy(ctx, x, y, width, height, format, type,
  827.                                pixels, packing)) {
  828.             _mesa_unmap_pbo_dest(ctx, &clippedPacking);
  829.             return;
  830.          }
  831.  
  832.          /* Otherwise take the slow path. */
  833.          switch (format) {
  834.          case GL_STENCIL_INDEX:
  835.             read_stencil_pixels(ctx, x, y, width, height, type, pixels,
  836.                                 &clippedPacking);
  837.             break;
  838.          case GL_DEPTH_COMPONENT:
  839.             read_depth_pixels(ctx, x, y, width, height, type, pixels,
  840.                               &clippedPacking);
  841.             break;
  842.          case GL_DEPTH_STENCIL_EXT:
  843.             read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
  844.                                       &clippedPacking);
  845.             break;
  846.          default:
  847.             /* all other formats should be color formats */
  848.             read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
  849.                              &clippedPacking);
  850.          }
  851.  
  852.          _mesa_unmap_pbo_dest(ctx, &clippedPacking);
  853.       }
  854.    }
  855. }
  856.  
  857.  
  858. static GLenum
  859. read_pixels_es3_error_check(GLenum format, GLenum type,
  860.                             const struct gl_renderbuffer *rb)
  861. {
  862.    const GLenum internalFormat = rb->InternalFormat;
  863.    const GLenum data_type = _mesa_get_format_datatype(rb->Format);
  864.    GLboolean is_unsigned_int = GL_FALSE;
  865.    GLboolean is_signed_int = GL_FALSE;
  866.  
  867.    if (!_mesa_is_color_format(internalFormat)) {
  868.       return GL_INVALID_OPERATION;
  869.    }
  870.  
  871.    is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
  872.    if (!is_unsigned_int) {
  873.       is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
  874.    }
  875.  
  876.    switch (format) {
  877.    case GL_RGBA:
  878.       if (type == GL_FLOAT && data_type == GL_FLOAT)
  879.          return GL_NO_ERROR; /* EXT_color_buffer_float */
  880.       if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
  881.          return GL_NO_ERROR;
  882.       if (internalFormat == GL_RGB10_A2 &&
  883.           type == GL_UNSIGNED_INT_2_10_10_10_REV)
  884.          return GL_NO_ERROR;
  885.       if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
  886.          return GL_NO_ERROR;
  887.       break;
  888.    case GL_BGRA:
  889.       /* GL_EXT_read_format_bgra */
  890.       if (type == GL_UNSIGNED_BYTE ||
  891.           type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
  892.           type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
  893.          return GL_NO_ERROR;
  894.       break;
  895.    case GL_RGBA_INTEGER:
  896.       if ((is_signed_int && type == GL_INT) ||
  897.           (is_unsigned_int && type == GL_UNSIGNED_INT))
  898.          return GL_NO_ERROR;
  899.       break;
  900.    }
  901.  
  902.    return GL_INVALID_OPERATION;
  903. }
  904.  
  905.  
  906. void GLAPIENTRY
  907. _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
  908.                       GLenum format, GLenum type, GLsizei bufSize,
  909.                       GLvoid *pixels )
  910. {
  911.    GLenum err = GL_NO_ERROR;
  912.    struct gl_renderbuffer *rb;
  913.  
  914.    GET_CURRENT_CONTEXT(ctx);
  915.  
  916.    FLUSH_VERTICES(ctx, 0);
  917.    FLUSH_CURRENT(ctx, 0);
  918.  
  919.    if (MESA_VERBOSE & VERBOSE_API)
  920.       _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
  921.                   width, height,
  922.                   _mesa_lookup_enum_by_nr(format),
  923.                   _mesa_lookup_enum_by_nr(type),
  924.                   pixels);
  925.  
  926.    if (width < 0 || height < 0) {
  927.       _mesa_error( ctx, GL_INVALID_VALUE,
  928.                    "glReadPixels(width=%d height=%d)", width, height );
  929.       return;
  930.    }
  931.  
  932.    if (ctx->NewState)
  933.       _mesa_update_state(ctx);
  934.  
  935.    if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  936.       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
  937.                   "glReadPixels(incomplete framebuffer)" );
  938.       return;
  939.    }
  940.  
  941.    rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
  942.    if (rb == NULL) {
  943.       _mesa_error(ctx, GL_INVALID_OPERATION,
  944.                   "glReadPixels(read buffer)");
  945.       return;
  946.    }
  947.  
  948.    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
  949.     * combinations of format and type that can be used.
  950.     *
  951.     * Technically, only two combinations are actually allowed:
  952.     * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
  953.     * preferred combination.  This code doesn't know what that preferred
  954.     * combination is, and Mesa can handle anything valid.  Just work instead.
  955.     */
  956.    if (_mesa_is_gles(ctx)) {
  957.       if (ctx->API == API_OPENGLES2 &&
  958.           _mesa_is_color_format(format) &&
  959.           _mesa_get_color_read_format(ctx) == format &&
  960.           _mesa_get_color_read_type(ctx) == type) {
  961.          err = GL_NO_ERROR;
  962.       } else if (ctx->Version < 30) {
  963.          err = _mesa_es_error_check_format_and_type(format, type, 2);
  964.          if (err == GL_NO_ERROR) {
  965.             if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
  966.                err = GL_INVALID_OPERATION;
  967.             }
  968.          }
  969.       } else {
  970.          err = read_pixels_es3_error_check(format, type, rb);
  971.       }
  972.  
  973.       if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT
  974.           || format == GL_DEPTH_STENCIL)) {
  975.          err = GL_INVALID_ENUM;
  976.       }
  977.  
  978.       if (err != GL_NO_ERROR) {
  979.          _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
  980.                      _mesa_lookup_enum_by_nr(format),
  981.                      _mesa_lookup_enum_by_nr(type));
  982.          return;
  983.       }
  984.    }
  985.  
  986.    err = _mesa_error_check_format_and_type(ctx, format, type);
  987.    if (err != GL_NO_ERROR) {
  988.       _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
  989.                   _mesa_lookup_enum_by_nr(format),
  990.                   _mesa_lookup_enum_by_nr(type));
  991.       return;
  992.    }
  993.  
  994.    if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
  995.        ctx->ReadBuffer->Visual.samples > 0) {
  996.       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
  997.       return;
  998.    }
  999.  
  1000.    if (!_mesa_source_buffer_exists(ctx, format)) {
  1001.       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
  1002.       return;
  1003.    }
  1004.  
  1005.    /* Check that the destination format and source buffer are both
  1006.     * integer-valued or both non-integer-valued.
  1007.     */
  1008.    if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
  1009.       const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
  1010.       const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
  1011.       const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
  1012.       if (dstInteger != srcInteger) {
  1013.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1014.                      "glReadPixels(integer / non-integer format mismatch");
  1015.          return;
  1016.       }
  1017.    }
  1018.  
  1019.    if (width == 0 || height == 0)
  1020.       return; /* nothing to do */
  1021.  
  1022.    if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
  1023.                                   format, type, bufSize, pixels)) {
  1024.       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
  1025.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1026.                      "glReadPixels(out of bounds PBO access)");
  1027.       } else {
  1028.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1029.                      "glReadnPixelsARB(out of bounds access:"
  1030.                      " bufSize (%d) is too small)", bufSize);
  1031.       }
  1032.       return;
  1033.    }
  1034.  
  1035.    if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
  1036.        _mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
  1037.       /* buffer is mapped - that's an error */
  1038.       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
  1039.       return;
  1040.    }
  1041.  
  1042.    ctx->Driver.ReadPixels(ctx, x, y, width, height,
  1043.                           format, type, &ctx->Pack, pixels);
  1044. }
  1045.  
  1046. void GLAPIENTRY
  1047. _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
  1048.                   GLenum format, GLenum type, GLvoid *pixels )
  1049. {
  1050.    _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
  1051. }
  1052.