Rewrite much of the pixel zoom code.
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 29 Sep 2005 03:20:15 +0000 (03:20 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 29 Sep 2005 03:20:15 +0000 (03:20 +0000)
Zoomed DrawPixels of packed depth/stencil works now.

src/mesa/swrast/s_copypix.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_readpix.c
src/mesa/swrast/s_zoom.c
src/mesa/swrast/s_zoom.h

index 4b8c7c4..99989b0 100644 (file)
@@ -226,19 +226,17 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) {
          drawRb->PutRow(ctx, drawRb, width, destx, dy, span.array->rgba, NULL);
       }
-      else if (zoom) {
-         span.x = destx;
-         span.y = dy;
-         span.end = width;
-         _swrast_write_zoomed_rgba_span(ctx, &span, 
-                                     (CONST GLchan (*)[4])span.array->rgba,
-                                     desty, 0);
-      }
       else {
          span.x = destx;
          span.y = dy;
          span.end = width;
-         _swrast_write_rgba_span(ctx, &span);
+         if (zoom) {
+            _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, 
+                                        (CONST GLchan (*)[4])span.array->rgba);
+         }
+         else {
+            _swrast_write_rgba_span(ctx, &span);
+         }
       }
    }
 
@@ -368,19 +366,17 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) {
          drawRb->PutRow(ctx, drawRb, width, destx, dy, span.array->rgba, NULL);
       }
-      else if (zoom) {
-         span.x = destx;
-         span.y = dy;
-         span.end = width;
-         _swrast_write_zoomed_rgba_span(ctx, &span,
-                                     (CONST GLchan (*)[4]) span.array->rgba,
-                                     desty, 0);
-      }
       else {
          span.x = destx;
          span.y = dy;
          span.end = width;
-         _swrast_write_rgba_span(ctx, &span);
+         if (zoom) {
+            _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span,
+                                       (CONST GLchan (*)[4]) span.array->rgba);
+         }
+         else {
+            _swrast_write_rgba_span(ctx, &span);
+         }
       }
    }
 
@@ -481,7 +477,7 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       span.y = dy;
       span.end = width;
       if (zoom)
-         _swrast_write_zoomed_index_span(ctx, &span, desty, 0);
+         _swrast_write_zoomed_index_span(ctx, destx, desty, &span);
       else
          _swrast_write_index_span(ctx, &span);
    }
@@ -585,14 +581,14 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       span.end = width;
       if (fb->Visual.rgbMode) {
          if (zoom)
-            _swrast_write_zoomed_rgba_span( ctx, &span, 
-                            (const GLchan (*)[4])span.array->rgba, desty, 0 );
+            _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, 
+                                       (const GLchan (*)[4]) span.array->rgba);
          else
             _swrast_write_rgba_span(ctx, &span);
       }
       else {
          if (zoom)
-            _swrast_write_zoomed_index_span( ctx, &span, desty, 0 );
+            _swrast_write_zoomed_index_span(ctx, destx, desty, &span);
          else
             _swrast_write_index_span(ctx, &span);
       }
@@ -686,8 +682,8 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
 
       /* Write stencil values */
       if (zoom) {
-         _swrast_write_zoomed_stencil_span( ctx, width, destx, dy,
-                                          stencil, desty, 0 );
+         _swrast_write_zoomed_stencil_span(ctx, destx, desty, width,
+                                           destx, dy, stencil);
       }
       else {
          _swrast_write_stencil_span( ctx, width, destx, dy, stencil );
index c1f33a2..1640459 100644 (file)
@@ -51,6 +51,7 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
                  const struct gl_pixelstore_attrib *unpack,
                  const GLvoid *pixels)
 {
+   const GLint imgX = x, imgY = y;
    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    struct sw_span span;
@@ -77,6 +78,9 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
        && !unpack->SwapBytes
        && !unpack->LsbFirst) {
 
+      /* XXX there's a lot of clipping code here that should be replaced
+       * by a call to _mesa_clip_drawpixels().
+       */
       GLint destX = x;
       GLint destY = y;
       GLint drawWidth = width;           /* actual width drawn */
@@ -84,7 +88,6 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
       GLint skipPixels = unpack->SkipPixels;
       GLint skipRows = unpack->SkipRows;
       GLint rowLength;
-      GLint zoomY0 = 0;
 
       if (unpack->RowLength > 0)
          rowLength = unpack->RowLength;
@@ -145,9 +148,6 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
       else {
          if (drawWidth > MAX_WIDTH)
             return GL_FALSE; /* fall back to general case path */
-
-         /* save Y value of first row */
-         zoomY0 = IROUND(ctx->Current.RasterPos[1]);
       }
 
 
@@ -187,12 +187,11 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
                GLint row;
                for (row=0; row<drawHeight; row++) {
                   span.x = destX;
-                  span.y = destY;
+                  span.y = destY + row;
                   span.end = drawWidth;
-                  _swrast_write_zoomed_rgba_span(ctx, &span,
-                                        (CONST GLchan (*)[4]) src, zoomY0, 0);
+                  _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
+                                                 (CONST GLchan (*)[4]) src);
                   src += rowLength * 4;
-                  destY++;
                }
             }
          }
@@ -227,8 +226,8 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
                   span.x = destX;
                   span.y = destY;
                   span.end = drawWidth;
-                  _swrast_write_zoomed_rgb_span(ctx, &span, 
-                                         (CONST GLchan (*)[3]) src, zoomY0, 0);
+                  _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span, 
+                                         (CONST GLchan (*)[3]) src);
                   src += rowLength * 3;
                   destY++;
                }
@@ -289,8 +288,8 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
                   span.x = destX;
                   span.y = destY;
                   span.end = drawWidth;
-                  _swrast_write_zoomed_rgb_span(ctx, &span,
-                             (CONST GLchan (*)[3]) span.array->rgb, zoomY0, 0);
+                  _swrast_write_zoomed_rgb_span(ctx, imgX, imgY, &span,
+                             (CONST GLchan (*)[3]) span.array->rgb);
                   src += rowLength;
                   destY++;
                }
@@ -357,8 +356,8 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
                   span.x = destX;
                   span.y = destY;
                   span.end = drawWidth;
-                  _swrast_write_zoomed_rgba_span(ctx, &span,
-                            (CONST GLchan (*)[4]) span.array->rgba, zoomY0, 0);
+                  _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
+                            (CONST GLchan (*)[4]) span.array->rgba);
                   src += rowLength*2;
                   destY++;
                }
@@ -405,8 +404,8 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
                   span.x = destX;
                   span.y = destY;
                   span.end = drawWidth;
-                  _swrast_write_zoomed_rgba_span(ctx, &span,
-                            (CONST GLchan (*)[4]) span.array->rgba, zoomY0, 0);
+                  _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
+                            (CONST GLchan (*)[4]) span.array->rgba);
                   src += rowLength;
                   destY++;
                }
@@ -457,6 +456,7 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels )
 {
+   const GLint imgX = x, imgY = y;
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    GLint row, skipPixels;
    struct sw_span span;
@@ -473,31 +473,28 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
     */
    skipPixels = 0;
    while (skipPixels < width) {
-      const GLint spanX = x + (zoom ? 0 : skipPixels);
-      GLint spanY = y;
-      const GLint spanEnd = (width - skipPixels > MAX_WIDTH)
-                          ? MAX_WIDTH : (width - skipPixels);
-      ASSERT(spanEnd <= MAX_WIDTH);
-      for (row = 0; row < height; row++, spanY++) {
+      const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
+      ASSERT(spanWidth <= MAX_WIDTH);
+      for (row = 0; row < height; row++) {
          const GLvoid *source = _mesa_image_address2d(unpack, pixels,
                                                       width, height,
                                                       GL_COLOR_INDEX, type,
                                                       row, skipPixels);
-         _mesa_unpack_index_span(ctx, spanEnd, GL_UNSIGNED_INT,
+         _mesa_unpack_index_span(ctx, spanWidth, GL_UNSIGNED_INT,
                                  span.array->index, type, source, unpack,
                                  ctx->_ImageTransferState);
 
          /* These may get changed during writing/clipping */
-         span.x = spanX;
-         span.y = spanY;
-         span.end = spanEnd;
+         span.x = x + skipPixels;
+         span.y = y + row;
+         span.end = spanWidth;
          
          if (zoom)
-            _swrast_write_zoomed_index_span(ctx, &span, y, skipPixels);
+            _swrast_write_zoomed_index_span(ctx, imgX, imgY, &span);
          else
             _swrast_write_index_span(ctx, &span);
       }
-      skipPixels += spanEnd;
+      skipPixels += spanWidth;
    }
 }
 
@@ -513,19 +510,17 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
                      const struct gl_pixelstore_attrib *unpack,
                      const GLvoid *pixels )
 {
-   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
-   const GLint desty = y;
-   GLint row, skipPixels;
+   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
+   GLint skipPixels;
 
    /* if width > MAX_WIDTH, have to process image in chunks */
    skipPixels = 0;
    while (skipPixels < width) {
-      const GLint spanX = x;
-      GLint spanY = y;
-      const GLint spanWidth = (width - skipPixels > MAX_WIDTH)
-                            ? MAX_WIDTH : (width - skipPixels);
-
-      for (row = 0; row < height; row++, spanY++) {
+      const GLint spanX = x + skipPixels;
+      const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
+      GLint row;
+      for (row = 0; row < height; row++) {
+         const GLint spanY = y + row;
          GLstencil values[MAX_WIDTH];
          GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
                          ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
@@ -544,8 +539,8 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
          }
 
          if (zoom) {
-            _swrast_write_zoomed_stencil_span(ctx, (GLuint) spanWidth,
-                                            spanX, spanY, values, desty, 0);
+            _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
+                                              spanX, spanY, values);
          }
          else {
             _swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values);
@@ -566,10 +561,11 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels )
 {
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
+   struct gl_renderbuffer *rb
+      = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+   const GLboolean scaleOrBias
+      = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
-   const GLint desty = y;
    struct sw_span span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
@@ -582,14 +578,14 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
       _swrast_span_default_texcoords(ctx, &span);
 
    if (type == GL_UNSIGNED_SHORT
-       && fb->Visual.depthBits == 16
-       && !bias_or_scale
+       && rb->DepthBits == 16
+       && !scaleOrBias
        && !zoom
        && ctx->Visual.rgbMode
        && width <= MAX_WIDTH) {
       /* Special case: directly write 16-bit depth values */
-      GLint row, spanY = y;
-      for (row = 0; row < height; row++, spanY++) {
+      GLint row;
+      for (row = 0; row < height; row++) {
          const GLushort *zSrc = (const GLushort *)
             _mesa_image_address2d(unpack, pixels, width, height,
                                   GL_DEPTH_COMPONENT, type, row, 0);
@@ -597,20 +593,20 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
          for (i = 0; i < width; i++)
             span.array->z[i] = zSrc[i];
          span.x = x;
-         span.y = spanY;
+         span.y = y + row;
          span.end = width;
          _swrast_write_rgba_span(ctx, &span);
       }
    }
    else if (type == GL_UNSIGNED_INT
-            && !bias_or_scale
+            && !scaleOrBias
             && !zoom
             && ctx->Visual.rgbMode
             && width <= MAX_WIDTH) {
       /* Special case: shift 32-bit values down to Visual.depthBits */
-      const GLint shift = 32 - fb->Visual.depthBits;
-      GLint row, spanY = y;
-      for (row = 0; row < height; row++, spanY++) {
+      const GLint shift = 32 - rb->DepthBits;
+      GLint row;
+      for (row = 0; row < height; row++) {
          const GLuint *zSrc = (const GLuint *)
             _mesa_image_address2d(unpack, pixels, width, height,
                                   GL_DEPTH_COMPONENT, type, row, 0);
@@ -623,7 +619,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
                span.array->z[col] = zSrc[col] >> shift;
          }
          span.x = x;
-         span.y = spanY;
+         span.y = y + row;
          span.end = width;
          _swrast_write_rgba_span(ctx, &span);
       }
@@ -631,16 +627,14 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
    else {
       /* General case */
       const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
-      GLint row, skipPixels = 0;
+      GLint skipPixels = 0;
 
       /* in case width > MAX_WIDTH do the copy in chunks */
       while (skipPixels < width) {
-         const GLint spanX = x + (zoom ? 0 : skipPixels);
-         GLint spanY = y;
-         const GLint spanEnd = (width - skipPixels > MAX_WIDTH)
-                             ? MAX_WIDTH : (width - skipPixels);
+         const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
+         GLint row;
          ASSERT(span.end <= MAX_WIDTH);
-         for (row = 0; row < height; row++, spanY++) {
+         for (row = 0; row < height; row++) {
             const GLvoid *zSrc = _mesa_image_address2d(unpack,
                                                       pixels, width, height,
                                                       GL_DEPTH_COMPONENT, type,
@@ -649,15 +643,15 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
             /* Set these for each row since the _swrast_write_* function may
              * change them while clipping.
              */
-            span.x = spanX;
-            span.y = spanY;
-            span.end = spanEnd;
+            span.x = x + skipPixels;
+            span.y = y + row;
+            span.end = spanWidth;
 
-            _mesa_unpack_depth_span(ctx, span.end,
+            _mesa_unpack_depth_span(ctx, spanWidth,
                                     GL_UNSIGNED_INT, span.array->z, depthMax,
                                     type, zSrc, unpack);
             if (zoom) {
-               _swrast_write_zoomed_depth_span(ctx, &span, desty, skipPixels);
+               _swrast_write_zoomed_depth_span(ctx, x, y, &span);
             }
             else if (ctx->Visual.rgbMode) {
                _swrast_write_rgba_span(ctx, &span);
@@ -666,7 +660,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
                _swrast_write_index_span(ctx, &span);
             }
          }
-         skipPixels += spanEnd;
+         skipPixels += spanWidth;
       }
    }
 }
@@ -683,9 +677,9 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
 {
+   const GLint imgX = x, imgY = y;
    struct gl_renderbuffer *rb = NULL; /* only used for quickDraw path */
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
-   const GLint desty = y;
    GLboolean quickDraw;
    GLfloat *convImage = NULL;
    GLuint transferOps = ctx->_ImageTransferState;
@@ -773,30 +767,29 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
    {
       const GLbitfield interpMask = span.interpMask;
       const GLbitfield arrayMask = span.arrayMask;
-      GLint row, skipPixels = 0;
+      GLint skipPixels = 0;
 
       /* if the span is wider than MAX_WIDTH we have to do it in chunks */
       while (skipPixels < width) {
-         const GLint spanX = x + (zoom ? 0 : skipPixels);
-         GLint spanY = y;
-         const GLint spanEnd = (width - skipPixels > MAX_WIDTH)
-                             ? MAX_WIDTH : (width - skipPixels);
+         const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
+         GLint row;
+
          ASSERT(span.end <= MAX_WIDTH);
 
-         for (row = 0; row < height; row++, spanY++) {
+         for (row = 0; row < height; row++) {
             const GLvoid *source = _mesa_image_address2d(unpack,
                      pixels, width, height, format, type, row, skipPixels);
 
             /* Set these for each row since the _swrast_write_* function may
              * change them while clipping.
              */
-            span.x = spanX;
-            span.y = spanY;
-            span.end = spanEnd;
+            span.x = x + skipPixels;
+            span.y = y + row;
+            span.end = spanWidth;
             span.arrayMask = arrayMask;
             span.interpMask = interpMask;
 
-            _mesa_unpack_color_span_chan(ctx, span.end, GL_RGBA,
+            _mesa_unpack_color_span_chan(ctx, spanWidth, GL_RGBA,
                                          (GLchan *) span.array->rgba,
                                          format, type, source, unpack,
                                          transferOps);
@@ -815,15 +808,15 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                           span.array->rgba, NULL);
             }
             else if (zoom) {
-               _swrast_write_zoomed_rgba_span(ctx, &span,
-                    (CONST GLchan (*)[4]) span.array->rgba, desty, skipPixels);
+               _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
+                                       (CONST GLchan (*)[4]) span.array->rgba);
             }
             else {
                _swrast_write_rgba_span(ctx, &span);
             }
          }
 
-         skipPixels += spanEnd;
+         skipPixels += spanWidth;
       }
    }
 
@@ -840,6 +833,7 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                           const struct gl_pixelstore_attrib *unpack,
                           const GLvoid *pixels)
 {
+   const GLint imgX = x, imgY = y;
    const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF;
    const GLuint stencilMask = ctx->Stencil.WriteMask[0];
    const GLuint stencilType = (STENCIL_BITS == 8) ? 
@@ -863,7 +857,7 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
       }
    }
 
-   /* XXX need to do pixelzoom! */
+   /* XXX need to handle very wide images (skippixels) */
 
    for (i = 0; i < height; i++) {
       const GLuint *depthStencilSrc = (const GLuint *)
@@ -881,7 +875,8 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                zValues[j] = depthStencilSrc[j] >> 8;
             }
             if (zoom)
-               ;
+               _swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
+                                           x, y + i, zValues);
             else
                depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
          }
@@ -895,20 +890,24 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                zValues[j] = depthStencilSrc[j] >> 16;
             }
             if (zoom)
-               ;
+               _swrast_write_zoomed_z_span(ctx, imgX, imgY, width,
+                                           x, y + i, zValues);
             else
                depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
          }
          else {
             /* general case */
-            GLuint zValues[MAX_WIDTH];
+            GLuint zValues[MAX_WIDTH];  /* 16 or 32-bit Z value storage */
             _mesa_unpack_depth_span(ctx, width,
                                     depthRb->DataType, zValues, depthScale,
                                     type, depthStencilSrc, &clippedUnpack);
-            if (zoom)
-               ;
-            else
+            if (zoom) {
+               _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
+                                           y + i, zValues);
+            }
+            else {
                depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL);
+            }
          }
       }
 
@@ -919,7 +918,8 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                                    type, depthStencilSrc, &clippedUnpack,
                                    ctx->_ImageTransferState);
          if (zoom)
-            ;
+            _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
+                                               x, y + i, stencilValues);
          else
             _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
       }
index 984205d..cae8972 100644 (file)
@@ -53,9 +53,7 @@ read_index_pixels( GLcontext *ctx,
    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
    GLint i;
 
-   if (!rb) {
-      return;  /* no readbuffer OK */
-   }
+   ASSERT(rb);
 
    /* width should never be > MAX_WIDTH since we did clipping earlier */
    ASSERT(width <= MAX_WIDTH);
@@ -99,9 +97,7 @@ read_depth_pixels( GLcontext *ctx,
    /* width should never be > MAX_WIDTH since we did clipping earlier */
    ASSERT(width <= MAX_WIDTH);
 
-   if (!rb) {
-      return;  /* no readbuffer OK */
-   }
+   ASSERT(rb);
 
    bias_or_scale = ctx->Pixel.DepthBias != 0.0 || ctx->Pixel.DepthScale != 1.0;
 
@@ -175,10 +171,7 @@ read_stencil_pixels( GLcontext *ctx,
    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
    GLint j;
 
-   if (!rb) {
-      /* no readbuffer - OK */
-      return;
-   }
+   ASSERT(rb);
 
    /* width should never be > MAX_WIDTH since we did clipping earlier */
    ASSERT(width <= MAX_WIDTH);
@@ -291,10 +284,7 @@ read_rgba_pixels( GLcontext *ctx,
    struct gl_framebuffer *fb = ctx->ReadBuffer;
    struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
 
-   if (!rb) {
-      /* No readbuffer is OK with GL_EXT_framebuffer_object */
-      return;
-   }
+   ASSERT(rb);
 
    /* Try optimized path first */
    if (read_fast_rgba_pixels( ctx, x, y, width, height,
index dfbc691..41feb11 100644 (file)
 #include "s_zoom.h"
 
 
-/*
- * Helper function called from _swrast_write_zoomed_rgba/rgb/index_span().
+/**
+ * Compute the bounds of the region resulting from zooming a pixel span.
+ * The resulting region will be entirely inside the window/scissor bounds
+ * so no additional clipping is needed.
+ * \param imageX, imageY  position of the overall image being drawn
+ * \param spanX, spanY  position of span being drawing
+ * \param x0, x1  returned X bounds of zoomed region [x0, x1)
+ * \param y0, y1  returned Y bounds of zoomed region [y0, y1)
+ * \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped
+ */
+static GLboolean
+compute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY,
+                      GLint spanX, GLint spanY, GLint width,
+                      GLint *x0, GLint *x1, GLint *y0, GLint *y1)
+{
+   const struct gl_framebuffer *fb = ctx->DrawBuffer;
+   GLint c0, c1, r0, r1;
+
+   ASSERT(spanX >= imageX);
+   ASSERT(spanY >= imageY);
+
+   /*
+    * Compute destination columns: [c0, c1)
+    */
+   c0 = imageX + (GLint) ((spanX - imageX) * ctx->Pixel.ZoomX);
+   c1 = imageX + (GLint) ((spanX + width - imageX) * ctx->Pixel.ZoomX);
+   if (c1 < c0) {
+      /* swap */
+      GLint tmp = c1;
+      c1 = c0;
+      c0 = tmp;
+   }
+   c0 = CLAMP(c0, fb->_Xmin, fb->_Xmax);
+   c1 = CLAMP(c1, fb->_Xmin, fb->_Xmax);
+   if (c0 == c1) {
+      return GL_FALSE; /* no width */
+   }
+
+   /*
+    * Compute destination rows: [r0, r1)
+    */
+   r0 = imageY + (GLint) ((spanY - imageY) * ctx->Pixel.ZoomY);
+   r1 = imageY + (GLint) ((spanY + 1 - imageY) * ctx->Pixel.ZoomY);
+   if (r1 < r0) {
+      /* swap */
+      GLint tmp = r1;
+      r1 = r0;
+      r0 = tmp;
+   }
+   r0 = CLAMP(r0, fb->_Ymin, fb->_Ymax);
+   r1 = CLAMP(r1, fb->_Ymin, fb->_Ymax);
+   if (r0 == r1) {
+      return GL_FALSE; /* no height */
+   }
+
+   *x0 = c0;
+   *x1 = c1;
+   *y0 = r0;
+   *y1 = r1;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Can use this for unzooming X or Y values.
+ */
+static INLINE GLint
+unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
+{
+   /*
+   zx = imageX + (x - imageX) * zoomX;
+   zx - imageX = (x - imageX) * zoomX;
+   (zx - imageX) / zoomX = x - imageX;
+   */
+   GLint x = imageX + (GLint) ((zx - imageX) / zoomX);
+   return x;
+}
+
+
+
+/**
+ * Helper function called from _swrast_write_zoomed_rgba/rgb/
+ * index/depth_span().
  */
 static void
-zoom_span( GLcontext *ctx, const struct sw_span *span,
-           const GLvoid *src, GLint y0, GLenum format, GLint skipPixels )
+zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const struct sw_span *span,
+           const GLvoid *src, GLenum format )
 {
-   GLint r0, r1, row;
-   GLint c0, c1, skipCol;
-   GLint i, j;
-   const GLuint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
    struct sw_span zoomed;
    struct span_arrays zoomed_arrays;  /* this is big! */
+   GLint x0, x1, y0, y1;
+   GLint zoomedWidth;
+
+   if (!compute_zoomed_bounds(ctx, imgX, imgY, span->x, span->y, span->end,
+                              &x0, &x1, &y0, &y1)) {
+      return;  /* totally clipped */
+   }
+
+   zoomedWidth = x1 - x0;
+   ASSERT(zoomedWidth > 0);
+   ASSERT(zoomedWidth <= MAX_WIDTH);
 
    /* no pixel arrays! must be horizontal spans. */
    ASSERT((span->arrayMask & SPAN_XY) == 0);
    ASSERT(span->primitive == GL_BITMAP);
 
    INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
+   zoomed.x = x0;
+   zoomed.end = zoomedWidth;
    zoomed.array = &zoomed_arrays;
 
    /* copy fog interp info */
@@ -66,6 +157,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
       /* we'll generate an array of colorss */
       zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
       zoomed.arrayMask |= SPAN_RGBA;
+      ASSERT(span->arrayMask & SPAN_RGBA);
    }
    else if (format == GL_COLOR_INDEX) {
       /* copy Z info */
@@ -74,6 +166,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
       /* we'll generate an array of color indexes */
       zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
       zoomed.arrayMask |= SPAN_INDEX;
+      ASSERT(span->arrayMask & SPAN_INDEX);
    }
    else if (format == GL_DEPTH_COMPONENT) {
       /* Copy color info */
@@ -88,203 +181,58 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
       /* we'll generate an array of depth values */
       zoomed.interpMask = span->interpMask & ~SPAN_Z;
       zoomed.arrayMask |= SPAN_Z;
-   }
-   else if (format == GL_DEPTH_COMPONENT16 ||
-            format == GL_DEPTH_COMPONENT32) {
-      /* writing Z values directly to depth buffer, bypassing fragment ops */
+      ASSERT(span->arrayMask & SPAN_Z);
    }
    else {
       _mesa_problem(ctx, "Bad format in zoom_span");
       return;
    }
 
-   /*
-    * Compute which columns to draw: [c0, c1)
-    */
-   c0 = (GLint) (span->x + skipPixels * ctx->Pixel.ZoomX);
-   c1 = (GLint) (span->x + (skipPixels + span->end) * ctx->Pixel.ZoomX);
-   if (c0 == c1) {
-      return;
-   }
-   else if (c1 < c0) {
-      /* swap */
-      GLint ctmp = c1;
-      c1 = c0;
-      c0 = ctmp;
-   }
-   if (c0 < 0) {
-      zoomed.x = 0;
-      zoomed.start = 0;
-      zoomed.end = c1;
-      skipCol = -c0;
-   }
-   else {
-      zoomed.x = c0;
-      zoomed.start = 0;
-      zoomed.end = c1 - c0;
-      skipCol = 0;
-   }
-   if (zoomed.end > maxWidth)
-      zoomed.end = maxWidth;
-
-   /*
-    * Compute which rows to draw: [r0, r1)
-    */
-   row = span->y - y0;
-   r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
-   r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
-   if (r0 == r1) {
-      return;
-   }
-   else if (r1 < r0) {
-      /* swap */
-      GLint rtmp = r1;
-      r1 = r0;
-      r0 = rtmp;
-   }
-
-   ASSERT(r0 < r1);
-   ASSERT(c0 < c1);
-
-   /*
-    * Trivial clip rejection testing.
-    */
-   if (r1 < 0) /* below window */
-      return;
-   if (r0 >= (GLint) ctx->DrawBuffer->Height) /* above window */
-      return;
-   if (c1 < 0) /* left of window */
-      return;
-   if (c0 >= (GLint) ctx->DrawBuffer->Width) /* right of window */
-      return;
-
    /* zoom the span horizontally */
    if (format == GL_RGBA) {
       const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
-      if (ctx->Pixel.ZoomX == -1.0F) {
-         /* common case */
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = span->end - (j + skipCol) - 1;
-            COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
-         }
-      }
-      else {
-         /* general solution */
-         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = (GLint) ((j + skipCol) * xscale);
-            if (ctx->Pixel.ZoomX < 0.0) {
-               ASSERT(i <= 0);
-               i = span->end + i - 1;
-            }
-            ASSERT(i >= 0);
-            ASSERT(i < (GLint)  span->end);
-            COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
-         }
+      GLint i;
+      for (i = 0; i < zoomedWidth; i++) {
+         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
+         ASSERT(j >= 0);
+         ASSERT(j < span->end);
+         COPY_CHAN4(zoomed.array->rgba[i], rgba[j]);
       }
    }
    else if (format == GL_RGB) {
       const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
-      if (ctx->Pixel.ZoomX == -1.0F) {
-         /* common case */
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = span->end - (j + skipCol) - 1;
-            zoomed.array->rgba[j][0] = rgb[i][0];
-            zoomed.array->rgba[j][1] = rgb[i][1];
-            zoomed.array->rgba[j][2] = rgb[i][2];
-            zoomed.array->rgba[j][3] = CHAN_MAX;
-         }
-      }
-      else {
-         /* general solution */
-         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = (GLint) ((j + skipCol) * xscale);
-            if (ctx->Pixel.ZoomX < 0.0) {
-               ASSERT(i <= 0);
-               i = span->end + i - 1;
-            }
-            ASSERT(i >= 0);
-            ASSERT(i < (GLint) span->end);
-            zoomed.array->rgba[j][0] = rgb[i][0];
-            zoomed.array->rgba[j][1] = rgb[i][1];
-            zoomed.array->rgba[j][2] = rgb[i][2];
-            zoomed.array->rgba[j][3] = CHAN_MAX;
-         }
+      GLint i;
+      for (i = 0; i < zoomedWidth; i++) {
+         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
+         ASSERT(j >= 0);
+         ASSERT(j < span->end);
+         zoomed.array->rgba[i][0] = rgb[j][0];
+         zoomed.array->rgba[i][1] = rgb[j][1];
+         zoomed.array->rgba[i][2] = rgb[j][2];
+         zoomed.array->rgba[i][3] = CHAN_MAX;
       }
    }
    else if (format == GL_COLOR_INDEX) {
       const GLuint *indexes = (const GLuint *) src;
-      if (ctx->Pixel.ZoomX == -1.0F) {
-         /* common case */
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = span->end - (j + skipCol) - 1;
-            zoomed.array->index[j] = indexes[i];
-         }
-      }
-      else {
-         /* general solution */
-         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = (GLint) ((j + skipCol) * xscale);
-            if (ctx->Pixel.ZoomX < 0.0) {
-               ASSERT(i <= 0);
-               i = span->end + i - 1;
-            }
-            ASSERT(i >= 0);
-            ASSERT(i < (GLint) span->end);
-            zoomed.array->index[j] = indexes[i];
-         }
+      GLint i;
+      for (i = 0; i < zoomedWidth; i++) {
+         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
+         ASSERT(j >= 0);
+         ASSERT(j < span->end);
+         zoomed.array->index[i] = indexes[j];
       }
    }
    else if (format == GL_DEPTH_COMPONENT) {
       const GLuint *zValues = (const GLuint *) src;
-      if (ctx->Pixel.ZoomX == -1.0F) {
-         /* common case */
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = span->end - (j + skipCol) - 1;
-            zoomed.array->z[j] = zValues[i];
-         }
-      }
-      else {
-         /* general solution */
-         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
-         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-            i = (GLint) ((j + skipCol) * xscale);
-            if (ctx->Pixel.ZoomX < 0.0) {
-               ASSERT(i <= 0);
-               i = span->end + i - 1;
-            }
-            ASSERT(i >= 0);
-            ASSERT(i < (GLint) span->end);
-            zoomed.array->z[j] = zValues[i];
-         }
+      GLint i;
+      for (i = 0; i < zoomedWidth; i++) {
+         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
+         ASSERT(j >= 0);
+         ASSERT(j < span->end);
+         zoomed.array->z[i] = zValues[j];
       }
       /* Now, fall into either the RGB or COLOR_INDEX path below */
-      if (ctx->Visual.rgbMode)
-         format = GL_RGBA;
-      else
-         format = GL_COLOR_INDEX;
-   }
-   else if (format == GL_DEPTH_COMPONENT32) {
-      /* 32-bit Z values */
-      struct gl_renderbuffer *rb
-         = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
-      const GLuint *zSrc32 = (const GLuint *) src;
-      GLuint zDst32[MAX_WIDTH];
-      const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
-      for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
-         i = (GLint) ((j + skipCol) * xscale);
-         if (ctx->Pixel.ZoomX < 0.0) {
-            ASSERT(i <= 0);
-            i = span->end + i - 1;
-         }
-         ASSERT(i >= 0);
-         ASSERT(i < (GLint) span->end);
-         zDst32[j] = zSrc32[i];
-      }
-      rb->PutRow(ctx, rb, zoomed.end, zoomed.x, zoomed.y, zDst32, NULL);
-      return;
+      format = ctx->Visual.rgbMode ? GL_RGBA : GL_COLOR_INDEX;
    }
 
    /* write the span in rows [r0, r1) */
@@ -295,13 +243,13 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
        */
       GLchan rgbaSave[MAX_WIDTH][4];
       const GLint end = zoomed.end; /* save */
-      if (r1 - r0 > 1) {
+      if (y1 - y0 > 1) {
          MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan));
       }
-      for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
+      for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
          _swrast_write_rgba_span(ctx, &zoomed);
          zoomed.end = end;  /* restore */
-         if (r1 - r0 > 1) {
+         if (y1 - y0 > 1) {
             /* restore the colors */
             MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan));
          }
@@ -310,13 +258,13 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
    else if (format == GL_COLOR_INDEX) {
       GLuint indexSave[MAX_WIDTH];
       const GLint end = zoomed.end; /* save */
-      if (r1 - r0 > 1) {
+      if (y1 - y0 > 1) {
          MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
       }
-      for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
+      for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
          _swrast_write_index_span(ctx, &zoomed);
          zoomed.end = end;  /* restore */
-         if (r1 - r0 > 1) {
+         if (y1 - y0 > 1) {
             /* restore the colors */
             MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
          }
@@ -326,127 +274,126 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
 
 
 void
-_swrast_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
-                              CONST GLchan rgba[][4], GLint y0,
-                              GLint skipPixels )
+_swrast_write_zoomed_rgba_span( GLcontext *ctx, GLint imgX, GLint imgY,
+                               const struct sw_span *span,
+                               CONST GLchan rgba[][4])
 {
-   zoom_span(ctx, span, (const GLvoid *) rgba, y0, GL_RGBA, skipPixels);
+   zoom_span(ctx, imgX, imgY, span, (const GLvoid *) rgba, GL_RGBA);
 }
 
 
 void
-_swrast_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
-                             CONST GLchan rgb[][3], GLint y0,
-                             GLint skipPixels )
+_swrast_write_zoomed_rgb_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                              const struct sw_span *span,
+                              CONST GLchan rgb[][3])
 {
-   zoom_span(ctx, span, (const GLvoid *) rgb, y0, GL_RGB, skipPixels);
+   zoom_span(ctx, imgX, imgY, span, (const GLvoid *) rgb, GL_RGB);
 }
 
 
 void
-_swrast_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
-                               GLint y0, GLint skipPixels )
+_swrast_write_zoomed_index_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                                const struct sw_span *span)
 {
-   zoom_span(ctx, span, (const GLvoid *) span->array->index, y0,
-             GL_COLOR_INDEX, skipPixels);
+   zoom_span(ctx, imgX, imgY, span,
+             (const GLvoid *) span->array->index, GL_COLOR_INDEX);
 }
 
 
 void
-_swrast_write_zoomed_depth_span( GLcontext *ctx, const struct sw_span *span,
-                                 GLint y0, GLint skipPixels )
+_swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                                const struct sw_span *span)
 {
-   zoom_span(ctx, span, (const GLvoid *) span->array->z, y0,
-             GL_DEPTH_COMPONENT, skipPixels);
+   zoom_span(ctx, imgX, imgY, span,
+             (const GLvoid *) span->array->z, GL_DEPTH_COMPONENT);
 }
 
 
-/*
- * As above, but write stencil values.
+/**
+ * Zoom/write stencil values.
+ * No per-fragment operations are applied.
  */
 void
-_swrast_write_zoomed_stencil_span( GLcontext *ctx,
-                                 GLuint n, GLint x, GLint y,
-                                 const GLstencil stencil[], GLint y0,
-                                 GLint skipPixels )
+_swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                                  GLint width, GLint spanX, GLint spanY,
+                                  const GLstencil stencil[])
 {
-   GLint m;
-   GLint r0, r1, row, r;
-   GLint i, j, skipcol;
-   GLstencil zstencil[MAX_WIDTH];  /* zoomed stencil values */
-   GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
-
-   (void) skipPixels;  /* XXX this shouldn't be ignored */
+   GLstencil zoomedVals[MAX_WIDTH];
+   GLint x0, x1, y0, y1, y;
+   GLint i, zoomedWidth;
 
-   /* compute width of output row */
-   m = (GLint) FABSF( n * ctx->Pixel.ZoomX );
-   if (m==0) {
-      return;
-   }
-   if (ctx->Pixel.ZoomX<0.0) {
-      /* adjust x coordinate for left/right mirroring */
-      x = x - m;
+   if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width,
+                              &x0, &x1, &y0, &y1)) {
+      return;  /* totally clipped */
    }
 
-   /* compute which rows to draw */
-   row = y - y0;
-   r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
-   r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
-   if (r0==r1) {
-      return;
-   }
-   else if (r1<r0) {
-      GLint rtmp = r1;
-      r1 = r0;
-      r0 = rtmp;
-   }
+   zoomedWidth = x1 - x0;
+   ASSERT(zoomedWidth > 0);
+   ASSERT(zoomedWidth <= MAX_WIDTH);
 
-   /* return early if r0...r1 is above or below window */
-   if (r0<0 && r1<0) {
-      /* below window */
-      return;
-   }
-   if (r0 >= (GLint) ctx->DrawBuffer->Height &&
-       r1 >= (GLint) ctx->DrawBuffer->Height) {
-      /* above window */
-      return;
+   /* zoom the span horizontally */
+   for (i = 0; i < zoomedWidth; i++) {
+      GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
+      ASSERT(j >= 0);
+      ASSERT(j < width);
+      zoomedVals[i] = stencil[j];
    }
 
-   /* check if left edge is outside window */
-   skipcol = 0;
-   if (x<0) {
-      skipcol = -x;
-      m += x;
-   }
-   /* make sure span isn't too long or short */
-   if (m>maxwidth) {
-      m = maxwidth;
+   /* write the zoomed spans */
+   for (y = y0; y < y1; y++) {
+      _swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals);
    }
-   else if (m<=0) {
-      return;
+}
+
+
+/**
+ * Zoom/write z values (16 or 32-bit).
+ * No per-fragment operations are applied.
+ */
+void
+_swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                            GLint width, GLint spanX, GLint spanY,
+                            const GLvoid *z)
+{
+   struct gl_renderbuffer *rb
+      = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+   GLushort zoomedVals16[MAX_WIDTH];
+   GLuint zoomedVals32[MAX_WIDTH];
+   GLint x0, x1, y0, y1, y;
+   GLint i, zoomedWidth;
+
+   if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width,
+                              &x0, &x1, &y0, &y1)) {
+      return;  /* totally clipped */
    }
 
-   ASSERT( m <= MAX_WIDTH );
+   zoomedWidth = x1 - x0;
+   ASSERT(zoomedWidth > 0);
+   ASSERT(zoomedWidth <= MAX_WIDTH);
 
    /* zoom the span horizontally */
-   if (ctx->Pixel.ZoomX==-1.0F) {
-      /* n==m */
-      for (j=0;j<m;j++) {
-         i = n - (j+skipcol) - 1;
-         zstencil[j] = stencil[i];
+   if (rb->DataType == GL_UNSIGNED_SHORT) {
+      for (i = 0; i < zoomedWidth; i++) {
+         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
+         ASSERT(j >= 0);
+         ASSERT(j < width);
+         zoomedVals16[i] = ((GLushort *) z)[j];
       }
+      z = zoomedVals16;
    }
    else {
-      GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
-      for (j=0;j<m;j++) {
-         i = (GLint) ((j+skipcol) * xscale);
-         if (i<0)  i = n + i - 1;
-         zstencil[j] = stencil[i];
+      ASSERT(rb->DataType == GL_UNSIGNED_INT);
+      for (i = 0; i < zoomedWidth; i++) {
+         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
+         ASSERT(j >= 0);
+         ASSERT(j < width);
+         zoomedVals32[i] = ((GLuint *) z)[j];
       }
+      z = zoomedVals32;
    }
 
-   /* write the span */
-   for (r=r0; r<r1; r++) {
-      _swrast_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
+   /* write the zoomed spans */
+   for (y = y0; y < y1; y++) {
+      rb->PutRow(ctx, rb, zoomedWidth, x0, y, z, NULL);
    }
 }
index aa9a891..d10c270 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.5
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "mtypes.h"
 #include "swrast.h"
 
+
 extern void
-_swrast_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
-                                CONST GLchan rgb[][4], GLint y0,
-                                GLint skipPixels );
+_swrast_write_zoomed_rgba_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                               const struct sw_span *span,
+                               CONST GLchan rgb[][4]);
 
 extern void
-_swrast_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
-                               CONST GLchan rgb[][3], GLint y0,
-                               GLint skipPixels );
+_swrast_write_zoomed_rgb_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                              const struct sw_span *span,
+                              CONST GLchan rgb[][3]);
 
 extern void
-_swrast_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
-                                 GLint y0, GLint skipPixels );
+_swrast_write_zoomed_index_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                                const struct sw_span *span);
 
 extern void
-_swrast_write_zoomed_depth_span( GLcontext *ctx, const struct sw_span *span,
-                                 GLint y0, GLint skipPixels );
+_swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                                const struct sw_span *span);
+
 
 extern void
-_swrast_write_zoomed_stencil_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                                   const GLstencil stencil[], GLint y0,
-                                   GLint skipPixels );
+_swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                                  GLint width, GLint spanX, GLint spanY,
+                                  const GLstencil stencil[]);
+
+extern void
+_swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY,
+                            GLint width, GLint spanX, GLint spanY,
+                            const GLvoid *z);
+
 
 #endif