Transplanet: Bug 724094 - Use fTexImage2D instead of TexSubImage2D when uploading full width. r=ajuma

--HG--
extra : rebase_source : 94595465a2b3eb3140f11e932a32575629a266dc
This commit is contained in:
Benoit Girard 2012-02-06 15:15:36 -05:00
Родитель 13bc9d7ea3
Коммит 6a6764ec7b
1 изменённых файлов: 71 добавлений и 84 удалений

Просмотреть файл

@ -2122,9 +2122,9 @@ static GLint GetAddressAlignment(ptrdiff_t aAddress)
} }
void void
GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat, GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat,
GLsizei width, GLsizei height, GLsizei stride, GLsizei width, GLsizei height, GLsizei stride,
GLint pixelsize, GLint border, GLenum format, GLint pixelsize, GLint border, GLenum format,
GLenum type, const GLvoid *pixels) GLenum type, const GLvoid *pixels)
{ {
#ifdef USE_GLES2 #ifdef USE_GLES2
@ -2155,7 +2155,7 @@ GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat,
type, type,
pixels); pixels);
#else #else
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
NS_MIN(GetAddressAlignment((ptrdiff_t)pixels), NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
GetAddressAlignment((ptrdiff_t)stride))); GetAddressAlignment((ptrdiff_t)stride)));
int rowLength = stride/pixelsize; int rowLength = stride/pixelsize;
@ -2175,17 +2175,32 @@ GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat,
} }
void void
GLContext::TexSubImage2D(GLenum target, GLint level, GLContext::TexSubImage2D(GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei stride, GLsizei width, GLsizei height, GLsizei stride,
GLint pixelsize, GLenum format, GLint pixelsize, GLenum format,
GLenum type, const GLvoid* pixels) GLenum type, const GLvoid* pixels)
{ {
#ifdef USE_GLES2 #ifdef USE_GLES2
if (IsExtensionSupported(EXT_unpack_subimage)) { if (stride == width * pixelsize) {
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
GetAddressAlignment((ptrdiff_t)stride)));
fTexSubImage2D(target,
level,
xoffset,
yoffset,
width,
height,
format,
type,
pixels);
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
} else if (IsExtensionSupported(EXT_unpack_subimage)) {
TexSubImage2DWithUnpackSubimageGLES(target, level, xoffset, yoffset, TexSubImage2DWithUnpackSubimageGLES(target, level, xoffset, yoffset,
width, height, stride, width, height, stride,
pixelsize, format, type, pixels); pixelsize, format, type, pixels);
} else { } else {
TexSubImage2DWithoutUnpackSubimage(target, level, xoffset, yoffset, TexSubImage2DWithoutUnpackSubimage(target, level, xoffset, yoffset,
width, height, stride, width, height, stride,
@ -2222,45 +2237,32 @@ GLContext::TexSubImage2DWithUnpackSubimageGLES(GLenum target, GLint level,
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
NS_MIN(GetAddressAlignment((ptrdiff_t)pixels), NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
GetAddressAlignment((ptrdiff_t)stride))); GetAddressAlignment((ptrdiff_t)stride)));
if (stride == width * pixelsize) { // When using GL_UNPACK_ROW_LENGTH, we need to work around a Tegra
// No need to use GL_UNPACK_ROW_LENGTH. // driver crash where the driver apparently tries to read
fTexSubImage2D(target, // (stride - width * pixelsize) bytes past the end of the last input
level, // row. We only upload the first height-1 rows using GL_UNPACK_ROW_LENGTH,
xoffset, // and then we upload the final row separately. See bug 697990.
yoffset, int rowLength = stride/pixelsize;
width, fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
height, fTexSubImage2D(target,
format, level,
type, xoffset,
pixels); yoffset,
} else { width,
// When using GL_UNPACK_ROW_LENGTH, we need to work around a Tegra height-1,
// driver crash where the driver apparently tries to read format,
// (stride - width * pixelsize) bytes past the end of the last input type,
// row. We only upload the first height-1 rows using GL_UNPACK_ROW_LENGTH, pixels);
// and then we upload the final row separately. See bug 697990. fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
int rowLength = stride/pixelsize; fTexSubImage2D(target,
fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength); level,
fTexSubImage2D(target, xoffset,
level, yoffset+height-1,
xoffset, width,
yoffset, 1,
width, format,
height-1, type,
format, (const unsigned char *)pixels+(height-1)*stride);
type,
pixels);
fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
fTexSubImage2D(target,
level,
xoffset,
yoffset+height-1,
width,
1,
format,
type,
(const unsigned char *)pixels+(height-1)*stride);
}
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4); fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
} }
@ -2272,48 +2274,33 @@ GLContext::TexSubImage2DWithoutUnpackSubimage(GLenum target, GLint level,
GLenum format, GLenum type, GLenum format, GLenum type,
const GLvoid* pixels) const GLvoid* pixels)
{ {
if (stride == width * pixelsize) { // Not using the whole row of texture data and GL_UNPACK_ROW_LENGTH
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, // isn't supported. We make a copy of the texture data we're using,
NS_MIN(GetAddressAlignment((ptrdiff_t)pixels), // such that we're using the whole row of data in the copy. This turns
GetAddressAlignment((ptrdiff_t)stride))); // out to be more efficient than uploading row-by-row; see bug 698197.
fTexSubImage2D(target, unsigned char *newPixels = new unsigned char[width*height*pixelsize];
level, unsigned char *rowDest = newPixels;
xoffset, const unsigned char *rowSource = (const unsigned char *)pixels;
yoffset, for (int h = 0; h < height; h++) {
width,
height,
format,
type,
pixels);
} else {
// Not using the whole row of texture data and GL_UNPACK_ROW_LENGTH
// isn't supported. We make a copy of the texture data we're using,
// such that we're using the whole row of data in the copy. This turns
// out to be more efficient than uploading row-by-row; see bug 698197.
unsigned char *newPixels = new unsigned char[width*height*pixelsize];
unsigned char *rowDest = newPixels;
const unsigned char *rowSource = (const unsigned char *)pixels;
for (int h = 0; h < height; h++) {
memcpy(rowDest, rowSource, width*pixelsize); memcpy(rowDest, rowSource, width*pixelsize);
rowDest += width*pixelsize; rowDest += width*pixelsize;
rowSource += stride; rowSource += stride;
}
stride = width*pixelsize;
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
NS_MIN(GetAddressAlignment((ptrdiff_t)newPixels),
GetAddressAlignment((ptrdiff_t)stride)));
fTexSubImage2D(target,
level,
xoffset,
yoffset,
width,
height,
format,
type,
newPixels);
delete [] newPixels;
} }
stride = width*pixelsize;
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
NS_MIN(GetAddressAlignment((ptrdiff_t)newPixels),
GetAddressAlignment((ptrdiff_t)stride)));
fTexSubImage2D(target,
level,
xoffset,
yoffset,
width,
height,
format,
type,
newPixels);
delete [] newPixels;
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4); fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
} }