Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / swrast / s_copypix.c
index bbe1081860d885a1721ae4caa128fea7f6a4f9ad..86fe3e0a8915576a080484d03e05d57f663e8d25 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.1
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  */
 
 
-#include "glheader.h"
-#include "context.h"
-#include "colormac.h"
-#include "convolve.h"
-#include "histogram.h"
-#include "image.h"
-#include "macros.h"
-#include "imports.h"
-#include "pixel.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/colormac.h"
+#include "main/condrender.h"
+#include "main/image.h"
+#include "main/macros.h"
+#include "main/imports.h"
 
 #include "s_context.h"
 #include "s_depth.h"
@@ -71,13 +69,20 @@ regions_overlap(GLint srcx, GLint srcy,
    }
    else {
       /* add one pixel of slop when zooming, just to be safe */
-      if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) {
+      if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) {
+         /* src is completely right of dest */
+         return GL_FALSE;
+      }
+      else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) {
+         /* src is completely left of dest */
          return GL_FALSE;
       }
       else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
+         /* src is completely below dest */
          return GL_FALSE;
       }
       else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
+         /* src is completely above dest */
          return GL_FALSE;
       }
       else {
@@ -87,107 +92,11 @@ regions_overlap(GLint srcx, GLint srcy,
 }
 
 
-/**
- * RGBA copypixels with convolution.
- */
-static void
-copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
-                      GLint width, GLint height, GLint destx, GLint desty)
-{
-   GLint row;
-   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
-   const GLbitfield transferOps = ctx->_ImageTransferState;
-   const GLboolean sink = (ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink)
-      || (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink);
-   GLfloat *dest, *tmpImage, *convImage;
-   SWspan span;
-
-   INIT_SPAN(span, GL_BITMAP);
-   _swrast_span_default_attribs(ctx, &span);
-   span.arrayMask = SPAN_RGBA;
-   span.arrayAttribs = FRAG_BIT_COL0;
-
-   /* allocate space for GLfloat image */
-   tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
-   if (!tmpImage) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
-      return;
-   }
-   convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
-   if (!convImage) {
-      _mesa_free(tmpImage);
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
-      return;
-   }
-
-   /* read source image as float/RGBA */
-   dest = tmpImage;
-   for (row = 0; row < height; row++) {
-      _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer,
-                             width, srcx, srcy + row, GL_FLOAT, dest);
-      dest += 4 * width;
-   }
-
-   /* do the image transfer ops which preceed convolution */
-   for (row = 0; row < height; row++) {
-      GLfloat (*rgba)[4] = (GLfloat (*)[4]) (tmpImage + row * width * 4);
-      _mesa_apply_rgba_transfer_ops(ctx,
-                                    transferOps & IMAGE_PRE_CONVOLUTION_BITS,
-                                    width, rgba);
-   }
-
-   /* do convolution */
-   if (ctx->Pixel.Convolution2DEnabled) {
-      _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
-   }
-   else {
-      ASSERT(ctx->Pixel.Separable2DEnabled);
-      _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
-   }
-   _mesa_free(tmpImage);
-
-   /* do remaining post-convolution image transfer ops */
-   for (row = 0; row < height; row++) {
-      GLfloat (*rgba)[4] = (GLfloat (*)[4]) (convImage + row * width * 4);
-      _mesa_apply_rgba_transfer_ops(ctx,
-                                    transferOps & IMAGE_POST_CONVOLUTION_BITS,
-                                    width, rgba);
-   }
-
-   if (!sink) {
-      /* write the new image */
-      for (row = 0; row < height; row++) {
-         const GLfloat *src = convImage + row * width * 4;
-         GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0];
-
-         /* copy convolved colors into span array */
-         _mesa_memcpy(rgba, src, width * 4 * sizeof(GLfloat));
-
-         /* write span */
-         span.x = destx;
-         span.y = desty + row;
-         span.end = width;
-         span.array->ChanType = GL_FLOAT;
-         if (zoom) {
-            _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba);
-         }
-         else {
-            _swrast_write_rgba_span(ctx, &span);
-         }
-      }
-      /* restore this */
-      span.array->ChanType = CHAN_TYPE;
-   }
-
-   _mesa_free(convImage);
-}
-
-
 /**
  * RGBA copypixels
  */
 static void
-copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
+copy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
                  GLint width, GLint height, GLint destx, GLint desty)
 {
    GLfloat *tmpImage, *p;
@@ -202,16 +111,6 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       return;
    }
 
-   if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
-      copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty);
-      return;
-   }
-   else if (ctx->Pixel.Convolution1DEnabled) {
-      /* make sure we don't apply 1D convolution */
-      transferOps &= ~(IMAGE_CONVOLUTION_BIT |
-                       IMAGE_POST_CONVOLUTION_SCALE_BIAS);
-   }
-
    if (ctx->DrawBuffer == ctx->ReadBuffer) {
       overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
                                     ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
@@ -240,7 +139,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    span.arrayAttribs = FRAG_BIT_COL0; /* we'll fill in COL0 attrib values */
 
    if (overlapping) {
-      tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4);
+      tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat) * 4);
       if (!tmpImage) {
          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
          return;
@@ -267,7 +166,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       /* Get row/span of source pixels */
       if (overlapping) {
          /* get from buffered image */
-         _mesa_memcpy(rgba, p, width * sizeof(GLfloat) * 4);
+         memcpy(rgba, p, width * sizeof(GLfloat) * 4);
          p += width * 4;
       }
       else {
@@ -297,101 +196,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    span.array->ChanType = CHAN_TYPE; /* restore */
 
    if (overlapping)
-      _mesa_free(tmpImage);
-}
-
-
-static void
-copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
-                GLint width, GLint height,
-                GLint destx, GLint desty )
-{
-   GLuint *tmpImage,*p;
-   GLint sy, dy, stepy;
-   GLint j;
-   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
-   GLint overlapping;
-   SWspan span;
-
-   if (!ctx->ReadBuffer->_ColorReadBuffer) {
-      /* no readbuffer - OK */
-      return;
-   }
-
-   INIT_SPAN(span, GL_BITMAP);
-   _swrast_span_default_attribs(ctx, &span);
-   span.arrayMask = SPAN_INDEX;
-
-   if (ctx->DrawBuffer == ctx->ReadBuffer) {
-      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
-                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
-   }
-   else {
-      overlapping = GL_FALSE;
-   }
-
-   /* Determine if copy should be bottom-to-top or top-to-bottom */
-   if (!overlapping && srcy < desty) {
-      /* top-down  max-to-min */
-      sy = srcy + height - 1;
-      dy = desty + height - 1;
-      stepy = -1;
-   }
-   else {
-      /* bottom-up  min-to-max */
-      sy = srcy;
-      dy = desty;
-      stepy = 1;
-   }
-
-   if (overlapping) {
-      GLint ssy = sy;
-      tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
-      if (!tmpImage) {
-         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
-         return;
-      }
-      /* read the image */
-      p = tmpImage;
-      for (j = 0; j < height; j++, ssy += stepy) {
-         _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
-                                  width, srcx, ssy, p );
-         p += width;
-      }
-      p = tmpImage;
-   }
-   else {
-      tmpImage = NULL;  /* silence compiler warning */
-      p = NULL;
-   }
-
-   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
-      /* Get color indexes */
-      if (overlapping) {
-         _mesa_memcpy(span.array->index, p, width * sizeof(GLuint));
-         p += width;
-      }
-      else {
-         _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
-                                  width, srcx, sy, span.array->index );
-      }
-
-      if (ctx->_ImageTransferState)
-         _mesa_apply_ci_transfer_ops(ctx, ctx->_ImageTransferState,
-                                     width, span.array->index);
-
-      /* write color indexes */
-      span.x = destx;
-      span.y = dy;
-      span.end = width;
-      if (zoom)
-         _swrast_write_zoomed_index_span(ctx, destx, desty, &span);
-      else
-         _swrast_write_index_span(ctx, &span);
-   }
-
-   if (overlapping)
-      _mesa_free(tmpImage);
+      free(tmpImage);
 }
 
 
@@ -400,7 +205,7 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
  * Z scale and bias.
  */
 static void
-scale_and_bias_z(GLcontext *ctx, GLuint width,
+scale_and_bias_z(struct gl_context *ctx, GLuint width,
                  const GLfloat depth[], GLuint z[])
 {
    const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
@@ -435,7 +240,7 @@ scale_and_bias_z(GLcontext *ctx, GLuint width,
  * TODO: Optimize!!!!
  */
 static void
-copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
+copy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
                    GLint width, GLint height,
                    GLint destx, GLint desty )
 {
@@ -481,7 +286,7 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
 
    if (overlapping) {
       GLint ssy = sy;
-      tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
+      tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat));
       if (!tmpImage) {
          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
          return;
@@ -502,7 +307,7 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       GLfloat depth[MAX_WIDTH];
       /* get depth values */
       if (overlapping) {
-         _mesa_memcpy(depth, p, width * sizeof(GLfloat));
+         memcpy(depth, p, width * sizeof(GLfloat));
          p += width;
       }
       else {
@@ -516,28 +321,20 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       span.x = destx;
       span.y = dy;
       span.end = width;
-      if (fb->Visual.rgbMode) {
-         if (zoom)
-            _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
-         else
-            _swrast_write_rgba_span(ctx, &span);
-      }
-      else {
-         if (zoom)
-            _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
-         else
-            _swrast_write_index_span(ctx, &span);
-      }
+      if (zoom)
+         _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
+      else
+         _swrast_write_rgba_span(ctx, &span);
    }
 
    if (overlapping)
-      _mesa_free(tmpImage);
+      free(tmpImage);
 }
 
 
 
 static void
-copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
+copy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
                      GLint width, GLint height,
                      GLint destx, GLint desty )
 {
@@ -578,7 +375,7 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
 
    if (overlapping) {
       GLint ssy = sy;
-      tmpImage = (GLstencil *) _mesa_malloc(width * height * sizeof(GLstencil));
+      tmpImage = (GLstencil *) malloc(width * height * sizeof(GLstencil));
       if (!tmpImage) {
          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
          return;
@@ -600,7 +397,7 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
 
       /* Get stencil values */
       if (overlapping) {
-         _mesa_memcpy(stencil, p, width * sizeof(GLstencil));
+         memcpy(stencil, p, width * sizeof(GLstencil));
          p += width;
       }
       else {
@@ -620,7 +417,7 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    if (overlapping)
-      _mesa_free(tmpImage);
+      free(tmpImage);
 }
 
 
@@ -630,7 +427,7 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
  * CopyPixels function.
  */
 static void
-copy_depth_stencil_pixels(GLcontext *ctx,
+copy_depth_stencil_pixels(struct gl_context *ctx,
                           const GLint srcX, const GLint srcY,
                           const GLint width, const GLint height,
                           const GLint destX, const GLint destY)
@@ -682,7 +479,7 @@ copy_depth_stencil_pixels(GLcontext *ctx,
 
       if (stencilMask != 0x0) {
          tempStencilImage
-            = (GLstencil *) _mesa_malloc(width * height * sizeof(GLstencil));
+            = (GLstencil *) malloc(width * height * sizeof(GLstencil));
          if (!tempStencilImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
             return;
@@ -700,10 +497,10 @@ copy_depth_stencil_pixels(GLcontext *ctx,
 
       if (ctx->Depth.Mask) {
          tempDepthImage
-            = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
+            = (GLfloat *) malloc(width * height * sizeof(GLfloat));
          if (!tempDepthImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
-            _mesa_free(tempStencilImage);
+            free(tempStencilImage);
             return;
          }
 
@@ -724,7 +521,7 @@ copy_depth_stencil_pixels(GLcontext *ctx,
 
          /* Get stencil values */
          if (overlapping) {
-            _mesa_memcpy(stencil, stencilPtr, width * sizeof(GLstencil));
+            memcpy(stencil, stencilPtr, width * sizeof(GLstencil));
             stencilPtr += width;
          }
          else {
@@ -753,7 +550,7 @@ copy_depth_stencil_pixels(GLcontext *ctx,
 
          /* get depth values */
          if (overlapping) {
-            _mesa_memcpy(depth, depthPtr, width * sizeof(GLfloat));
+            memcpy(depth, depthPtr, width * sizeof(GLfloat));
             depthPtr += width;
          }
          else {
@@ -793,10 +590,10 @@ copy_depth_stencil_pixels(GLcontext *ctx,
    }
 
    if (tempStencilImage)
-      _mesa_free(tempStencilImage);
+      free(tempStencilImage);
 
    if (tempDepthImage)
-      _mesa_free(tempDepthImage);
+      free(tempDepthImage);
 }
 
 
@@ -805,7 +602,7 @@ copy_depth_stencil_pixels(GLcontext *ctx,
  * Try to do a fast copy pixels.
  */
 static GLboolean
-fast_copy_pixels(GLcontext *ctx,
+fast_copy_pixels(struct gl_context *ctx,
                  GLint srcX, GLint srcY, GLsizei width, GLsizei height,
                  GLint dstX, GLint dstY, GLenum type)
 {
@@ -823,10 +620,10 @@ fast_copy_pixels(GLcontext *ctx,
    }
 
    if (type == GL_COLOR) {
-      if (dstFb->_NumColorDrawBuffers[0] != 1)
+      if (dstFb->_NumColorDrawBuffers != 1)
          return GL_FALSE;
       srcRb = srcFb->_ColorReadBuffer;
-      dstRb = dstFb->_ColorDrawBuffers[0][0];
+      dstRb = dstFb->_ColorDrawBuffers[0];
    }
    else if (type == GL_STENCIL) {
       srcRb = srcFb->_StencilBuffer;
@@ -887,25 +684,23 @@ fast_copy_pixels(GLcontext *ctx,
  * By time we get here, all parameters will have been error-checked.
  */
 void
-_swrast_CopyPixels( GLcontext *ctx,
+_swrast_CopyPixels( struct gl_context *ctx,
                    GLint srcx, GLint srcy, GLsizei width, GLsizei height,
                    GLint destx, GLint desty, GLenum type )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   RENDER_START(swrast,ctx);
+   swrast_render_start(ctx);
       
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't copy */
+
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
    if (!fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, type)) {
       switch (type) {
       case GL_COLOR:
-         if (ctx->Visual.rgbMode) {
-            copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
-         }
-         else {
-            copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty );
-         }
+         copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
          break;
       case GL_DEPTH:
          copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
@@ -921,5 +716,5 @@ _swrast_CopyPixels( GLcontext *ctx,
       }
    }
 
-   RENDER_FINISH(swrast,ctx);
+   swrast_render_finish(ctx);
 }