From eaf3360db23575b5e0faa6bb4b3eabad19b7c8aa Mon Sep 17 00:00:00 2001 From: Kelsey Gilbert Date: Tue, 21 Mar 2023 18:05:09 +0000 Subject: [PATCH] Bug 1812932 - Add size outvar to GetImageBuffer. r=gfx-reviewers,bradwerth Differential Revision: https://phabricator.services.mozilla.com/D171764 --- dom/canvas/CanvasRenderingContext2D.cpp | 17 ++++++++++------- dom/canvas/CanvasRenderingContext2D.h | 3 ++- dom/canvas/CanvasRenderingContextHelper.cpp | 7 ++++--- dom/canvas/ClientWebGLContext.cpp | 5 ++++- dom/canvas/ClientWebGLContext.h | 3 ++- dom/canvas/ImageBitmapRenderingContext.cpp | 13 ++++++++----- dom/canvas/ImageBitmapRenderingContext.h | 2 +- dom/canvas/nsICanvasRenderingContextInternal.h | 3 ++- dom/webgpu/CanvasContext.cpp | 10 +++++++--- dom/webgpu/CanvasContext.h | 3 ++- 10 files changed, 42 insertions(+), 24 deletions(-) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 4988670da023..fc0e21c6d265 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1845,10 +1845,11 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, } UniquePtr CanvasRenderingContext2D::GetImageBuffer( - int32_t* aFormat) { + int32_t* out_format, gfx::IntSize* out_imageSize) { UniquePtr ret; - *aFormat = 0; + *out_format = 0; + *out_imageSize = {}; if (!GetBufferProvider() && !EnsureTarget()) { return nullptr; @@ -1858,7 +1859,8 @@ UniquePtr CanvasRenderingContext2D::GetImageBuffer( if (snapshot) { RefPtr 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 imageBuffer = GetImageBuffer(&format); + gfx::IntSize imageSize = {}; + UniquePtr 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 diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index 6c7d1da80e6f..ccba8bf49949 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -516,7 +516,8 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, } } - virtual UniquePtr GetImageBuffer(int32_t* aFormat) override; + virtual UniquePtr GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) override; virtual void OnShutdown(); diff --git a/dom/canvas/CanvasRenderingContextHelper.cpp b/dom/canvas/CanvasRenderingContextHelper.cpp index 46edc4a2bb18..d45ad8883ec5 100644 --- a/dom/canvas/CanvasRenderingContextHelper.cpp +++ b/dom/canvas/CanvasRenderingContextHelper.cpp @@ -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 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 callback = aCallback; aRv = ImageEncoder::ExtractDataAsync( aType, aEncodeOptions, aUsingCustomOptions, std::move(imageBuffer), - format, GetWidthHeight(), aUsePlaceholder, callback); + format, {imageSize.width, imageSize.height}, aUsePlaceholder, callback); } already_AddRefed diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index 947bcfc2919e..1b6810fe157e 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -1170,8 +1170,10 @@ RefPtr ClientWebGLContext::BackBufferSnapshot() { return surf; } -UniquePtr ClientWebGLContext::GetImageBuffer(int32_t* out_format) { +UniquePtr 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 ClientWebGLContext::GetImageBuffer(int32_t* out_format) { RefPtr dataSurface = snapshot->GetDataSurface(); const auto& premultAlpha = mNotLost->info.options.premultipliedAlpha; + *out_imageSize = dataSurface->GetSize(); return gfxUtils::GetImageBuffer(dataSurface, premultAlpha, out_format); } diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h index 4691234be7be..5bbbcfb8a769 100644 --- a/dom/canvas/ClientWebGLContext.h +++ b/dom/canvas/ClientWebGLContext.h @@ -970,7 +970,8 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal, void ResetBitmap() override; - UniquePtr GetImageBuffer(int32_t* out_format) override; + UniquePtr GetImageBuffer(int32_t* out_format, + gfx::IntSize* out_imageSize) override; NS_IMETHOD GetInputStream(const char* mimeType, const nsAString& encoderOptions, nsIInputStream** out_stream) override; diff --git a/dom/canvas/ImageBitmapRenderingContext.cpp b/dom/canvas/ImageBitmapRenderingContext.cpp index f6af848bda8c..6519a800b565 100644 --- a/dom/canvas/ImageBitmapRenderingContext.cpp +++ b/dom/canvas/ImageBitmapRenderingContext.cpp @@ -141,8 +141,9 @@ ImageBitmapRenderingContext::MatchWithIntrinsicSize() { } mozilla::UniquePtr ImageBitmapRenderingContext::GetImageBuffer( - int32_t* aFormat) { + int32_t* aFormat, gfx::IntSize* aImageSize) { *aFormat = 0; + *aImageSize = {}; if (!mImage) { return nullptr; @@ -165,6 +166,7 @@ mozilla::UniquePtr 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 imageBuffer = GetImageBuffer(&format); + gfx::IntSize imageSize = {}; + UniquePtr 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 diff --git a/dom/canvas/ImageBitmapRenderingContext.h b/dom/canvas/ImageBitmapRenderingContext.h index e34781ec1836..bba271ec60a8 100644 --- a/dom/canvas/ImageBitmapRenderingContext.h +++ b/dom/canvas/ImageBitmapRenderingContext.h @@ -70,7 +70,7 @@ class ImageBitmapRenderingContext final nsIDocShell* aDocShell, NotNull aTarget) override; virtual mozilla::UniquePtr 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; diff --git a/dom/canvas/nsICanvasRenderingContextInternal.h b/dom/canvas/nsICanvasRenderingContextInternal.h index ffba48154c64..b30842fbd97f 100644 --- a/dom/canvas/nsICanvasRenderingContextInternal.h +++ b/dom/canvas/nsICanvasRenderingContextInternal.h @@ -106,7 +106,8 @@ class nsICanvasRenderingContextInternal : public nsISupports, mozilla::NotNull aTarget) = 0; // Creates an image buffer. Returns null on failure. - virtual mozilla::UniquePtr GetImageBuffer(int32_t* format) = 0; + virtual mozilla::UniquePtr 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". diff --git a/dom/webgpu/CanvasContext.cpp b/dom/webgpu/CanvasContext.cpp index cdf2c5e53d92..4ca499c01c84 100644 --- a/dom/webgpu/CanvasContext.cpp +++ b/dom/webgpu/CanvasContext.cpp @@ -159,17 +159,21 @@ bool CanvasContext::InitializeCanvasRenderer( return true; } -mozilla::UniquePtr CanvasContext::GetImageBuffer(int32_t* aFormat) { +mozilla::UniquePtr CanvasContext::GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) { + *out_format = 0; + *out_imageSize = {}; + gfxAlphaType any; RefPtr snapshot = GetSurfaceSnapshot(&any); if (!snapshot) { - *aFormat = 0; return nullptr; } RefPtr dataSurface = snapshot->GetDataSurface(); + *out_imageSize = dataSurface->GetSize(); return gfxUtils::GetImageBuffer(dataSurface, /* aIsAlphaPremultiplied */ true, - aFormat); + &*out_format); } NS_IMETHODIMP CanvasContext::GetInputStream(const char* aMimeType, diff --git a/dom/webgpu/CanvasContext.h b/dom/webgpu/CanvasContext.h index 120e08e7c605..40eb41f8a0aa 100644 --- a/dom/webgpu/CanvasContext.h +++ b/dom/webgpu/CanvasContext.h @@ -57,7 +57,8 @@ class CanvasContext final : public nsICanvasRenderingContextInternal, bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder, layers::CanvasRenderer* aRenderer) override; - mozilla::UniquePtr GetImageBuffer(int32_t* aFormat) override; + mozilla::UniquePtr GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) override; NS_IMETHOD GetInputStream(const char* aMimeType, const nsAString& aEncoderOptions, nsIInputStream** aStream) override;