|
|
Try to do a fast and simple RGB(a) glDrawPixels. Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
Definition at line 48 of file s_drawpix.c.
Referenced by draw_rgba_pixels().
{
const GLint imgX = x, imgY = y;
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
GLenum rbType;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
SWspan span;
GLboolean simpleZoom;
GLint yStep;
struct gl_pixelstore_attrib unpack;
GLint destX, destY, drawWidth, drawHeight;
if (!rb)
return GL_TRUE;
rbType = rb->DataType;
if ((swrast->_RasterMask & ~CLIP_BIT) ||
ctx->Texture._EnabledCoordUnits ||
userUnpack->SwapBytes ||
ctx->_ImageTransferState) {
return GL_FALSE;
}
INIT_SPAN(span, GL_BITMAP);
span.arrayMask = SPAN_RGBA;
span.arrayAttribs = FRAG_BIT_COL0;
_swrast_span_default_attribs(ctx, &span);
unpack = *userUnpack;
destX = x;
destY = y;
drawWidth = width;
drawHeight = height;
if (ctx->Pixel.ZoomX == 1.0F &&
(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)) {
if (!_mesa_clip_drawpixels(ctx, &destX, &destY,
&drawWidth, &drawHeight, &unpack)) {
return GL_TRUE;
}
simpleZoom = GL_TRUE;
yStep = (GLint) ctx->Pixel.ZoomY;
ASSERT(yStep == 1 || yStep == -1);
}
else {
simpleZoom = GL_FALSE;
yStep = 1;
if (unpack.RowLength == 0)
unpack.RowLength = width;
}
if (format == GL_RGBA && type == rbType) {
const GLubyte *src
= (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width,
height, format, type, 0, 0);
const GLint srcStride = _mesa_image_row_stride(&unpack, width,
format, type);
if (simpleZoom) {
GLint row;
for (row = 0; row < drawHeight; row++) {
rb->PutRow(ctx, rb, drawWidth, destX, destY, src, NULL);
src += srcStride;
destY += yStep;
}
}
else {
GLint row;
for (row = 0; row < drawHeight; row++) {
span.x = destX;
span.y = destY + row;
span.end = drawWidth;
span.array->ChanType = rbType;
_swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, src);
src += srcStride;
}
span.array->ChanType = CHAN_TYPE;
}
return GL_TRUE;
}
if (format == GL_RGB && type == rbType) {
const GLubyte *src
= (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width,
height, format, type, 0, 0);
const GLint srcStride = _mesa_image_row_stride(&unpack, width,
format, type);
if (simpleZoom) {
GLint row;
for (row = 0; row < drawHeight; row++) {
rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, src, NULL);
src += srcStride;
destY += yStep;
}
}
else {
GLint row;
for (row = 0; row < drawHeight; row++) {
span.x = destX;
span.y = destY;
span.end = drawWidth;
span.array->ChanType = rbType;
_swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, src);
src += srcStride;
destY++;
}
span.array->ChanType = CHAN_TYPE;
}
return GL_TRUE;
}
if (userUnpack->Alignment != 1)
return GL_FALSE;
if (format == GL_LUMINANCE && type == CHAN_TYPE && rbType == CHAN_TYPE) {
const GLchan *src = (const GLchan *) pixels
+ (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels);
if (simpleZoom) {
GLint row;
ASSERT(drawWidth <= MAX_WIDTH);
for (row = 0; row < drawHeight; row++) {
GLchan rgb[MAX_WIDTH][3];
GLint i;
for (i = 0;i<drawWidth;i++) {
rgb[i][0] = src[i];
rgb[i][1] = src[i];
rgb[i][2] = src[i];
}
rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, rgb, NULL);
src += unpack.RowLength;
destY += yStep;
}
}
else {
GLint row;
ASSERT(drawWidth <= MAX_WIDTH);
for (row = 0; row < drawHeight; row++) {
GLchan rgb[MAX_WIDTH][3];
GLint i;
for (i = 0;i<drawWidth;i++) {
rgb[i][0] = src[i];
rgb[i][1] = src[i];
rgb[i][2] = src[i];
}
span.x = destX;
span.y = destY;
span.end = drawWidth;
_swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, rgb);
src += unpack.RowLength;
destY++;
}
}
return GL_TRUE;
}
if (format == GL_LUMINANCE_ALPHA && type == CHAN_TYPE && rbType == CHAN_TYPE) {
const GLchan *src = (const GLchan *) pixels
+ (unpack.SkipRows * unpack.RowLength + unpack.SkipPixels)*2;
if (simpleZoom) {
GLint row;
ASSERT(drawWidth <= MAX_WIDTH);
for (row = 0; row < drawHeight; row++) {
GLint i;
const GLchan *ptr = src;
for (i = 0;i<drawWidth;i++) {
span.array->rgba[i][0] = *ptr;
span.array->rgba[i][1] = *ptr;
span.array->rgba[i][2] = *ptr++;
span.array->rgba[i][3] = *ptr++;
}
rb->PutRow(ctx, rb, drawWidth, destX, destY,
span.array->rgba, NULL);
src += unpack.RowLength*2;
destY += yStep;
}
}
else {
GLint row;
ASSERT(drawWidth <= MAX_WIDTH);
for (row = 0; row < drawHeight; row++) {
const GLchan *ptr = src;
GLint i;
for (i = 0;i<drawWidth;i++) {
span.array->rgba[i][0] = *ptr;
span.array->rgba[i][1] = *ptr;
span.array->rgba[i][2] = *ptr++;
span.array->rgba[i][3] = *ptr++;
}
span.x = destX;
span.y = destY;
span.end = drawWidth;
_swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
span.array->rgba);
src += unpack.RowLength*2;
destY++;
}
}
return GL_TRUE;
}
if (format == GL_COLOR_INDEX && type == GL_UNSIGNED_BYTE) {
const GLubyte *src = (const GLubyte *) pixels
+ unpack.SkipRows * unpack.RowLength + unpack.SkipPixels;
if (ctx->Visual.rgbMode && rbType == GL_UNSIGNED_BYTE) {
if (simpleZoom) {
GLint row;
for (row = 0; row < drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
span.array->rgba8);
rb->PutRow(ctx, rb, drawWidth, destX, destY,
span.array->rgba8, NULL);
src += unpack.RowLength;
destY += yStep;
}
}
else {
GLint row;
for (row = 0; row < drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
span.array->rgba8);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
span.array->rgba8);
src += unpack.RowLength;
destY++;
}
}
return GL_TRUE;
}
else if (!ctx->Visual.rgbMode && rbType == GL_UNSIGNED_INT) {
GLint row;
if (simpleZoom) {
for (row = 0; row < drawHeight; row++) {
GLuint index32[MAX_WIDTH];
GLint col;
for (col = 0; col < drawWidth; col++)
index32[col] = src[col];
rb->PutRow(ctx, rb, drawWidth, destX, destY, index32, NULL);
src += unpack.RowLength;
destY += yStep;
}
return GL_TRUE;
}
}
}
return GL_FALSE;
}
|