mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 23:40:10 +01:00
basic glDrawPixels convolution implemented
This commit is contained in:
parent
6339e621f5
commit
46e8a51383
1 changed files with 102 additions and 27 deletions
|
|
@ -1,8 +1,8 @@
|
|||
/* $Id: drawpix.c,v 1.28 2000/08/16 20:51:53 brianp Exp $ */
|
||||
/* $Id: drawpix.c,v 1.29 2000/08/21 14:24:10 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.4
|
||||
* Version: 3.5
|
||||
*
|
||||
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
|
||||
*
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#else
|
||||
#include "glheader.h"
|
||||
#include "context.h"
|
||||
#include "convolve.h"
|
||||
#include "drawpix.h"
|
||||
#include "feedback.h"
|
||||
#include "image.h"
|
||||
|
|
@ -99,10 +100,21 @@ _mesa_clip_pixelrect(const GLcontext *ctx,
|
|||
* Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
|
||||
*/
|
||||
static GLboolean
|
||||
simple_DrawPixels( GLcontext *ctx, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const GLvoid *pixels )
|
||||
fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type, const GLvoid *pixels)
|
||||
{
|
||||
const GLuint cantTransferBits =
|
||||
IMAGE_SCALE_BIAS_BIT |
|
||||
IMAGE_SHIFT_OFFSET_BIT |
|
||||
IMAGE_MAP_COLOR_BIT |
|
||||
IMAGE_COLOR_TABLE_BIT |
|
||||
IMAGE_CONVOLUTION_BIT |
|
||||
IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT |
|
||||
IMAGE_COLOR_MATRIX_BIT |
|
||||
IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT |
|
||||
IMAGE_HISTOGRAM_BIT |
|
||||
IMAGE_MIN_MAX_BIT;
|
||||
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
|
||||
GLubyte rgb[MAX_WIDTH][3];
|
||||
GLubyte rgba[MAX_WIDTH][4];
|
||||
|
|
@ -112,23 +124,13 @@ simple_DrawPixels( GLcontext *ctx, GLint x, GLint y,
|
|||
|
||||
|
||||
if (!ctx->Current.RasterPosValid) {
|
||||
/* no-op */
|
||||
return GL_TRUE;
|
||||
return GL_TRUE; /* no-op */
|
||||
}
|
||||
|
||||
if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
|
||||
&& !ctx->Pixel.ScaleOrBiasRGBA
|
||||
&& !ctx->Pixel.ScaleOrBiasRGBApcm
|
||||
&& ctx->ColorMatrix.type == MATRIX_IDENTITY
|
||||
&& !ctx->Pixel.ColorTableEnabled
|
||||
&& !ctx->Pixel.PostColorMatrixColorTableEnabled
|
||||
&& !ctx->Pixel.PostConvolutionColorTableEnabled
|
||||
&& !ctx->Pixel.MinMaxEnabled
|
||||
&& !ctx->Pixel.HistogramEnabled
|
||||
&& ctx->Pixel.IndexShift==0 && ctx->Pixel.IndexOffset==0
|
||||
&& ctx->Pixel.MapColorFlag==0
|
||||
&& (ctx->ImageTransferState & cantTransferBits) == 0
|
||||
&& ctx->Texture.ReallyEnabled == 0
|
||||
&& unpack->Alignment==1
|
||||
&& unpack->Alignment == 1
|
||||
&& !unpack->SwapBytes
|
||||
&& !unpack->LsbFirst) {
|
||||
|
||||
|
|
@ -525,7 +527,8 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
const GLvoid *source = _mesa_image_address(&ctx->Unpack,
|
||||
pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
|
||||
_mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes,
|
||||
type, source, &ctx->Unpack, GL_TRUE);
|
||||
type, source, &ctx->Unpack,
|
||||
ctx->ImageTransferState);
|
||||
if (zoom) {
|
||||
gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty);
|
||||
}
|
||||
|
|
@ -547,7 +550,6 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
GLenum type, const GLvoid *pixels )
|
||||
{
|
||||
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
|
||||
const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
|
||||
const GLint desty = y;
|
||||
GLint row, drawWidth;
|
||||
|
||||
|
|
@ -572,8 +574,9 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
const GLvoid *source = _mesa_image_address(&ctx->Unpack,
|
||||
pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
|
||||
_mesa_unpack_index_span(ctx, drawWidth, destType, values,
|
||||
type, source, &ctx->Unpack, GL_FALSE);
|
||||
if (shift_or_offset) {
|
||||
type, source, &ctx->Unpack,
|
||||
ctx->ImageTransferState);
|
||||
if (ctx->ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) {
|
||||
_mesa_shift_and_offset_stencil( ctx, drawWidth, values );
|
||||
}
|
||||
if (ctx->Pixel.MapStencilFlag) {
|
||||
|
|
@ -671,7 +674,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
const GLvoid *src = _mesa_image_address(&ctx->Unpack,
|
||||
pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
|
||||
_mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src,
|
||||
&ctx->Unpack, GL_TRUE );
|
||||
&ctx->Unpack, ctx->ImageTransferState );
|
||||
if (ctx->Visual->RGBAflag) {
|
||||
if (zoom) {
|
||||
gl_write_zoomed_rgba_span(ctx, width, x, y, zspan,
|
||||
|
|
@ -709,9 +712,11 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
const GLint desty = y;
|
||||
GLdepth zspan[MAX_WIDTH];
|
||||
GLboolean quickDraw;
|
||||
GLfloat *convImage = NULL;
|
||||
GLuint transferOps = ctx->ImageTransferState;
|
||||
|
||||
/* Try an optimized glDrawPixels first */
|
||||
if (simple_DrawPixels(ctx, x, y, width, height, format, type, pixels))
|
||||
if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels))
|
||||
return;
|
||||
|
||||
/* Fragment depth values */
|
||||
|
|
@ -725,8 +730,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
}
|
||||
|
||||
|
||||
if (ctx->RasterMask == 0 && !zoom
|
||||
&& x >= 0 && y >= 0
|
||||
if (ctx->RasterMask == 0 && !zoom && x >= 0 && y >= 0
|
||||
&& x + width <= ctx->DrawBuffer->Width
|
||||
&& y + height <= ctx->DrawBuffer->Height) {
|
||||
quickDraw = GL_TRUE;
|
||||
|
|
@ -735,6 +739,69 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
quickDraw = GL_FALSE;
|
||||
}
|
||||
|
||||
if (ctx->ImageTransferState & IMAGE_CONVOLUTION_BIT) {
|
||||
/* Convolution has to be handled specially. We'll create an
|
||||
* intermediate image, applying all pixel transfer operations
|
||||
* up to convolution. Then we'll convolve the image. Then
|
||||
* we'll proceed with the rest of the transfer operations and
|
||||
* rasterize the image.
|
||||
*/
|
||||
const GLuint preConvTransferOps =
|
||||
IMAGE_SCALE_BIAS_BIT |
|
||||
IMAGE_SHIFT_OFFSET_BIT |
|
||||
IMAGE_MAP_COLOR_BIT |
|
||||
IMAGE_COLOR_TABLE_BIT;
|
||||
const GLuint postConvTransferOps =
|
||||
IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT |
|
||||
IMAGE_COLOR_MATRIX_BIT |
|
||||
IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT |
|
||||
IMAGE_HISTOGRAM_BIT |
|
||||
IMAGE_MIN_MAX_BIT;
|
||||
GLint row;
|
||||
GLfloat *dest, *tmpImage;
|
||||
|
||||
tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
|
||||
if (!tmpImage) {
|
||||
gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
|
||||
return;
|
||||
}
|
||||
convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
|
||||
if (!convImage) {
|
||||
FREE(tmpImage);
|
||||
gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unpack the image and apply transfer ops up to convolution */
|
||||
dest = tmpImage;
|
||||
for (row = 0; row < height; row++) {
|
||||
const GLvoid *source = _mesa_image_address(unpack,
|
||||
pixels, width, height, format, type, 0, row, 0);
|
||||
_mesa_unpack_float_color_span(ctx, width, GL_RGBA, (void *) dest,
|
||||
format, type, source, unpack,
|
||||
transferOps & preConvTransferOps,
|
||||
GL_FALSE);
|
||||
dest += width * 4;
|
||||
}
|
||||
|
||||
/* do convolution */
|
||||
if (ctx->Pixel.Convolution2DEnabled) {
|
||||
_mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
|
||||
}
|
||||
else if (ctx->Pixel.Separable2DEnabled) {
|
||||
_mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
|
||||
}
|
||||
|
||||
FREE(tmpImage);
|
||||
|
||||
/* continue transfer ops and draw the convolved image */
|
||||
unpack = &_mesa_native_packing;
|
||||
pixels = convImage;
|
||||
format = GL_RGBA;
|
||||
type = GL_FLOAT;
|
||||
transferOps &= postConvTransferOps;
|
||||
}
|
||||
|
||||
/*
|
||||
* General solution
|
||||
*/
|
||||
|
|
@ -747,7 +814,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
const GLvoid *source = _mesa_image_address(unpack,
|
||||
pixels, width, height, format, type, 0, row, 0);
|
||||
_mesa_unpack_ubyte_color_span(ctx, width, GL_RGBA, (void*) rgba,
|
||||
format, type, source, unpack, GL_TRUE);
|
||||
format, type, source, unpack,
|
||||
transferOps);
|
||||
if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) ||
|
||||
(ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink))
|
||||
continue;
|
||||
|
|
@ -781,6 +849,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (convImage) {
|
||||
FREE(convImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -805,6 +877,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
|
|||
gl_update_state(ctx);
|
||||
}
|
||||
|
||||
if (ctx->ImageTransferState == UPDATE_IMAGE_TRANSFER_STATE)
|
||||
_mesa_update_image_transfer_state(ctx);
|
||||
|
||||
x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
|
||||
y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue