1 /* 2 * Mesa 3-D graphics library 3 * Version: 7.1 4 * 5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26 #include "main/glheader.h" 27 #include "main/bufferobj.h" 28 #include "main/colormac.h" 29 #include "main/condrender.h" 30 #include "main/context.h" 31 #include "main/format_pack.h" 32 #include "main/image.h" 33 #include "main/imports.h" 34 #include "main/macros.h" 35 #include "main/pack.h" 36 #include "main/pbo.h" 37 #include "main/pixeltransfer.h" 38 #include "main/state.h" 39 40 #include "s_context.h" 41 #include "s_span.h" 42 #include "s_stencil.h" 43 #include "s_zoom.h" 44 45 46 /** 47 * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a 48 * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer. 49 */ 50 static void 51 fast_draw_rgb_ubyte_pixels(struct gl_context *ctx, 52 struct gl_renderbuffer *rb, 53 GLint x, GLint y, 54 GLsizei width, GLsizei height, 55 const struct gl_pixelstore_attrib *unpack, 56 const GLvoid *pixels) 57 { 58 const GLubyte *src = (const GLubyte *) 59 _mesa_image_address2d(unpack, pixels, width, 60 height, GL_RGB, GL_UNSIGNED_BYTE, 0, 0); 61 const GLint srcRowStride = _mesa_image_row_stride(unpack, width, 62 GL_RGB, GL_UNSIGNED_BYTE); 63 GLint i, j; 64 GLubyte *dst; 65 GLint dstRowStride; 66 67 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 68 GL_MAP_WRITE_BIT, &dst, &dstRowStride); 69 70 if (!dst) { 71 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 72 return; 73 } 74 75 if (ctx->Pixel.ZoomY == -1.0f) { 76 dst = dst + (height - 1) * dstRowStride; 77 dstRowStride = -dstRowStride; 78 } 79 80 for (i = 0; i < height; i++) { 81 GLuint *dst4 = (GLuint *) dst; 82 for (j = 0; j < width; j++) { 83 dst4[j] = PACK_COLOR_8888(0xff, src[j*3+0], src[j*3+1], src[j*3+2]); 84 } 85 dst += dstRowStride; 86 src += srcRowStride; 87 } 88 89 ctx->Driver.UnmapRenderbuffer(ctx, rb); 90 } 91 92 93 /** 94 * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a 95 * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer. 96 */ 97 static void 98 fast_draw_rgba_ubyte_pixels(struct gl_context *ctx, 99 struct gl_renderbuffer *rb, 100 GLint x, GLint y, 101 GLsizei width, GLsizei height, 102 const struct gl_pixelstore_attrib *unpack, 103 const GLvoid *pixels) 104 { 105 const GLubyte *src = (const GLubyte *) 106 _mesa_image_address2d(unpack, pixels, width, 107 height, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); 108 const GLint srcRowStride = 109 _mesa_image_row_stride(unpack, width, GL_RGBA, GL_UNSIGNED_BYTE); 110 GLint i, j; 111 GLubyte *dst; 112 GLint dstRowStride; 113 114 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 115 GL_MAP_WRITE_BIT, &dst, &dstRowStride); 116 117 if (!dst) { 118 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 119 return; 120 } 121 122 if (ctx->Pixel.ZoomY == -1.0f) { 123 dst = dst + (height - 1) * dstRowStride; 124 dstRowStride = -dstRowStride; 125 } 126 127 for (i = 0; i < height; i++) { 128 GLuint *dst4 = (GLuint *) dst; 129 for (j = 0; j < width; j++) { 130 dst4[j] = PACK_COLOR_8888(src[j*4+3], src[j*4+0], 131 src[j*4+1], src[j*4+2]); 132 } 133 dst += dstRowStride; 134 src += srcRowStride; 135 } 136 137 ctx->Driver.UnmapRenderbuffer(ctx, rb); 138 } 139 140 141 /** 142 * Handle a common case of drawing a format/type combination that 143 * exactly matches the renderbuffer format. 144 */ 145 static void 146 fast_draw_generic_pixels(struct gl_context *ctx, 147 struct gl_renderbuffer *rb, 148 GLint x, GLint y, 149 GLsizei width, GLsizei height, 150 GLenum format, GLenum type, 151 const struct gl_pixelstore_attrib *unpack, 152 const GLvoid *pixels) 153 { 154 const GLubyte *src = (const GLubyte *) 155 _mesa_image_address2d(unpack, pixels, width, 156 height, format, type, 0, 0); 157 const GLint srcRowStride = 158 _mesa_image_row_stride(unpack, width, format, type); 159 const GLint rowLength = width * _mesa_get_format_bytes(rb->Format); 160 GLint i; 161 GLubyte *dst; 162 GLint dstRowStride; 163 164 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 165 GL_MAP_WRITE_BIT, &dst, &dstRowStride); 166 167 if (!dst) { 168 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 169 return; 170 } 171 172 if (ctx->Pixel.ZoomY == -1.0f) { 173 dst = dst + (height - 1) * dstRowStride; 174 dstRowStride = -dstRowStride; 175 } 176 177 for (i = 0; i < height; i++) { 178 memcpy(dst, src, rowLength); 179 dst += dstRowStride; 180 src += srcRowStride; 181 } 182 183 ctx->Driver.UnmapRenderbuffer(ctx, rb); 184 } 185 186 187 /** 188 * Try to do a fast and simple RGB(a) glDrawPixels. 189 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead 190 */ 191 static GLboolean 192 fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y, 193 GLsizei width, GLsizei height, 194 GLenum format, GLenum type, 195 const struct gl_pixelstore_attrib *userUnpack, 196 const GLvoid *pixels) 197 { 198 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 199 SWcontext *swrast = SWRAST_CONTEXT(ctx); 200 struct gl_pixelstore_attrib unpack; 201 202 if (!rb) 203 return GL_TRUE; /* no-op */ 204 205 if (ctx->DrawBuffer->_NumColorDrawBuffers > 1 || 206 (swrast->_RasterMask & ~CLIP_BIT) || 207 ctx->Texture._EnabledCoordUnits || 208 userUnpack->SwapBytes || 209 ctx->Pixel.ZoomX != 1.0f || 210 fabsf(ctx->Pixel.ZoomY) != 1.0f || 211 ctx->_ImageTransferState) { 212 /* can't handle any of those conditions */ 213 return GL_FALSE; 214 } 215 216 unpack = *userUnpack; 217 218 /* clipping */ 219 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &unpack)) { 220 /* image was completely clipped: no-op, all done */ 221 return GL_TRUE; 222 } 223 224 if (format == GL_RGB && 225 type == GL_UNSIGNED_BYTE && 226 (rb->Format == MESA_FORMAT_XRGB8888 || 227 rb->Format == MESA_FORMAT_ARGB8888)) { 228 fast_draw_rgb_ubyte_pixels(ctx, rb, x, y, width, height, 229 &unpack, pixels); 230 return GL_TRUE; 231 } 232 233 if (format == GL_RGBA && 234 type == GL_UNSIGNED_BYTE && 235 (rb->Format == MESA_FORMAT_XRGB8888 || 236 rb->Format == MESA_FORMAT_ARGB8888)) { 237 fast_draw_rgba_ubyte_pixels(ctx, rb, x, y, width, height, 238 &unpack, pixels); 239 return GL_TRUE; 240 } 241 242 if (_mesa_format_matches_format_and_type(rb->Format, format, type, 243 ctx->Unpack.SwapBytes)) { 244 fast_draw_generic_pixels(ctx, rb, x, y, width, height, 245 format, type, &unpack, pixels); 246 return GL_TRUE; 247 } 248 249 /* can't handle this pixel format and/or data type */ 250 return GL_FALSE; 251 } 252 253 254 255 /* 256 * Draw stencil image. 257 */ 258 static void 259 draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y, 260 GLsizei width, GLsizei height, 261 GLenum type, 262 const struct gl_pixelstore_attrib *unpack, 263 const GLvoid *pixels ) 264 { 265 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 266 const GLenum destType = GL_UNSIGNED_BYTE; 267 GLint row; 268 GLubyte *values; 269 270 values = (GLubyte *) malloc(width * sizeof(GLubyte)); 271 if (!values) { 272 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 273 return; 274 } 275 276 for (row = 0; row < height; row++) { 277 const GLvoid *source = _mesa_image_address2d(unpack, pixels, 278 width, height, 279 GL_STENCIL_INDEX, type, 280 row, 0); 281 _mesa_unpack_stencil_span(ctx, width, destType, values, 282 type, source, unpack, 283 ctx->_ImageTransferState); 284 if (zoom) { 285 _swrast_write_zoomed_stencil_span(ctx, x, y, width, 286 x, y, values); 287 } 288 else { 289 _swrast_write_stencil_span(ctx, width, x, y, values); 290 } 291 292 y++; 293 } 294 295 free(values); 296 } 297 298 299 /* 300 * Draw depth image. 301 */ 302 static void 303 draw_depth_pixels( struct gl_context *ctx, GLint x, GLint y, 304 GLsizei width, GLsizei height, 305 GLenum type, 306 const struct gl_pixelstore_attrib *unpack, 307 const GLvoid *pixels ) 308 { 309 const GLboolean scaleOrBias 310 = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; 311 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 312 SWspan span; 313 314 INIT_SPAN(span, GL_BITMAP); 315 span.arrayMask = SPAN_Z; 316 _swrast_span_default_attribs(ctx, &span); 317 318 if (type == GL_UNSIGNED_SHORT 319 && ctx->DrawBuffer->Visual.depthBits == 16 320 && !scaleOrBias 321 && !zoom 322 && width <= SWRAST_MAX_WIDTH 323 && !unpack->SwapBytes) { 324 /* Special case: directly write 16-bit depth values */ 325 GLint row; 326 for (row = 0; row < height; row++) { 327 const GLushort *zSrc = (const GLushort *) 328 _mesa_image_address2d(unpack, pixels, width, height, 329 GL_DEPTH_COMPONENT, type, row, 0); 330 GLint i; 331 for (i = 0; i < width; i++) 332 span.array->z[i] = zSrc[i]; 333 span.x = x; 334 span.y = y + row; 335 span.end = width; 336 _swrast_write_rgba_span(ctx, &span); 337 } 338 } 339 else if (type == GL_UNSIGNED_INT 340 && !scaleOrBias 341 && !zoom 342 && width <= SWRAST_MAX_WIDTH 343 && !unpack->SwapBytes) { 344 /* Special case: shift 32-bit values down to Visual.depthBits */ 345 const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits; 346 GLint row; 347 for (row = 0; row < height; row++) { 348 const GLuint *zSrc = (const GLuint *) 349 _mesa_image_address2d(unpack, pixels, width, height, 350 GL_DEPTH_COMPONENT, type, row, 0); 351 if (shift == 0) { 352 memcpy(span.array->z, zSrc, width * sizeof(GLuint)); 353 } 354 else { 355 GLint col; 356 for (col = 0; col < width; col++) 357 span.array->z[col] = zSrc[col] >> shift; 358 } 359 span.x = x; 360 span.y = y + row; 361 span.end = width; 362 _swrast_write_rgba_span(ctx, &span); 363 } 364 } 365 else { 366 /* General case */ 367 const GLuint depthMax = ctx->DrawBuffer->_DepthMax; 368 GLint skipPixels = 0; 369 370 /* in case width > SWRAST_MAX_WIDTH do the copy in chunks */ 371 while (skipPixels < width) { 372 const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH); 373 GLint row; 374 ASSERT(span.end <= SWRAST_MAX_WIDTH); 375 for (row = 0; row < height; row++) { 376 const GLvoid *zSrc = _mesa_image_address2d(unpack, 377 pixels, width, height, 378 GL_DEPTH_COMPONENT, type, 379 row, skipPixels); 380 381 /* Set these for each row since the _swrast_write_* function may 382 * change them while clipping. 383 */ 384 span.x = x + skipPixels; 385 span.y = y + row; 386 span.end = spanWidth; 387 388 _mesa_unpack_depth_span(ctx, spanWidth, 389 GL_UNSIGNED_INT, span.array->z, depthMax, 390 type, zSrc, unpack); 391 if (zoom) { 392 _swrast_write_zoomed_depth_span(ctx, x, y, &span); 393 } 394 else { 395 _swrast_write_rgba_span(ctx, &span); 396 } 397 } 398 skipPixels += spanWidth; 399 } 400 } 401 } 402 403 404 405 /** 406 * Draw RGBA image. 407 */ 408 static void 409 draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, 410 GLsizei width, GLsizei height, 411 GLenum format, GLenum type, 412 const struct gl_pixelstore_attrib *unpack, 413 const GLvoid *pixels ) 414 { 415 const GLint imgX = x, imgY = y; 416 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 417 GLfloat *convImage = NULL; 418 GLbitfield transferOps = ctx->_ImageTransferState; 419 SWspan span; 420 421 /* Try an optimized glDrawPixels first */ 422 if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type, 423 unpack, pixels)) { 424 return; 425 } 426 427 swrast_render_start(ctx); 428 429 INIT_SPAN(span, GL_BITMAP); 430 _swrast_span_default_attribs(ctx, &span); 431 span.arrayMask = SPAN_RGBA; 432 span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */ 433 434 if (ctx->DrawBuffer->_NumColorDrawBuffers > 0) { 435 GLenum datatype = _mesa_get_format_datatype( 436 ctx->DrawBuffer->_ColorDrawBuffers[0]->Format); 437 if (datatype != GL_FLOAT && 438 ctx->Color.ClampFragmentColor != GL_FALSE) { 439 /* need to clamp colors before applying fragment ops */ 440 transferOps |= IMAGE_CLAMP_BIT; 441 } 442 } 443 444 /* 445 * General solution 446 */ 447 { 448 const GLbitfield interpMask = span.interpMask; 449 const GLbitfield arrayMask = span.arrayMask; 450 const GLint srcStride 451 = _mesa_image_row_stride(unpack, width, format, type); 452 GLint skipPixels = 0; 453 /* use span array for temp color storage */ 454 GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0]; 455 456 /* if the span is wider than SWRAST_MAX_WIDTH we have to do it in chunks */ 457 while (skipPixels < width) { 458 const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH); 459 const GLubyte *source 460 = (const GLubyte *) _mesa_image_address2d(unpack, pixels, 461 width, height, format, 462 type, 0, skipPixels); 463 GLint row; 464 465 for (row = 0; row < height; row++) { 466 /* get image row as float/RGBA */ 467 _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba, 468 format, type, source, unpack, 469 transferOps); 470 /* Set these for each row since the _swrast_write_* functions 471 * may change them while clipping/rendering. 472 */ 473 span.array->ChanType = GL_FLOAT; 474 span.x = x + skipPixels; 475 span.y = y + row; 476 span.end = spanWidth; 477 span.arrayMask = arrayMask; 478 span.interpMask = interpMask; 479 if (zoom) { 480 _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba); 481 } 482 else { 483 _swrast_write_rgba_span(ctx, &span); 484 } 485 486 source += srcStride; 487 } /* for row */ 488 489 skipPixels += spanWidth; 490 } /* while skipPixels < width */ 491 492 /* XXX this is ugly/temporary, to undo above change */ 493 span.array->ChanType = CHAN_TYPE; 494 } 495 496 if (convImage) { 497 free(convImage); 498 } 499 500 swrast_render_finish(ctx); 501 } 502 503 504 /** 505 * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_S8_Z24 506 * renderbuffer. No masking, zooming, scaling, etc. 507 */ 508 static void 509 fast_draw_depth_stencil(struct gl_context *ctx, GLint x, GLint y, 510 GLsizei width, GLsizei height, 511 const struct gl_pixelstore_attrib *unpack, 512 const GLvoid *pixels) 513 { 514 const GLenum format = GL_DEPTH_STENCIL_EXT; 515 const GLenum type = GL_UNSIGNED_INT_24_8; 516 struct gl_renderbuffer *rb = 517 ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 518 struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 519 GLubyte *src, *dst; 520 GLint srcRowStride, dstRowStride; 521 GLint i; 522 523 src = _mesa_image_address2d(unpack, pixels, width, height, 524 format, type, 0, 0); 525 srcRowStride = _mesa_image_row_stride(unpack, width, format, type); 526 527 dst = _swrast_pixel_address(rb, x, y); 528 dstRowStride = srb->RowStride; 529 530 for (i = 0; i < height; i++) { 531 _mesa_pack_uint_24_8_depth_stencil_row(rb->Format, width, 532 (const GLuint *) src, dst); 533 dst += dstRowStride; 534 src += srcRowStride; 535 } 536 } 537 538 539 540 /** 541 * This is a bit different from drawing GL_DEPTH_COMPONENT pixels. 542 * The only per-pixel operations that apply are depth scale/bias, 543 * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK, 544 * and pixel zoom. 545 * Also, only the depth buffer and stencil buffers are touched, not the 546 * color buffer(s). 547 */ 548 static void 549 draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y, 550 GLsizei width, GLsizei height, GLenum type, 551 const struct gl_pixelstore_attrib *unpack, 552 const GLvoid *pixels) 553 { 554 const GLint imgX = x, imgY = y; 555 const GLboolean scaleOrBias 556 = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; 557 const GLuint stencilMask = ctx->Stencil.WriteMask[0]; 558 const GLenum stencilType = GL_UNSIGNED_BYTE; 559 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 560 struct gl_renderbuffer *depthRb, *stencilRb; 561 struct gl_pixelstore_attrib clippedUnpack = *unpack; 562 563 if (!zoom) { 564 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, 565 &clippedUnpack)) { 566 /* totally clipped */ 567 return; 568 } 569 } 570 571 depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 572 stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 573 ASSERT(depthRb); 574 ASSERT(stencilRb); 575 576 if (depthRb == stencilRb && 577 (depthRb->Format == MESA_FORMAT_Z24_S8 || 578 depthRb->Format == MESA_FORMAT_S8_Z24) && 579 type == GL_UNSIGNED_INT_24_8 && 580 !scaleOrBias && 581 !zoom && 582 ctx->Depth.Mask && 583 (stencilMask & 0xff) == 0xff) { 584 fast_draw_depth_stencil(ctx, x, y, width, height, 585 &clippedUnpack, pixels); 586 } 587 else { 588 /* sub-optimal cases: 589 * Separate depth/stencil buffers, or pixel transfer ops required. 590 */ 591 /* XXX need to handle very wide images (skippixels) */ 592 GLuint *zValues; /* 32-bit Z values */ 593 GLint i; 594 595 zValues = (GLuint *) malloc(width * sizeof(GLuint)); 596 if (!zValues) { 597 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 598 return; 599 } 600 601 for (i = 0; i < height; i++) { 602 const GLuint *depthStencilSrc = (const GLuint *) 603 _mesa_image_address2d(&clippedUnpack, pixels, width, height, 604 GL_DEPTH_STENCIL_EXT, type, i, 0); 605 606 if (ctx->Depth.Mask) { 607 _mesa_unpack_depth_span(ctx, width, 608 GL_UNSIGNED_INT, /* dest type */ 609 zValues, /* dest addr */ 610 0xffffffff, /* depth max */ 611 type, /* src type */ 612 depthStencilSrc, /* src addr */ 613 &clippedUnpack); 614 if (zoom) { 615 _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, 616 y + i, zValues); 617 } 618 else { 619 GLubyte *dst = _swrast_pixel_address(depthRb, x, y + i); 620 _mesa_pack_uint_z_row(depthRb->Format, width, zValues, dst); 621 } 622 } 623 624 if (stencilMask != 0x0) { 625 GLubyte *stencilValues = (GLubyte *) zValues; /* re-use buffer */ 626 /* get stencil values, with shift/offset/mapping */ 627 _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues, 628 type, depthStencilSrc, &clippedUnpack, 629 ctx->_ImageTransferState); 630 if (zoom) 631 _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width, 632 x, y + i, stencilValues); 633 else 634 _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues); 635 } 636 } 637 638 free(zValues); 639 } 640 } 641 642 643 /** 644 * Execute software-based glDrawPixels. 645 * By time we get here, all error checking will have been done. 646 */ 647 void 648 _swrast_DrawPixels( struct gl_context *ctx, 649 GLint x, GLint y, 650 GLsizei width, GLsizei height, 651 GLenum format, GLenum type, 652 const struct gl_pixelstore_attrib *unpack, 653 const GLvoid *pixels ) 654 { 655 SWcontext *swrast = SWRAST_CONTEXT(ctx); 656 GLboolean save_vp_override = ctx->VertexProgram._Overriden; 657 658 if (!_mesa_check_conditional_render(ctx)) 659 return; /* don't draw */ 660 661 /* We are creating fragments directly, without going through vertex 662 * programs. 663 * 664 * This override flag tells the fragment processing code that its input 665 * comes from a non-standard source, and it may therefore not rely on 666 * optimizations that assume e.g. constant color if there is no color 667 * vertex array. 668 */ 669 _mesa_set_vp_override(ctx, GL_TRUE); 670 671 if (ctx->NewState) 672 _mesa_update_state(ctx); 673 674 if (swrast->NewState) 675 _swrast_validate_derived( ctx ); 676 677 pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 678 if (!pixels) { 679 _mesa_set_vp_override(ctx, save_vp_override); 680 return; 681 } 682 683 /* 684 * By time we get here, all error checking should have been done. 685 */ 686 switch (format) { 687 case GL_STENCIL_INDEX: 688 swrast_render_start(ctx); 689 draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels ); 690 swrast_render_finish(ctx); 691 break; 692 case GL_DEPTH_COMPONENT: 693 swrast_render_start(ctx); 694 draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels ); 695 swrast_render_finish(ctx); 696 break; 697 case GL_DEPTH_STENCIL_EXT: 698 swrast_render_start(ctx); 699 draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels); 700 swrast_render_finish(ctx); 701 break; 702 default: 703 /* all other formats should be color formats */ 704 draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels); 705 } 706 707 _mesa_set_vp_override(ctx, save_vp_override); 708 709 _mesa_unmap_pbo_source(ctx, unpack); 710 } 711