mesa: handle MapTextureImage() failures in mipmap generation code

And handle potential malloc failures too.

Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Brian Paul 2011-11-26 09:10:54 -07:00
parent e984085299
commit c5012c1d56
1 changed files with 57 additions and 24 deletions

View File

@ -1825,6 +1825,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
GLint slice;
GLboolean nextLevel;
GLubyte **srcMaps, **dstMaps;
GLboolean success = GL_TRUE;
/* get src image parameters */
srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
@ -1873,42 +1874,74 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
}
/* Map src texture image slices */
srcMaps = (GLubyte **) malloc(srcDepth * sizeof(GLubyte *));
for (slice = 0; slice < srcDepth; slice++) {
ctx->Driver.MapTextureImage(ctx, srcImage, slice,
0, 0, srcWidth, srcHeight,
GL_MAP_READ_BIT,
&srcMaps[slice], &srcRowStride);
srcMaps = (GLubyte **) calloc(srcDepth, sizeof(GLubyte *));
if (srcMaps) {
for (slice = 0; slice < srcDepth; slice++) {
ctx->Driver.MapTextureImage(ctx, srcImage, slice,
0, 0, srcWidth, srcHeight,
GL_MAP_READ_BIT,
&srcMaps[slice], &srcRowStride);
if (!srcMaps[slice]) {
success = GL_FALSE;
break;
}
}
}
else {
success = GL_FALSE;
}
/* Map dst texture image slices */
dstMaps = (GLubyte **) malloc(dstDepth * sizeof(GLubyte *));
for (slice = 0; slice < dstDepth; slice++) {
ctx->Driver.MapTextureImage(ctx, dstImage, slice,
0, 0, dstWidth, dstHeight,
GL_MAP_WRITE_BIT,
&dstMaps[slice], &dstRowStride);
dstMaps = (GLubyte **) calloc(dstDepth, sizeof(GLubyte *));
if (dstMaps) {
for (slice = 0; slice < dstDepth; slice++) {
ctx->Driver.MapTextureImage(ctx, dstImage, slice,
0, 0, dstWidth, dstHeight,
GL_MAP_WRITE_BIT,
&dstMaps[slice], &dstRowStride);
if (!dstMaps[slice]) {
success = GL_FALSE;
break;
}
}
}
else {
success = GL_FALSE;
}
/* generate one mipmap level (for 1D/2D/3D/array/etc texture) */
_mesa_generate_mipmap_level(target, datatype, comps, border,
srcWidth, srcHeight, srcDepth,
(const GLubyte **) srcMaps, srcRowStride,
dstWidth, dstHeight, dstDepth,
dstMaps, dstRowStride);
if (success) {
/* generate one mipmap level (for 1D/2D/3D/array/etc texture) */
_mesa_generate_mipmap_level(target, datatype, comps, border,
srcWidth, srcHeight, srcDepth,
(const GLubyte **) srcMaps, srcRowStride,
dstWidth, dstHeight, dstDepth,
dstMaps, dstRowStride);
}
/* Unmap src image slices */
for (slice = 0; slice < srcDepth; slice++) {
ctx->Driver.UnmapTextureImage(ctx, srcImage, slice);
if (srcMaps) {
for (slice = 0; slice < srcDepth; slice++) {
if (srcMaps[slice]) {
ctx->Driver.UnmapTextureImage(ctx, srcImage, slice);
}
}
free(srcMaps);
}
free(srcMaps);
/* Unmap dst image slices */
for (slice = 0; slice < dstDepth; slice++) {
ctx->Driver.UnmapTextureImage(ctx, dstImage, slice);
if (dstMaps) {
for (slice = 0; slice < dstDepth; slice++) {
if (dstMaps[slice]) {
ctx->Driver.UnmapTextureImage(ctx, dstImage, slice);
}
}
free(dstMaps);
}
free(dstMaps);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation");
break;
}
} /* loop over mipmap levels */
}