• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 "pixel.h"
40 #include "state.h"
41 #include "glformats.h"
42 #include "fbobject.h"
43 #include "format_utils.h"
44 #include "pixeltransfer.h"
45 
46 
47 /**
48  * Return true if the conversion L=R+G+B is needed.
49  */
50 GLboolean
_mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,GLenum dstBaseFormat)51 _mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,
52                                        GLenum dstBaseFormat)
53 {
54    return (srcBaseFormat == GL_RG ||
55            srcBaseFormat == GL_RGB ||
56            srcBaseFormat == GL_RGBA) &&
57           (dstBaseFormat == GL_LUMINANCE ||
58            dstBaseFormat == GL_LUMINANCE_ALPHA);
59 }
60 
61 /**
62  * Return true if the conversion L,I to RGB conversion is needed.
63  */
64 GLboolean
_mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,GLenum dstBaseFormat)65 _mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,
66                                        GLenum dstBaseFormat)
67 {
68    return (srcBaseFormat == GL_LUMINANCE ||
69            srcBaseFormat == GL_LUMINANCE_ALPHA ||
70            srcBaseFormat == GL_INTENSITY) &&
71           (dstBaseFormat == GL_GREEN ||
72            dstBaseFormat == GL_BLUE ||
73            dstBaseFormat == GL_RG ||
74            dstBaseFormat == GL_RGB ||
75            dstBaseFormat == GL_BGR ||
76            dstBaseFormat == GL_RGBA ||
77            dstBaseFormat == GL_BGRA);
78 }
79 
80 /**
81  * Return transfer op flags for this ReadPixels operation.
82  */
83 GLbitfield
_mesa_get_readpixels_transfer_ops(const struct gl_context * ctx,mesa_format texFormat,GLenum format,GLenum type,GLboolean uses_blit)84 _mesa_get_readpixels_transfer_ops(const struct gl_context *ctx,
85                                   mesa_format texFormat,
86                                   GLenum format, GLenum type,
87                                   GLboolean uses_blit)
88 {
89    GLbitfield transferOps = ctx->_ImageTransferState;
90    GLenum srcBaseFormat = _mesa_get_format_base_format(texFormat);
91    GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
92 
93    if (format == GL_DEPTH_COMPONENT ||
94        format == GL_DEPTH_STENCIL ||
95        format == GL_STENCIL_INDEX) {
96       return 0;
97    }
98 
99    /* Pixel transfer ops (scale, bias, table lookup) do not apply
100     * to integer formats.
101     */
102    if (_mesa_is_enum_format_integer(format)) {
103       return 0;
104    }
105 
106    if (uses_blit) {
107       /* For blit-based ReadPixels packing, the clamping is done automatically
108        * unless the type is float. */
109       if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
110           (type == GL_FLOAT || type == GL_HALF_FLOAT ||
111            type == GL_UNSIGNED_INT_10F_11F_11F_REV)) {
112          transferOps |= IMAGE_CLAMP_BIT;
113       }
114    }
115    else {
116       /* For CPU-based ReadPixels packing, the clamping must always be done
117        * for non-float types, */
118       if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) ||
119           (type != GL_FLOAT && type != GL_HALF_FLOAT &&
120            type != GL_UNSIGNED_INT_10F_11F_11F_REV)) {
121          transferOps |= IMAGE_CLAMP_BIT;
122       }
123 
124       /* For SNORM formats we only clamp if `type` is signed and clamp is `true` */
125       if (!_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
126           _mesa_get_format_datatype(texFormat) == GL_SIGNED_NORMALIZED &&
127           (type == GL_BYTE || type == GL_SHORT || type == GL_INT)) {
128          transferOps &= ~IMAGE_CLAMP_BIT;
129       }
130    }
131 
132    /* If the format is unsigned normalized, we can ignore clamping
133     * because the values are already in the range [0,1] so it won't
134     * have any effect anyway.
135     */
136    if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
137        !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat, dstBaseFormat)) {
138       transferOps &= ~IMAGE_CLAMP_BIT;
139    }
140 
141    return transferOps;
142 }
143 
144 
145 /**
146  * Return true if memcpy cannot be used for ReadPixels.
147  *
148  * If uses_blit is true, the function returns true if a simple 3D engine blit
149  * cannot be used for ReadPixels packing.
150  *
151  * NOTE: This doesn't take swizzling and format conversions between
152  *       the readbuffer and the pixel pack buffer into account.
153  */
154 GLboolean
_mesa_readpixels_needs_slow_path(const struct gl_context * ctx,GLenum format,GLenum type,GLboolean uses_blit)155 _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
156                                  GLenum type, GLboolean uses_blit)
157 {
158    struct gl_renderbuffer *rb =
159          _mesa_get_read_renderbuffer_for_format(ctx, format);
160    GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
161 
162    assert(rb);
163 
164    /* There are different rules depending on the base format. */
165    switch (format) {
166    case GL_DEPTH_STENCIL:
167       return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
168              ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
169              ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
170              ctx->Pixel.MapStencilFlag;
171 
172    case GL_DEPTH_COMPONENT:
173       return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
174 
175    case GL_STENCIL_INDEX:
176       return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
177              ctx->Pixel.MapStencilFlag;
178 
179    default:
180       /* Color formats. */
181       if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat,
182                                                  dstBaseFormat)) {
183          return GL_TRUE;
184       }
185 
186       /* And finally, see if there are any transfer ops. */
187       return _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, type,
188                                                uses_blit) != 0;
189    }
190    return GL_FALSE;
191 }
192 
193 
194 static GLboolean
readpixels_can_use_memcpy(const struct gl_context * ctx,GLenum format,GLenum type,const struct gl_pixelstore_attrib * packing)195 readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
196                           const struct gl_pixelstore_attrib *packing)
197 {
198    struct gl_renderbuffer *rb =
199          _mesa_get_read_renderbuffer_for_format(ctx, format);
200 
201    assert(rb);
202 
203    if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
204       return GL_FALSE;
205    }
206 
207    /* The base internal format and the base Mesa format must match. */
208    if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
209       return GL_FALSE;
210    }
211 
212    /* The Mesa format must match the input format and type. */
213    if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
214                                              packing->SwapBytes, NULL)) {
215       return GL_FALSE;
216    }
217 
218    return GL_TRUE;
219 }
220 
221 
222 static GLboolean
readpixels_memcpy(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)223 readpixels_memcpy(struct gl_context *ctx,
224                   GLint x, GLint y,
225                   GLsizei width, GLsizei height,
226                   GLenum format, GLenum type,
227                   GLvoid *pixels,
228                   const struct gl_pixelstore_attrib *packing)
229 {
230    struct gl_renderbuffer *rb =
231          _mesa_get_read_renderbuffer_for_format(ctx, format);
232    GLubyte *dst, *map;
233    int dstStride, stride, j, texelBytes, bytesPerRow;
234 
235    /* Fail if memcpy cannot be used. */
236    if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
237       return GL_FALSE;
238    }
239 
240    dstStride = _mesa_image_row_stride(packing, width, format, type);
241    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
242 					   format, type, 0, 0);
243 
244    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
245 			       &map, &stride, ctx->ReadBuffer->FlipY);
246    if (!map) {
247       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
248       return GL_TRUE;  /* don't bother trying the slow path */
249    }
250 
251    texelBytes = _mesa_get_format_bytes(rb->Format);
252    bytesPerRow = texelBytes * width;
253 
254    /* memcpy*/
255    if (dstStride == stride && dstStride == bytesPerRow) {
256       memcpy(dst, map, bytesPerRow * height);
257    } else {
258       for (j = 0; j < height; j++) {
259          memcpy(dst, map, bytesPerRow);
260          dst += dstStride;
261          map += stride;
262       }
263    }
264 
265    ctx->Driver.UnmapRenderbuffer(ctx, rb);
266    return GL_TRUE;
267 }
268 
269 
270 /**
271  * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
272  * GL_UNSIGNED_INT.
273  */
274 static GLboolean
read_uint_depth_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)275 read_uint_depth_pixels( struct gl_context *ctx,
276 			GLint x, GLint y,
277 			GLsizei width, GLsizei height,
278 			GLenum type, GLvoid *pixels,
279 			const struct gl_pixelstore_attrib *packing )
280 {
281    struct gl_framebuffer *fb = ctx->ReadBuffer;
282    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
283    GLubyte *map, *dst;
284    int stride, dstStride, j;
285 
286    if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F)
287       return GL_FALSE;
288 
289    if (packing->SwapBytes)
290       return GL_FALSE;
291 
292    if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
293       return GL_FALSE;
294 
295    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
296 			       &map, &stride, fb->FlipY);
297 
298    if (!map) {
299       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
300       return GL_TRUE;  /* don't bother trying the slow path */
301    }
302 
303    dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
304    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
305 					   GL_DEPTH_COMPONENT, type, 0, 0);
306 
307    for (j = 0; j < height; j++) {
308       _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
309 
310       map += stride;
311       dst += dstStride;
312    }
313    ctx->Driver.UnmapRenderbuffer(ctx, rb);
314 
315    return GL_TRUE;
316 }
317 
318 /**
319  * Read pixels for format=GL_DEPTH_COMPONENT.
320  */
321 static void
read_depth_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)322 read_depth_pixels( struct gl_context *ctx,
323                    GLint x, GLint y,
324                    GLsizei width, GLsizei height,
325                    GLenum type, GLvoid *pixels,
326                    const struct gl_pixelstore_attrib *packing )
327 {
328    struct gl_framebuffer *fb = ctx->ReadBuffer;
329    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
330    GLint j;
331    GLubyte *dst, *map;
332    int dstStride, stride;
333    GLfloat *depthValues;
334 
335    if (!rb)
336       return;
337 
338    /* clipping should have been done already */
339    assert(x >= 0);
340    assert(y >= 0);
341    assert(x + width <= (GLint) rb->Width);
342    assert(y + height <= (GLint) rb->Height);
343 
344    if (type == GL_UNSIGNED_INT &&
345        read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
346       return;
347    }
348 
349    dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
350    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
351 					   GL_DEPTH_COMPONENT, type, 0, 0);
352 
353    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
354 			       &map, &stride, fb->FlipY);
355    if (!map) {
356       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
357       return;
358    }
359 
360    depthValues = malloc(width * sizeof(GLfloat));
361 
362    if (depthValues) {
363       /* General case (slower) */
364       for (j = 0; j < height; j++, y++) {
365          _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
366          _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
367 
368          dst += dstStride;
369          map += stride;
370       }
371    }
372    else {
373       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
374    }
375 
376    free(depthValues);
377 
378    ctx->Driver.UnmapRenderbuffer(ctx, rb);
379 }
380 
381 
382 /**
383  * Read pixels for format=GL_STENCIL_INDEX.
384  */
385 static void
read_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)386 read_stencil_pixels( struct gl_context *ctx,
387                      GLint x, GLint y,
388                      GLsizei width, GLsizei height,
389                      GLenum type, GLvoid *pixels,
390                      const struct gl_pixelstore_attrib *packing )
391 {
392    struct gl_framebuffer *fb = ctx->ReadBuffer;
393    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
394    GLint j;
395    GLubyte *map, *stencil;
396    GLint stride;
397 
398    if (!rb)
399       return;
400 
401    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
402 			       &map, &stride, fb->FlipY);
403    if (!map) {
404       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
405       return;
406    }
407 
408    stencil = malloc(width * sizeof(GLubyte));
409 
410    if (stencil) {
411       /* process image row by row */
412       for (j = 0; j < height; j++) {
413          GLvoid *dest;
414 
415          _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
416          dest = _mesa_image_address2d(packing, pixels, width, height,
417                                       GL_STENCIL_INDEX, type, j, 0);
418 
419          _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
420 
421          map += stride;
422       }
423    }
424    else {
425       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
426    }
427 
428    free(stencil);
429 
430    ctx->Driver.UnmapRenderbuffer(ctx, rb);
431 }
432 
433 /*
434  * Read R, G, B, A, RGB, L, or LA pixels.
435  */
436 static void
read_rgba_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)437 read_rgba_pixels( struct gl_context *ctx,
438                   GLint x, GLint y,
439                   GLsizei width, GLsizei height,
440                   GLenum format, GLenum type, GLvoid *pixels,
441                   const struct gl_pixelstore_attrib *packing )
442 {
443    GLbitfield transferOps;
444    bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
445    int dst_stride, src_stride, rb_stride;
446    uint32_t dst_format, src_format;
447    GLubyte *dst, *map;
448    mesa_format rb_format;
449    bool needs_rgba;
450    void *rgba, *src;
451    bool src_is_uint = false;
452    uint8_t rebase_swizzle[4];
453    struct gl_framebuffer *fb = ctx->ReadBuffer;
454    struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
455    GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
456 
457    if (!rb)
458       return;
459 
460    transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format,
461                                                    type, GL_FALSE);
462    /* Describe the dst format */
463    dst_is_integer = _mesa_is_enum_format_integer(format);
464    dst_stride = _mesa_image_row_stride(packing, width, format, type);
465    dst_format = _mesa_format_from_format_and_type(format, type);
466    convert_rgb_to_lum =
467       _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat);
468    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
469                                            format, type, 0, 0);
470 
471    /* Map the source render buffer */
472    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
473                                &map, &rb_stride, fb->FlipY);
474    if (!map) {
475       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
476       return;
477    }
478    rb_format = _mesa_get_srgb_format_linear(rb->Format);
479 
480    /*
481     * Depending on the base formats involved in the conversion we might need to
482     * rebase some values, so for these formats we compute a rebase swizzle.
483     */
484    if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) {
485       needs_rebase = true;
486       rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
487       rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
488       rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
489       rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
490    } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) {
491       needs_rebase = true;
492       rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
493       rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
494       rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
495       rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W;
496    } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) {
497       needs_rebase =
498          _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat,
499                                                         rebase_swizzle);
500    } else {
501       needs_rebase = false;
502    }
503 
504    /* Since _mesa_format_convert does not handle transferOps we need to handle
505     * them before we call the function. This requires to convert to RGBA float
506     * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is
507     * integer transferOps do not apply.
508     *
509     * Converting to luminance also requires converting to RGBA first, so we can
510     * then compute luminance values as L=R+G+B. Notice that this is different
511     * from GetTexImage, where we compute L=R.
512     */
513    assert(!transferOps || (transferOps && !dst_is_integer));
514 
515    needs_rgba = transferOps || convert_rgb_to_lum;
516    rgba = NULL;
517    if (needs_rgba) {
518       uint32_t rgba_format;
519       int rgba_stride;
520       bool need_convert;
521 
522       /* Convert to RGBA float or int/uint depending on the type of the src */
523       if (dst_is_integer) {
524          src_is_uint = _mesa_is_format_unsigned(rb_format);
525          if (src_is_uint) {
526             rgba_format = RGBA32_UINT;
527             rgba_stride = width * 4 * sizeof(GLuint);
528          } else {
529             rgba_format = RGBA32_INT;
530             rgba_stride = width * 4 * sizeof(GLint);
531          }
532       } else {
533          rgba_format = RGBA32_FLOAT;
534          rgba_stride = width * 4 * sizeof(GLfloat);
535       }
536 
537       /* If we are lucky and the dst format matches the RGBA format we need to
538        * convert to, then we can convert directly into the dst buffer and avoid
539        * the final conversion/copy from the rgba buffer to the dst buffer.
540        */
541       if (dst_format == rgba_format &&
542           dst_stride == rgba_stride) {
543          need_convert = false;
544          rgba = dst;
545       } else {
546          need_convert = true;
547          rgba = malloc(height * rgba_stride);
548          if (!rgba) {
549             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
550             goto done_unmap;
551          }
552       }
553 
554       /* Convert to RGBA now */
555       _mesa_format_convert(rgba, rgba_format, rgba_stride,
556                            map, rb_format, rb_stride,
557                            width, height,
558                            needs_rebase ? rebase_swizzle : NULL);
559 
560       /* Handle transfer ops if necessary */
561       if (transferOps)
562          _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
563 
564       /* If we had to rebase, we have already taken care of that */
565       needs_rebase = false;
566 
567       /* If we were lucky and our RGBA conversion matches the dst format, then
568        * we are done.
569        */
570       if (!need_convert)
571          goto done_swap;
572 
573       /* Otherwise, we need to convert from RGBA to dst next */
574       src = rgba;
575       src_format = rgba_format;
576       src_stride = rgba_stride;
577    } else {
578       /* No RGBA conversion needed, convert directly to dst */
579       src = map;
580       src_format = rb_format;
581       src_stride = rb_stride;
582    }
583 
584    /* Do the conversion.
585     *
586     * If the dst format is Luminance, we need to do the conversion by computing
587     * L=R+G+B values.
588     */
589    if (!convert_rgb_to_lum) {
590       _mesa_format_convert(dst, dst_format, dst_stride,
591                            src, src_format, src_stride,
592                            width, height,
593                            needs_rebase ? rebase_swizzle : NULL);
594    } else if (!dst_is_integer) {
595       /* Compute float Luminance values from RGBA float */
596       int luminance_stride, luminance_bytes;
597       void *luminance;
598       uint32_t luminance_format;
599 
600       luminance_stride = width * sizeof(GLfloat);
601       if (format == GL_LUMINANCE_ALPHA)
602          luminance_stride *= 2;
603       luminance_bytes = height * luminance_stride;
604       luminance = malloc(luminance_bytes);
605       if (!luminance) {
606          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
607          free(rgba);
608          goto done_unmap;
609       }
610       _mesa_pack_luminance_from_rgba_float(width * height, src,
611                                            luminance, format, transferOps);
612 
613       /* Convert from Luminance float to dst (this will hadle type conversion
614        * from float to the type of dst if necessary)
615        */
616       luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT);
617       _mesa_format_convert(dst, dst_format, dst_stride,
618                            luminance, luminance_format, luminance_stride,
619                            width, height, NULL);
620       free(luminance);
621    } else {
622       _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint,
623                                              dst, format, type);
624    }
625 
626    free(rgba);
627 
628 done_swap:
629    /* Handle byte swapping if required */
630    if (packing->SwapBytes) {
631       _mesa_swap_bytes_2d_image(format, type, packing,
632                                 width, height, dst, dst);
633    }
634 
635 done_unmap:
636    ctx->Driver.UnmapRenderbuffer(ctx, rb);
637 }
638 
639 /**
640  * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
641  * data (possibly swapping 8/24 vs 24/8 as we go).
642  */
643 static GLboolean
fast_read_depth_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLubyte * dst,int dstStride)644 fast_read_depth_stencil_pixels(struct gl_context *ctx,
645 			       GLint x, GLint y,
646 			       GLsizei width, GLsizei height,
647 			       GLubyte *dst, int dstStride)
648 {
649    struct gl_framebuffer *fb = ctx->ReadBuffer;
650    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
651    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
652    GLubyte *map;
653    int stride, i;
654 
655    if (rb != stencilRb)
656       return GL_FALSE;
657 
658    if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
659        rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
660       return GL_FALSE;
661 
662    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
663 			       &map, &stride, fb->FlipY);
664    if (!map) {
665       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
666       return GL_TRUE;  /* don't bother trying the slow path */
667    }
668 
669    for (i = 0; i < height; i++) {
670       _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
671 					       map, (GLuint *)dst);
672       map += stride;
673       dst += dstStride;
674    }
675 
676    ctx->Driver.UnmapRenderbuffer(ctx, rb);
677 
678    return GL_TRUE;
679 }
680 
681 
682 /**
683  * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
684  * copy the integer data directly instead of converting depth to float and
685  * re-packing.
686  */
687 static GLboolean
fast_read_depth_stencil_pixels_separate(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,uint32_t * dst,int dstStride)688 fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
689 					GLint x, GLint y,
690 					GLsizei width, GLsizei height,
691 					uint32_t *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, *stencilVals;
697    int depthStride, stencilStride, i, j;
698 
699    if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
700       return GL_FALSE;
701 
702    ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
703 			       GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY);
704    if (!depthMap) {
705       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
706       return GL_TRUE;  /* don't bother trying the slow path */
707    }
708 
709    ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
710 			       GL_MAP_READ_BIT, &stencilMap, &stencilStride, fb->FlipY);
711    if (!stencilMap) {
712       ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
713       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
714       return GL_TRUE;  /* don't bother trying the slow path */
715    }
716 
717    stencilVals = malloc(width * sizeof(GLubyte));
718 
719    if (stencilVals) {
720       for (j = 0; j < height; j++) {
721          _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
722          _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
723                                         stencilMap, stencilVals);
724 
725          for (i = 0; i < width; i++) {
726             dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
727          }
728 
729          depthMap += depthStride;
730          stencilMap += stencilStride;
731          dst += dstStride / 4;
732       }
733    }
734    else {
735       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
736    }
737 
738    free(stencilVals);
739 
740    ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
741    ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
742 
743    return GL_TRUE;
744 }
745 
746 static void
slow_read_depth_stencil_pixels_separate(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,const struct gl_pixelstore_attrib * packing,GLubyte * dst,int dstStride)747 slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
748 					GLint x, GLint y,
749 					GLsizei width, GLsizei height,
750 					GLenum type,
751 					const struct gl_pixelstore_attrib *packing,
752 					GLubyte *dst, int dstStride)
753 {
754    struct gl_framebuffer *fb = ctx->ReadBuffer;
755    struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
756    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
757    GLubyte *depthMap, *stencilMap;
758    int depthStride, stencilStride, j;
759    GLubyte *stencilVals;
760    GLfloat *depthVals;
761 
762 
763    /* The depth and stencil buffers might be separate, or a single buffer.
764     * If one buffer, only map it once.
765     */
766    ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
767 			       GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY);
768    if (!depthMap) {
769       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
770       return;
771    }
772 
773    if (stencilRb != depthRb) {
774       ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
775                                   GL_MAP_READ_BIT, &stencilMap,
776                                   &stencilStride, fb->FlipY);
777       if (!stencilMap) {
778          ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
779          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
780          return;
781       }
782    }
783    else {
784       stencilMap = depthMap;
785       stencilStride = depthStride;
786    }
787 
788    stencilVals = malloc(width * sizeof(GLubyte));
789    depthVals = malloc(width * sizeof(GLfloat));
790 
791    if (stencilVals && depthVals) {
792       for (j = 0; j < height; j++) {
793          _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
794          _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
795                                         stencilMap, stencilVals);
796 
797          _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
798                                        depthVals, stencilVals, packing);
799 
800          depthMap += depthStride;
801          stencilMap += stencilStride;
802          dst += dstStride;
803       }
804    }
805    else {
806       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
807    }
808 
809    free(stencilVals);
810    free(depthVals);
811 
812    ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
813    if (stencilRb != depthRb) {
814       ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
815    }
816 }
817 
818 
819 /**
820  * Read combined depth/stencil values.
821  * We'll have already done error checking to be sure the expected
822  * depth and stencil buffers really exist.
823  */
824 static void
read_depth_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)825 read_depth_stencil_pixels(struct gl_context *ctx,
826                           GLint x, GLint y,
827                           GLsizei width, GLsizei height,
828                           GLenum type, GLvoid *pixels,
829                           const struct gl_pixelstore_attrib *packing )
830 {
831    const GLboolean scaleOrBias
832       = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F;
833    const GLboolean stencilTransfer = ctx->Pixel.IndexShift
834       || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
835    GLubyte *dst;
836    int dstStride;
837 
838    dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
839 					   width, height,
840 					   GL_DEPTH_STENCIL_EXT,
841 					   type, 0, 0);
842    dstStride = _mesa_image_row_stride(packing, width,
843 				      GL_DEPTH_STENCIL_EXT, type);
844 
845    /* Fast 24/8 reads. */
846    if (type == GL_UNSIGNED_INT_24_8 &&
847        !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
848       if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
849 					 dst, dstStride))
850 	 return;
851 
852       if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
853 						  (uint32_t *)dst, dstStride))
854 	 return;
855    }
856 
857    slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
858 					   type, packing,
859 					   dst, dstStride);
860 }
861 
862 
863 
864 /**
865  * Software fallback routine for ctx->Driver.ReadPixels().
866  * By time we get here, all error checking will have been done.
867  */
868 void
_mesa_readpixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * packing,GLvoid * pixels)869 _mesa_readpixels(struct gl_context *ctx,
870                  GLint x, GLint y, GLsizei width, GLsizei height,
871                  GLenum format, GLenum type,
872                  const struct gl_pixelstore_attrib *packing,
873                  GLvoid *pixels)
874 {
875    if (ctx->NewState)
876       _mesa_update_state(ctx);
877 
878    pixels = _mesa_map_pbo_dest(ctx, packing, pixels);
879 
880    if (pixels) {
881       /* Try memcpy first. */
882       if (readpixels_memcpy(ctx, x, y, width, height, format, type,
883                             pixels, packing)) {
884          _mesa_unmap_pbo_dest(ctx, packing);
885          return;
886       }
887 
888       /* Otherwise take the slow path. */
889       switch (format) {
890       case GL_STENCIL_INDEX:
891          read_stencil_pixels(ctx, x, y, width, height, type, pixels,
892                              packing);
893          break;
894       case GL_DEPTH_COMPONENT:
895          read_depth_pixels(ctx, x, y, width, height, type, pixels,
896                            packing);
897          break;
898       case GL_DEPTH_STENCIL_EXT:
899          read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
900                                    packing);
901          break;
902       default:
903          /* all other formats should be color formats */
904          read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
905                           packing);
906       }
907 
908       _mesa_unmap_pbo_dest(ctx, packing);
909    }
910 }
911 
912 
913 static GLenum
read_pixels_es3_error_check(struct gl_context * ctx,GLenum format,GLenum type,const struct gl_renderbuffer * rb)914 read_pixels_es3_error_check(struct gl_context *ctx, GLenum format, GLenum type,
915                             const struct gl_renderbuffer *rb)
916 {
917    const GLenum internalFormat = rb->InternalFormat;
918    const GLenum data_type = _mesa_get_format_datatype(rb->Format);
919    GLboolean is_unsigned_int = GL_FALSE;
920    GLboolean is_signed_int = GL_FALSE;
921    GLboolean is_float_depth = _mesa_has_depth_float_channel(internalFormat);
922 
923    is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
924    if (!is_unsigned_int) {
925       is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
926    }
927 
928    switch (format) {
929    case GL_RGBA:
930       if (type == GL_FLOAT && data_type == GL_FLOAT)
931          return GL_NO_ERROR; /* EXT_color_buffer_float */
932       if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
933          return GL_NO_ERROR;
934       if (internalFormat == GL_RGB10_A2 &&
935           type == GL_UNSIGNED_INT_2_10_10_10_REV)
936          return GL_NO_ERROR;
937       if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
938          return GL_NO_ERROR;
939       if (type == GL_UNSIGNED_SHORT) {
940          switch (internalFormat) {
941          case GL_R16:
942          case GL_RG16:
943          case GL_RGB16:
944          case GL_RGBA16:
945             if (_mesa_has_EXT_texture_norm16(ctx))
946                return GL_NO_ERROR;
947          }
948       }
949       if (type == GL_SHORT) {
950          switch (internalFormat) {
951          case GL_R16_SNORM:
952          case GL_RG16_SNORM:
953          case GL_RGBA16_SNORM:
954             if (_mesa_has_EXT_texture_norm16(ctx) &&
955                 _mesa_has_EXT_render_snorm(ctx))
956                return GL_NO_ERROR;
957          }
958       }
959       if (type == GL_BYTE) {
960          switch (internalFormat) {
961          case GL_R8_SNORM:
962          case GL_RG8_SNORM:
963          case GL_RGBA8_SNORM:
964             if (_mesa_has_EXT_render_snorm(ctx))
965                return GL_NO_ERROR;
966          }
967       }
968       if (type == GL_UNSIGNED_BYTE) {
969          switch (internalFormat) {
970          case GL_R8_SNORM:
971          case GL_RG8_SNORM:
972          case GL_RGBA8_SNORM:
973             if (_mesa_has_EXT_render_snorm(ctx))
974                return GL_NO_ERROR;
975          }
976       }
977       break;
978    case GL_BGRA:
979       /* GL_EXT_read_format_bgra */
980       if (type == GL_UNSIGNED_BYTE ||
981           type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
982           type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
983          return GL_NO_ERROR;
984       break;
985    case GL_RGBA_INTEGER:
986       if ((is_signed_int && type == GL_INT) ||
987           (is_unsigned_int && type == GL_UNSIGNED_INT))
988          return GL_NO_ERROR;
989       break;
990    case GL_DEPTH_STENCIL:
991       switch (type) {
992       case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
993          if (is_float_depth)
994             return GL_NO_ERROR;
995          break;
996       case GL_UNSIGNED_INT_24_8:
997          if (!is_float_depth)
998             return GL_NO_ERROR;
999          break;
1000       default:
1001          return GL_INVALID_ENUM;
1002       }
1003       break;
1004    case GL_DEPTH_COMPONENT:
1005       switch (type) {
1006       case GL_FLOAT:
1007          if (is_float_depth)
1008             return GL_NO_ERROR;
1009          break;
1010       case GL_UNSIGNED_SHORT:
1011       case GL_UNSIGNED_INT:
1012       case GL_UNSIGNED_INT_24_8:
1013          if (!is_float_depth)
1014             return GL_NO_ERROR;
1015          break;
1016       default:
1017          return GL_INVALID_ENUM;
1018       }
1019       break;
1020    case GL_STENCIL_INDEX:
1021       switch (type) {
1022       case GL_UNSIGNED_BYTE:
1023          return GL_NO_ERROR;
1024       default:
1025          return GL_INVALID_ENUM;
1026       }
1027       break;
1028    }
1029 
1030    return GL_INVALID_OPERATION;
1031 }
1032 
1033 
1034 static ALWAYS_INLINE void
read_pixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels,bool no_error)1035 read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
1036             GLenum type, GLsizei bufSize, GLvoid *pixels, bool no_error)
1037 {
1038    GLenum err = GL_NO_ERROR;
1039    struct gl_renderbuffer *rb;
1040    struct gl_pixelstore_attrib clippedPacking;
1041 
1042    GET_CURRENT_CONTEXT(ctx);
1043 
1044    FLUSH_VERTICES(ctx, 0, 0);
1045 
1046    if (MESA_VERBOSE & VERBOSE_API)
1047       _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
1048                   width, height,
1049                   _mesa_enum_to_string(format),
1050                   _mesa_enum_to_string(type),
1051                   pixels);
1052 
1053    if (!no_error && (width < 0 || height < 0)) {
1054       _mesa_error( ctx, GL_INVALID_VALUE,
1055                    "glReadPixels(width=%d height=%d)", width, height );
1056       return;
1057    }
1058 
1059    _mesa_update_pixel(ctx);
1060 
1061    if (ctx->NewState)
1062       _mesa_update_state(ctx);
1063 
1064    if (!no_error && ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1065       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1066                   "glReadPixels(incomplete framebuffer)" );
1067       return;
1068    }
1069 
1070    rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1071    if (!no_error) {
1072       if (rb == NULL) {
1073          _mesa_error(ctx, GL_INVALID_OPERATION,
1074                      "glReadPixels(read buffer)");
1075          return;
1076       }
1077 
1078       /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1079        * combinations of format and type that can be used.
1080        *
1081        * Technically, only two combinations are actually allowed:
1082        * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1083        * preferred combination.  This code doesn't know what that preferred
1084        * combination is, and Mesa can handle anything valid.  Just work instead.
1085        */
1086       if (_mesa_is_gles(ctx)) {
1087          if (ctx->API == API_OPENGLES2 &&
1088              _mesa_is_color_format(format) &&
1089              _mesa_get_color_read_format(ctx, NULL, "glReadPixels") == format &&
1090              _mesa_get_color_read_type(ctx, NULL, "glReadPixels") == type) {
1091             err = GL_NO_ERROR;
1092          } else if (ctx->Version < 30) {
1093             err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
1094             if (err == GL_NO_ERROR) {
1095                if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1096                   err = GL_INVALID_OPERATION;
1097                }
1098             }
1099          } else {
1100             err = read_pixels_es3_error_check(ctx, format, type, rb);
1101          }
1102 
1103          if (err != GL_NO_ERROR) {
1104             _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1105                         _mesa_enum_to_string(format),
1106                         _mesa_enum_to_string(type));
1107             return;
1108          }
1109       }
1110 
1111       err = _mesa_error_check_format_and_type(ctx, format, type);
1112       if (err != GL_NO_ERROR) {
1113          _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1114                      _mesa_enum_to_string(format),
1115                      _mesa_enum_to_string(type));
1116          return;
1117       }
1118 
1119       if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1120           ctx->ReadBuffer->Visual.samples > 0) {
1121          _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1122          return;
1123       }
1124 
1125       if (!_mesa_source_buffer_exists(ctx, format)) {
1126          _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1127          return;
1128       }
1129 
1130       /* Check that the destination format and source buffer are both
1131        * integer-valued or both non-integer-valued.
1132        */
1133       if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1134          const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1135          const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1136          const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1137          if (dstInteger != srcInteger) {
1138             _mesa_error(ctx, GL_INVALID_OPERATION,
1139                         "glReadPixels(integer / non-integer format mismatch");
1140             return;
1141          }
1142       }
1143    }
1144 
1145    /* Do all needed clipping here, so that we can forget about it later */
1146    clippedPacking = ctx->Pack;
1147    if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking))
1148       return; /* nothing to do */
1149 
1150    if (!no_error) {
1151       if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1152                                      format, type, bufSize, pixels)) {
1153          if (ctx->Pack.BufferObj) {
1154             _mesa_error(ctx, GL_INVALID_OPERATION,
1155                         "glReadPixels(out of bounds PBO access)");
1156          } else {
1157             _mesa_error(ctx, GL_INVALID_OPERATION,
1158                         "glReadnPixelsARB(out of bounds access:"
1159                         " bufSize (%d) is too small)", bufSize);
1160          }
1161          return;
1162       }
1163 
1164       if (ctx->Pack.BufferObj &&
1165           _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1166          /* buffer is mapped - that's an error */
1167          _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1168          return;
1169       }
1170    }
1171 
1172    ctx->Driver.ReadPixels(ctx, x, y, width, height,
1173                           format, type, &clippedPacking, pixels);
1174 }
1175 
1176 void GLAPIENTRY
_mesa_ReadnPixelsARB_no_error(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1177 _mesa_ReadnPixelsARB_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1178                               GLenum format, GLenum type, GLsizei bufSize,
1179                               GLvoid *pixels)
1180 {
1181    read_pixels(x, y, width, height, format, type, bufSize, pixels, true);
1182 }
1183 
1184 void GLAPIENTRY
_mesa_ReadnPixelsARB(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1185 _mesa_ReadnPixelsARB(GLint x, GLint y, GLsizei width, GLsizei height,
1186                      GLenum format, GLenum type, GLsizei bufSize,
1187                      GLvoid *pixels)
1188 {
1189    read_pixels(x, y, width, height, format, type, bufSize, pixels, false);
1190 }
1191 
1192 void GLAPIENTRY
_mesa_ReadPixels_no_error(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1193 _mesa_ReadPixels_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1194                           GLenum format, GLenum type, GLvoid *pixels)
1195 {
1196    _mesa_ReadnPixelsARB_no_error(x, y, width, height, format, type, INT_MAX,
1197                                  pixels);
1198 }
1199 
1200 void GLAPIENTRY
_mesa_ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1201 _mesa_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1202                  GLenum format, GLenum type, GLvoid *pixels)
1203 {
1204    _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1205 }
1206