From 44139eec4c042f81e60a484368d8003e78c215da Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Sat, 23 Apr 2022 16:48:20 +0000 Subject: [PATCH 1/4] Bug 1766056 - Fix YUV color matrix for SWGL slow and fast paths. r=jrmuizel The brush_yuv_image slow path expected a YUV color matrix that applies scaling, whereas we set up a matrix for SWGL that had no scaling to support the fast path. To work around the fact that both paths have different scaling requirements, we pass the matrix with scaling down to the fast path and undo the scaling later when constructing SWGL's internal YUVMatrix from it. This allows both paths to just use the same matrix and avoids the footgun. Differential Revision: https://phabricator.services.mozilla.com/D144479 --- .../test/reftest/color_quads/reftest.list | 4 +- gfx/wr/swgl/src/composite.h | 54 +++++++++++-------- gfx/wr/swgl/src/swgl_ext.h | 8 +-- gfx/wr/webrender/res/brush_yuv_image.glsl | 3 -- gfx/wr/webrender/res/composite.glsl | 3 -- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/dom/media/test/reftest/color_quads/reftest.list b/dom/media/test/reftest/color_quads/reftest.list index 0813d6407af2..e7154455d010 100644 --- a/dom/media/test/reftest/color_quads/reftest.list +++ b/dom/media/test/reftest/color_quads/reftest.list @@ -33,10 +33,10 @@ skip-if(Android) skip-if(!(winWidget&&swgl)) fuzzy(0-31,0-8240) == ../reftest_vi # yuv420p10 skip-if(Android) fuzzy(33-49,2263-2579) fuzzy-if(swgl,34-52,180421-270528) fuzzy-if(useDrawSnapshot,16-16,183840-183840) fuzzy-if(OSX,60-74,270329-271024) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm ../reftest_img.html?src=color_quads/720p.png -skip-if(Android) fuzzy-if(OSX,12-36,187246-273726) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm +skip-if(Android) fuzzy-if(OSX,12-36,187246-273730) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm #[2] skip-if(Android) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.h264.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm -skip-if(Android) fuzzy-if(OSX,12-36,187246-273726) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm +skip-if(Android) fuzzy-if(OSX,12-36,187246-273730) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.vp9.mp4 ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.tv.yuv420p10.av1.webm skip-if(Android) fuzzy(33-49,174699-270059) fuzzy-if(swgl&&!winWidget,36-52,11553-11555) fuzzy-if(swgl&&winWidget,40-52,11555-187200) fuzzy-if(swgl&&OSX,34-50,11465-270059) fuzzy-if(useDrawSnapshot,20-20,186800-186800) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm ../reftest_img.html?src=color_quads/720p.png skip-if(Android) fuzzy-if(OSX,12-27,267487-273726) == ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.vp9.webm ../reftest_video.html?src=color_quads/720p.png.bt709.bt709.pc.yuv420p10.av1.webm diff --git a/gfx/wr/swgl/src/composite.h b/gfx/wr/swgl/src/composite.h index 4caf80446b4e..8a5c3a6d14e3 100644 --- a/gfx/wr/swgl/src/composite.h +++ b/gfx/wr/swgl/src/composite.h @@ -534,7 +534,8 @@ struct YUVMatrix { // [ yScale, g_from_u, g_from_v ] x ([cb] - ycbcr_bias ) // [ yScale, b_from_u, 0 ] ([cr] ) static YUVMatrix From(const vec3_scalar& ycbcr_bias, - const mat3_scalar& rgb_from_debiased_ycbcr) { + const mat3_scalar& rgb_from_debiased_ycbcr, + int rescale_factor = 0) { assert(ycbcr_bias.z == ycbcr_bias.y); const auto rgb_from_y = rgb_from_debiased_ycbcr[0].y; @@ -544,14 +545,14 @@ struct YUVMatrix { if (rgb_from_debiased_ycbcr[0].x == 0.0) { // gbr-identity matrix? assert(rgb_from_debiased_ycbcr[0].x == 0); - assert(rgb_from_debiased_ycbcr[0].y == 1); + assert(rgb_from_debiased_ycbcr[0].y >= 1); assert(rgb_from_debiased_ycbcr[0].z == 0); assert(rgb_from_debiased_ycbcr[1].x == 0); assert(rgb_from_debiased_ycbcr[1].y == 0); - assert(rgb_from_debiased_ycbcr[1].z == 1); + assert(rgb_from_debiased_ycbcr[1].z >= 1); - assert(rgb_from_debiased_ycbcr[2].x == 1); + assert(rgb_from_debiased_ycbcr[2].x >= 1); assert(rgb_from_debiased_ycbcr[2].y == 0); assert(rgb_from_debiased_ycbcr[2].z == 0); @@ -573,24 +574,30 @@ struct YUVMatrix { assert(rgb_from_debiased_ycbcr[2].z == 0.0); return YUVMatrix({ycbcr_bias.x, ycbcr_bias.y}, rgb_from_y, br_from_y_mask, - r_from_v, g_from_u, g_from_v, b_from_u); + r_from_v, g_from_u, g_from_v, b_from_u, rescale_factor); } - // Convert matrix coefficients to fixed-point representation. + // Convert matrix coefficients to fixed-point representation. If the matrix + // has a rescaling applied to it, then we need to take care to undo the + // scaling so that we can convert the coefficients to fixed-point range. The + // bias still requires shifting to apply the rescaling. The rescaling will be + // applied to the actual YCbCr sample data later by manually shifting it + // before applying this matrix. YUVMatrix(vec2_scalar yuv_bias, double yCoeff, int16_t br_yMask_, double rv, - double gu, double gv, double bu) - : br_uvCoeffs(zip(I16(int16_t(bu * (1 << 6) + 0.5)), - I16(int16_t(rv * (1 << 6) + 0.5)))), - gg_uvCoeffs(zip(I16(-int16_t(-gu * (1 << 6) + - 0.5)), // These are negative coeffs, so - // round them away from zero - I16(-int16_t(-gv * (1 << 6) + 0.5)))), - yCoeffs(uint16_t(yCoeff * (1 << (6 + 1)) + 0.5)), + double gu, double gv, double bu, int rescale_factor = 0) + : br_uvCoeffs(zip(I16(int16_t(bu * (1 << (6 - rescale_factor)) + 0.5)), + I16(int16_t(rv * (1 << (6 - rescale_factor)) + 0.5)))), + gg_uvCoeffs( + zip(I16(-int16_t(-gu * (1 << (6 - rescale_factor)) + + 0.5)), // These are negative coeffs, so + // round them away from zero + I16(-int16_t(-gv * (1 << (6 - rescale_factor)) + 0.5)))), + yCoeffs(uint16_t(yCoeff * (1 << (6 + 1 - rescale_factor)) + 0.5)), // We have a +0.5 fudge-factor for -ybias. // Without this, we get white=254 not 255. // This approximates rounding rather than truncation during `gg >>= 6`. - yBias(int16_t( ((yuv_bias.x * 255 * yCoeff) - 0.5 ) * (1<<6) )), - uvBias(int16_t(yuv_bias.y * 255 + 0.5)), + yBias(int16_t(((yuv_bias.x * 255 * yCoeff) - 0.5) * (1 << 6))), + uvBias(int16_t(yuv_bias.y * (255 << rescale_factor) + 0.5)), br_yMask(br_yMask_) { assert(yuv_bias.x >= 0); assert(yuv_bias.y >= 0); @@ -600,6 +607,7 @@ struct YUVMatrix { assert(rv > 0); assert(gu <= 0); assert(gv <= 0); + assert(rescale_factor <= 6); } ALWAYS_INLINE PackedRGBA8 convert(V8 yy, V8 uv) const { @@ -881,11 +889,15 @@ static void linear_row_yuv(uint32_t* dest, int span, sampler2DRect samplerY, // If the source row has less than 2 pixels, it's not safe to use a linear // filter because it may overread the row. Just convert the single pixel // with nearest filtering and fill the row with it. - I16 yuv = CONVERT( - round_pixel((Float){texelFetch(samplerY, ivec2(srcUV)).x.x, - texelFetch(samplerU, ivec2(chromaUV)).x.x, - texelFetch(samplerV, ivec2(chromaUV)).x.x, 1.0f}), - I16); + Float yuvF = {texelFetch(samplerY, ivec2(srcUV)).x.x, + texelFetch(samplerU, ivec2(chromaUV)).x.x, + texelFetch(samplerV, ivec2(chromaUV)).x.x, 1.0f}; + // If this is an HDR LSB format, we need to renormalize the result. + if (colorDepth > 8) { + int rescaleFactor = 16 - colorDepth; + yuvF *= float(1 << rescaleFactor); + } + I16 yuv = CONVERT(round_pixel(yuvF), I16); commit_solid_span( dest, unpack(colorSpace.convert(V8(yuv.x), diff --git a/gfx/wr/swgl/src/swgl_ext.h b/gfx/wr/swgl/src/swgl_ext.h index 462ba24c0d38..0eb750564951 100644 --- a/gfx/wr/swgl/src/swgl_ext.h +++ b/gfx/wr/swgl/src/swgl_ext.h @@ -1029,7 +1029,7 @@ static int blendYUV(P* buf, int span, S0 sampler0, vec2 uv0, } LINEAR_QUANTIZE_UV(sampler0, uv0, uv_step0, uv_rect0, min_uv0, max_uv0); const auto rgb_from_ycbcr = - YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr); + YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr, rescaleFactor); auto c = packColor(buf, color); auto* end = buf + span; for (; buf < end; buf += swgl_StepSize, uv0 += uv_step0) { @@ -1095,7 +1095,7 @@ static int blendYUV(P* buf, int span, S0 sampler0, vec2 uv0, LINEAR_QUANTIZE_UV(sampler0, uv0, uv_step0, uv_rect0, min_uv0, max_uv0); LINEAR_QUANTIZE_UV(sampler1, uv1, uv_step1, uv_rect1, min_uv1, max_uv1); const auto rgb_from_ycbcr = - YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr); + YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr, rescaleFactor); auto c = packColor(buf, color); auto* end = buf + span; for (; buf < end; buf += swgl_StepSize, uv0 += uv_step0, uv1 += uv_step1) { @@ -1157,7 +1157,7 @@ static void blendYUVFallback(P* buf, int span, S0 sampler0, vec2 uv0, const mat3_scalar& rgb_from_debiased_ycbcr, int rescaleFactor, C color) { const auto rgb_from_ycbcr = - YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr); + YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr, rescaleFactor); for (auto* end = buf + span; buf < end; buf += swgl_StepSize, uv0 += uv_step0, uv1 += uv_step1, uv2 += uv_step2) { commit_blend_span( @@ -1255,7 +1255,7 @@ static int blendYUV(uint32_t* buf, int span, sampler2DRect sampler0, vec2 uv0, (sampler0->format == TextureFormat::R16 ? 16 : 8) - rescaleFactor; // Finally, call the inner loop of CompositeYUV. const auto rgb_from_ycbcr = - YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr); + YUVMatrix::From(ycbcr_bias, rgb_from_debiased_ycbcr, rescaleFactor); linear_row_yuv( buf, inside * swgl_StepSize, sampler0, force_scalar(uv0), uv_step0.x / swgl_StepSize, sampler1, sampler2, force_scalar(uv1), diff --git a/gfx/wr/webrender/res/brush_yuv_image.glsl b/gfx/wr/webrender/res/brush_yuv_image.glsl index eb41ecb490fb..28abcab66f8d 100644 --- a/gfx/wr/webrender/res/brush_yuv_image.glsl +++ b/gfx/wr/webrender/res/brush_yuv_image.glsl @@ -60,9 +60,6 @@ void brush_vs( if (prim.channel_bit_depth > 8 && prim.yuv_format != YUV_FORMAT_P010) { vRescaleFactor = 16 - prim.channel_bit_depth; } - // Since SWGL rescales filtered YUV values to 8bpc before yuv->rgb - // conversion, don't embed a 10bpc channel multiplier into the yuv matrix. - prim.channel_bit_depth = 8; #endif YuvColorMatrixInfo mat_info = get_rgb_from_ycbcr_info(prim); diff --git a/gfx/wr/webrender/res/composite.glsl b/gfx/wr/webrender/res/composite.glsl index 576199fe5c46..4c52f36de178 100644 --- a/gfx/wr/webrender/res/composite.glsl +++ b/gfx/wr/webrender/res/composite.glsl @@ -97,9 +97,6 @@ void main(void) { if (prim.channel_bit_depth > 8 && prim.yuv_format != YUV_FORMAT_P010) { vRescaleFactor = 16 - prim.channel_bit_depth; } - // Since SWGL rescales filtered YUV values to 8bpc before yuv->rgb - // conversion, don't embed a 10bpc channel multiplier into the yuv matrix. - prim.channel_bit_depth = 8; #endif YuvColorMatrixInfo mat_info = get_rgb_from_ycbcr_info(prim); From 6504eb38b3c8206ded14dc99735aa26081581f8d Mon Sep 17 00:00:00 2001 From: Andrew Osmond Date: Sat, 23 Apr 2022 18:15:51 +0000 Subject: [PATCH 2/4] Bug 1752155 - Refactor WebGPU's ValidationError to make it constructable from JS. r=gfx-reviewers,lsalzman,webidl,edgar Differential Revision: https://phabricator.services.mozilla.com/D144322 --- dom/webgpu/Device.cpp | 4 ++-- dom/webgpu/ValidationError.cpp | 38 +++++++++++++++++++++------------- dom/webgpu/ValidationError.h | 19 +++++++++++------ dom/webgpu/ipc/WebGPUChild.cpp | 2 +- dom/webidl/WebGPU.webidl | 1 + 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/dom/webgpu/Device.cpp b/dom/webgpu/Device.cpp index 9c5a243670c3..3b5ee70bf4c6 100644 --- a/dom/webgpu/Device.cpp +++ b/dom/webgpu/Device.cpp @@ -360,8 +360,8 @@ already_AddRefed Device::PopErrorScope(ErrorResult& aRv) { if (aMaybeError->validationMessage.IsEmpty()) { error.SetAsGPUOutOfMemoryError(); } else { - error.SetAsGPUValidationError() = - new ValidationError(self, aMaybeError->validationMessage); + error.SetAsGPUValidationError() = new ValidationError( + self->GetParentObject(), aMaybeError->validationMessage); } promise->MaybeResolve(std::move(error)); } diff --git a/dom/webgpu/ValidationError.cpp b/dom/webgpu/ValidationError.cpp index 287326dab052..119156713cf0 100644 --- a/dom/webgpu/ValidationError.cpp +++ b/dom/webgpu/ValidationError.cpp @@ -4,28 +4,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ValidationError.h" -#include "Device.h" #include "mozilla/dom/WebGPUBinding.h" +#include "mozilla/ErrorResult.h" +#include "nsIGlobalObject.h" +#include "nsReadableUtils.h" -namespace mozilla { -namespace webgpu { +namespace mozilla::webgpu { -GPU_IMPL_CYCLE_COLLECTION(ValidationError, mParent) +GPU_IMPL_CYCLE_COLLECTION(ValidationError, mGlobal) GPU_IMPL_JS_WRAP(ValidationError) -ValidationError::ValidationError(Device* aParent, const nsACString& aMessage) - : ChildOf(aParent), mMessage(aMessage) {} +ValidationError::ValidationError(nsIGlobalObject* aGlobal, + const nsACString& aMessage) + : mGlobal(aGlobal) { + CopyUTF8toUTF16(aMessage, mMessage); +} + +ValidationError::ValidationError(nsIGlobalObject* aGlobal, + const nsAString& aMessage) + : mGlobal(aGlobal), mMessage(aMessage) {} ValidationError::~ValidationError() = default; already_AddRefed ValidationError::Constructor( - const dom::GlobalObject& aGlobal, const nsAString& aString) { - MOZ_CRASH("TODO"); + const dom::GlobalObject& aGlobal, const nsAString& aString, + ErrorResult& aRv) { + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (!global) { + aRv.ThrowInvalidStateError("aGlobal is not nsIGlobalObject"); + return nullptr; + } + + return MakeAndAddRef(global, aString); } -void ValidationError::GetMessage(nsAString& aMessage) const { - CopyUTF8toUTF16(mMessage, aMessage); -} - -} // namespace webgpu -} // namespace mozilla +} // namespace mozilla::webgpu diff --git a/dom/webgpu/ValidationError.h b/dom/webgpu/ValidationError.h index a46c39a2bf4d..bdbc1ce2eba9 100644 --- a/dom/webgpu/ValidationError.h +++ b/dom/webgpu/ValidationError.h @@ -6,23 +6,28 @@ #ifndef GPU_ValidationError_H_ #define GPU_ValidationError_H_ +#include "nsCOMPtr.h" +#include "nsString.h" #include "nsWrapperCache.h" #include "ObjectModel.h" namespace mozilla { +class ErrorResult; + namespace dom { class GlobalObject; } // namespace dom namespace webgpu { -class Device; -class ValidationError final : public nsWrapperCache, public ChildOf { - nsCString mMessage; +class ValidationError final : public nsWrapperCache { + nsCOMPtr mGlobal; + nsString mMessage; public: GPU_DECL_CYCLE_COLLECTION(ValidationError) GPU_DECL_JS_WRAP(ValidationError) - ValidationError(Device* aParent, const nsACString& aMessage); + ValidationError(nsIGlobalObject* aGlobal, const nsACString& aMessage); + ValidationError(nsIGlobalObject* aGlobal, const nsAString& aMessage); private: virtual ~ValidationError(); @@ -30,8 +35,10 @@ class ValidationError final : public nsWrapperCache, public ChildOf { public: static already_AddRefed Constructor( - const dom::GlobalObject& aGlobal, const nsAString& aString); - void GetMessage(nsAString& aMessage) const; + const dom::GlobalObject& aGlobal, const nsAString& aString, + ErrorResult& aRv); + void GetMessage(nsAString& aMessage) const { aMessage = mMessage; } + nsIGlobalObject* GetParentObject() const { return mGlobal; } }; } // namespace webgpu diff --git a/dom/webgpu/ipc/WebGPUChild.cpp b/dom/webgpu/ipc/WebGPUChild.cpp index 5a8f1f593738..155718755209 100644 --- a/dom/webgpu/ipc/WebGPUChild.cpp +++ b/dom/webgpu/ipc/WebGPUChild.cpp @@ -998,7 +998,7 @@ ipc::IPCResult WebGPUChild::RecvDeviceUncapturedError( dom::GPUUncapturedErrorEventInit init; init.mError.SetAsGPUValidationError() = - new ValidationError(target, aMessage); + new ValidationError(target->GetParentObject(), aMessage); RefPtr event = dom::GPUUncapturedErrorEvent::Constructor( target, u"uncapturederror"_ns, init); diff --git a/dom/webidl/WebGPU.webidl b/dom/webidl/WebGPU.webidl index 2c04644a2a8e..de49682fe07e 100644 --- a/dom/webidl/WebGPU.webidl +++ b/dom/webidl/WebGPU.webidl @@ -208,6 +208,7 @@ interface GPUOutOfMemoryError { [Pref="dom.webgpu.enabled", Exposed=(Window,DedicatedWorker)] interface GPUValidationError { + [Throws] constructor(DOMString message); readonly attribute DOMString message; }; From 8f3654680c7c50c69cbf93b3c79b55e0615de41f Mon Sep 17 00:00:00 2001 From: Csoregi Natalia Date: Sun, 24 Apr 2022 02:33:33 +0300 Subject: [PATCH 3/4] Backed out 3 changesets (bug 1755704, bug 1765816) for causing reftest failures on webgl-color-test.html Backed out changeset 2f074e2385d4 (bug 1765816) Backed out changeset cd0b9e084bcd (bug 1755704) Backed out changeset 39a846e43162 (bug 1755704) --- dom/canvas/OffscreenCanvasDisplayHelper.cpp | 6 +-- .../nsICanvasRenderingContextInternal.cpp | 10 ---- .../nsICanvasRenderingContextInternal.h | 4 +- dom/webgpu/CanvasContext.cpp | 51 +------------------ dom/webgpu/CanvasContext.h | 14 +++-- dom/webgpu/ipc/WebGPUParent.cpp | 30 ----------- dom/webgpu/ipc/WebGPUParent.h | 11 ++-- gfx/ipc/CanvasManagerChild.cpp | 43 ++++++---------- gfx/ipc/CanvasManagerChild.h | 8 ++- gfx/ipc/CanvasManagerParent.cpp | 31 +++-------- gfx/ipc/CanvasManagerParent.h | 1 - gfx/ipc/PCanvasManager.ipdl | 4 +- 12 files changed, 46 insertions(+), 167 deletions(-) diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.cpp b/dom/canvas/OffscreenCanvasDisplayHelper.cpp index 0d0701ad4eab..8d75cff2f7a5 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.cpp +++ b/dom/canvas/OffscreenCanvasDisplayHelper.cpp @@ -252,14 +252,12 @@ OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() { Maybe childId; HTMLCanvasElement* canvasElement; RefPtr surface; - layers::CompositableHandle handle; { MutexAutoLock lock(mMutex); hasAlpha = !mData.mIsOpaque; isAlphaPremult = mData.mIsAlphaPremult; originPos = mData.mOriginPos; - handle = mData.mHandle; managerId = mContextManagerId; childId = mContextChildId; canvasElement = mCanvasElement; @@ -313,9 +311,7 @@ OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() { // We don't have a usable surface, and the context lives in the compositor // process. return gfx::CanvasManagerChild::Get()->GetSnapshot( - managerId.value(), childId.value(), handle, - hasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8, - hasAlpha && !isAlphaPremult, originPos == gl::OriginPos::BottomLeft); + managerId.value(), childId.value(), hasAlpha); } // If we don't have any protocol IDs, or an existing surface, it is possible diff --git a/dom/canvas/nsICanvasRenderingContextInternal.cpp b/dom/canvas/nsICanvasRenderingContextInternal.cpp index ffa24289a46b..103de14ce6b6 100644 --- a/dom/canvas/nsICanvasRenderingContextInternal.cpp +++ b/dom/canvas/nsICanvasRenderingContextInternal.cpp @@ -9,7 +9,6 @@ #include "mozilla/dom/Document.h" #include "mozilla/PresShell.h" #include "nsRefreshDriver.h" -#include "ImageContainer.h" nsICanvasRenderingContextInternal::nsICanvasRenderingContextInternal() = default; @@ -73,12 +72,3 @@ void nsICanvasRenderingContextInternal::DoSecurityCheck( mOffscreenCanvas->SetWriteOnly(); } } - -already_AddRefed -nsICanvasRenderingContextInternal::GetAsImage() { - RefPtr snapshot = GetFrontBufferSnapshot(true); - if (!snapshot) { - return nullptr; - } - return mozilla::MakeAndAddRef(snapshot); -} diff --git a/dom/canvas/nsICanvasRenderingContextInternal.h b/dom/canvas/nsICanvasRenderingContextInternal.h index 6c4bbcdef663..f284f44b672e 100644 --- a/dom/canvas/nsICanvasRenderingContextInternal.h +++ b/dom/canvas/nsICanvasRenderingContextInternal.h @@ -146,7 +146,9 @@ class nsICanvasRenderingContextInternal : public nsISupports, // for possibly reinitializing with SetDimensions/InitializeWithSurface. NS_IMETHOD Reset() = 0; - virtual already_AddRefed GetAsImage(); + virtual already_AddRefed GetAsImage() { + return nullptr; + } virtual bool UpdateWebRenderCanvasData( mozilla::nsDisplayListBuilder* aBuilder, diff --git a/dom/webgpu/CanvasContext.cpp b/dom/webgpu/CanvasContext.cpp index 676188ca4859..d4b4689faad9 100644 --- a/dom/webgpu/CanvasContext.cpp +++ b/dom/webgpu/CanvasContext.cpp @@ -5,11 +5,9 @@ #include "mozilla/dom/WebGPUBinding.h" #include "CanvasContext.h" -#include "gfxUtils.h" -#include "LayerUserData.h" #include "nsDisplayList.h" +#include "LayerUserData.h" #include "mozilla/dom/HTMLCanvasElement.h" -#include "mozilla/gfx/CanvasManagerChild.h" #include "mozilla/layers/CompositableInProcessManager.h" #include "mozilla/layers/ImageDataSerializer.h" #include "mozilla/layers/LayersSurfaces.h" @@ -80,7 +78,6 @@ void CanvasContext::Configure(const dom::GPUCanvasConfiguration& aDesc) { } else if (mOffscreenCanvas) { dom::OffscreenCanvasDisplayData data; data.mSize = {mWidth, mHeight}; - data.mIsOpaque = false; data.mHandle = mHandle; mOffscreenCanvas->UpdateDisplayData(data); } @@ -126,51 +123,5 @@ void CanvasContext::SwapChainPresent() { } } -mozilla::UniquePtr CanvasContext::GetImageBuffer(int32_t* aFormat) { - gfxAlphaType any; - RefPtr snapshot = GetSurfaceSnapshot(&any); - if (!snapshot) { - *aFormat = 0; - return nullptr; - } - - RefPtr dataSurface = snapshot->GetDataSurface(); - return gfxUtils::GetImageBuffer(dataSurface, /* aIsAlphaPremultiplied */ true, - aFormat); -} - -NS_IMETHODIMP CanvasContext::GetInputStream(const char* aMimeType, - const nsAString& aEncoderOptions, - nsIInputStream** aStream) { - gfxAlphaType any; - RefPtr snapshot = GetSurfaceSnapshot(&any); - if (!snapshot) { - return NS_ERROR_FAILURE; - } - - RefPtr dataSurface = snapshot->GetDataSurface(); - return gfxUtils::GetInputStream(dataSurface, /* aIsAlphaPremultiplied */ true, - aMimeType, aEncoderOptions, aStream); -} - -already_AddRefed CanvasContext::GetSurfaceSnapshot( - gfxAlphaType* aOutAlphaType) { - if (aOutAlphaType) { - *aOutAlphaType = gfxAlphaType::Premult; - } - - auto* const cm = gfx::CanvasManagerChild::Get(); - if (!cm) { - return nullptr; - } - - if (!mBridge || !mBridge->IsOpen() || !mHandle) { - return nullptr; - } - - return cm->GetSnapshot(cm->Id(), mBridge->Id(), mHandle, mGfxFormat, - /* aPremultiply */ false, /* aYFlip */ false); -} - } // namespace webgpu } // namespace mozilla diff --git a/dom/webgpu/CanvasContext.h b/dom/webgpu/CanvasContext.h index 2ef574000201..05aca8caf58f 100644 --- a/dom/webgpu/CanvasContext.h +++ b/dom/webgpu/CanvasContext.h @@ -54,12 +54,20 @@ class CanvasContext final : public nsICanvasRenderingContextInternal, return NS_OK; } - mozilla::UniquePtr GetImageBuffer(int32_t* aFormat) override; + mozilla::UniquePtr GetImageBuffer(int32_t* aFormat) override { + MOZ_CRASH("todo"); + } NS_IMETHOD GetInputStream(const char* aMimeType, const nsAString& aEncoderOptions, - nsIInputStream** aStream) override; + nsIInputStream** aStream) override { + *aStream = nullptr; + return NS_ERROR_NOT_IMPLEMENTED; + } + already_AddRefed GetSurfaceSnapshot( - gfxAlphaType* aOutAlphaType) override; + gfxAlphaType* aOutAlphaType) override { + return nullptr; + } void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) override {} bool GetIsOpaque() override { return true; } diff --git a/dom/webgpu/ipc/WebGPUParent.cpp b/dom/webgpu/ipc/WebGPUParent.cpp index 2a8cc73f73e6..d23f84132f28 100644 --- a/dom/webgpu/ipc/WebGPUParent.cpp +++ b/dom/webgpu/ipc/WebGPUParent.cpp @@ -640,36 +640,6 @@ static void PresentCallback(ffi::WGPUBufferMapAsyncStatus status, delete req; } -ipc::IPCResult WebGPUParent::GetFrontBufferSnapshot( - IProtocol* aProtocol, const CompositableHandle& aHandle, - Maybe& aShmem, gfx::IntSize& aSize) { - const auto& lookup = mCanvasMap.find(aHandle.Value()); - if (lookup == mCanvasMap.end()) { - return IPC_OK(); - } - - RefPtr data = lookup->second.get(); - aSize = data->mTextureHost->GetSize(); - uint32_t stride = - aSize.width * BytesPerPixel(data->mTextureHost->GetFormat()); - uint32_t len = data->mRowCount * stride; - Shmem shmem; - if (!AllocShmem(len, ipc::Shmem::SharedMemory::TYPE_BASIC, &shmem)) { - return IPC_OK(); - } - - uint8_t* dst = shmem.get(); - uint8_t* src = data->mTextureHost->GetBuffer(); - for (uint32_t row = 0; row < data->mRowCount; ++row) { - memcpy(dst, src, stride); - src += data->mTargetPitch; - dst += stride; - } - - aShmem.emplace(std::move(shmem)); - return IPC_OK(); -} - ipc::IPCResult WebGPUParent::RecvSwapChainPresent( const CompositableHandle& aHandle, RawId aTextureId, RawId aCommandEncoderId) { diff --git a/dom/webgpu/ipc/WebGPUParent.h b/dom/webgpu/ipc/WebGPUParent.h index f4591d52f885..0bee6a34cc1e 100644 --- a/dom/webgpu/ipc/WebGPUParent.h +++ b/dom/webgpu/ipc/WebGPUParent.h @@ -11,7 +11,8 @@ #include "WebGPUTypes.h" #include "base/timer.h" -namespace mozilla::webgpu { +namespace mozilla { +namespace webgpu { class ErrorBuffer; class PresentationData; @@ -89,11 +90,6 @@ class WebGPUParent final : public PWebGPUParent { ipc::IPCResult RecvDevicePopErrorScope( RawId aSelfId, DevicePopErrorScopeResolver&& aResolver); - ipc::IPCResult GetFrontBufferSnapshot(IProtocol* aProtocol, - const CompositableHandle& aHandle, - Maybe& aShmem, - gfx::IntSize& aSize); - void ActorDestroy(ActorDestroyReason aWhy) override; private: @@ -113,6 +109,7 @@ class WebGPUParent final : public PWebGPUParent { std::unordered_map mErrorScopeMap; }; -} // namespace mozilla::webgpu +} // namespace webgpu +} // namespace mozilla #endif // WEBGPU_PARENT_H_ diff --git a/gfx/ipc/CanvasManagerChild.cpp b/gfx/ipc/CanvasManagerChild.cpp index 76e46b98b40b..e4dd68696160 100644 --- a/gfx/ipc/CanvasManagerChild.cpp +++ b/gfx/ipc/CanvasManagerChild.cpp @@ -144,15 +144,13 @@ RefPtr CanvasManagerChild::GetWebGPUChild() { } already_AddRefed CanvasManagerChild::GetSnapshot( - uint32_t aManagerId, int32_t aProtocolId, - const layers::CompositableHandle& aHandle, SurfaceFormat aFormat, - bool aPremultiply, bool aYFlip) { + uint32_t aManagerId, int32_t aProtocolId, bool aHasAlpha) { if (!CanSend()) { return nullptr; } webgl::FrontBufferSnapshotIpc res; - if (!SendGetSnapshot(aManagerId, aProtocolId, aHandle, &res)) { + if (!SendGetSnapshot(aManagerId, aProtocolId, &res)) { return nullptr; } @@ -180,7 +178,7 @@ already_AddRefed CanvasManagerChild::GetSnapshot( } SurfaceFormat format = - IsOpaque(aFormat) ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8; + aHasAlpha ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; RefPtr surface = Factory::CreateDataSourceSurfaceWithStride(size, format, stride.value(), /* aZero */ false); @@ -194,32 +192,21 @@ already_AddRefed CanvasManagerChild::GetSnapshot( return nullptr; } - // The buffer we may readback from the canvas could be R8G8B8A8, not - // premultiplied, and/or has its rows iverted. For the general case, we want - // surfaces represented as premultiplied B8G8R8A8, with its rows ordered top - // to bottom. Given this path is used for screenshots/SurfaceFromElement, - // that's the representation we need. - if (aYFlip) { - if (aPremultiply) { - if (!PremultiplyYFlipData(res.shmem->get(), stride.value(), - aFormat, map.GetData(), map.GetStride(), format, - size)) { - return nullptr; - } - } else { - if (!SwizzleYFlipData(res.shmem->get(), stride.value(), aFormat, - map.GetData(), map.GetStride(), format, size)) { - return nullptr; - } - } - } else if (aPremultiply) { - if (!PremultiplyData(res.shmem->get(), stride.value(), aFormat, - map.GetData(), map.GetStride(), format, size)) { + // The buffer we read back from WebGL is R8G8B8A8, not premultiplied and has + // its rows inverted. For the general case, we want surfaces represented as + // premultiplied B8G8R8A8, with its rows ordered top to bottom. Given this + // path is used for screenshots/SurfaceFromElement, that's the representation + // we need. + if (aHasAlpha) { + if (!PremultiplyYFlipData(res.shmem->get(), stride.value(), + SurfaceFormat::R8G8B8A8, map.GetData(), + map.GetStride(), format, size)) { return nullptr; } } else { - if (!SwizzleData(res.shmem->get(), stride.value(), aFormat, - map.GetData(), map.GetStride(), format, size)) { + if (!SwizzleYFlipData(res.shmem->get(), stride.value(), + SurfaceFormat::R8G8B8X8, map.GetData(), + map.GetStride(), format, size)) { return nullptr; } } diff --git a/gfx/ipc/CanvasManagerChild.h b/gfx/ipc/CanvasManagerChild.h index f5d1dac2bcae..2538e3c17bca 100644 --- a/gfx/ipc/CanvasManagerChild.h +++ b/gfx/ipc/CanvasManagerChild.h @@ -8,7 +8,6 @@ #include "mozilla/Atomics.h" #include "mozilla/gfx/PCanvasManagerChild.h" -#include "mozilla/gfx/Types.h" #include "mozilla/ThreadLocal.h" namespace mozilla { @@ -30,10 +29,9 @@ class CanvasManagerChild final : public PCanvasManagerChild { explicit CanvasManagerChild(uint32_t aId); uint32_t Id() const { return mId; } - already_AddRefed GetSnapshot( - uint32_t aManagerId, int32_t aProtocolId, - const layers::CompositableHandle& aHandle, SurfaceFormat aFormat, - bool aPremultiply, bool aYFlip); + already_AddRefed GetSnapshot(uint32_t aManagerId, + int32_t aProtocolId, + bool aHasAlpha); void ActorDestroy(ActorDestroyReason aReason) override; static CanvasManagerChild* Get(); diff --git a/gfx/ipc/CanvasManagerParent.cpp b/gfx/ipc/CanvasManagerParent.cpp index 076b2ce4fc01..65fd4d6c632f 100644 --- a/gfx/ipc/CanvasManagerParent.cpp +++ b/gfx/ipc/CanvasManagerParent.cpp @@ -111,7 +111,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvInitialize( mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot( const uint32_t& aManagerId, const int32_t& aProtocolId, - const CompositableHandle& aHandle, webgl::FrontBufferSnapshotIpc* aResult) { + webgl::FrontBufferSnapshotIpc* aResult) { if (!aManagerId) { return IPC_FAIL(this, "invalid id"); } @@ -129,33 +129,16 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot( return IPC_FAIL(this, "invalid actor"); } - if (actor->GetSide() != mozilla::ipc::Side::ParentSide) { + if (actor->GetProtocolId() != ProtocolId::PWebGLMsgStart || + actor->GetSide() != mozilla::ipc::Side::ParentSide) { return IPC_FAIL(this, "unsupported actor"); } + RefPtr webgl = static_cast(actor); webgl::FrontBufferSnapshotIpc buffer; - switch (actor->GetProtocolId()) { - case ProtocolId::PWebGLMsgStart: { - RefPtr webgl = static_cast(actor); - mozilla::ipc::IPCResult rv = webgl->GetFrontBufferSnapshot(&buffer, this); - if (!rv) { - return rv; - } - } break; - case ProtocolId::PWebGPUMsgStart: { - RefPtr webgpu = - static_cast(actor); - IntSize size; - mozilla::ipc::IPCResult rv = - webgpu->GetFrontBufferSnapshot(this, aHandle, buffer.shmem, size); - if (!rv) { - return rv; - } - buffer.surfSize.x = static_cast(size.width); - buffer.surfSize.y = static_cast(size.height); - } break; - default: - return IPC_FAIL(this, "unsupported protocol"); + mozilla::ipc::IPCResult rv = webgl->GetFrontBufferSnapshot(&buffer, this); + if (!rv) { + return rv; } *aResult = std::move(buffer); diff --git a/gfx/ipc/CanvasManagerParent.h b/gfx/ipc/CanvasManagerParent.h index c652dd670283..6cf0e7138be1 100644 --- a/gfx/ipc/CanvasManagerParent.h +++ b/gfx/ipc/CanvasManagerParent.h @@ -30,7 +30,6 @@ class CanvasManagerParent final : public PCanvasManagerParent { mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId); mozilla::ipc::IPCResult RecvGetSnapshot( const uint32_t& aManagerId, const int32_t& aProtocolId, - const CompositableHandle& aHandle, webgl::FrontBufferSnapshotIpc* aResult); private: diff --git a/gfx/ipc/PCanvasManager.ipdl b/gfx/ipc/PCanvasManager.ipdl index d625b4c5e7ef..8bea31a7a8bd 100644 --- a/gfx/ipc/PCanvasManager.ipdl +++ b/gfx/ipc/PCanvasManager.ipdl @@ -5,11 +5,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -include "mozilla/layers/LayersMessageUtils.h"; include protocol PWebGL; include protocol PWebGPU; -using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h"; using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h"; namespace mozilla { @@ -41,7 +39,7 @@ parent: // intended to be used by the main thread in the content process to block // reading without having to block on the worker thread that owns the context // instance. - sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId, CompositableHandle aHandle) returns (FrontBufferSnapshotIpc ret); + sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId) returns (FrontBufferSnapshotIpc ret); }; } // gfx From 9579f560ccddfcd049e2b2af17ed3e524819d9ac Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Sun, 24 Apr 2022 03:54:27 +0000 Subject: [PATCH 4/4] Bug 1727562: Avoid else-after-break in nsFrameTraversal.cpp, and add braces to one-liner if-statements. r=emilio This patch doesn't change behavior; it just makes this code more consistent with our coding style. Differential Revision: https://phabricator.services.mozilla.com/D144514 --- layout/base/nsFrameTraversal.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/layout/base/nsFrameTraversal.cpp b/layout/base/nsFrameTraversal.cpp index 2f86fe55d44f..64280e10d33b 100644 --- a/layout/base/nsFrameTraversal.cpp +++ b/layout/base/nsFrameTraversal.cpp @@ -256,16 +256,17 @@ void nsFrameIterator::Next() { result = parent; } break; - } else { - result = GetParentFrameNotPopup(parent); - if (!result || IsRootFrame(result) || - (mLockScroll && result->IsScrollFrame())) { - result = nullptr; - break; - } - if (mType == ePostOrder) break; - parent = result; } + result = GetParentFrameNotPopup(parent); + if (!result || IsRootFrame(result) || + (mLockScroll && result->IsScrollFrame())) { + result = nullptr; + break; + } + if (mType == ePostOrder) { + break; + } + parent = result; } } @@ -313,7 +314,9 @@ void nsFrameIterator::Prev() { result = nullptr; break; } - if (mType == ePreOrder) break; + if (mType == ePreOrder) { + break; + } parent = result; } }