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