Bug 1083611 - Use UniquePtr and fallible allocations. - r=kamidphish
--- a/dom/canvas/WebGLContextBuffers.cpp
+++ b/dom/canvas/WebGLContextBuffers.cpp
@@ -155,25 +155,24 @@ WebGLContext::BufferData(GLenum target,
if (!CheckedInt<GLsizeiptr>(size).isValid())
return ErrorOutOfMemory("bufferData: bad size");
WebGLBuffer* boundBuffer = bufferSlot->get();
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
- void* zeroBuffer = calloc(size, 1);
+ UniquePtr<uint8_t> zeroBuffer((uint8_t*)moz_calloc(size, 1));
if (!zeroBuffer)
return ErrorOutOfMemory("bufferData: out of memory");
MakeContextCurrent();
InvalidateBufferFetching();
- GLenum error = CheckedBufferData(target, size, zeroBuffer, usage);
- free(zeroBuffer);
+ GLenum error = CheckedBufferData(target, size, zeroBuffer.get(), usage);
if (error) {
GenerateWarning("bufferData generated error %s", ErrorName(error));
return;
}
boundBuffer->SetByteLength(size);
if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) {
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -573,24 +573,28 @@ WebGLContext::DoFakeVertexAttrib0(GLuint
mFakeVertexAttrib0BufferObjectVector[2] = mVertexAttrib0Vector[2];
mFakeVertexAttrib0BufferObjectVector[3] = mVertexAttrib0Vector[3];
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
GetAndFlushUnderlyingGLErrors();
if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) {
- nsAutoArrayPtr<GLfloat> array(new GLfloat[4 * vertexCount]);
+ UniquePtr<GLfloat[]> array(new ((fallible_t())) GLfloat[4 * vertexCount]);
+ if (!array) {
+ ErrorOutOfMemory("Fake attrib0 array.");
+ return false;
+ }
for(size_t i = 0; i < vertexCount; ++i) {
array[4 * i + 0] = mVertexAttrib0Vector[0];
array[4 * i + 1] = mVertexAttrib0Vector[1];
array[4 * i + 2] = mVertexAttrib0Vector[2];
array[4 * i + 3] = mVertexAttrib0Vector[3];
}
- gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array, LOCAL_GL_DYNAMIC_DRAW);
+ gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array.get(), LOCAL_GL_DYNAMIC_DRAW);
} else {
gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, nullptr, LOCAL_GL_DYNAMIC_DRAW);
}
GLenum error = GetAndFlushUnderlyingGLErrors();
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
// note that we do this error checking and early return AFTER having restored the buffer binding above
@@ -745,27 +749,26 @@ WebGLContext::FakeBlackTexture::FakeBlac
&formerBinding);
gl->fGenTextures(1, &mGLName);
gl->fBindTexture(target.get(), mGLName);
// we allocate our zeros on the heap, and we overallocate (16 bytes instead of 4)
// to minimize the risk of running into a driver bug in texImage2D, as it is
// a bit unusual maybe to create 1x1 textures, and the stack may not have the alignment
// that texImage2D expects.
- void* zeros = calloc(1, 16);
+ UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1, 16));
if (target == LOCAL_GL_TEXTURE_2D) {
gl->fTexImage2D(target.get(), 0, format, 1, 1,
- 0, format, LOCAL_GL_UNSIGNED_BYTE, zeros);
+ 0, format, LOCAL_GL_UNSIGNED_BYTE, zeros.get());
} else {
for (GLuint i = 0; i < 6; ++i) {
gl->fTexImage2D(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, 1, 1,
- 0, format, LOCAL_GL_UNSIGNED_BYTE, zeros);
+ 0, format, LOCAL_GL_UNSIGNED_BYTE, zeros.get());
}
}
- free(zeros);
gl->fBindTexture(target.get(), formerBinding);
}
WebGLContext::FakeBlackTexture::~FakeBlackTexture()
{
if (mGL) {
mGL->MakeCurrent();
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -2321,30 +2321,33 @@ WebGLContext::ReadPixels(GLint x, GLint
// no need to check again for integer overflow here, since we already know the sizes aren't greater than before
uint32_t subrect_plainRowSize = subrect_width * bytesPerPixel;
// There are checks above to ensure that this doesn't overflow.
uint32_t subrect_alignedRowSize =
RoundedToNextMultipleOf(subrect_plainRowSize, mPixelStorePackAlignment).value();
uint32_t subrect_byteLength = (subrect_height-1)*subrect_alignedRowSize + subrect_plainRowSize;
// create subrect buffer, call glReadPixels, copy pixels into destination buffer, delete subrect buffer
- GLubyte *subrect_data = new GLubyte[subrect_byteLength];
- gl->fReadPixels(subrect_x, subrect_y, subrect_width, subrect_height, format, type, subrect_data);
+ UniquePtr<GLubyte> subrect_data(new ((fallible_t())) GLubyte[subrect_byteLength]);
+ if (!subrect_data)
+ return ErrorOutOfMemory("readPixels: subrect_data");
+
+ gl->fReadPixels(subrect_x, subrect_y, subrect_width, subrect_height,
+ format, type, subrect_data.get());
// notice that this for loop terminates because we already checked that subrect_height is at most height
for (GLint y_inside_subrect = 0; y_inside_subrect < subrect_height; ++y_inside_subrect) {
GLint subrect_x_in_dest_buffer = subrect_x - x;
GLint subrect_y_in_dest_buffer = subrect_y - y;
memcpy(static_cast<GLubyte*>(data)
+ checked_alignedRowSize.value() * (subrect_y_in_dest_buffer + y_inside_subrect)
+ bytesPerPixel * subrect_x_in_dest_buffer, // destination
- subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
+ subrect_data.get() + subrect_alignedRowSize * y_inside_subrect, // source
subrect_plainRowSize); // size
}
- delete [] subrect_data;
}
// if we're reading alpha, we may need to do fixup. Note that we don't allow
// GL_ALPHA to readpixels currently, but we had the code written for it already.
if (format == LOCAL_GL_ALPHA ||
format == LOCAL_GL_RGBA)
{
bool needAlphaFixup;
@@ -3805,17 +3808,17 @@ WebGLContext::TexImage2D_base(TexImageTa
!mPixelStoreFlipY)
{
// no conversion, no flipping, so we avoid copying anything and just pass the source pointer
pixels = data;
}
else
{
size_t convertedDataSize = height * dstStride;
- convertedData = (uint8_t*)moz_malloc(convertedDataSize);
+ convertedData = new ((fallible_t())) uint8_t[convertedDataSize];
if (!convertedData) {
ErrorOutOfMemory("texImage2D: Ran out of memory when allocating"
" a buffer for doing format conversion.");
return;
}
if (!ConvertImage(width, height, srcStride, dstStride,
static_cast<uint8_t*>(data), convertedData,
actualSrcFormat, srcPremultiplied,
@@ -4009,17 +4012,17 @@ WebGLContext::TexSubImage2D_base(TexImag
// no conversion, no flipping, so we avoid copying anything and just pass the source pointer
bool noConversion = (actualSrcFormat == dstFormat &&
srcPremultiplied == mPixelStorePremultiplyAlpha &&
srcStride == dstStride &&
!mPixelStoreFlipY);
if (!noConversion) {
size_t convertedDataSize = height * dstStride;
- convertedData = (uint8_t*)moz_malloc(convertedDataSize);
+ convertedData = new ((fallible_t())) uint8_t[convertedDataSize];
if (!convertedData) {
ErrorOutOfMemory("texImage2D: Ran out of memory when allocating"
" a buffer for doing format conversion.");
return;
}
if (!ConvertImage(width, height, srcStride, dstStride,
static_cast<const uint8_t*>(data), convertedData,
actualSrcFormat, srcPremultiplied,
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -590,44 +590,44 @@ WebGLTexture::EnsureNoUninitializedImage
CheckedUint32 checked_byteLength
= WebGLContext::GetImageSize(
imageInfo.mHeight,
imageInfo.mWidth,
imageInfo.mDepth,
bytespertexel,
mContext->mPixelStoreUnpackAlignment);
MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
- ScopedFreePtr<void> zeros;
- zeros = calloc(1, checked_byteLength.value());
+
+ UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1, checked_byteLength.value())); // Infallible for now.
gl::GLContext* gl = mContext->gl;
GLenum driverInternalFormat = LOCAL_GL_NONE;
GLenum driverFormat = LOCAL_GL_NONE;
GLenum driverType = LOCAL_GL_NONE;
DriverFormatsFromEffectiveInternalFormat(gl, imageInfo.mEffectiveInternalFormat,
&driverInternalFormat, &driverFormat, &driverType);
mContext->GetAndFlushUnderlyingGLErrors();
if (imageTarget == LOCAL_GL_TEXTURE_3D) {
MOZ_ASSERT(mImmutable, "Shouldn't be possible to have non-immutable-format 3D textures in WebGL");
gl->fTexSubImage3D(imageTarget.get(), level, 0, 0, 0,
imageInfo.mWidth, imageInfo.mHeight, imageInfo.mDepth,
driverFormat, driverType,
- zeros);
+ zeros.get());
} else {
if (mImmutable) {
gl->fTexSubImage2D(imageTarget.get(), level, 0, 0,
imageInfo.mWidth, imageInfo.mHeight,
driverFormat, driverType,
- zeros);
+ zeros.get());
} else {
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,
imageInfo.mWidth, imageInfo.mHeight,
0, driverFormat, driverType,
- zeros);
+ zeros.get());
}
}
GLenum error = mContext->GetAndFlushUnderlyingGLErrors();
if (error) {
// Should only be OUT_OF_MEMORY. Anyway, there's no good way to recover from this here.
printf_stderr("Error: 0x%4x\n", error);
MOZ_CRASH(); // errors on texture upload have been related to video memory exposure in the past.
}