Bug 1812932 - Add size outvar to GetImageBuffer. r=gfx-reviewers,bradwerth

Differential Revision: https://phabricator.services.mozilla.com/D171764
This commit is contained in:
Kelsey Gilbert 2023-03-21 18:05:09 +00:00
parent 44baa0f688
commit eaf3360db2
10 changed files with 42 additions and 24 deletions

View File

@ -1845,10 +1845,11 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx,
}
UniquePtr<uint8_t[]> CanvasRenderingContext2D::GetImageBuffer(
int32_t* aFormat) {
int32_t* out_format, gfx::IntSize* out_imageSize) {
UniquePtr<uint8_t[]> ret;
*aFormat = 0;
*out_format = 0;
*out_imageSize = {};
if (!GetBufferProvider() && !EnsureTarget()) {
return nullptr;
@ -1858,7 +1859,8 @@ UniquePtr<uint8_t[]> CanvasRenderingContext2D::GetImageBuffer(
if (snapshot) {
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
if (data && data->GetSize() == GetSize()) {
*aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB;
*out_format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
*out_imageSize = data->GetSize();
ret = SurfaceToPackedBGRA(data);
}
}
@ -1880,14 +1882,15 @@ CanvasRenderingContext2D::GetInputStream(const char* aMimeType,
}
int32_t format = 0;
UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(&format);
gfx::IntSize imageSize = {};
UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(&format, &imageSize);
if (!imageBuffer) {
return NS_ERROR_FAILURE;
}
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(),
format, encoder, aEncoderOptions,
aStream);
return ImageEncoder::GetInputStream(imageSize.width, imageSize.height,
imageBuffer.get(), format, encoder,
aEncoderOptions, aStream);
}
already_AddRefed<mozilla::gfx::SourceSurface>

View File

@ -516,7 +516,8 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
}
}
virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
virtual UniquePtr<uint8_t[]> GetImageBuffer(
int32_t* out_format, gfx::IntSize* out_imageSize) override;
virtual void OnShutdown();

View File

@ -98,11 +98,11 @@ void CanvasRenderingContextHelper::ToBlob(EncodeCompleteCallback* aCallback,
bool aUsingCustomOptions,
bool aUsePlaceholder,
ErrorResult& aRv) {
const nsIntSize elementSize = GetWidthHeight();
if (mCurrentContext) {
// We disallow canvases of width or height zero, and set them to 1, so
// we will have a discrepancy with the sizes of the canvas and the context.
// That discrepancy is OK, the rest are not.
nsIntSize elementSize = GetWidthHeight();
if ((elementSize.width != mCurrentContext->GetWidth() &&
(elementSize.width != 0 || mCurrentContext->GetWidth() != 1)) ||
(elementSize.height != mCurrentContext->GetHeight() &&
@ -114,15 +114,16 @@ void CanvasRenderingContextHelper::ToBlob(EncodeCompleteCallback* aCallback,
UniquePtr<uint8_t[]> imageBuffer;
int32_t format = 0;
auto imageSize = gfx::IntSize{elementSize.width, elementSize.height};
if (mCurrentContext) {
imageBuffer = mCurrentContext->GetImageBuffer(&format);
imageBuffer = mCurrentContext->GetImageBuffer(&format, &imageSize);
}
RefPtr<EncodeCompleteCallback> callback = aCallback;
aRv = ImageEncoder::ExtractDataAsync(
aType, aEncodeOptions, aUsingCustomOptions, std::move(imageBuffer),
format, GetWidthHeight(), aUsePlaceholder, callback);
format, {imageSize.width, imageSize.height}, aUsePlaceholder, callback);
}
already_AddRefed<nsICanvasRenderingContextInternal>

View File

@ -1170,8 +1170,10 @@ RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() {
return surf;
}
UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer(int32_t* out_format) {
UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer(
int32_t* out_format, gfx::IntSize* out_imageSize) {
*out_format = 0;
*out_imageSize = {};
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
gfxAlphaType any;
@ -1181,6 +1183,7 @@ UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer(int32_t* out_format) {
RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
const auto& premultAlpha = mNotLost->info.options.premultipliedAlpha;
*out_imageSize = dataSurface->GetSize();
return gfxUtils::GetImageBuffer(dataSurface, premultAlpha, out_format);
}

View File

@ -970,7 +970,8 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
void ResetBitmap() override;
UniquePtr<uint8_t[]> GetImageBuffer(int32_t* out_format) override;
UniquePtr<uint8_t[]> GetImageBuffer(int32_t* out_format,
gfx::IntSize* out_imageSize) override;
NS_IMETHOD GetInputStream(const char* mimeType,
const nsAString& encoderOptions,
nsIInputStream** out_stream) override;

View File

@ -141,8 +141,9 @@ ImageBitmapRenderingContext::MatchWithIntrinsicSize() {
}
mozilla::UniquePtr<uint8_t[]> ImageBitmapRenderingContext::GetImageBuffer(
int32_t* aFormat) {
int32_t* aFormat, gfx::IntSize* aImageSize) {
*aFormat = 0;
*aImageSize = {};
if (!mImage) {
return nullptr;
@ -165,6 +166,7 @@ mozilla::UniquePtr<uint8_t[]> ImageBitmapRenderingContext::GetImageBuffer(
}
*aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB;
*aImageSize = data->GetSize();
return gfx::SurfaceToPackedBGRA(data);
}
@ -180,14 +182,15 @@ ImageBitmapRenderingContext::GetInputStream(const char* aMimeType,
}
int32_t format = 0;
UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(&format);
gfx::IntSize imageSize = {};
UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(&format, &imageSize);
if (!imageBuffer) {
return NS_ERROR_FAILURE;
}
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(),
format, encoder, aEncoderOptions,
aStream);
return ImageEncoder::GetInputStream(imageSize.width, imageSize.height,
imageBuffer.get(), format, encoder,
aEncoderOptions, aStream);
}
already_AddRefed<mozilla::gfx::SourceSurface>

View File

@ -70,7 +70,7 @@ class ImageBitmapRenderingContext final
nsIDocShell* aDocShell, NotNull<gfx::DrawTarget*> aTarget) override;
virtual mozilla::UniquePtr<uint8_t[]> GetImageBuffer(
int32_t* aFormat) override;
int32_t* out_format, gfx::IntSize* out_imageSize) override;
NS_IMETHOD GetInputStream(const char* aMimeType,
const nsAString& aEncoderOptions,
nsIInputStream** aStream) override;

View File

@ -106,7 +106,8 @@ class nsICanvasRenderingContextInternal : public nsISupports,
mozilla::NotNull<mozilla::gfx::DrawTarget*> aTarget) = 0;
// Creates an image buffer. Returns null on failure.
virtual mozilla::UniquePtr<uint8_t[]> GetImageBuffer(int32_t* format) = 0;
virtual mozilla::UniquePtr<uint8_t[]> GetImageBuffer(
int32_t* out_format, mozilla::gfx::IntSize* out_imageSize) = 0;
// Gives you a stream containing the image represented by this context.
// The format is given in mimeTime, for example "image/png".

View File

@ -159,17 +159,21 @@ bool CanvasContext::InitializeCanvasRenderer(
return true;
}
mozilla::UniquePtr<uint8_t[]> CanvasContext::GetImageBuffer(int32_t* aFormat) {
mozilla::UniquePtr<uint8_t[]> CanvasContext::GetImageBuffer(
int32_t* out_format, gfx::IntSize* out_imageSize) {
*out_format = 0;
*out_imageSize = {};
gfxAlphaType any;
RefPtr<gfx::SourceSurface> snapshot = GetSurfaceSnapshot(&any);
if (!snapshot) {
*aFormat = 0;
return nullptr;
}
RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
*out_imageSize = dataSurface->GetSize();
return gfxUtils::GetImageBuffer(dataSurface, /* aIsAlphaPremultiplied */ true,
aFormat);
&*out_format);
}
NS_IMETHODIMP CanvasContext::GetInputStream(const char* aMimeType,

View File

@ -57,7 +57,8 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
layers::CanvasRenderer* aRenderer) override;
mozilla::UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
mozilla::UniquePtr<uint8_t[]> GetImageBuffer(
int32_t* out_format, gfx::IntSize* out_imageSize) override;
NS_IMETHOD GetInputStream(const char* aMimeType,
const nsAString& aEncoderOptions,
nsIInputStream** aStream) override;