Changeset 3598 for trunk/src/opengl/mesa/drawpix.c
- Timestamp:
- May 23, 2000, 10:41:28 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/opengl/mesa/drawpix.c
r2962 r3598 1 /* $Id: drawpix.c,v 1. 2 2000-03-01 18:49:27jeroen Exp $ */1 /* $Id: drawpix.c,v 1.3 2000-05-23 20:40:31 jeroen Exp $ */ 2 2 3 3 /* 4 4 * Mesa 3-D graphics library 5 * Version: 3. 15 * Version: 3.3 6 6 * 7 7 * Copyright (C) 1999 Brian Paul All Rights Reserved. … … 26 26 27 27 28 29 30 31 28 #ifdef PC_HEADER 32 29 #include "all.h" 33 30 #else 34 #ifndef XFree86Server 35 #include <assert.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #else 39 #include "GL/xf86glx.h" 40 #endif 31 #include "glheader.h" 41 32 #include "types.h" 42 33 #include "context.h" 43 34 #include "drawpix.h" 35 #include "mem.h" 44 36 #include "feedback.h" 45 37 #include "image.h" … … 50 42 #include "stencil.h" 51 43 #include "zoom.h" 44 #include "state.h" 52 45 #endif 53 46 54 47 55 56 /* TODO: apply texture mapping to fragments */57 58 59 48 /* 60 * Try to do a fast glDrawPixels. Conditions include: 61 * not using a display list 62 * simple pixel unpacking 63 * no raster ops 64 * etc.... 49 * Given the dest position, size and skipPixels and skipRows values 50 * for a glDrawPixels command, perform clipping of the image bounds 51 * so the result lies withing the context's buffer bounds. 52 * Return: GL_TRUE if image is ready for drawing 53 * GL_FALSE if image was completely clipped away (draw nothing) 54 */ 55 GLboolean 56 _mesa_clip_pixelrect(const GLcontext *ctx, 57 GLint *destX, GLint *destY, 58 GLsizei *width, GLsizei *height, 59 GLint *skipPixels, GLint *skipRows) 60 { 61 const GLframebuffer *buffer = ctx->DrawBuffer; 62 63 /* left clipping */ 64 if (*destX < buffer->Xmin) { 65 *skipPixels += (buffer->Xmin - *destX); 66 *width -= (buffer->Xmin - *destX); 67 *destX = buffer->Xmin; 68 } 69 /* right clipping */ 70 if (*destX + *width > buffer->Xmax) 71 *width -= (*destX + *width - buffer->Xmax - 1); 72 73 if (*width <= 0) 74 return GL_FALSE; 75 76 /* bottom clipping */ 77 if (*destY < buffer->Ymin) { 78 *skipRows += (buffer->Ymin - *destY); 79 *height -= (buffer->Ymin - *destY); 80 *destY = buffer->Ymin; 81 } 82 /* top clipping */ 83 if (*destY + *height > buffer->Ymax) 84 *height -= (*destY + *height - buffer->Ymax - 1); 85 86 if (*height <= 0) 87 return GL_TRUE; 88 89 return GL_TRUE; 90 } 91 92 93 94 /* 95 * Try to do a fast and simple RGB(a) glDrawPixels. 65 96 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead 66 97 */ 67 GLboolean gl_direct_DrawPixels( GLcontext *ctx, 68 const struct gl_pixelstore_attrib *unpack, 69 GLsizei width, GLsizei height, 70 GLenum format, GLenum type, 71 const GLvoid *pixels ) 98 static GLboolean 99 simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, 100 GLsizei width, GLsizei height, GLenum format, GLenum type, 101 const GLvoid *pixels ) 72 102 { 103 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 73 104 GLubyte rgb[MAX_WIDTH][3]; 74 105 GLubyte rgba[MAX_WIDTH][4]; 75 106 76 107 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels", 77 108 GL_FALSE); 78 109 79 110 … … 85 116 if (ctx->NewState) { 86 117 gl_update_state(ctx); 87 }88 89 /* see if device driver can do the drawpix */90 if (ctx->Driver.DrawPixels) {91 GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);92 GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);93 if ((*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,94 unpack, pixels))95 return GL_TRUE;96 118 } 97 119 … … 107 129 && !unpack->LsbFirst) { 108 130 109 GLint destX = (GLint) (ctx->Current.RasterPos[0] + 0.5F);110 GLint destY = (GLint) (ctx->Current.RasterPos[1] + 0.5F);131 GLint destX = x; 132 GLint destY = y; 111 133 GLint drawWidth = width; /* actual width drawn */ 112 134 GLint drawHeight = height; /* actual height drawn */ … … 128 150 if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 129 151 /* horizontal clipping */ 130 if (destX < ctx-> Buffer->Xmin) {131 skipPixels += (ctx-> Buffer->Xmin - destX);132 drawWidth -= (ctx-> Buffer->Xmin - destX);133 destX = ctx-> Buffer->Xmin;134 } 135 if (destX + drawWidth > ctx-> Buffer->Xmax)136 drawWidth -= (destX + drawWidth - ctx-> Buffer->Xmax - 1);152 if (destX < ctx->DrawBuffer->Xmin) { 153 skipPixels += (ctx->DrawBuffer->Xmin - destX); 154 drawWidth -= (ctx->DrawBuffer->Xmin - destX); 155 destX = ctx->DrawBuffer->Xmin; 156 } 157 if (destX + drawWidth > ctx->DrawBuffer->Xmax) 158 drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax - 1); 137 159 if (drawWidth <= 0) 138 160 return GL_TRUE; 139 161 140 162 /* vertical clipping */ 141 if (destY < ctx-> Buffer->Ymin) {142 skipRows += (ctx-> Buffer->Ymin - destY);143 drawHeight -= (ctx-> Buffer->Ymin - destY);144 destY = ctx-> Buffer->Ymin;145 } 146 if (destY + drawHeight > ctx-> Buffer->Ymax)147 drawHeight -= (destY + drawHeight - ctx-> Buffer->Ymax - 1);163 if (destY < ctx->DrawBuffer->Ymin) { 164 skipRows += (ctx->DrawBuffer->Ymin - destY); 165 drawHeight -= (ctx->DrawBuffer->Ymin - destY); 166 destY = ctx->DrawBuffer->Ymin; 167 } 168 if (destY + drawHeight > ctx->DrawBuffer->Ymax) 169 drawHeight -= (destY + drawHeight - ctx->DrawBuffer->Ymax - 1); 148 170 if (drawHeight <= 0) 149 171 return GL_TRUE; 172 173 zoomY0 = 0; /* not used - silence compiler warning */ 150 174 } 151 175 else { 152 176 /* setup array of fragment Z value to pass to zoom function */ 153 GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);177 GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF); 154 178 GLint i; 155 assert(drawWidth < MAX_WIDTH);179 ASSERT(drawWidth < MAX_WIDTH); 156 180 for (i=0; i<drawWidth; i++) 157 181 zSpan[i] = z; … … 179 203 for (row=0; row<drawHeight; row++) { 180 204 (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 181 (const GLubyte (*)[4])src, 182 NULL); 205 (const GLubyte(*)[4]) src, NULL); 183 206 src += rowLength * 4; 184 207 destY++; … … 190 213 for (row=0; row<drawHeight; row++) { 191 214 gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, 192 zSpan, 193 (const GLubyte (*)[4]) src, 194 zoomY0); 215 zSpan, (const GLubyte(*)[4]) src, zoomY0); 195 216 src += rowLength * 4; 196 217 destY++; … … 208 229 for (row=0; row<drawHeight; row++) { 209 230 (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, 210 (const GLubyte (*)[3]) src, 211 NULL); 231 (const GLubyte(*)[3]) src, NULL); 212 232 src += rowLength * 3; 213 233 destY++; … … 219 239 for (row=0; row<drawHeight; row++) { 220 240 gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY, 221 zSpan, 222 (const GLubyte (*)[3]) src, 223 zoomY0); 241 zSpan, (const GLubyte(*)[3]) src, zoomY0); 224 242 src += rowLength * 3; 225 243 destY++; … … 236 254 /* no zooming */ 237 255 GLint row; 238 assert(drawWidth < MAX_WIDTH);256 ASSERT(drawWidth < MAX_WIDTH); 239 257 for (row=0; row<drawHeight; row++) { 240 258 GLint i; … … 245 263 } 246 264 (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, 247 (const GLubyte (*)[3]) rgb, 248 NULL); 265 (const GLubyte(*)[3]) rgb, NULL); 249 266 src += rowLength; 250 267 destY++; … … 254 271 /* with zooming */ 255 272 GLint row; 256 assert(drawWidth < MAX_WIDTH);273 ASSERT(drawWidth < MAX_WIDTH); 257 274 for (row=0; row<drawHeight; row++) { 258 275 GLint i; … … 263 280 } 264 281 gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY, 265 zSpan, 266 (const GLubyte (*)[3]) rgb, 267 zoomY0); 282 zSpan, (const GLubyte(*)[3]) rgb, zoomY0); 268 283 src += rowLength; 269 284 destY++; … … 280 295 /* no zooming */ 281 296 GLint row; 282 assert(drawWidth < MAX_WIDTH);297 ASSERT(drawWidth < MAX_WIDTH); 283 298 for (row=0; row<drawHeight; row++) { 284 299 GLint i; … … 291 306 } 292 307 (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 293 (const GLubyte (*)[4]) rgba, 294 NULL); 308 (const GLubyte (*)[4]) rgba, NULL); 295 309 src += rowLength*2; 296 310 destY++; … … 300 314 /* with zooming */ 301 315 GLint row; 302 assert(drawWidth < MAX_WIDTH);316 ASSERT(drawWidth < MAX_WIDTH); 303 317 for (row=0; row<drawHeight; row++) { 304 318 GLubyte *ptr = src; … … 311 325 } 312 326 gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, 313 zSpan, 314 (const GLubyte (*)[4]) rgba, 315 zoomY0); 327 zSpan, (const GLubyte (*)[4]) rgba, zoomY0); 316 328 src += rowLength*2; 317 329 destY++; … … 329 341 GLint row; 330 342 for (row=0; row<drawHeight; row++) { 331 assert(drawWidth < MAX_WIDTH);343 ASSERT(drawWidth < MAX_WIDTH); 332 344 gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba); 333 345 (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, … … 343 355 GLint row; 344 356 for (row=0; row<drawHeight; row++) { 345 assert(drawWidth < MAX_WIDTH);357 ASSERT(drawWidth < MAX_WIDTH); 346 358 gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba); 347 359 gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, 348 zSpan, 349 (const GLubyte (*)[4]) rgba, 350 zoomY0); 360 zSpan, (const GLubyte(*)[4]) rgba, zoomY0); 351 361 src += rowLength; 352 362 destY++; … … 379 389 } 380 390 } 381 else { 382 /* can't do direct render, have to use slow path */ 383 return GL_FALSE; 384 } 391 392 /* can't do a simple draw, have to use slow path */ 393 return GL_FALSE; 385 394 } 386 395 … … 390 399 * Do glDrawPixels of index pixels. 391 400 */ 392 static void draw_index_pixels( GLcontext *ctx, GLint x, GLint y, 393 const struct gl_image *image ) 401 static void 402 draw_index_pixels( GLcontext *ctx, GLint x, GLint y, 403 GLsizei width, GLsizei height, 404 GLenum type, const GLvoid *pixels ) 394 405 { 395 GLint width, height, widthInBytes;406 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 396 407 const GLint desty = y; 397 GLint i, j;408 GLint row, drawWidth; 398 409 GLdepth zspan[MAX_WIDTH]; 399 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 400 401 assert(image); 402 assert(image->Format == GL_COLOR_INDEX); 403 404 width = image->Width; 405 height = image->Height; 406 if (image->Type == GL_BITMAP) 407 widthInBytes = (width + 7) / 8; 408 else 409 widthInBytes = width; 410 411 drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; 410 412 411 413 /* Fragment depth values */ 412 414 if (ctx->Depth.Test || ctx->Fog.Enabled) { 413 GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); 414 for (i=0;i<width;i++) { 415 zspan[i] = zval; 416 } 417 } 418 419 /* process the image row by row */ 420 for (i=0;i<height;i++,y++) { 421 GLuint ispan[MAX_WIDTH]; 422 423 /* convert to uints */ 424 switch (image->Type) { 425 case GL_UNSIGNED_BYTE: 426 { 427 GLubyte *src = (GLubyte *) image->Data + i * width; 428 for (j=0;j<width;j++) { 429 ispan[j] = (GLuint) *src++; 430 } 431 } 432 break; 433 case GL_FLOAT: 434 { 435 GLfloat *src = (GLfloat *) image->Data + i * width; 436 for (j=0;j<width;j++) { 437 ispan[j] = (GLuint) (GLint) *src++; 438 } 439 } 440 break; 441 case GL_BITMAP: 442 { 443 GLubyte *src = (GLubyte *) image->Data + i * widthInBytes; 444 for (j=0;j<width;j++) { 445 ispan[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1; 446 } 447 } 448 break; 449 default: 450 gl_problem( ctx, "draw_index_pixels type" ); 451 return; 452 } 453 454 /* apply shift and offset */ 455 if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) { 456 gl_shift_and_offset_ci( ctx, width, ispan ); 457 } 458 459 if (ctx->Visual->RGBAflag) { 460 /* Convert index to RGBA and write to frame buffer */ 461 GLubyte rgba[MAX_WIDTH][4]; 462 gl_map_ci_to_rgba( ctx, width, ispan, rgba ); 463 if (zoom) { 464 gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 465 (const GLubyte (*)[4])rgba, desty ); 466 } 467 else { 468 gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); 469 } 415 GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF); 416 GLint i; 417 for (i = 0; i < drawWidth; i++) { 418 zspan[i] = zval; 419 } 420 } 421 422 /* 423 * General solution 424 */ 425 for (row = 0; row < height; row++, y++) { 426 GLuint indexes[MAX_WIDTH]; 427 const GLvoid *source = _mesa_image_address(&ctx->Unpack, 428 pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); 429 _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes, 430 type, source, &ctx->Unpack, GL_TRUE); 431 if (zoom) { 432 gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty); 470 433 } 471 434 else { 472 /* optionally apply index map then write to frame buffer */ 473 if (ctx->Pixel.MapColorFlag) { 474 gl_map_ci(ctx, width, ispan); 475 } 476 if (zoom) { 477 gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty ); 478 } 479 else { 480 gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP ); 481 } 482 } 483 } 484 435 gl_write_index_span(ctx, drawWidth, x, y, zspan, indexes, GL_BITMAP); 436 } 437 } 485 438 } 486 439 … … 491 444 * be GLubyte or GLbitmap. 492 445 */ 493 static void draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, 494 const struct gl_image *image ) 446 static void 447 draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, 448 GLsizei width, GLsizei height, 449 GLenum type, const GLvoid *pixels ) 495 450 { 496 GLint widthInBytes, width, height;451 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 497 452 const GLint desty = y; 498 GLint i; 499 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 500 501 if (image->Type != GL_BYTE && 502 image->Type != GL_UNSIGNED_BYTE && 503 image->Type != GL_SHORT && 504 image->Type != GL_UNSIGNED_SHORT && 505 image->Type != GL_INT && 506 image->Type != GL_UNSIGNED_INT && 507 image->Type != GL_FLOAT && 508 image->Type != GL_BITMAP) { 509 gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels(stencil type)"); 453 GLint row, drawWidth; 454 455 if (type != GL_BYTE && 456 type != GL_UNSIGNED_BYTE && 457 type != GL_SHORT && 458 type != GL_UNSIGNED_SHORT && 459 type != GL_INT && 460 type != GL_UNSIGNED_INT && 461 type != GL_FLOAT && 462 type != GL_BITMAP) { 463 gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)"); 510 464 return; 511 465 } 512 466 513 assert(image); 514 assert(image->Format == GL_STENCIL_INDEX); 515 assert(image->Type == GL_UNSIGNED_BYTE || image->Type == GL_BITMAP); 516 517 if (image->Type == GL_UNSIGNED_BYTE) 518 widthInBytes = image->Width; 519 else 520 widthInBytes = (image->Width + 7) / 8; 521 width = image->Width; 522 height = image->Height; 523 524 /* process the image row by row */ 525 for (i=0;i<height;i++,y++) { 526 GLstencil *src = (GLstencil*)image->Data + i * widthInBytes; 527 GLstencil *stencilValues; 528 GLstencil stencilCopy[MAX_WIDTH]; 529 530 if (image->Type == GL_BITMAP) { 531 /* convert bitmap data to GLubyte (0 or 1) data */ 532 GLint j; 533 for (j = 0; j < width; j++) { 534 stencilCopy[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1; 535 } 536 src = stencilCopy; 537 } 538 539 if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift 540 || ctx->Pixel.MapStencilFlag) { 541 542 /* make copy of stencil values */ 543 if (src != stencilCopy) 544 MEMCPY( stencilCopy, src, width * sizeof(GLstencil)); 545 546 /* apply shift and offset */ 547 if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) { 548 gl_shift_and_offset_stencil( ctx, width, stencilCopy ); 549 } 550 551 /* mapping */ 552 if (ctx->Pixel.MapStencilFlag) { 553 gl_map_stencil( ctx, width, stencilCopy ); 554 } 555 556 stencilValues = stencilCopy; 467 drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; 468 469 for (row = 0; row < height; row++, y++) { 470 GLstencil values[MAX_WIDTH]; 471 GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte)) 472 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; 473 const GLvoid *source = _mesa_image_address(&ctx->Unpack, 474 pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); 475 _mesa_unpack_index_span(ctx, drawWidth, destType, values, 476 type, source, &ctx->Unpack, GL_TRUE); 477 478 if (zoom) { 479 gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y, 480 values, desty ); 557 481 } 558 482 else { 559 /* use stencil values in-place */ 560 stencilValues = src; 561 } 562 563 /* write stencil values to stencil buffer */ 564 if (zoom) { 565 gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y, 566 stencilValues, desty ); 567 } 568 else { 569 gl_write_stencil_span( ctx, (GLuint) width, x, y, stencilValues ); 483 gl_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values ); 570 484 } 571 485 } … … 577 491 * Do a glDrawPixels of depth values. 578 492 */ 579 static void draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, 580 const struct gl_image *image ) 493 static void 494 draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, 495 GLsizei width, GLsizei height, 496 GLenum type, const GLvoid *pixels ) 581 497 { 582 GLint width, height; 498 const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; 499 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 583 500 const GLint desty = y; 584 501 GLubyte rgba[MAX_WIDTH][4]; 585 502 GLuint ispan[MAX_WIDTH]; 586 const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; 587 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 588 589 assert(image); 590 assert(image->Format == GL_DEPTH_COMPONENT); 591 592 width = image->Width; 593 height = image->Height; 594 595 /* Color or index */ 503 GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; 504 505 if (type != GL_UNSIGNED_BYTE 506 && type != GL_UNSIGNED_BYTE 507 && type != GL_UNSIGNED_SHORT 508 && type != GL_UNSIGNED_SHORT 509 && type != GL_UNSIGNED_INT 510 && type != GL_UNSIGNED_INT 511 && type != GL_FLOAT) { 512 gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)"); 513 return; 514 } 515 516 /* Colors or indexes */ 596 517 if (ctx->Visual->RGBAflag) { 597 518 GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F); … … 600 521 GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F); 601 522 GLint i; 602 for (i =0; i<width; i++) {523 for (i = 0; i < drawWidth; i++) { 603 524 rgba[i][RCOMP] = r; 604 525 rgba[i][GCOMP] = g; … … 609 530 else { 610 531 GLint i; 611 for (i =0;i<width;i++) {612 613 } 614 } 615 616 if ( image->Type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)532 for (i = 0; i < drawWidth; i++) { 533 ispan[i] = ctx->Current.RasterIndex; 534 } 535 } 536 537 if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort) 617 538 && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { 618 539 /* Special case: directly write 16-bit depth values */ 619 GLint j; 620 for (j=0;j<height;j++,y++) { 621 GLdepth *zptr = (GLdepth *) image->Data + j * width; 622 gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP ); 623 } 624 } 625 else if (image->Type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint) 540 GLint row; 541 for (row = 0; row < height; row++, y++) { 542 GLdepth zspan[MAX_WIDTH]; 543 const GLushort *zptr = (const GLushort *)_mesa_image_address(&ctx->Unpack, 544 pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); 545 GLint i; 546 for (i = 0; i < width; i++) 547 zspan[i] = zptr[i]; 548 gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); 549 } 550 } 551 else if (type==GL_UNSIGNED_INT && ctx->Visual->DepthBits == 32 626 552 && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { 627 553 /* Special case: directly write 32-bit depth values */ 628 GLint i, j; 629 /* Compute shift value to scale 32-bit uints down to depth values. */ 630 GLuint shift = 0; 631 GLuint max = MAX_DEPTH; 632 while ((max&0x80000000)==0) { 633 max = max << 1; 634 shift++; 635 } 636 for (j=0;j<height;j++,y++) { 554 GLint row; 555 for (row = 0; row < height; row++, y++) { 556 const GLuint *zptr = (GLuint *)_mesa_image_address(&ctx->Unpack, 557 pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); 558 gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP ); 559 } 560 } 561 else { 562 /* General case */ 563 GLint row; 564 for (row = 0; row < height; row++, y++) { 637 565 GLdepth zspan[MAX_WIDTH]; 638 GLuint *zptr = (GLuint *) image->Data + j * width; 639 for (i=0;i<width;i++) { 640 zspan[i] = zptr[i] >> shift; 641 } 642 gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); 643 } 644 } 645 else { 646 /* General case (slower) */ 647 GLint i, j; 648 649 /* process image row by row */ 650 for (i=0;i<height;i++,y++) { 651 GLfloat depth[MAX_WIDTH]; 652 GLdepth zspan[MAX_WIDTH]; 653 654 switch (image->Type) { 655 case GL_UNSIGNED_SHORT: 656 { 657 GLushort *src = (GLushort *) image->Data + i * width; 658 for (j=0;j<width;j++) { 659 depth[j] = USHORT_TO_FLOAT( *src++ ); 660 } 661 } 662 break; 663 case GL_UNSIGNED_INT: 664 { 665 GLuint *src = (GLuint *) image->Data + i * width; 666 for (j=0;j<width;j++) { 667 depth[j] = UINT_TO_FLOAT( *src++ ); 668 } 669 } 670 break; 671 case GL_FLOAT: 672 { 673 GLfloat *src = (GLfloat *) image->Data + i * width; 674 for (j=0;j<width;j++) { 675 depth[j] = *src++; 676 } 677 } 678 break; 679 default: 680 gl_problem(ctx, "Bad type in draw_depth_pixels"); 681 return; 682 } 683 684 /* apply depth scale and bias */ 685 if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) { 686 for (j=0;j<width;j++) { 687 depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; 688 } 689 } 690 691 /* clamp depth values to [0,1] and convert from floats to integers */ 692 for (j=0;j<width;j++) { 693 zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE); 694 } 695 566 const GLvoid *src = _mesa_image_address(&ctx->Unpack, 567 pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); 568 _mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src, 569 &ctx->Unpack, GL_TRUE ); 696 570 if (ctx->Visual->RGBAflag) { 697 571 if (zoom) { 698 gl_write_zoomed_rgba_span( 699 (const GLubyte (*)[4])rgba, desty);572 gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, 573 (const GLubyte (*)[4])rgba, desty); 700 574 } 701 575 else { 702 gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP);576 gl_write_rgba_span(ctx, width, x, y, zspan, rgba, GL_BITMAP); 703 577 } 704 578 } 705 579 else { 706 580 if (zoom) { 707 gl_write_zoomed_index_span( 708 ispan, GL_BITMAP);581 gl_write_zoomed_index_span(ctx, width, x, y, zspan, 582 ispan, GL_BITMAP); 709 583 } 710 584 else { 711 gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP);585 gl_write_index_span(ctx, width, x, y, zspan, ispan, GL_BITMAP); 712 586 } 713 587 } … … 716 590 } 717 591 } 718 719 720 721 /* Simple unpacking parameters: */722 static struct gl_pixelstore_attrib NoUnpack = {723 1, /* Alignment */724 0, /* RowLength */725 0, /* SkipPixels */726 0, /* SkipRows */727 0, /* ImageHeight */728 0, /* SkipImages */729 GL_FALSE, /* SwapBytes */730 GL_FALSE /* LsbFirst */731 };732 592 733 593 … … 735 595 * Do glDrawPixels of RGBA pixels. 736 596 */ 737 static void draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, 738 const struct gl_image *image ) 597 static void 598 draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, 599 GLsizei width, GLsizei height, 600 GLenum format, GLenum type, const GLvoid *pixels ) 739 601 { 740 GLint width, height;741 GLint i, j;602 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 603 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 742 604 const GLint desty = y; 743 605 GLdepth zspan[MAX_WIDTH]; 744 606 GLboolean quickDraw; 745 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;746 747 assert(image);748 607 749 608 /* Try an optimized glDrawPixels first */ 750 if (gl_direct_DrawPixels(ctx, &NoUnpack, image->Width, image->Height, 751 image->Format, image->Type, image->Data )) 609 if (simple_DrawPixels(ctx, x, y, width, height, format, type, pixels)) 752 610 return; 753 754 width = image->Width;755 height = image->Height;756 611 757 612 /* Fragment depth values */ 758 613 if (ctx->Depth.Test || ctx->Fog.Enabled) { 759 614 /* fill in array of z values */ 760 GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); 615 GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF); 616 GLint i; 761 617 for (i=0;i<width;i++) { 762 zspan[i] = z; 763 } 764 } 765 766 if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0 767 && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) { 618 zspan[i] = z; 619 } 620 } 621 622 623 if (ctx->RasterMask == 0 && !zoom 624 && x >= 0 && y >= 0 625 && x + width <= ctx->DrawBuffer->Width 626 && y + height <= ctx->DrawBuffer->Height) { 768 627 quickDraw = GL_TRUE; 769 628 } … … 772 631 } 773 632 633 /* 634 * General solution 635 */ 774 636 { 775 /* General solution */776 GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;777 GLuint components;778 637 GLubyte rgba[MAX_WIDTH][4]; 779 GLfloat rf[MAX_WIDTH]; 780 GLfloat gf[MAX_WIDTH]; 781 GLfloat bf[MAX_WIDTH]; 782 DEFARRAY(GLfloat,af,MAX_WIDTH); 783 CHECKARRAY(af,return); 784 785 r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE; 786 switch (image->Format) { 787 case GL_RED: 788 r_flag = GL_TRUE; 789 components = 1; 790 break; 791 case GL_GREEN: 792 g_flag = GL_TRUE; 793 components = 1; 794 break; 795 case GL_BLUE: 796 b_flag = GL_TRUE; 797 components = 1; 798 break; 799 case GL_ALPHA: 800 a_flag = GL_TRUE; 801 components = 1; 802 break; 803 case GL_RGB: 804 r_flag = g_flag = b_flag = GL_TRUE; 805 components = 3; 806 break; 807 case GL_LUMINANCE: 808 l_flag = GL_TRUE; 809 components = 1; 810 break; 811 case GL_LUMINANCE_ALPHA: 812 l_flag = a_flag = GL_TRUE; 813 components = 2; 814 break; 815 case GL_RGBA: 816 r_flag = g_flag = b_flag = a_flag = GL_TRUE; 817 components = 4; 818 break; 819 default: 820 gl_problem(ctx, "Bad type in draw_rgba_pixels"); 821 goto cleanup; 822 } 823 824 /* process the image row by row */ 825 for (i=0;i<height;i++,y++) { 826 /* convert to floats */ 827 switch (image->Type) { 828 case GL_UNSIGNED_BYTE: 829 { 830 GLubyte *src = (GLubyte *) image->Data + i * width * components; 831 for (j=0;j<width;j++) { 832 if (l_flag) { 833 rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++); 834 } 835 else { 836 rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0; 837 gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0; 838 bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0; 839 } 840 af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0; 841 } 842 } 843 break; 844 case GL_FLOAT: 845 { 846 GLfloat *src = (GLfloat *) image->Data + i * width * components; 847 for (j=0;j<width;j++) { 848 if (l_flag) { 849 rf[j] = gf[j] = bf[j] = *src++; 850 } 851 else { 852 rf[j] = r_flag ? *src++ : 0.0; 853 gf[j] = g_flag ? *src++ : 0.0; 854 bf[j] = b_flag ? *src++ : 0.0; 855 } 856 af[j] = a_flag ? *src++ : 1.0; 857 } 858 } 859 break; 860 default: 861 gl_problem( ctx, "draw_rgba_pixels type" ); 862 goto cleanup; 863 } 864 865 /* apply scale and bias */ 866 if (ctx->Pixel.ScaleOrBiasRGBA) { 867 gl_scale_and_bias_color(ctx, width, rf, gf, bf, af); 868 } 869 870 /* apply pixel mappings */ 871 if (ctx->Pixel.MapColorFlag) { 872 gl_map_color(ctx, width, rf, gf, bf, af); 873 } 874 875 /* convert to integers */ 876 for (j=0;j<width;j++) { 877 rgba[j][RCOMP] = (GLint) (rf[j] * 255.0F); 878 rgba[j][GCOMP] = (GLint) (gf[j] * 255.0F); 879 rgba[j][BCOMP] = (GLint) (bf[j] * 255.0F); 880 rgba[j][ACOMP] = (GLint) (af[j] * 255.0F); 881 } 882 883 /* write to frame buffer */ 638 GLint row; 639 if (width > MAX_WIDTH) 640 width = MAX_WIDTH; 641 for (row = 0; row < height; row++, y++) { 642 const GLvoid *source = _mesa_image_address(unpack, 643 pixels, width, height, format, type, 0, row, 0); 644 _mesa_unpack_ubyte_color_span(ctx, width, GL_RGBA, (GLubyte *) rgba, 645 format, type, source, unpack, GL_TRUE); 646 884 647 if (quickDraw) { 885 648 (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, 886 (const GLubyte (*)[4])rgba, NULL);649 (CONST GLubyte (*)[4]) rgba, NULL); 887 650 } 888 651 else if (zoom) { 889 652 gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 890 (const GLubyte (*)[4])rgba, desty );653 (CONST GLubyte (*)[4]) rgba, desty ); 891 654 } 892 655 else { … … 894 657 } 895 658 } 896 cleanup:897 UNDEFARRAY(af);898 659 } 899 660 } … … 904 665 * Execute glDrawPixels 905 666 */ 906 void gl_DrawPixels( GLcontext* ctx, struct gl_image *image ) 667 void 668 _mesa_DrawPixels( GLsizei width, GLsizei height, 669 GLenum format, GLenum type, const GLvoid *pixels ) 907 670 { 671 GET_CURRENT_CONTEXT(ctx); 908 672 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels"); 909 910 911 if (gl_image_error_test( ctx, image, "glDrawPixels" ))912 return;913 673 914 674 if (ctx->RenderMode==GL_RENDER) { 915 675 GLint x, y; 916 if (! ctx->Current.RasterPosValid) {917 676 if (!pixels || !ctx->Current.RasterPosValid) { 677 return; 918 678 } 919 679 … … 921 681 y = (GLint) (ctx->Current.RasterPos[1] + 0.5F); 922 682 923 switch (image->Format) { 924 case GL_COLOR_INDEX: 925 draw_index_pixels( ctx, x, y, image ); 926 break; 927 case GL_STENCIL_INDEX: 928 draw_stencil_pixels( ctx, x, y, image ); 929 break; 930 case GL_DEPTH_COMPONENT: 931 draw_depth_pixels( ctx, x, y, image ); 932 break; 933 case GL_RED: 934 case GL_GREEN: 935 case GL_BLUE: 936 case GL_ALPHA: 937 case GL_RGB: 938 case GL_LUMINANCE: 939 case GL_LUMINANCE_ALPHA: 940 case GL_RGBA: 941 draw_rgba_pixels( ctx, x, y, image ); 942 break; 943 default: 944 gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" ); 683 /* see if device driver can do the drawpix */ 684 if (ctx->Driver.DrawPixels 685 && (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type, 686 &ctx->Unpack, pixels)) { 687 return; 688 } 689 690 switch (format) { 691 case GL_STENCIL_INDEX: 692 draw_stencil_pixels( ctx, x, y, width, height, type, pixels ); 693 break; 694 case GL_DEPTH_COMPONENT: 695 draw_depth_pixels( ctx, x, y, width, height, type, pixels ); 696 break; 697 case GL_COLOR_INDEX: 698 if (ctx->Visual->RGBAflag) 699 draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels); 700 else 701 draw_index_pixels(ctx, x, y, width, height, type, pixels); 702 break; 703 case GL_RED: 704 case GL_GREEN: 705 case GL_BLUE: 706 case GL_ALPHA: 707 case GL_LUMINANCE: 708 case GL_LUMINANCE_ALPHA: 709 case GL_RGB: 710 case GL_BGR: 711 case GL_RGBA: 712 case GL_BGRA: 713 case GL_ABGR_EXT: 714 draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels); 715 break; 716 default: 717 gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" ); 945 718 return; 946 719 } … … 949 722 if (ctx->Current.RasterPosValid) { 950 723 GLfloat color[4]; 951 952 724 GLfloat texcoord[4], invq; 725 UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor); 953 726 invq = 1.0F / ctx->Current.Texcoord[0][3]; 954 727 texcoord[0] = ctx->Current.Texcoord[0][0] * invq;
Note:
See TracChangeset
for help on using the changeset viewer.