_swrast_use_read_buffer(ctx);
+ /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
/* process image row by row */
+/**
+ * Read pixels for format=GL_DEPTH_COMPONENT.
+ */
static void
read_depth_pixels( GLcontext *ctx,
GLint x, GLint y,
return;
}
+ /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
if (type != GL_BYTE &&
}
-
+/**
+ * Read pixels for format=GL_STENCIL_INDEX.
+ */
static void
read_stencil_pixels( GLcontext *ctx,
GLint x, GLint y,
return;
}
+ /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
if (ctx->Visual.stencilBits <= 0) {
-/*
+/**
* Optimized glReadPixels for particular pixel formats:
* GL_UNSIGNED_BYTE, GL_RGBA
* when pixel scaling, biasing and mapping are disabled.
else
rowLength = width;
- /* horizontal clipping */
- if (srcX < 0) {
- skipPixels -= srcX;
- readWidth += srcX;
- srcX = 0;
- }
- if (srcX + readWidth > (GLint) ctx->ReadBuffer->Width)
- readWidth -= (srcX + readWidth - (GLint) ctx->ReadBuffer->Width);
- if (readWidth <= 0)
- return GL_TRUE;
-
- /* vertical clipping */
- if (srcY < 0) {
- skipRows -= srcY;
- readHeight += srcY;
- srcY = 0;
- }
- if (srcY + readHeight > (GLint) ctx->ReadBuffer->Height)
- readHeight -= (srcY + readHeight - (GLint) ctx->ReadBuffer->Height);
- if (readHeight <= 0)
- return GL_TRUE;
-
/*
* Ready to read!
* The window region at (destX, destY) of size (readWidth, readHeight)
return; /* done! */
}
+ /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
/* do error checking on pixel type, format was already checked by caller */
}
-
+/**
+ * Software fallback routine for ctx->Driver.ReadPixels().
+ * We wind up using the swrast->ReadSpan() routines to do the job.
+ */
void
_swrast_ReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLvoid *pixels )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ struct gl_pixelstore_attrib clippedPacking;
if (swrast->NewState)
_swrast_validate_derived( ctx );
- if (packing->BufferObj->Name) {
+ /* Do all needed clipping here, so that we can forget about it later */
+ clippedPacking = *packing;
+ if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height,
+ &clippedPacking.SkipPixels,
+ &clippedPacking.SkipRows)) {
+ /* The ReadPixels region is totally outside the window bounds */
+ return;
+ }
+
+ if (clippedPacking.BufferObj->Name) {
/* pack into PBO */
GLubyte *buf;
- if (!_mesa_validate_pbo_access(packing, width, height, 1,
+ if (!_mesa_validate_pbo_access(&clippedPacking, width, height, 1,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glReadPixels(invalid PBO access)");
}
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
GL_WRITE_ONLY_ARB,
- packing->BufferObj);
+ clippedPacking.BufferObj);
if (!buf) {
/* buffer is already mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
switch (format) {
case GL_COLOR_INDEX:
- read_index_pixels(ctx, x, y, width, height, type, pixels, packing);
+ read_index_pixels(ctx, x, y, width, height, type, pixels,
+ &clippedPacking);
break;
case GL_STENCIL_INDEX:
- read_stencil_pixels(ctx, x,y, width,height, type, pixels, packing);
+ read_stencil_pixels(ctx, x,y, width,height, type, pixels,
+ &clippedPacking);
break;
case GL_DEPTH_COMPONENT:
- read_depth_pixels(ctx, x, y, width, height, type, pixels, packing);
+ read_depth_pixels(ctx, x, y, width, height, type, pixels,
+ &clippedPacking);
break;
case GL_RED:
case GL_GREEN:
case GL_BGRA:
case GL_ABGR_EXT:
read_rgba_pixels(ctx, x, y, width, height,
- format, type, pixels, packing);
+ format, type, pixels, &clippedPacking);
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
RENDER_FINISH(swrast, ctx);
- if (packing->BufferObj->Name) {
+ if (clippedPacking.BufferObj->Name) {
/* done with PBO so unmap it now */
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- packing->BufferObj);
+ clippedPacking.BufferObj);
}
}