mesa: split get_tex_rgba() into compressed/uncompressed versions

This just splits one big function into two smaller ones for better
readability.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
Brian Paul 2011-12-24 08:54:25 -07:00
parent 5e6a6e49e9
commit fb758aab27

View file

@ -215,6 +215,182 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
}
/**
* Get a color texture image with decompression.
*/
static void
get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage,
GLbitfield transferOps)
{
/* don't want to apply sRGB -> RGB conversion here so override the format */
const gl_format texFormat =
_mesa_get_srgb_format_linear(texImage->TexFormat);
const GLenum baseFormat = _mesa_get_format_base_format(texFormat);
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
const GLuint depth = texImage->Depth;
GLfloat *tempImage, *srcRow;
GLuint row;
/* Decompress into temp float buffer, then pack into user buffer */
tempImage = (GLfloat *) malloc(width * height * depth
* 4 * sizeof(GLfloat));
if (!tempImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
return;
}
/* Decompress the texture image - results in 'tempImage' */
{
GLubyte *srcMap;
GLint srcRowStride;
GLuint bytes, bw, bh;
bytes = _mesa_get_format_bytes(texFormat);
_mesa_get_format_block_size(texFormat, &bw, &bh);
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, height,
GL_MAP_READ_BIT,
&srcMap, &srcRowStride);
if (srcMap) {
/* XXX This line is a bit of a hack to work around the
* mismatch of compressed row strides as returned by
* MapTextureImage() vs. what the texture decompression code
* uses. This will be fixed in the future.
*/
srcRowStride = srcRowStride * bh / bytes;
_mesa_decompress_image(texFormat, width, height,
srcMap, srcRowStride, tempImage);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
}
}
if (baseFormat == GL_LUMINANCE ||
baseFormat == GL_LUMINANCE_ALPHA) {
/* Set green and blue to zero since the pack function here will
* compute L=R+G+B.
*/
GLuint i;
for (i = 0; i < width * height; i++) {
tempImage[i * 4 + GCOMP] = tempImage[i * 4 + BCOMP] = 0.0f;
}
}
srcRow = tempImage;
for (row = 0; row < height; row++) {
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
0, row, 0);
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow,
format, type, dest, &ctx->Pack, transferOps);
srcRow += width * 4;
}
free(tempImage);
}
/**
* Get an uncompressed color texture image.
*/
static void
get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage,
GLbitfield transferOps)
{
/* don't want to apply sRGB -> RGB conversion here so override the format */
const gl_format texFormat =
_mesa_get_srgb_format_linear(texImage->TexFormat);
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
const GLuint depth = texImage->Depth;
GLuint img, row;
GLfloat (*rgba)[4];
/* Allocate buffer for one row of texels */
rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
if (!rgba) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
return;
}
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
/* map src texture buffer */
ctx->Driver.MapTextureImage(ctx, texImage, img,
0, 0, width, height, GL_MAP_READ_BIT,
&srcMap, &rowstride);
if (srcMap) {
for (row = 0; row < height; row++) {
const GLubyte *src = srcMap + row * rowstride;
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
_mesa_unpack_rgba_row(texFormat, width, src, rgba);
if (texImage->_BaseFormat == GL_ALPHA) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][RCOMP] = 0.0F;
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
}
}
else if (texImage->_BaseFormat == GL_LUMINANCE) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
rgba[col][ACOMP] = 1.0F;
}
}
else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
}
}
else if (texImage->_BaseFormat == GL_INTENSITY) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
rgba[col][ACOMP] = 1.0F;
}
}
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
format, type, dest,
&ctx->Pack, transferOps);
}
/* Unmap the src texture buffer */
ctx->Driver.UnmapTextureImage(ctx, texImage, img);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
break;
}
}
free(rgba);
}
/**
* glGetTexImage for color formats (RGBA, RGB, alpha, LA, etc).
* Compressed textures are handled here as well.
@ -224,16 +400,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
struct gl_texture_image *texImage)
{
/* don't want to apply sRGB -> RGB conversion here so override the format */
const gl_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat);
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
const GLuint depth = texImage->Depth;
const GLenum dataType = _mesa_get_format_datatype(texFormat);
const GLenum baseFormat = _mesa_get_format_base_format(texFormat);
/* Normally, no pixel transfer ops are performed during glGetTexImage.
* The only possible exception is component clamping to [0,1].
*/
const GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
GLbitfield transferOps = 0x0;
/* In general, clamping does not apply to glGetTexImage, except when
@ -249,150 +416,13 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
}
}
if (_mesa_is_format_compressed(texFormat)) {
/* Decompress into temp buffer, then pack into user buffer */
GLfloat *tempImage, *srcRow;
GLuint row;
tempImage = (GLfloat *) malloc(texImage->Width * texImage->Height *
texImage->Depth * 4 * sizeof(GLfloat));
if (!tempImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
return;
}
/* Decompress the texture image - results in 'tempImage' */
{
GLubyte *srcMap;
GLint srcRowStride;
GLuint bytes, bw, bh;
bytes = _mesa_get_format_bytes(texImage->TexFormat);
_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, height,
GL_MAP_READ_BIT,
&srcMap, &srcRowStride);
if (srcMap) {
/* XXX This line is a bit of a hack to work around the
* mismatch of compressed row strides as returned by
* MapTextureImage() vs. what the texture decompression code
* uses. This will be fixed in the future.
*/
srcRowStride = srcRowStride * bh / bytes;
_mesa_decompress_image(texFormat, width, height,
srcMap, srcRowStride, tempImage);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
}
}
if (baseFormat == GL_LUMINANCE ||
baseFormat == GL_LUMINANCE_ALPHA) {
/* Set green and blue to zero since the pack function here will
* compute L=R+G+B.
*/
GLuint i;
for (i = 0; i < width * height; i++) {
tempImage[i * 4 + GCOMP] = tempImage[i * 4 + BCOMP] = 0.0f;
}
}
srcRow = tempImage;
for (row = 0; row < height; row++) {
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
0, row, 0);
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow,
format, type, dest, &ctx->Pack, transferOps);
srcRow += width * 4;
}
free(tempImage);
if (_mesa_is_format_compressed(texImage->TexFormat)) {
get_tex_rgba_compressed(ctx, dimensions, format, type,
pixels, texImage, transferOps);
}
else {
/* No decompression needed */
GLuint img, row;
GLfloat (*rgba)[4];
rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
if (!rgba) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
return;
}
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
/* map src texture buffer */
ctx->Driver.MapTextureImage(ctx, texImage, img,
0, 0, width, height, GL_MAP_READ_BIT,
&srcMap, &rowstride);
if (srcMap) {
for (row = 0; row < height; row++) {
const GLubyte *src = srcMap + row * rowstride;
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
_mesa_unpack_rgba_row(texFormat, width, src, rgba);
if (texImage->_BaseFormat == GL_ALPHA) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][RCOMP] = 0.0F;
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
}
}
else if (texImage->_BaseFormat == GL_LUMINANCE) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
rgba[col][ACOMP] = 1.0F;
}
}
else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
}
}
else if (texImage->_BaseFormat == GL_INTENSITY) {
GLint col;
for (col = 0; col < width; col++) {
rgba[col][GCOMP] = 0.0F;
rgba[col][BCOMP] = 0.0F;
rgba[col][ACOMP] = 1.0F;
}
}
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
format, type, dest,
&ctx->Pack, transferOps);
}
/* Unmap the src texture buffer */
ctx->Driver.UnmapTextureImage(ctx, texImage, img);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
break;
}
}
free(rgba);
get_tex_rgba_uncompressed(ctx, dimensions, format, type,
pixels, texImage, transferOps);
}
}