зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1324312 - Handle alloc failure when uploading texture. r=sotaro
When GL_UNPACK_ROW_LENGTH is not supported and the source data has a different stride to that of the texture (often because we are uploading only the modified subimage) we allocate a temporary buffer with the correct stride. This was found to be more efficient than uploading each row of texture data individually. Sometimes allocating the buffer will fail, however. In such cases fall back to uploading the texture row-by-row, rather than aborting. MozReview-Commit-ID: E7LE8nHPE0M --HG-- extra : rebase_source : 5f6ddcb617d9f4730ce864722ee06f2f7c3b850e
This commit is contained in:
Родитель
673d193089
Коммит
e92d2ce49b
|
@ -161,30 +161,52 @@ TexSubImage2DWithoutUnpackSubimage(GLContext* gl,
|
||||||
// isn't supported. We make a copy of the texture data we're using,
|
// 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
|
// 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.
|
// out to be more efficient than uploading row-by-row; see bug 698197.
|
||||||
unsigned char* newPixels = new unsigned char[width*height*pixelsize];
|
unsigned char* newPixels = new (fallible) unsigned char[width*height*pixelsize];
|
||||||
unsigned char* rowDest = newPixels;
|
|
||||||
const unsigned char* rowSource = (const unsigned char*)pixels;
|
if (newPixels) {
|
||||||
for (int h = 0; h < height; h++) {
|
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;
|
stride = width*pixelsize;
|
||||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
|
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
|
||||||
std::min(GetAddressAlignment((ptrdiff_t)newPixels),
|
std::min(GetAddressAlignment((ptrdiff_t)newPixels),
|
||||||
GetAddressAlignment((ptrdiff_t)stride)));
|
GetAddressAlignment((ptrdiff_t)stride)));
|
||||||
gl->fTexSubImage2D(target,
|
gl->fTexSubImage2D(target,
|
||||||
level,
|
level,
|
||||||
xoffset,
|
xoffset,
|
||||||
yoffset,
|
yoffset,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
type,
|
type,
|
||||||
newPixels);
|
newPixels);
|
||||||
delete [] newPixels;
|
delete [] newPixels;
|
||||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
|
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If we did not have sufficient memory for the required
|
||||||
|
// temporary buffer, then fall back to uploading row-by-row.
|
||||||
|
const unsigned char* rowSource = (const unsigned char*)pixels;
|
||||||
|
|
||||||
|
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
|
||||||
|
std::min(GetAddressAlignment((ptrdiff_t)pixels),
|
||||||
|
GetAddressAlignment((ptrdiff_t)stride)));
|
||||||
|
|
||||||
|
for (int i = 0; i < height; i++) {
|
||||||
|
gl->fTexSubImage2D(target, level,
|
||||||
|
xoffset, yoffset + i,
|
||||||
|
width, 1,
|
||||||
|
format, type, rowSource);
|
||||||
|
rowSource += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Загрузка…
Ссылка в новой задаче