/*
 * Draw color index image.
 */
static void
draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
                   GLsizei width, GLsizei height,
                   GLenum type,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
{
   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
   GLint row, skipPixels;
   struct sw_span span;

   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);

   if (ctx->Depth.Test)
      _swrast_span_default_z(ctx, &span);
   if (ctx->Fog.Enabled)
      _swrast_span_default_fog(ctx, &span);

   /*
    * General solution
    */
   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 GLvoid *source = _mesa_image_address2d(unpack, pixels,
                                                      width, height,
                                                      GL_COLOR_INDEX, type,
                                                      row, skipPixels);
         _mesa_unpack_index_span(ctx, spanEnd, 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;
         
         if (zoom)
            _swrast_write_zoomed_index_span(ctx, &span, y, skipPixels);
         else
            _swrast_write_index_span(ctx, &span);
      }
      skipPixels += spanEnd;
   }
}
Exemple #2
0
/*
 * Draw color index image.
 */
static void
draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
                   GLsizei width, GLsizei height,
                   GLenum type,
                   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;
   SWspan span;

   INIT_SPAN(span, GL_BITMAP);
   span.arrayMask = SPAN_INDEX;
   _swrast_span_default_attribs(ctx, &span);

   /*
    * General solution
    */
   skipPixels = 0;
   while (skipPixels < width) {
      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, spanWidth, GL_UNSIGNED_INT,
                                 span.array->index, type, source, unpack,
                                 ctx->_ImageTransferState);

         /* These may get changed during writing/clipping */
         span.x = x + skipPixels;
         span.y = y + row;
         span.end = spanWidth;
         
         if (zoom)
            _swrast_write_zoomed_index_span(ctx, imgX, imgY, &span);
         else
            _swrast_write_index_span(ctx, &span);
      }
      skipPixels += spanWidth;
   }
}
Exemple #3
0
/*
 * TODO: Optimize!!!!
 */
static void
copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                   GLint width, GLint height,
                   GLint destx, GLint desty )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   struct gl_framebuffer *fb = ctx->ReadBuffer;
   struct gl_renderbuffer *readRb = fb->_DepthBuffer;
   const GLfloat depthMax = fb->_DepthMaxF;
   GLfloat *p, *tmpImage;
   GLint sy, dy, stepy;
   GLint i, j;
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
   GLint overlapping;
   struct sw_span span;

   if (!readRb) {
      /* no readbuffer - OK */
      return;
   }

   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);

   /* Determine if copy should be bottom-to-top or top-to-bottom */
   if (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 (ctx->DrawBuffer == ctx->ReadBuffer) {
      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
   }
   else {
      overlapping = GL_FALSE;
   }

   _swrast_span_default_color(ctx, &span);
   if (swrast->_FogEnabled)
      _swrast_span_default_fog(ctx, &span);

   if (overlapping) {
      GLint ssy = sy;
      tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
      if (!tmpImage) {
         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
         return;
      }
      p = tmpImage;
      for (j = 0; j < height; j++, ssy += stepy) {
         _swrast_read_depth_span_float(ctx, readRb, 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) {
      GLfloat depth[MAX_WIDTH];
      /* get depth values */
      if (overlapping) {
         _mesa_memcpy(depth, p, width * sizeof(GLfloat));
         p += width;
      }
      else {
         _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);
      }

      /* apply scale and bias */
      for (i = 0; i < width; i++) {
         GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
         span.array->z[i] = (GLuint) (CLAMP(d, 0.0F, 1.0F) * depthMax);
      }

      /* write depth values */
      span.x = destx;
      span.y = dy;
      span.end = width;
      if (fb->Visual.rgbMode) {
         if (zoom)
            _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, destx, desty, &span);
         else
            _swrast_write_index_span(ctx, &span);
      }
   }

   if (overlapping)
      _mesa_free(tmpImage);
}
Exemple #4
0
static void
copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                GLint width, GLint height,
                GLint destx, GLint desty )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLuint *tmpImage,*p;
   GLint sy, dy, stepy;
   GLint j;
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
   const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
   GLint overlapping;
   struct sw_span span;

   if (!ctx->ReadBuffer->_ColorReadBuffer) {
      /* no readbuffer - OK */
      return;
   }

   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);

   /* Determine if copy should be bottom-to-top or top-to-bottom */
   if (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 (ctx->DrawBuffer == ctx->ReadBuffer) {
      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
   }
   else {
      overlapping = GL_FALSE;
   }

   if (ctx->Depth.Test)
      _swrast_span_default_z(ctx, &span);
   if (swrast->_FogEnabled)
      _swrast_span_default_fog(ctx, &span);

   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 );
      }

      /* Apply shift, offset, look-up table */
      if (shift_or_offset) {
         _mesa_shift_and_offset_ci( ctx, width, span.array->index );
      }
      if (ctx->Pixel.MapColorFlag) {
         _mesa_map_ci( ctx, 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);
}
Exemple #5
0
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);
}