void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
			   GLint x, GLint y, GLsizei width)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLchan data[MAX_WIDTH][4];
   struct gl_buffer_object *bufferSave;

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

   if (width > MAX_WIDTH)
      width = MAX_WIDTH;

   RENDER_START( swrast, ctx );

   /* read the data from framebuffer */
   _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
                           width, x, y, CHAN_TYPE, data );

   RENDER_FINISH(swrast,ctx);

   /* save PBO binding */
   bufferSave = ctx->Unpack.BufferObj;
   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;

   _mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);

   /* restore PBO binding */
   ctx->Unpack.BufferObj = bufferSave;
}
void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, 
				GLenum internalFormat, 
				GLint x, GLint y, GLsizei width)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLchan rgba[MAX_CONVOLUTION_WIDTH][4];
   struct gl_buffer_object *bufferSave;

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

   RENDER_START( swrast, ctx );

   /* read the data from framebuffer */
   _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
                           width, x, y, CHAN_TYPE, rgba );
   
   RENDER_FINISH( swrast, ctx );

   /* save PBO binding */
   bufferSave = ctx->Unpack.BufferObj;
   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;

   /* store as convolution filter */
   _mesa_ConvolutionFilter1D(target, internalFormat, width,
                             GL_RGBA, CHAN_TYPE, rgba);

   /* restore PBO binding */
   ctx->Unpack.BufferObj = bufferSave;
}
Beispiel #3
0
/**
 * Do software-based glCopyPixels.
 * By time we get here, all parameters will have been error-checked.
 */
void
_swrast_CopyPixels( GLcontext *ctx,
		    GLint srcx, GLint srcy, GLsizei width, GLsizei height,
		    GLint destx, GLint desty, GLenum type )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   RENDER_START(swrast,ctx);
      
   if (swrast->NewState)
      _swrast_validate_derived( ctx );

   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 );
      }
      break;
   case GL_DEPTH:
      copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
      break;
   case GL_STENCIL:
      copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
      break;
   case GL_DEPTH_STENCIL_EXT:
      copy_depth_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
      break;
   default:
      _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
   }

   RENDER_FINISH(swrast,ctx);
}
Beispiel #4
0
void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, 
				GLenum internalFormat, 
				GLint x, GLint y, GLsizei width)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLchan rgba[MAX_CONVOLUTION_WIDTH][4];

   /* Select buffer to read from */
   _swrast_use_read_buffer(ctx);

   RENDER_START( swrast, ctx );

   /* read the data from framebuffer */
   _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y,
				(GLchan (*)[4]) rgba );
   
   RENDER_FINISH( swrast, ctx );

   /* Restore reading from draw buffer (the default) */
   _swrast_use_draw_buffer(ctx);

   /* store as convolution filter */
   glConvolutionFilter1D(target, internalFormat, width,
			 GL_RGBA, CHAN_TYPE, rgba);
}
void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, 
				GLenum internalFormat, 
				GLint x, GLint y, GLsizei width, GLsizei height)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   struct gl_pixelstore_attrib packSave;
   GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4];
   GLint i;
   struct gl_buffer_object *bufferSave;

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

   RENDER_START(swrast,ctx);
   
   /* read pixels from framebuffer */
   for (i = 0; i < height; i++) {
      _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
                              width, x, y + i, CHAN_TYPE, rgba[i] );
   }

   RENDER_FINISH(swrast,ctx);

   /*
    * HACK: save & restore context state so we can store this as a
    * convolution filter via the GL api.  Doesn't call any callbacks
    * hanging off ctx->Unpack statechanges.
    */

   packSave = ctx->Unpack;  /* save pixel packing params */

   ctx->Unpack.Alignment = 1;
   ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH;
   ctx->Unpack.SkipPixels = 0;
   ctx->Unpack.SkipRows = 0;
   ctx->Unpack.ImageHeight = 0;
   ctx->Unpack.SkipImages = 0;
   ctx->Unpack.SwapBytes = GL_FALSE;
   ctx->Unpack.LsbFirst = GL_FALSE;
   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
   ctx->NewState |= _NEW_PACKUNPACK;

   /* save PBO binding */
   bufferSave = ctx->Unpack.BufferObj;
   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;

   _mesa_ConvolutionFilter2D(target, internalFormat, width, height,
                             GL_RGBA, CHAN_TYPE, rgba);

   /* restore PBO binding */
   ctx->Unpack.BufferObj = bufferSave;

   ctx->Unpack = packSave;  /* restore pixel packing params */
   ctx->NewState |= _NEW_PACKUNPACK; 
}
/**
 * Software fallback for glAccum.
 */
void
_swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLint xpos, ypos, width, height;

   if (SWRAST_CONTEXT(ctx)->NewState)
      _swrast_validate_derived( ctx );

   if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) {
      _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer");
      return;
   }

   RENDER_START(swrast, ctx);

   /* Compute region after calling RENDER_START so that we know the
    * drawbuffer's size/bounds are up to date.
    */
   xpos = ctx->DrawBuffer->_Xmin;
   ypos = ctx->DrawBuffer->_Ymin;
   width =  ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
   height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;

   switch (op) {
      case GL_ADD:
         if (value != 0.0F) {
            accum_add(ctx, value, xpos, ypos, width, height);
	 }
	 break;
      case GL_MULT:
         if (value != 1.0F) {
            accum_mult(ctx, value, xpos, ypos, width, height);
	 }
	 break;
      case GL_ACCUM:
         if (value != 0.0F) {
            accum_accum(ctx, value, xpos, ypos, width, height);
         }
	 break;
      case GL_LOAD:
         accum_load(ctx, value, xpos, ypos, width, height);
	 break;
      case GL_RETURN:
         accum_return(ctx, value, xpos, ypos, width, height);
	 break;
      default:
         _mesa_problem(ctx, "invalid mode in _swrast_Accum()");
         break;
   }

   RENDER_FINISH(swrast, ctx);
}
Beispiel #7
0
/**
 * Called via the device driver's ctx->Driver.Clear() function if the
 * device driver can't clear one or more of the buffers itself.
 * \param mask  bitfield of BUFER_BIT_* values indicating which renderbuffers
 *              are to be cleared.
 * \param all  if GL_TRUE, clear whole buffer, else clear specified region.
 */
void
_swrast_Clear(GLcontext *ctx, GLbitfield mask,
              GLboolean all, GLint x, GLint y, GLint width, GLint height)
{
    SWcontext *swrast = SWRAST_CONTEXT(ctx);

    (void) all;
    (void) x;
    (void) y;
    (void) width;
    (void) height;

#ifdef DEBUG_FOO
    {
        const GLbitfield legalBits =
            BUFFER_BIT_FRONT_LEFT |
            BUFFER_BIT_FRONT_RIGHT |
            BUFFER_BIT_BACK_LEFT |
            BUFFER_BIT_BACK_RIGHT |
            BUFFER_BIT_DEPTH |
            BUFFER_BIT_STENCIL |
            BUFFER_BIT_ACCUM |
            BUFFER_BIT_AUX0 |
            BUFFER_BIT_AUX1 |
            BUFFER_BIT_AUX2 |
            BUFFER_BIT_AUX3;
        assert((mask & (~legalBits)) == 0);
    }
#endif

    RENDER_START(swrast,ctx);

    /* do software clearing here */
    if (mask) {
        if (mask & ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
            clear_color_buffers(ctx);
        }
        if (mask & BUFFER_BIT_DEPTH) {
            _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer);
        }
        if (mask & BUFFER_BIT_ACCUM) {
            _swrast_clear_accum_buffer(ctx,
                                       ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
        }
        if (mask & BUFFER_BIT_STENCIL) {
            _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer);
        }
    }

    RENDER_FINISH(swrast,ctx);
}
Beispiel #8
0
void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, 
				GLenum internalFormat, 
				GLint x, GLint y, GLsizei width, GLsizei height)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   struct gl_pixelstore_attrib packSave;
   GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4];
   GLint i;

   /* Select buffer to read from */
   _swrast_use_read_buffer(ctx);

   RENDER_START(swrast,ctx);
   
   /* read pixels from framebuffer */
   for (i = 0; i < height; i++) {
      _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i,
				(GLchan (*)[4]) rgba[i] );
   }

   RENDER_FINISH(swrast,ctx);

   /* Restore reading from draw buffer (the default) */
   _swrast_use_draw_buffer(ctx);

   /*
    * HACK: save & restore context state so we can store this as a
    * convolution filter via the GL api.  Doesn't call any callbacks
    * hanging off ctx->Unpack statechanges.
    */

   packSave = ctx->Unpack;  /* save pixel packing params */

   ctx->Unpack.Alignment = 1;
   ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH;
   ctx->Unpack.SkipPixels = 0;
   ctx->Unpack.SkipRows = 0;
   ctx->Unpack.ImageHeight = 0;
   ctx->Unpack.SkipImages = 0;
   ctx->Unpack.SwapBytes = GL_FALSE;
   ctx->Unpack.LsbFirst = GL_FALSE;
   ctx->NewState |= _NEW_PACKUNPACK;

   glConvolutionFilter2D(target, internalFormat, width, height,
			 GL_RGBA, CHAN_TYPE, rgba);

   ctx->Unpack = packSave;  /* restore pixel packing params */
   ctx->NewState |= _NEW_PACKUNPACK; 
}
Beispiel #9
0
void
_swrast_Clear( GLcontext *ctx, GLbitfield mask,
	       GLboolean all,
	       GLint x, GLint y, GLint width, GLint height )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
#ifdef DEBUG
   {
      GLbitfield legalBits = DD_FRONT_LEFT_BIT |
	 DD_FRONT_RIGHT_BIT |
	 DD_BACK_LEFT_BIT |
	 DD_BACK_RIGHT_BIT |
	 DD_DEPTH_BIT |
	 DD_STENCIL_BIT |
	 DD_ACCUM_BIT;
      assert((mask & (~legalBits)) == 0);
   }
#endif

   RENDER_START(swrast,ctx);

   /* do software clearing here */
   if (mask) {
      if (mask & ctx->Color._DrawDestMask)   clear_color_buffers(ctx);
      if (mask & GL_DEPTH_BUFFER_BIT)    _swrast_clear_depth_buffer(ctx);
      if (mask & GL_ACCUM_BUFFER_BIT)    _swarst_clear_accum_buffer(ctx);
      if (mask & GL_STENCIL_BUFFER_BIT)  _swrast_clear_stencil_buffer(ctx);
   }

   /* clear software-based alpha buffer(s) */
   if ( (mask & GL_COLOR_BUFFER_BIT)
	&& ctx->DrawBuffer->UseSoftwareAlphaBuffers
	&& ctx->Color.ColorMask[ACOMP]) {
      _swrast_clear_alpha_buffers( ctx );
   }

   RENDER_FINISH(swrast,ctx);
}
Beispiel #10
0
/*
 * Render a bitmap.
 */
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
		GLsizei width, GLsizei height,
		const struct gl_pixelstore_attrib *unpack,
		const GLubyte *bitmap )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLint row, col;
   GLuint count = 0;
   struct sw_span span;

   ASSERT(ctx->RenderMode == GL_RENDER);
   ASSERT(bitmap);

   RENDER_START(swrast,ctx);

   if (SWRAST_CONTEXT(ctx)->NewState)
      _swrast_validate_derived( ctx );

   INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);

   if (ctx->Visual.rgbMode) {
      span.interpMask |= SPAN_RGBA;
      span.red   = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
      span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
      span.blue  = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
      span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
      span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
   }
   else {
      span.interpMask |= SPAN_INDEX;
      span.index = ChanToFixed(ctx->Current.RasterIndex);
      span.indexStep = 0;
   }

   if (ctx->Depth.Test)
      _mesa_span_default_z(ctx, &span);
   if (ctx->Fog.Enabled)
      _mesa_span_default_fog(ctx, &span);
   if (ctx->Texture._EnabledUnits)
      _mesa_span_default_texcoords(ctx, &span);

   for (row = 0; row < height; row++, span.y++) {
      const GLubyte *src = (const GLubyte *) _mesa_image_address( unpack,
                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );

      if (unpack->LsbFirst) {
         /* Lsb first */
         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
         for (col = 0; col < width; col++) {
            if (*src & mask) {
               span.array->x[count] = px + col;
               span.array->y[count] = py + row;
               count++;
            }
            if (mask == 128U) {
               src++;
               mask = 1U;
            }
            else {
               mask = mask << 1;
            }
         }

         /* get ready for next row */
         if (mask != 1)
            src++;
      }
      else {
         /* Msb first */
         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
         for (col = 0; col < width; col++) {
            if (*src & mask) {
               span.array->x[count] = px + col;
               span.array->y[count] = py + row;
               count++;
            }
            if (mask == 1U) {
               src++;
               mask = 128U;
            }
            else {
               mask = mask >> 1;
            }
         }

         /* get ready for next row */
         if (mask != 128)
            src++;
      }

      if (count + width >= MAX_WIDTH || row + 1 == height) {
         /* flush the span */
         span.end = count;
         if (ctx->Visual.rgbMode)
            _mesa_write_rgba_span(ctx, &span);
         else
            _mesa_write_index_span(ctx, &span);
         span.end = 0;
         count = 0;
      }
   }

   RENDER_FINISH(swrast,ctx);
}
/**
 * Render a bitmap.
 * Called via ctx->Driver.Bitmap()
 * All parameter error checking will have been done before this is called.
 */
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
		GLsizei width, GLsizei height,
		const struct gl_pixelstore_attrib *unpack,
		const GLubyte *bitmap )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLint row, col;
   GLuint count = 0;
   SWspan span;

   ASSERT(ctx->RenderMode == GL_RENDER);

   bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
   if (!bitmap)
      return;

   RENDER_START(swrast,ctx);

   if (SWRAST_CONTEXT(ctx)->NewState)
      _swrast_validate_derived( ctx );

   INIT_SPAN(span, GL_BITMAP);
   span.end = width;
   span.arrayMask = SPAN_XY;
   _swrast_span_default_attribs(ctx, &span);

   for (row = 0; row < height; row++) {
      const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);

      if (unpack->LsbFirst) {
         /* Lsb first */
         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
         for (col = 0; col < width; col++) {
            if (*src & mask) {
               span.array->x[count] = px + col;
               span.array->y[count] = py + row;
               count++;
            }
            if (mask == 128U) {
               src++;
               mask = 1U;
            }
            else {
               mask = mask << 1;
            }
         }

         /* get ready for next row */
         if (mask != 1)
            src++;
      }
      else {
         /* Msb first */
         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
         for (col = 0; col < width; col++) {
            if (*src & mask) {
               span.array->x[count] = px + col;
               span.array->y[count] = py + row;
               count++;
            }
            if (mask == 1U) {
               src++;
               mask = 128U;
            }
            else {
               mask = mask >> 1;
            }
         }

         /* get ready for next row */
         if (mask != 128)
            src++;
      }

      if (count + width >= MAX_WIDTH || row + 1 == height) {
         /* flush the span */
         span.end = count;
         if (ctx->Visual.rgbMode)
            _swrast_write_rgba_span(ctx, &span);
         else
            _swrast_write_index_span(ctx, &span);
         span.end = 0;
         count = 0;
      }
   }

   RENDER_FINISH(swrast,ctx);

   _mesa_unmap_bitmap_pbo(ctx, unpack);
}
/*
 * XXX this is another way to implement Bitmap.  Use horizontal runs of
 * fragments, initializing the mask array to indicate which fragments to
 * draw or skip.
 */
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
		GLsizei width, GLsizei height,
		const struct gl_pixelstore_attrib *unpack,
		const GLubyte *bitmap )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLint row, col;
   SWspan span;

   ASSERT(ctx->RenderMode == GL_RENDER);
   ASSERT(bitmap);

   RENDER_START(swrast,ctx);

   if (SWRAST_CONTEXT(ctx)->NewState)
      _swrast_validate_derived( ctx );

   INIT_SPAN(span, GL_BITMAP);
   span.end = width;
   span.arrayMask = SPAN_MASK;
   _swrast_span_default_attribs(ctx, &span);

   /*span.arrayMask |= SPAN_MASK;*/  /* we'll init span.mask[] */
   span.x = px;
   span.y = py;
   /*span.end = width;*/

   for (row=0; row<height; row++, span.y++) {
      const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);

      if (unpack->LsbFirst) {
         /* Lsb first */
         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
         for (col=0; col<width; col++) {
            span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
            if (mask == 128U) {
               src++;
               mask = 1U;
            }
            else {
               mask = mask << 1;
            }
         }

         if (ctx->Visual.rgbMode)
            _swrast_write_rgba_span(ctx, &span);
         else
	    _swrast_write_index_span(ctx, &span);

         /* get ready for next row */
         if (mask != 1)
            src++;
      }
      else {
         /* Msb first */
         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
         for (col=0; col<width; col++) {
            span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
            if (mask == 1U) {
               src++;
               mask = 128U;
            }
            else {
               mask = mask >> 1;
            }
         }

         if (ctx->Visual.rgbMode)
            _swrast_write_rgba_span(ctx, &span);
         else
            _swrast_write_index_span(ctx, &span);

         /* get ready for next row */
         if (mask != 128)
            src++;
      }
   }

   RENDER_FINISH(swrast,ctx);
}