Example #1
0
/**
 * Called via the swrast->TextureSample[i] function pointer.
 * Basically, given a texture object, an array of texture coords
 * and an array of level-of-detail values, return an array of colors.
 * In this case, determine the correct texture sampling routine
 * (depending on filter mode, texture dimensions, etc) then call the
 * sampler routine.
 */
static void
_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit,
				 const struct gl_texture_object *tObj,
				 GLuint n, const GLfloat texcoords[][4],
				 const GLfloat lambda[], GLchan rgba[][4] )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );

   /* Compute min/mag filter threshold */
   if (tObj && tObj->MinFilter != tObj->MagFilter) {
      if (tObj->MagFilter == GL_LINEAR
          && (tObj->MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
              tObj->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
         swrast->_MinMagThresh[texUnit] = 0.5F;
      }
      else {
         swrast->_MinMagThresh[texUnit] = 0.0F;
      }
   }

   swrast->TextureSample[texUnit] =
      _swrast_choose_texture_sample_func( ctx, tObj );

   swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords,
                                   lambda, rgba );
}
Example #2
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);
}
Example #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);
   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:
         copy_rgba_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");
      }
   }

   swrast_render_finish(ctx);
}
Example #4
0
/**
 * Software fallback for glBlitFramebufferEXT().
 */
void
_swrast_BlitFramebuffer(struct gl_context *ctx,
                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                        GLbitfield mask, GLenum filter)
{
   static const GLbitfield buffers[3] = {
      GL_COLOR_BUFFER_BIT,
      GL_DEPTH_BUFFER_BIT,
      GL_STENCIL_BUFFER_BIT
   };
   GLint i;

   if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
                        &dstX0, &dstY0, &dstX1, &dstY1)) {
      return;
   }

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

   swrast_render_start(ctx);

   if (srcX1 - srcX0 == dstX1 - dstX0 &&
       srcY1 - srcY0 == dstY1 - dstY0 &&
       srcX0 < srcX1 &&
       srcY0 < srcY1 &&
       dstX0 < dstX1 &&
       dstY0 < dstY1) {
      /* no stretching or flipping.
       * filter doesn't matter.
       */
      for (i = 0; i < 3; i++) {
         if (mask & buffers[i]) {
            simple_blit(ctx, srcX0, srcY0, srcX1, srcY1,
                        dstX0, dstY0, dstX1, dstY1, buffers[i]);
         }
      }
   }
   else {
      if (filter == GL_NEAREST) {
         for (i = 0; i < 3; i++) {
            if (mask & buffers[i]) {
               blit_nearest(ctx,  srcX0, srcY0, srcX1, srcY1,
                            dstX0, dstY0, dstX1, dstY1, buffers[i]);
            }
         }
      }
      else {
         ASSERT(filter == GL_LINEAR);
         if (mask & GL_COLOR_BUFFER_BIT) {  /* depth/stencil not allowed */
            blit_linear(ctx,  srcX0, srcY0, srcX1, srcY1,
                        dstX0, dstY0, dstX1, dstY1);
         }
      }
   }

   swrast_render_finish(ctx);
}
Example #5
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 buffers  bitfield of BUFFER_BIT_* values indicating which
 *                 renderbuffers are to be cleared.
 * \param all  if GL_TRUE, clear whole buffer, else clear specified region.
 */
void
_swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
{
   const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL;

#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;
      assert((buffers & (~legalBits)) == 0);
   }
#endif

   if (!_mesa_check_conditional_render(ctx))
      return; /* don't clear */

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

   if ((buffers & BUFFER_BITS_COLOR)
       && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
      clear_color_buffers(ctx);
   }

   if (buffers & BUFFER_BIT_ACCUM) {
      _mesa_clear_accum_buffer(ctx);
   }

   if (buffers & BUFFER_DS) {
      struct gl_renderbuffer *depthRb =
         ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
      struct gl_renderbuffer *stencilRb =
         ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;

      if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) {
         /* clear depth and stencil together */
         _swrast_clear_depth_stencil_buffer(ctx);
      }
      else {
         /* clear depth, stencil separately */
         if (buffers & BUFFER_BIT_DEPTH) {
            _swrast_clear_depth_buffer(ctx);
         }
         if (buffers & BUFFER_BIT_STENCIL) {
            _swrast_clear_stencil_buffer(ctx);
         }
      }
   }
}
Example #6
0
/**
 * Do software-based glCopyPixels.
 * By time we get here, all parameters will have been error-checked.
 */
void
_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);
    struct gl_renderbuffer *rb;

    if (!_mesa_check_conditional_render(ctx))
        return; /* don't copy */

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

    if (!(SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 ||
            ctx->Pixel.ZoomX != 1.0F ||
            ctx->Pixel.ZoomY != 1.0F ||
            ctx->_ImageTransferState) &&
            swrast_fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty,
                                    type)) {
        /* all done */
        return;
    }

    swrast_render_start(ctx);
    rb = map_readbuffer(ctx, type);

    switch (type) {
    case GL_COLOR:
        copy_rgba_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 buffers separately (if the fast copy path wasn't taken) */
        copy_depth_pixels(ctx, srcx, srcy, width, height, destx, desty);
        copy_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
        break;
    default:
        _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
    }

    swrast_render_finish(ctx);

    if (rb) {
        struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
        ctx->Driver.UnmapRenderbuffer(ctx, rb);
        srb->Map = NULL;
    }
}
/**
 * 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);
}
Example #8
0
/**
 * Called via swrast->BlendFunc.  Examine GL state to choose a blending
 * function, then call it.
 */
static void
_swrast_validate_blend_func(struct gl_context *ctx, GLuint n, const GLubyte mask[],
                            GLvoid *src, const GLvoid *dst,
                            GLenum chanType )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx ); /* why is this needed? */
   _swrast_choose_blend_func( ctx, chanType );

   swrast->BlendFunc( ctx, n, mask, src, dst, chanType );
}
Example #9
0
/**
 * Called via swrast->BlendFunc.  Examine GL state to choose a blending
 * function, then call it.
 */
static void _ASMAPI
_swrast_validate_blend_func( GLcontext *ctx, GLuint n,
			     const GLubyte mask[],
			     GLchan src[][4],
			     CONST GLchan dst[][4] )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   _swrast_choose_blend_func( ctx );

   swrast->BlendFunc( ctx, n, mask, src, dst );
}
Example #10
0
/**
 * Called via swrast->Point.  Examine current GL state and choose a software
 * point routine.  Then call it.
 */
static void
_swrast_validate_point( struct gl_context *ctx, const SWvertex *v0 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_point( ctx );

   if (swrast->SpecularVertexAdd) {
      swrast->SpecPoint = swrast->Point;
      swrast->Point = _swrast_add_spec_terms_point;
   }

   swrast->Point( ctx, v0 );
}
Example #11
0
/**
 * Called via swrast->Line.  Examine current GL state and choose a software
 * line routine.  Then call it.
 */
static void
_swrast_validate_line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_line( ctx );
   assert(swrast->Line);

   if (swrast->SpecularVertexAdd) {
      swrast->SpecLine = swrast->Line;
      swrast->Line = _swrast_add_spec_terms_line;
   }

   swrast->Line( ctx, v0, v1 );
}
Example #12
0
/**
 * Called via swrast->Point.  Examine current GL state and choose a software
 * point routine.  Then call it.
 */
static void
_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_point( ctx );

   if (ctx->Texture._EnabledUnits == 0
       && NEED_SECONDARY_COLOR(ctx)
       && !ctx->FragmentProgram._Enabled) {
      swrast->SpecPoint = swrast->Point;
      swrast->Point = _swrast_add_spec_terms_point;
   }

   swrast->Point( ctx, v0 );
}
Example #13
0
/**
 * Called via swrast->Line.  Examine current GL state and choose a software
 * line routine.  Then call it.
 */
static void
_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_line( ctx );
   ASSERT(swrast->Line);

   if (ctx->Texture._EnabledUnits == 0
       && NEED_SECONDARY_COLOR(ctx)
       && !ctx->FragmentProgram._Current) {
      swrast->SpecLine = swrast->Line;
      swrast->Line = _swrast_add_spec_terms_line;
   }

   swrast->Line( ctx, v0, v1 );
}
Example #14
0
/**
 * Stub for swrast->Triangle to select a true triangle function
 * after a state change.
 */
static void
_swrast_validate_triangle( struct gl_context *ctx,
			   const SWvertex *v0,
                           const SWvertex *v1,
                           const SWvertex *v2 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_triangle( ctx );
   assert(swrast->Triangle);

   if (swrast->SpecularVertexAdd) {
      /* separate specular color, but no texture */
      swrast->SpecTriangle = swrast->Triangle;
      swrast->Triangle = _swrast_add_spec_terms_triangle;
   }

   swrast->Triangle( ctx, v0, v1, v2 );
}
Example #15
0
/**
 * Stub for swrast->Triangle to select a true triangle function
 * after a state change.
 */
static void
_swrast_validate_triangle( GLcontext *ctx,
			   const SWvertex *v0,
                           const SWvertex *v1,
                           const SWvertex *v2 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_triangle( ctx );

   if (ctx->Texture._EnabledUnits == 0
       && NEED_SECONDARY_COLOR(ctx)
       && !ctx->FragmentProgram._Enabled) {
      /* separate specular color, but no texture */
      swrast->SpecTriangle = swrast->Triangle;
      swrast->Triangle = _swrast_add_spec_terms_triangle;
   }

   swrast->Triangle( ctx, v0, v1, v2 );
}
Example #16
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 buffers  bitfield of BUFFER_BIT_* values indicating which
 *                 renderbuffers are to be cleared.
 * \param all  if GL_TRUE, clear whole buffer, else clear specified region.
 */
void
_swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
{
#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;
      assert((buffers & (~legalBits)) == 0);
   }
#endif

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

   if (buffers & BUFFER_BITS_COLOR) {
      clear_color_buffers(ctx);
   }

   if (buffers & BUFFER_BIT_ACCUM) {
      _mesa_clear_accum_buffer(ctx);
   }

   if (buffers & BUFFER_BIT_DEPTH) {
      _swrast_clear_depth_buffer(ctx);
   }
   if (buffers & BUFFER_BIT_STENCIL) {
      _swrast_clear_stencil_buffer(ctx);
   }
}
Example #17
0
/**
 * Software fallback for glBlitFramebufferEXT().
 */
void
_swrast_BlitFramebuffer(struct gl_context *ctx,
                        struct gl_framebuffer *readFb,
                        struct gl_framebuffer *drawFb,
                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                        GLbitfield mask, GLenum filter)
{
   static const GLbitfield buffers[3] = {
      GL_COLOR_BUFFER_BIT,
      GL_DEPTH_BUFFER_BIT,
      GL_STENCIL_BUFFER_BIT
   };
   static const GLenum buffer_enums[3] = {
      GL_COLOR,
      GL_DEPTH,
      GL_STENCIL,
   };
   GLint i;

   /* Page 679 of OpenGL 4.4 spec says:
    *    "Added BlitFramebuffer to commands affected by conditional rendering in
    *     section 10.10 (Bug 9562)."
    */
   if (!_mesa_check_conditional_render(ctx))
      return; /* Do not blit */

   if (!_mesa_clip_blit(ctx, readFb, drawFb, &srcX0, &srcY0, &srcX1, &srcY1,
                        &dstX0, &dstY0, &dstX1, &dstY1)) {
      return;
   }

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

   /* First, try covering whatever buffers possible using the fast 1:1 copy
    * path.
    */
   if (srcX1 - srcX0 == dstX1 - dstX0 &&
       srcY1 - srcY0 == dstY1 - dstY0 &&
       srcX0 < srcX1 &&
       srcY0 < srcY1 &&
       dstX0 < dstX1 &&
       dstY0 < dstY1) {
      for (i = 0; i < 3; i++) {
         if (mask & buffers[i]) {
            if (swrast_fast_copy_pixels(ctx,
                                        readFb, drawFb,
                                        srcX0, srcY0,
                                        srcX1 - srcX0, srcY1 - srcY0,
                                        dstX0, dstY0,
                                        buffer_enums[i])) {
               mask &= ~buffers[i];
            }
         }
      }

      if (!mask)
         return;
   }

   if (filter == GL_NEAREST) {
      for (i = 0; i < 3; i++) {
          if (mask & buffers[i]) {
             blit_nearest(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
                          dstX0, dstY0, dstX1, dstY1, buffers[i]);
          }
      }
   }
   else {
      assert(filter == GL_LINEAR);
      if (mask & GL_COLOR_BUFFER_BIT) {  /* depth/stencil not allowed */
         blit_linear(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
                     dstX0, dstY0, dstX1, dstY1);
      }
   }

}
Example #18
0
/**
 * Software fallback for glBlitFramebufferEXT().
 */
void
_swrast_BlitFramebuffer(struct gl_context *ctx,
                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                        GLbitfield mask, GLenum filter)
{
   static const GLbitfield buffers[3] = {
      GL_COLOR_BUFFER_BIT,
      GL_DEPTH_BUFFER_BIT,
      GL_STENCIL_BUFFER_BIT
   };
   static const GLenum buffer_enums[3] = {
      GL_COLOR,
      GL_DEPTH,
      GL_STENCIL,
   };
   GLint i;

   if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
                        &dstX0, &dstY0, &dstX1, &dstY1)) {
      return;
   }

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

   /* First, try covering whatever buffers possible using the fast 1:1 copy
    * path.
    */
   if (srcX1 - srcX0 == dstX1 - dstX0 &&
       srcY1 - srcY0 == dstY1 - dstY0 &&
       srcX0 < srcX1 &&
       srcY0 < srcY1 &&
       dstX0 < dstX1 &&
       dstY0 < dstY1) {
      for (i = 0; i < 3; i++) {
         if (mask & buffers[i]) {
	    if (swrast_fast_copy_pixels(ctx,
					srcX0, srcY0,
					srcX1 - srcX0, srcY1 - srcY0,
					dstX0, dstY0,
					buffer_enums[i])) {
	       mask &= ~buffers[i];
	    }
	 }
      }

      if (!mask)
	 return;
   }

   if (filter == GL_NEAREST) {
      for (i = 0; i < 3; i++) {
	 if (mask & buffers[i]) {
	    blit_nearest(ctx,  srcX0, srcY0, srcX1, srcY1,
			 dstX0, dstY0, dstX1, dstY1, buffers[i]);
	 }
      }
   }
   else {
      ASSERT(filter == GL_LINEAR);
      if (mask & GL_COLOR_BUFFER_BIT) {  /* depth/stencil not allowed */
	 blit_linear(ctx,  srcX0, srcY0, srcX1, srcY1,
		     dstX0, dstY0, dstX1, dstY1);
      }
   }

}
Example #19
0
/*
 * 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( struct gl_context *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);

   swrast_render_start(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;
            }
         }

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

         _swrast_write_rgba_span(ctx, &span);

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

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

   ASSERT(ctx->RenderMode == GL_RENDER);

   if (!_mesa_check_conditional_render(ctx))
      return; /* don't draw */

   bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap);
   if (!bitmap)
      return;

   swrast_render_start(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 >= SWRAST_MAX_WIDTH || row + 1 == height) {
         /* flush the span */
         span.end = count;
         _swrast_write_rgba_span(ctx, &span);
         span.end = 0;
         count = 0;
      }
   }

   swrast_render_finish(ctx);

   _mesa_unmap_pbo_source(ctx, unpack);
}
Example #21
0
File: s_bitmap.c Project: aosm/X11
/*
 * 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);
}