Bug 1218488 - clarify buffer ownership for nsICanvasRenderingContextInternal::GetBuffer; r=Bas,baku

This patch started life as making ImageEncoder.cpp:EncodingRunnable not
use nsAutoArrayPtr, but the API effects rippled out from there.  On the
whole, I think using UniquePtr throughout has made the code clearer.
This commit is contained in:
Nathan Froyd 2015-10-26 14:31:12 -04:00
parent f564979614
commit d9e6000c7f
15 changed files with 67 additions and 67 deletions

View File

@ -138,7 +138,7 @@ public:
EncodingRunnable(const nsAString& aType, EncodingRunnable(const nsAString& aType,
const nsAString& aOptions, const nsAString& aOptions,
uint8_t* aImageBuffer, UniquePtr<uint8_t[]> aImageBuffer,
layers::Image* aImage, layers::Image* aImage,
imgIEncoder* aEncoder, imgIEncoder* aEncoder,
EncodingCompleteEvent* aEncodingCompleteEvent, EncodingCompleteEvent* aEncodingCompleteEvent,
@ -147,7 +147,7 @@ public:
bool aUsingCustomOptions) bool aUsingCustomOptions)
: mType(aType) : mType(aType)
, mOptions(aOptions) , mOptions(aOptions)
, mImageBuffer(aImageBuffer) , mImageBuffer(Move(aImageBuffer))
, mImage(aImage) , mImage(aImage)
, mEncoder(aEncoder) , mEncoder(aEncoder)
, mEncodingCompleteEvent(aEncodingCompleteEvent) , mEncodingCompleteEvent(aEncodingCompleteEvent)
@ -161,7 +161,7 @@ public:
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
nsresult rv = ImageEncoder::ExtractDataInternal(mType, nsresult rv = ImageEncoder::ExtractDataInternal(mType,
mOptions, mOptions,
mImageBuffer, mImageBuffer.get(),
mFormat, mFormat,
mSize, mSize,
mImage, mImage,
@ -175,7 +175,7 @@ public:
if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) { if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) {
rv = ImageEncoder::ExtractDataInternal(mType, rv = ImageEncoder::ExtractDataInternal(mType,
EmptyString(), EmptyString(),
mImageBuffer, mImageBuffer.get(),
mFormat, mFormat,
mSize, mSize,
mImage, mImage,
@ -220,7 +220,7 @@ public:
private: private:
nsAutoString mType; nsAutoString mType;
nsAutoString mOptions; nsAutoString mOptions;
nsAutoArrayPtr<uint8_t> mImageBuffer; UniquePtr<uint8_t[]> mImageBuffer;
RefPtr<layers::Image> mImage; RefPtr<layers::Image> mImage;
nsCOMPtr<imgIEncoder> mEncoder; nsCOMPtr<imgIEncoder> mEncoder;
RefPtr<EncodingCompleteEvent> mEncodingCompleteEvent; RefPtr<EncodingCompleteEvent> mEncodingCompleteEvent;
@ -287,7 +287,7 @@ nsresult
ImageEncoder::ExtractDataAsync(nsAString& aType, ImageEncoder::ExtractDataAsync(nsAString& aType,
const nsAString& aOptions, const nsAString& aOptions,
bool aUsingCustomOptions, bool aUsingCustomOptions,
uint8_t* aImageBuffer, UniquePtr<uint8_t[]> aImageBuffer,
int32_t aFormat, int32_t aFormat,
const nsIntSize aSize, const nsIntSize aSize,
EncodeCompleteCallback* aEncodeCallback) EncodeCompleteCallback* aEncodeCallback)
@ -306,7 +306,7 @@ ImageEncoder::ExtractDataAsync(nsAString& aType,
nsCOMPtr<nsIRunnable> event = new EncodingRunnable(aType, nsCOMPtr<nsIRunnable> event = new EncodingRunnable(aType,
aOptions, aOptions,
aImageBuffer, Move(aImageBuffer),
nullptr, nullptr,
encoder, encoder,
completeEvent, completeEvent,

View File

@ -11,6 +11,7 @@
#include "nsError.h" #include "nsError.h"
#include "mozilla/dom/File.h" #include "mozilla/dom/File.h"
#include "mozilla/dom/HTMLCanvasElementBinding.h" #include "mozilla/dom/HTMLCanvasElementBinding.h"
#include "mozilla/UniquePtr.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsSize.h" #include "nsSize.h"
@ -58,7 +59,7 @@ public:
static nsresult ExtractDataAsync(nsAString& aType, static nsresult ExtractDataAsync(nsAString& aType,
const nsAString& aOptions, const nsAString& aOptions,
bool aUsingCustomOptions, bool aUsingCustomOptions,
uint8_t* aImageBuffer, UniquePtr<uint8_t[]> aImageBuffer,
int32_t aFormat, int32_t aFormat,
const nsIntSize aSize, const nsIntSize aSize,
EncodeCompleteCallback* aEncodeCallback); EncodeCompleteCallback* aEncodeCallback);

View File

@ -1646,26 +1646,24 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx,
return NS_OK; return NS_OK;
} }
void UniquePtr<uint8_t[]>
CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer, CanvasRenderingContext2D::GetImageBuffer(int32_t* aFormat)
int32_t* aFormat)
{ {
*aImageBuffer = nullptr;
*aFormat = 0; *aFormat = 0;
EnsureTarget(); EnsureTarget();
RefPtr<SourceSurface> snapshot = mTarget->Snapshot(); RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
if (!snapshot) { if (!snapshot) {
return; return nullptr;
} }
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface(); RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
if (!data || data->GetSize() != IntSize(mWidth, mHeight)) { if (!data || data->GetSize() != IntSize(mWidth, mHeight)) {
return; return nullptr;
} }
*aImageBuffer = SurfaceToPackedBGRA(data);
*aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB; *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB;
return SurfaceToPackedBGRA(data);
} }
nsString CanvasRenderingContext2D::GetHitRegion(const mozilla::gfx::Point& aPoint) nsString CanvasRenderingContext2D::GetHitRegion(const mozilla::gfx::Point& aPoint)
@ -1691,15 +1689,15 @@ CanvasRenderingContext2D::GetInputStream(const char *aMimeType,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsAutoArrayPtr<uint8_t> imageBuffer;
int32_t format = 0; int32_t format = 0;
GetImageBuffer(getter_Transfers(imageBuffer), &format); UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(&format);
if (!imageBuffer) { if (!imageBuffer) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format, return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(),
encoder, aEncoderOptions, aStream); format, encoder, aEncoderOptions,
aStream);
} }
SurfaceFormat SurfaceFormat

View File

@ -20,6 +20,7 @@
#include "mozilla/dom/CanvasPattern.h" #include "mozilla/dom/CanvasPattern.h"
#include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/UniquePtr.h"
#include "gfx2DGlue.h" #include "gfx2DGlue.h"
#include "imgIEncoder.h" #include "imgIEncoder.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
@ -526,7 +527,7 @@ public:
friend class CanvasRenderingContext2DUserData; friend class CanvasRenderingContext2DUserData;
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) override; virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
// Given a point, return hit region ID if it exists // Given a point, return hit region ID if it exists

View File

@ -7,6 +7,7 @@
#include "ImageEncoder.h" #include "ImageEncoder.h"
#include "mozilla/dom/CanvasRenderingContext2D.h" #include "mozilla/dom/CanvasRenderingContext2D.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "nsIScriptContext.h" #include "nsIScriptContext.h"
@ -49,10 +50,10 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
} }
} }
uint8_t* imageBuffer = nullptr; UniquePtr<uint8_t[]> imageBuffer;
int32_t format = 0; int32_t format = 0;
if (mCurrentContext) { if (mCurrentContext) {
mCurrentContext->GetImageBuffer(&imageBuffer, &format); imageBuffer = mCurrentContext->GetImageBuffer(&format);
} }
// Encoder callback when encoding is complete. // Encoder callback when encoding is complete.
@ -99,7 +100,7 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
aRv = ImageEncoder::ExtractDataAsync(type, aRv = ImageEncoder::ExtractDataAsync(type,
params, params,
usingCustomParseOptions, usingCustomParseOptions,
imageBuffer, Move(imageBuffer),
format, format,
GetWidthHeight(), GetWidthHeight(),
callback); callback);

View File

@ -1052,25 +1052,25 @@ WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
} }
} }
void UniquePtr<uint8_t[]>
WebGLContext::GetImageBuffer(uint8_t** out_imageBuffer, int32_t* out_format) WebGLContext::GetImageBuffer(int32_t* out_format)
{ {
*out_imageBuffer = nullptr;
*out_format = 0; *out_format = 0;
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied // Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
bool premult; bool premult;
RefPtr<SourceSurface> snapshot = RefPtr<SourceSurface> snapshot =
GetSurfaceSnapshot(mOptions.premultipliedAlpha ? nullptr : &premult); GetSurfaceSnapshot(mOptions.premultipliedAlpha ? nullptr : &premult);
if (!snapshot) if (!snapshot) {
return; return nullptr;
}
MOZ_ASSERT(mOptions.premultipliedAlpha || !premult, "We must get unpremult when we ask for it!"); MOZ_ASSERT(mOptions.premultipliedAlpha || !premult, "We must get unpremult when we ask for it!");
RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface(); RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface();
return gfxUtils::GetImageBuffer(dataSurface, mOptions.premultipliedAlpha, return gfxUtils::GetImageBuffer(dataSurface, mOptions.premultipliedAlpha,
out_imageBuffer, out_format); out_format);
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -237,8 +237,7 @@ public:
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
virtual void GetImageBuffer(uint8_t** out_imageBuffer, virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* out_format) override;
int32_t* out_format) override;
NS_IMETHOD GetInputStream(const char* mimeType, NS_IMETHOD GetInputStream(const char* mimeType,
const char16_t* encoderOptions, const char16_t* encoderOptions,
nsIInputStream** out_stream) override; nsIInputStream** out_stream) override;

View File

@ -14,6 +14,7 @@
#include "mozilla/dom/HTMLCanvasElement.h" #include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/OffscreenCanvas.h" #include "mozilla/dom/OffscreenCanvas.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \ #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
{ 0xb84f2fed, 0x9d4b, 0x430b, \ { 0xb84f2fed, 0x9d4b, 0x430b, \
@ -96,7 +97,7 @@ public:
NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) = 0; NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) = 0;
// Creates an image buffer. Returns null on failure. // Creates an image buffer. Returns null on failure.
virtual void GetImageBuffer(uint8_t** imageBuffer, int32_t* format) = 0; virtual mozilla::UniquePtr<uint8_t[]> GetImageBuffer(int32_t* format) = 0;
// Gives you a stream containing the image represented by this context. // Gives you a stream containing the image represented by this context.
// The format is given in mimeTime, for example "image/png". // The format is given in mimeTime, for example "image/png".

View File

@ -110,7 +110,7 @@ CopyBGRXSurfaceDataToPackedBGRArray(uint8_t* aSrc, uint8_t* aDst,
} }
} }
uint8_t* UniquePtr<uint8_t[]>
SurfaceToPackedBGRA(DataSourceSurface *aSurface) SurfaceToPackedBGRA(DataSourceSurface *aSurface)
{ {
SurfaceFormat format = aSurface->GetFormat(); SurfaceFormat format = aSurface->GetFormat();
@ -120,25 +120,25 @@ SurfaceToPackedBGRA(DataSourceSurface *aSurface)
IntSize size = aSurface->GetSize(); IntSize size = aSurface->GetSize();
uint8_t* imageBuffer = new (std::nothrow) uint8_t[size.width * size.height * sizeof(uint32_t)]; UniquePtr<uint8_t[]> imageBuffer(
new (std::nothrow) uint8_t[size.width * size.height * sizeof(uint32_t)]);
if (!imageBuffer) { if (!imageBuffer) {
return nullptr; return nullptr;
} }
DataSourceSurface::MappedSurface map; DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) { if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) {
delete [] imageBuffer;
return nullptr; return nullptr;
} }
CopySurfaceDataToPackedArray(map.mData, imageBuffer, size, CopySurfaceDataToPackedArray(map.mData, imageBuffer.get(), size,
map.mStride, 4 * sizeof(uint8_t)); map.mStride, 4 * sizeof(uint8_t));
aSurface->Unmap(); aSurface->Unmap();
if (format == SurfaceFormat::B8G8R8X8) { if (format == SurfaceFormat::B8G8R8X8) {
// Convert BGRX to BGRA by setting a to 255. // Convert BGRX to BGRA by setting a to 255.
ConvertBGRXToBGRA(reinterpret_cast<uint8_t *>(imageBuffer), size, size.width * sizeof(uint32_t)); ConvertBGRXToBGRA(imageBuffer.get(), size, size.width * sizeof(uint32_t));
} }
return imageBuffer; return imageBuffer;

View File

@ -8,6 +8,8 @@
#include "2D.h" #include "2D.h"
#include "mozilla/UniquePtr.h"
namespace mozilla { namespace mozilla {
namespace gfx { namespace gfx {
@ -25,11 +27,9 @@ CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize,
int32_t aSrcStride, int32_t aBytesPerPixel); int32_t aSrcStride, int32_t aBytesPerPixel);
/** /**
* Convert aSurface to a packed buffer in BGRA format. The pixel data is * Convert aSurface to a packed buffer in BGRA format.
* returned in a buffer allocated with new uint8_t[]. The caller then has
* ownership of the buffer and is responsible for delete[]'ing it.
*/ */
uint8_t* UniquePtr<uint8_t[]>
SurfaceToPackedBGRA(DataSourceSurface *aSurface); SurfaceToPackedBGRA(DataSourceSurface *aSurface);
/** /**

View File

@ -1547,26 +1547,24 @@ gfxUtils::CopyAsDataURI(DrawTarget* aDT)
} }
} }
/* static */ void /* static */ UniquePtr<uint8_t[]>
gfxUtils::GetImageBuffer(gfx::DataSourceSurface* aSurface, gfxUtils::GetImageBuffer(gfx::DataSourceSurface* aSurface,
bool aIsAlphaPremultiplied, bool aIsAlphaPremultiplied,
uint8_t** outImageBuffer,
int32_t* outFormat) int32_t* outFormat)
{ {
*outImageBuffer = nullptr;
*outFormat = 0; *outFormat = 0;
DataSourceSurface::MappedSurface map; DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) if (!aSurface->Map(DataSourceSurface::MapType::READ, &map))
return; return nullptr;
uint32_t bufferSize = aSurface->GetSize().width * aSurface->GetSize().height * 4; uint32_t bufferSize = aSurface->GetSize().width * aSurface->GetSize().height * 4;
uint8_t* imageBuffer = new (fallible) uint8_t[bufferSize]; UniquePtr<uint8_t[]> imageBuffer(new (fallible) uint8_t[bufferSize]);
if (!imageBuffer) { if (!imageBuffer) {
aSurface->Unmap(); aSurface->Unmap();
return; return nullptr;
} }
memcpy(imageBuffer, map.mData, bufferSize); memcpy(imageBuffer.get(), map.mData, bufferSize);
aSurface->Unmap(); aSurface->Unmap();
@ -1577,12 +1575,12 @@ gfxUtils::GetImageBuffer(gfx::DataSourceSurface* aSurface,
// Yes, it is THAT silly. // Yes, it is THAT silly.
// Except for different lossy conversions by color, // Except for different lossy conversions by color,
// we could probably just change the label, and not change the data. // we could probably just change the label, and not change the data.
gfxUtils::ConvertBGRAtoRGBA(imageBuffer, bufferSize); gfxUtils::ConvertBGRAtoRGBA(imageBuffer.get(), bufferSize);
format = imgIEncoder::INPUT_FORMAT_RGBA; format = imgIEncoder::INPUT_FORMAT_RGBA;
} }
*outImageBuffer = imageBuffer;
*outFormat = format; *outFormat = format;
return imageBuffer;
} }
/* static */ nsresult /* static */ nsresult
@ -1598,15 +1596,14 @@ gfxUtils::GetInputStream(gfx::DataSourceSurface* aSurface,
if (!encoder) if (!encoder)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
nsAutoArrayPtr<uint8_t> imageBuffer;
int32_t format = 0; int32_t format = 0;
GetImageBuffer(aSurface, aIsAlphaPremultiplied, getter_Transfers(imageBuffer), &format); UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(aSurface, aIsAlphaPremultiplied, &format);
if (!imageBuffer) if (!imageBuffer)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return dom::ImageEncoder::GetInputStream(aSurface->GetSize().width, return dom::ImageEncoder::GetInputStream(aSurface->GetSize().width,
aSurface->GetSize().height, aSurface->GetSize().height,
imageBuffer, format, imageBuffer.get(), format,
encoder, aEncoderOptions, outStream); encoder, aEncoderOptions, outStream);
} }

View File

@ -10,6 +10,7 @@
#include "imgIContainer.h" #include "imgIContainer.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsColor.h" #include "nsColor.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Rect.h"
@ -282,10 +283,9 @@ public:
static nsCString GetAsDataURI(DrawTarget* aDT); static nsCString GetAsDataURI(DrawTarget* aDT);
static nsCString GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface); static nsCString GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface);
static void GetImageBuffer(DataSourceSurface* aSurface, static mozilla::UniquePtr<uint8_t[]> GetImageBuffer(DataSourceSurface* aSurface,
bool aIsAlphaPremultiplied, bool aIsAlphaPremultiplied,
uint8_t** outImageBuffer, int32_t* outFormat);
int32_t* outFormat);
static nsresult GetInputStream(DataSourceSurface* aSurface, static nsresult GetInputStream(DataSourceSurface* aSurface,
bool aIsAlphaPremultiplied, bool aIsAlphaPremultiplied,

View File

@ -1212,7 +1212,7 @@ AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI,
// Allocate a new buffer that we own and can use out of line in // Allocate a new buffer that we own and can use out of line in
// another thread. // another thread.
uint8_t *data = SurfaceToPackedBGRA(dataSurface); UniquePtr<uint8_t[]> data = SurfaceToPackedBGRA(dataSurface);
if (!data) { if (!data) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
@ -1220,7 +1220,7 @@ AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI,
int32_t dataLength = stride * size.height; int32_t dataLength = stride * size.height;
// AsyncEncodeAndWriteIcon takes ownership of the heap allocated buffer // AsyncEncodeAndWriteIcon takes ownership of the heap allocated buffer
nsCOMPtr<nsIRunnable> event = new AsyncEncodeAndWriteIcon(path, data, nsCOMPtr<nsIRunnable> event = new AsyncEncodeAndWriteIcon(path, Move(data),
dataLength, dataLength,
stride, stride,
size.width, size.width,
@ -1234,7 +1234,7 @@ AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI,
// Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in // Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in
AsyncEncodeAndWriteIcon::AsyncEncodeAndWriteIcon(const nsAString &aIconPath, AsyncEncodeAndWriteIcon::AsyncEncodeAndWriteIcon(const nsAString &aIconPath,
uint8_t *aBuffer, UniquePtr<uint8_t[]> aBuffer,
uint32_t aBufferLength, uint32_t aBufferLength,
uint32_t aStride, uint32_t aStride,
uint32_t aWidth, uint32_t aWidth,
@ -1242,7 +1242,7 @@ AsyncEncodeAndWriteIcon::AsyncEncodeAndWriteIcon(const nsAString &aIconPath,
const bool aURLShortcut) : const bool aURLShortcut) :
mURLShortcut(aURLShortcut), mURLShortcut(aURLShortcut),
mIconPath(aIconPath), mIconPath(aIconPath),
mBuffer(aBuffer), mBuffer(Move(aBuffer)),
mBufferLength(aBufferLength), mBufferLength(aBufferLength),
mStride(aStride), mStride(aStride),
mWidth(aWidth), mWidth(aWidth),
@ -1257,7 +1257,7 @@ NS_IMETHODIMP AsyncEncodeAndWriteIcon::Run()
// Note that since we're off the main thread we can't use // Note that since we're off the main thread we can't use
// gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget() // gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()
RefPtr<DataSourceSurface> surface = RefPtr<DataSourceSurface> surface =
Factory::CreateWrappingDataSourceSurface(mBuffer, mStride, Factory::CreateWrappingDataSourceSurface(mBuffer.get(), mStride,
IntSize(mWidth, mHeight), IntSize(mWidth, mHeight),
SurfaceFormat::B8G8R8A8); SurfaceFormat::B8G8R8A8);

View File

@ -36,6 +36,7 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h" #include "mozilla/EventForwards.h"
#include "mozilla/UniquePtr.h"
/** /**
* NS_INLINE_DECL_IUNKNOWN_REFCOUNTING should be used for defining and * NS_INLINE_DECL_IUNKNOWN_REFCOUNTING should be used for defining and
@ -459,15 +460,15 @@ public:
// Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in // Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in
AsyncEncodeAndWriteIcon(const nsAString &aIconPath, AsyncEncodeAndWriteIcon(const nsAString &aIconPath,
uint8_t *aData, uint32_t aDataLen, uint32_t aStride, UniquePtr<uint8_t[]> aData, uint32_t aDataLen,
uint32_t aWidth, uint32_t aHeight, uint32_t aStride, uint32_t aWidth, uint32_t aHeight,
const bool aURLShortcut); const bool aURLShortcut);
private: private:
virtual ~AsyncEncodeAndWriteIcon(); virtual ~AsyncEncodeAndWriteIcon();
nsAutoString mIconPath; nsAutoString mIconPath;
nsAutoArrayPtr<uint8_t> mBuffer; UniquePtr<uint8_t[]> mBuffer;
HMODULE sDwmDLL; HMODULE sDwmDLL;
uint32_t mBufferLength; uint32_t mBufferLength;
uint32_t mStride; uint32_t mStride;

View File

@ -640,7 +640,7 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
MOZ_ASSERT(dataSurface->GetFormat() == SurfaceFormat::B8G8R8A8); MOZ_ASSERT(dataSurface->GetFormat() == SurfaceFormat::B8G8R8A8);
uint8_t* data = nullptr; uint8_t* data = nullptr;
nsAutoArrayPtr<uint8_t> autoDeleteArray; UniquePtr<uint8_t[]> autoDeleteArray;
if (map.mStride == BytesPerPixel(dataSurface->GetFormat()) * iconSize.width) { if (map.mStride == BytesPerPixel(dataSurface->GetFormat()) * iconSize.width) {
// Mapped data is already packed // Mapped data is already packed
data = map.mData; data = map.mData;
@ -653,7 +653,8 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
dataSurface->Unmap(); dataSurface->Unmap();
map.mData = nullptr; map.mData = nullptr;
data = autoDeleteArray = SurfaceToPackedBGRA(dataSurface); autoDeleteArray = SurfaceToPackedBGRA(dataSurface);
data = autoDeleteArray.get();
NS_ENSURE_TRUE(data, NS_ERROR_FAILURE); NS_ENSURE_TRUE(data, NS_ERROR_FAILURE);
} }