From d76e7b634448ae9287fbf0fc7e0346cfaa81c29f Mon Sep 17 00:00:00 2001 From: Stanca Serban Date: Tue, 23 Apr 2024 22:19:00 +0300 Subject: [PATCH] Backed out changeset 995596d4362c (bug 1885447) for causing build bustages in AutoMappable.h. CLOSED TREE --- dom/canvas/ClientWebGLContext.cpp | 17 +- dom/canvas/ClientWebGLContext.h | 14 - dom/canvas/HostWebGLContext.h | 3 - dom/canvas/WebGLContext.cpp | 293 ++++++---------- dom/canvas/WebGLContext.h | 25 -- dom/canvas/WebGLContextTextures.cpp | 2 +- dom/canvas/WebGLIpdl.h | 28 -- dom/canvas/WebGLMethodDispatcher.h | 1 - dom/canvas/WebGLQueueParamTraits.h | 41 ++- dom/canvas/WebGLTypes.h | 4 +- .../reftest/colors/_generated_reftest.list | 309 +++++++--------- .../test/reftest/colors/color_canvas.html | 1 - .../colors/generate_color_canvas_reftests.py | 44 +-- dom/webidl/WebGLRenderingContext.webidl | 5 - gfx/gl/AutoMappable.h | 161 ++++++--- gfx/gl/Colorspaces.h | 126 +++---- gfx/gl/GLBlitHelper.cpp | 331 ++++-------------- gfx/gl/GLBlitHelper.h | 31 +- gfx/gl/GLBlitHelperD3D.cpp | 15 +- gfx/gl/GLContext.h | 51 +-- gfx/gl/SharedSurface.h | 5 - gfx/gl/SharedSurfaceIO.h | 2 - gfx/gl/gtest/TestColorspaces.cpp | 12 +- gfx/thebes/gfxPlatform.cpp | 2 +- gfx/thebes/gfxPlatform.h | 2 +- gfx/webrender_bindings/DCLayerTree.cpp | 14 +- gfx/webrender_bindings/DCLayerTree.h | 8 +- 27 files changed, 519 insertions(+), 1028 deletions(-) diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index 5c92ba003d9b..236ea916d0cc 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -736,21 +736,6 @@ void ClientWebGLContext::GetCanvas( } } -void ClientWebGLContext::SetDrawingBufferColorSpace( - const dom::PredefinedColorSpace val) { - mDrawingBufferColorSpace = val; - - // Just in case, update in Options too. - // Why not treat our WebGLContextOptions as the source of truth? Well, - // mNotLost is lost on context-loss, so we'd lose any setting we had here if - // that happens. - if (mNotLost) { - mNotLost->info.options.colorSpace = mDrawingBufferColorSpace; - } - - Run(mDrawingBufferColorSpace); -} - void ClientWebGLContext::GetContextAttributes( dom::Nullable& retval) { retval.SetNull(); @@ -1073,7 +1058,9 @@ ClientWebGLContext::SetContextOptions(JSContext* cx, if (attributes.mAntialias.WasPassed()) { newOpts.antialias = attributes.mAntialias.Value(); } + newOpts.ignoreColorSpace = true; if (attributes.mColorSpace.WasPassed()) { + newOpts.ignoreColorSpace = false; newOpts.colorSpace = attributes.mColorSpace.Value(); } diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h index e870d5860a75..e736235361ee 100644 --- a/dom/canvas/ClientWebGLContext.h +++ b/dom/canvas/ClientWebGLContext.h @@ -1052,20 +1052,6 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal, const FuncScope funcScope(*this, "drawingBufferHeight"); return AutoAssertCast(DrawingBufferSize().y); } - - // - - - private: - dom::PredefinedColorSpace mDrawingBufferColorSpace = - dom::PredefinedColorSpace::Srgb; - - public: - auto DrawingBufferColorSpace() const { return mDrawingBufferColorSpace; } - - void SetDrawingBufferColorSpace(dom::PredefinedColorSpace); - - // - - void GetContextAttributes(dom::Nullable& retval); private: diff --git a/dom/canvas/HostWebGLContext.h b/dom/canvas/HostWebGLContext.h index 7d8fe29cd8a2..23b836f9db94 100644 --- a/dom/canvas/HostWebGLContext.h +++ b/dom/canvas/HostWebGLContext.h @@ -201,9 +201,6 @@ class HostWebGLContext final : public SupportsWeakPtr { // - - void SetDrawingBufferColorSpace(const dom::PredefinedColorSpace val) const { - mContext->SetDrawingBufferColorSpace(val); - } void Resize(const uvec2& size) { return mContext->Resize(size); } uvec2 DrawingBufferSize() { return mContext->DrawingBufferSize(); } diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index d664a1e1171b..4bd189c46c02 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -894,62 +894,63 @@ void WebGLContext::BlitBackbufferToCurDriverFB( if (mScissorTestEnabled) { gl->fDisable(LOCAL_GL_SCISSOR_TEST); } - const auto cleanup = MakeScopeExit([&]() { - if (mScissorTestEnabled) { - gl->fEnable(LOCAL_GL_SCISSOR_TEST); + + [&]() { + // If a MozFramebuffer is supplied, ensure that a WebGLFramebuffer is not + // used since it might not have completeness info, while the MozFramebuffer + // can still supply the needed information. + MOZ_ASSERT(!(srcAsMozFb && srcAsWebglFb)); + const auto* mozFb = srcAsMozFb ? srcAsMozFb : mDefaultFB.get(); + GLuint fbo = 0; + gfx::IntSize size; + if (srcAsWebglFb) { + fbo = srcAsWebglFb->mGLName; + const auto* info = srcAsWebglFb->GetCompletenessInfo(); + MOZ_ASSERT(info); + size = gfx::IntSize(info->width, info->height); + } else { + fbo = mozFb->mFB; + size = mozFb->mSize; } - }); - // If a MozFramebuffer is supplied, ensure that a WebGLFramebuffer is not - // used since it might not have completeness info, while the MozFramebuffer - // can still supply the needed information. - MOZ_ASSERT(!(srcAsMozFb && srcAsWebglFb)); - const auto* mozFb = srcAsMozFb ? srcAsMozFb : mDefaultFB.get(); - GLuint fbo = 0; - gfx::IntSize size; - if (srcAsWebglFb) { - fbo = srcAsWebglFb->mGLName; - const auto* info = srcAsWebglFb->GetCompletenessInfo(); - MOZ_ASSERT(info); - size = gfx::IntSize(info->width, info->height); - } else { - fbo = mozFb->mFB; - size = mozFb->mSize; - } - - // If no format conversion is necessary, then attempt to directly blit - // between framebuffers. Otherwise, if we need to convert to RGBA from - // the source format, then we will need to use the texture blit path - // below. - if (!srcIsBGRA) { - if (gl->IsSupported(gl::GLFeature::framebuffer_blit)) { - gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fbo); - gl->fBlitFramebuffer(0, 0, size.width, size.height, 0, 0, size.width, - size.height, LOCAL_GL_COLOR_BUFFER_BIT, - LOCAL_GL_NEAREST); - return; + // If no format conversion is necessary, then attempt to directly blit + // between framebuffers. Otherwise, if we need to convert to RGBA from + // the source format, then we will need to use the texture blit path + // below. + if (!srcIsBGRA) { + if (gl->IsSupported(gl::GLFeature::framebuffer_blit)) { + gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fbo); + gl->fBlitFramebuffer(0, 0, size.width, size.height, 0, 0, size.width, + size.height, LOCAL_GL_COLOR_BUFFER_BIT, + LOCAL_GL_NEAREST); + return; + } + if (mDefaultFB->mSamples && + gl->IsExtensionSupported( + gl::GLContext::APPLE_framebuffer_multisample)) { + gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fbo); + gl->fResolveMultisampleFramebufferAPPLE(); + return; + } } - if (mDefaultFB->mSamples && - gl->IsExtensionSupported( - gl::GLContext::APPLE_framebuffer_multisample)) { - gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fbo); - gl->fResolveMultisampleFramebufferAPPLE(); - return; + + GLuint colorTex = 0; + if (srcAsWebglFb) { + const auto& attach = srcAsWebglFb->ColorAttachment0(); + MOZ_ASSERT(attach.Texture()); + colorTex = attach.Texture()->mGLName; + } else { + colorTex = mozFb->ColorTex(); } - } - GLuint colorTex = 0; - if (srcAsWebglFb) { - const auto& attach = srcAsWebglFb->ColorAttachment0(); - MOZ_ASSERT(attach.Texture()); - colorTex = attach.Texture()->mGLName; - } else { - colorTex = mozFb->ColorTex(); - } + // DrawBlit handles ColorMask itself. + gl->BlitHelper()->DrawBlitTextureToFramebuffer( + colorTex, size, size, LOCAL_GL_TEXTURE_2D, srcIsBGRA); + }(); - // DrawBlit handles ColorMask itself. - gl->BlitHelper()->DrawBlitTextureToFramebuffer( - colorTex, size, size, LOCAL_GL_TEXTURE_2D, srcIsBGRA); + if (mScissorTestEnabled) { + gl->fEnable(LOCAL_GL_SCISSOR_TEST); + } } // - @@ -959,34 +960,19 @@ constexpr auto MakeArray(Args... args) -> std::array { return {{static_cast(args)...}}; } -inline gfx::ColorSpace2 ToColorSpace2ForOutput( - const std::optional chosenCspace) { - const auto cmsMode = GfxColorManagementMode(); - switch (cmsMode) { - case CMSMode::Off: - return gfx::ColorSpace2::Display; - case CMSMode::TaggedOnly: - if (!chosenCspace) { - return gfx::ColorSpace2::Display; - } - break; - case CMSMode::All: - if (!chosenCspace) { - return gfx::ColorSpace2::SRGB; - } - break; +inline gfx::ColorSpace2 ToColorSpace2(const WebGLContextOptions& options) { + auto ret = gfx::ColorSpace2::UNKNOWN; + if (true) { + ret = gfx::ColorSpace2::SRGB; } - return gfx::ToColorSpace2(*chosenCspace); + if (!options.ignoreColorSpace) { + ret = gfx::ToColorSpace2(options.colorSpace); + } + return ret; } // - -template -GLuint GLNameOrZero(const T& t) { - if (t) return t->mGLName; - return 0; -} - // For an overview of how WebGL compositing works, see: // https://wiki.mozilla.org/Platform/GFX/WebGL/Compositing bool WebGLContext::PresentInto(gl::SwapChain& swapChain) { @@ -994,100 +980,46 @@ bool WebGLContext::PresentInto(gl::SwapChain& swapChain) { if (!ValidateAndInitFB(nullptr)) return false; - const auto size = mDefaultFB->mSize; - - const auto error = [&]() -> std::optional { - const auto canvasCspace = ToColorSpace2ForOutput(mOptions.colorSpace); - auto presenter = swapChain.Acquire(size, canvasCspace); + { + const auto colorSpace = ToColorSpace2(mOptions); + auto presenter = swapChain.Acquire(mDefaultFB->mSize, colorSpace); if (!presenter) { - return "Swap chain surface creation failed."; + GenerateWarning("Swap chain surface creation failed."); + LoseContext(); + return false; } - const auto outputCspace = presenter->BackBuffer()->mDesc.colorSpace; + const auto destFb = presenter->Fb(); + gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, destFb); - // - + BlitBackbufferToCurDriverFB(); - bool colorManage = (canvasCspace != gfx::ColorSpace2::Display); - if (canvasCspace == outputCspace) { - colorManage = false; - } - if (!gl->IsSupported(gl::GLFeature::texture_3D)) { - NS_WARNING("Missing GLFeature::texture_3D => colorManage = false."); - colorManage = false; - } - - auto colorLut = std::shared_ptr{}; - if (colorManage) { - MOZ_ASSERT(canvasCspace != gfx::ColorSpace2::Display); - colorLut = gl->BlitHelper()->GetColorLutTex( - {.src = canvasCspace, .dst = outputCspace}); - if (!colorLut) { - NS_WARNING("GetColorLutTex() -> nullptr => colorManage = false."); - colorManage = false; + if (!mOptions.preserveDrawingBuffer) { + if (gl->IsSupported(gl::GLFeature::invalidate_framebuffer)) { + gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, mDefaultFB->mFB); + constexpr auto attachments = MakeArray( + LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT); + gl->fInvalidateFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, + attachments.size(), attachments.data()); } + mDefaultFB_IsInvalid = true; } - if (!colorManage) { - gl->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, destFb); - BlitBackbufferToCurDriverFB(); - return {}; +#ifdef DEBUG + if (!mOptions.alpha) { + gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, destFb); + gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4); + if (IsWebGL2()) { + gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, 0); + gl->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, 0); + gl->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, 0); + } + uint32_t pixel = 0xffbadbad; + gl->fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, + &pixel); + MOZ_ASSERT((pixel & 0xff000000) == 0xff000000); } - - // - - - const auto canvasFb = GetDefaultFBForRead({.endOfFrame = true}); - if (!canvasFb) { - return "[WebGLContext::PresentInto] BindDefaultFBForRead failed."; - } - - const auto& blitter = gl->BlitHelper()->GetDrawBlitProg({ - .fragHeader = gl::kFragHeader_Tex2D, - .fragParts = {gl::kFragSample_OnePlane, gl::kFragConvert_ColorLut3d}, - }); - - constexpr uint8_t texUnit_src = 0; - constexpr uint8_t texUnit_lut = 1; - gl->BindSamplerTexture(texUnit_src, SamplerLinear(), LOCAL_GL_TEXTURE_2D, - canvasFb->ColorTex()); - gl->BindSamplerTexture(texUnit_lut, SamplerLinear(), LOCAL_GL_TEXTURE_3D, - colorLut->name); - const auto texCleanup = MakeScopeExit([&]() { - gl->BindSamplerTexture( - texUnit_src, GLNameOrZero(mBoundSamplers[texUnit_src]), - LOCAL_GL_TEXTURE_2D, GLNameOrZero(mBound2DTextures[texUnit_src])); - gl->BindSamplerTexture( - texUnit_lut, GLNameOrZero(mBoundSamplers[texUnit_lut]), - LOCAL_GL_TEXTURE_3D, GLNameOrZero(mBound3DTextures[texUnit_lut])); - gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture); - }); - - gl->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, destFb); - - gl->fUseProgram(blitter.mProg); - const auto cleanupProg = MakeScopeExit( - [&]() { gl->fUseProgram(GLNameOrZero(mCurrentProgram)); }); - - gl->fUniform1i(blitter.mLoc_uColorLut, texUnit_lut); - - blitter.Draw({ - .texMatrix0 = gl::Mat3::I(), - .yFlip = false, - .destSize = size, - .destRect = {}, - }); - - gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, canvasFb->mFB); - return {}; - }(); - if (error) { - GenerateWarning("%s", error->c_str()); - LoseContext(); - return false; - } - - if (!mOptions.preserveDrawingBuffer) { - gl->InvalidateFramebuffer(LOCAL_GL_READ_FRAMEBUFFER); - mDefaultFB_IsInvalid = true; +#endif } return true; @@ -1097,7 +1029,7 @@ bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& fb) { OnEndOfFrame(); - const auto colorSpace = ToColorSpace2ForOutput(mOptions.colorSpace); + const auto colorSpace = ToColorSpace2(mOptions); auto presenter = swapChain.Acquire(fb.mSize, colorSpace); if (!presenter) { GenerateWarning("Swap chain surface creation failed."); @@ -1221,7 +1153,7 @@ bool WebGLContext::CopyToSwapChain( { // ColorSpace will need to be part of SwapChainOptions for DTWebgl. - const auto colorSpace = ToColorSpace2ForOutput(mOptions.colorSpace); + const auto colorSpace = ToColorSpace2(mOptions); auto presenter = srcFb->mSwapChain.Acquire(size, colorSpace); if (!presenter) { GenerateWarning("Swap chain surface creation failed."); @@ -1765,12 +1697,12 @@ bool WebGLContext::BindCurFBForColorRead( return true; } -const gl::MozFramebuffer* WebGLContext::GetDefaultFBForRead( - const GetDefaultFBForReadDesc& desc) { - if (!ValidateAndInitFB(nullptr)) return nullptr; +bool WebGLContext::BindDefaultFBForRead() { + if (!ValidateAndInitFB(nullptr)) return false; if (!mDefaultFB->mSamples) { - return mDefaultFB.get(); + gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mDefaultFB->mFB); + return true; } if (!mResolvedDefaultFB) { @@ -1778,24 +1710,14 @@ const gl::MozFramebuffer* WebGLContext::GetDefaultFBForRead( gl::MozFramebuffer::Create(gl, mDefaultFB->mSize, 0, false); if (!mResolvedDefaultFB) { gfxCriticalNote << FuncName() << ": Failed to create mResolvedDefaultFB."; - return nullptr; + return false; } } - gl->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, mResolvedDefaultFB->mFB); + gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mResolvedDefaultFB->mFB); BlitBackbufferToCurDriverFB(); - if (desc.endOfFrame && !mOptions.preserveDrawingBuffer) { - gl->InvalidateFramebuffer(LOCAL_GL_READ_FRAMEBUFFER); - } - - return mResolvedDefaultFB.get(); -} - -bool WebGLContext::BindDefaultFBForRead() { - const auto fb = GetDefaultFBForRead(); - if (!fb) return false; - gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fb->mFB); + gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mResolvedDefaultFB->mFB); return true; } @@ -2739,21 +2661,4 @@ webgl::ExplicitPixelPackingState::ForUseWith( return {{state, metrics}}; } -GLuint WebGLContext::SamplerLinear() const { - if (!mSamplerLinear) { - mSamplerLinear = std::make_unique(*gl); - gl->fSamplerParameteri(mSamplerLinear->name, LOCAL_GL_TEXTURE_MAG_FILTER, - LOCAL_GL_LINEAR); - gl->fSamplerParameteri(mSamplerLinear->name, LOCAL_GL_TEXTURE_MIN_FILTER, - LOCAL_GL_LINEAR); - gl->fSamplerParameteri(mSamplerLinear->name, LOCAL_GL_TEXTURE_WRAP_S, - LOCAL_GL_CLAMP_TO_EDGE); - gl->fSamplerParameteri(mSamplerLinear->name, LOCAL_GL_TEXTURE_WRAP_T, - LOCAL_GL_CLAMP_TO_EDGE); - gl->fSamplerParameteri(mSamplerLinear->name, LOCAL_GL_TEXTURE_WRAP_R, - LOCAL_GL_CLAMP_TO_EDGE); - } - return mSamplerLinear->name; -} - } // namespace mozilla diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 69cff4e7dd7a..d144584f4fd9 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -10,7 +10,6 @@ #include #include -#include "Colorspaces.h" #include "GLContextTypes.h" #include "GLDefs.h" #include "GLScreenBuffer.h" @@ -97,7 +96,6 @@ namespace gl { class GLScreenBuffer; class MozFramebuffer; class SharedSurface; -class Sampler; class Texture; } // namespace gl @@ -538,12 +536,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { Maybe GetFrontBuffer(WebGLFramebuffer*, const bool webvr); - std::optional mDisplayProfile; - - void SetDrawingBufferColorSpace(const dom::PredefinedColorSpace val) { - mOptions.colorSpace = val; - } - void ClearVRSwapChain(); void RunContextLossTimer(); @@ -1164,10 +1156,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { nsTArray> mBound2DArrayTextures; nsTArray> mBoundSamplers; - mutable std::unique_ptr mSamplerLinear; - - GLuint SamplerLinear() const; - void ResolveTexturesForDraw() const; RefPtr mCurrentProgram; @@ -1277,10 +1265,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { mutable bool mDefaultFB_IsInvalid = false; mutable UniquePtr mResolvedDefaultFB; - mutable std::unordered_map, - std::shared_ptr> - mLutTexByColorMapping; - gl::SwapChain mSwapChain; gl::SwapChain mWebVRSwapChain; @@ -1319,15 +1303,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { WebGLFramebuffer* const srcAsWebglFb = nullptr, const gl::MozFramebuffer* const srcAsMozFb = nullptr, bool srcIsBGRA = false) const; - - struct GetDefaultFBForReadDesc { - bool endOfFrame = false; - }; - const gl::MozFramebuffer* GetDefaultFBForRead(const GetDefaultFBForReadDesc&); - const gl::MozFramebuffer* GetDefaultFBForRead() { - return GetDefaultFBForRead({}); - } - bool BindDefaultFBForRead(); // -- diff --git a/dom/canvas/WebGLContextTextures.cpp b/dom/canvas/WebGLContextTextures.cpp index 2bc56f4b0521..e65533ec9486 100644 --- a/dom/canvas/WebGLContextTextures.cpp +++ b/dom/canvas/WebGLContextTextures.cpp @@ -96,7 +96,7 @@ void WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex) { return; } - const auto texTarget = TexTarget(rawTarget); + const TexTarget texTarget(rawTarget); if (newTex) { if (!newTex->BindTexture(texTarget)) return; } else { diff --git a/dom/canvas/WebGLIpdl.h b/dom/canvas/WebGLIpdl.h index 4c81393b704c..45a5c5ad648d 100644 --- a/dom/canvas/WebGLIpdl.h +++ b/dom/canvas/WebGLIpdl.h @@ -18,8 +18,6 @@ #include "TupleUtils.h" #include "WebGLTypes.h" -#include - namespace mozilla { namespace webgl { @@ -654,32 +652,6 @@ struct ParamTraits> final { } }; -// - - -template -struct ParamTraits> final { - using T = std::optional; - - static void Write(MessageWriter* const writer, const T& in) { - WriteParam(writer, bool{in}); - if (in) { - WriteParam(writer, *in); - } - } - - static bool Read(MessageReader* const reader, T* const out) { - bool isSome; - if (!ReadParam(reader, &isSome)) return false; - - if (!isSome) { - out->reset(); - return true; - } - out->emplace(); - return ReadParam(reader, &**out); - } -}; - } // namespace IPC #endif diff --git a/dom/canvas/WebGLMethodDispatcher.h b/dom/canvas/WebGLMethodDispatcher.h index e55b19d0b40b..4bf67deb0854 100644 --- a/dom/canvas/WebGLMethodDispatcher.h +++ b/dom/canvas/WebGLMethodDispatcher.h @@ -93,7 +93,6 @@ DEFINE_ASYNC(HostWebGLContext::ProvokingVertex) DEFINE_ASYNC(HostWebGLContext::Present) DEFINE_ASYNC(HostWebGLContext::SampleCoverage) DEFINE_ASYNC(HostWebGLContext::Scissor) -DEFINE_ASYNC(HostWebGLContext::SetDrawingBufferColorSpace) DEFINE_ASYNC(HostWebGLContext::ShaderSource) DEFINE_ASYNC(HostWebGLContext::StencilFuncSeparate) DEFINE_ASYNC(HostWebGLContext::StencilMaskSeparate) diff --git a/dom/canvas/WebGLQueueParamTraits.h b/dom/canvas/WebGLQueueParamTraits.h index 136316433f9a..3c74f0875041 100644 --- a/dom/canvas/WebGLQueueParamTraits.h +++ b/dom/canvas/WebGLQueueParamTraits.h @@ -61,6 +61,25 @@ struct QueueParamTraits> : QueueParamTraits_TiedFields> {}; // --------------------------------------------------------------------- // Enums! +inline constexpr bool IsEnumCase(const dom::WebGLPowerPreference raw) { + switch (raw) { + case dom::WebGLPowerPreference::Default: + case dom::WebGLPowerPreference::Low_power: + case dom::WebGLPowerPreference::High_performance: + return true; + } + return false; +} + +inline constexpr bool IsEnumCase(const dom::PredefinedColorSpace raw) { + switch (raw) { + case dom::PredefinedColorSpace::Srgb: + case dom::PredefinedColorSpace::Display_p3: + return true; + } + return false; +} + inline constexpr bool IsEnumCase(const webgl::AttribBaseType raw) { switch (raw) { case webgl::AttribBaseType::Boolean: @@ -72,14 +91,16 @@ inline constexpr bool IsEnumCase(const webgl::AttribBaseType raw) { return false; } -static_assert(IsEnumCase(webgl::AttribBaseType(3))); -static_assert(!IsEnumCase(webgl::AttribBaseType(4))); -static_assert(!IsEnumCase(webgl::AttribBaseType(5))); +static_assert(IsEnumCase(dom::WebGLPowerPreference(2))); +static_assert(!IsEnumCase(dom::WebGLPowerPreference(3))); +static_assert(!IsEnumCase(dom::WebGLPowerPreference(5))); #define USE_IS_ENUM_CASE(T) \ template <> \ struct QueueParamTraits : QueueParamTraits_IsEnumCase {}; +USE_IS_ENUM_CASE(dom::WebGLPowerPreference) +USE_IS_ENUM_CASE(dom::PredefinedColorSpace) USE_IS_ENUM_CASE(webgl::AttribBaseType) USE_IS_ENUM_CASE(webgl::ProvokingVertex) @@ -262,20 +283,6 @@ struct QueueParamTraits : public ContiguousEnumSerializerInclusive< gfxAlphaType, gfxAlphaType::Opaque, gfxAlphaType::NonPremult> {}; -// - - -template -using WebIDLEnumQueueSerializer = - ContiguousEnumSerializerInclusive::min, - ContiguousEnumValues::max>; - -template <> -struct QueueParamTraits - : public WebIDLEnumQueueSerializer {}; -template <> -struct QueueParamTraits - : public WebIDLEnumQueueSerializer {}; - } // namespace webgl } // namespace mozilla diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index 2f1d9331a750..f5f78e98cb9e 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -362,7 +362,8 @@ struct WebGLContextOptions final { dom::WebGLPowerPreference powerPreference = dom::WebGLPowerPreference::Default; - std::optional colorSpace; + bool ignoreColorSpace = true; + dom::PredefinedColorSpace colorSpace = dom::PredefinedColorSpace::Srgb; bool shouldResistFingerprinting = true; bool enableDebugRendererInfo = false; @@ -382,6 +383,7 @@ struct WebGLContextOptions final { powerPreference, colorSpace, + ignoreColorSpace, shouldResistFingerprinting, enableDebugRendererInfo); diff --git a/dom/canvas/test/reftest/colors/_generated_reftest.list b/dom/canvas/test/reftest/colors/_generated_reftest.list index df5fa9884737..29761e3df8df 100644 --- a/dom/canvas/test/reftest/colors/_generated_reftest.list +++ b/dom/canvas/test/reftest/colors/_generated_reftest.list @@ -17,217 +17,160 @@ defaults pref(webgl.colorspaces.prototype,true) ### Generated, do not edit. ### # - -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) -skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) +skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) ### Generated, do not edit. ### -skip-if(cocoaWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) -skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) +skip-if(cocoaWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) +skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) ### Generated, do not edit. ### -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) -skip-if(!cocoaWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) ### Generated, do not edit. ### -skip-if(cocoaWidget) fuzzy(0-1,0-10000) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) -skip-if(cocoaWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) -skip-if(cocoaWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) +skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) +skip-if(cocoaWidget) fails-if(!Android) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) ### Generated, do not edit. ### -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) -skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) +skip-if(cocoaWidget) fails == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) ### Generated, do not edit. ### -skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) -skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) +skip-if(!cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) +skip-if(cocoaWidget) == color_canvas.html?e_context=webgl&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) -skip-if(cocoaWidget||winWidget) fails == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) ### Generated, do not edit. ### -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) -skip-if(cocoaWidget||winWidget) fails-if(!Android) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) -skip-if(cocoaWidget||winWidget) fails == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) ### Generated, do not edit. ### -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) -skip-if(!cocoaWidget&&!winWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) -skip-if(cocoaWidget||winWidget) fuzzy(0-1,0-10000) fails == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) -skip-if(cocoaWidget||winWidget) fuzzy(0-1,0-10000) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) ### Generated, do not edit. ### -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) -skip-if(cocoaWidget||winWidget) fails-if(!Android) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) ### Generated, do not edit. ### -skip-if(cocoaWidget||winWidget) fails == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) -skip-if(!cocoaWidget&&!winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) -skip-if(cocoaWidget||winWidget) == color_canvas.html?e_context=webgl2&e_webgl_format=RGBA8&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=srgb&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"true"}&e_cspace=display-p3&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=srgb&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.200,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.200,0.000) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.502,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.502,0.000) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(srgb,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(srgb,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(srgb,1.000,1.000,1.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.200,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.200,0.200) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.200,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.200,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.200,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.200,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.200) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.200) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.502,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.502,0.502) - ### Generated, do not edit. ### - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.502,0.000,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.502,0.000,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.502,0.000) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.502,0.000) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) - == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,0.000,0.000,0.502) color_canvas.html?e_context=css&e_color=color(display-p3,0.000,0.000,0.502) + == color_canvas.html?e_context=2d&e_options={"willReadFrequently":"false"}&e_cspace=display-p3&e_color=color(display-p3,1.000,1.000,1.000) color_canvas.html?e_context=css&e_color=color(display-p3,1.000,1.000,1.000) diff --git a/dom/canvas/test/reftest/colors/color_canvas.html b/dom/canvas/test/reftest/colors/color_canvas.html index 53314f2714bc..7abbc8625528 100644 --- a/dom/canvas/test/reftest/colors/color_canvas.html +++ b/dom/canvas/test/reftest/colors/color_canvas.html @@ -29,7 +29,6 @@ -
Options: diff --git a/dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py b/dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py index ad04d9a524e4..8c1e5f378844 100644 --- a/dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py +++ b/dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py @@ -120,8 +120,9 @@ WEBGL_FORMATS = keyed_alternatives( #'RGBA16F', ], ) -WEBGL_VERSIONS = keyed_alternatives("e_context", ["webgl", "webgl2"]) -WEBGL = cross_combine(WEBGL_VERSIONS, WEBGL_FORMATS, CANVAS_CSPACES, WEBGL_COLORS) +WEBGL = cross_combine( + [{"e_context": "webgl"}], WEBGL_FORMATS, CANVAS_CSPACES, WEBGL_COLORS +) # - @@ -211,7 +212,7 @@ def correct_color_from_test_config(test_config: Config) -> CssColor: canvas_cspace = "srgb" correct_color = parse_css_color(test_config["e_color"]) - if test_config["e_context"].startswith("webgl"): + if test_config["e_context"] == "webgl": # Webgl ignores the color's cspace, because webgl has no concept of # source colorspace for clears/draws to the backbuffer. # This (correct) behavior is as if the color's cspace were overwritten by the @@ -230,12 +231,12 @@ def correct_color_from_test_config(test_config: Config) -> CssColor: def reftests_from_config(test_config: Config) -> Iterable[ColorReftest]: correct_color = correct_color_from_test_config(test_config) - if test_config["e_context"] in ["2d"]: + if test_config["e_context"] == "2d": # Canvas2d generally has the same behavior as css, so expect all passing. yield ColorReftest([], test_config, correct_color) return - assert test_config["e_context"].startswith("webgl"), test_config["e_context"] + assert test_config["e_context"] == "webgl", test_config["e_context"] # - @@ -248,11 +249,6 @@ def reftests_from_config(test_config: Config) -> Iterable[ColorReftest]: # If we fix an error, we'll see one unexpected-pass and one unexpected-fail. # If we get a new wrong answer, we'll see one unexpected-fail. - if correct_color.is_same_color( - parse_css_color("color(display-p3 0.502 0.000 0.000)") - ): - notes += ["fuzzy(0-1,0-10000)"] - if not expected_color.is_same_color(correct_color): yield ColorReftest(notes + ["fails"], test_config, correct_color) yield ColorReftest(notes, test_config, expected_color) @@ -265,26 +261,12 @@ def reftests_from_config(test_config: Config) -> Iterable[ColorReftest]: # right now. This is the same as "srgb". expected_color_srgb = CssColor("srgb", correct_color.rgb) - if test_config["e_context"] == "webgl2": - # Win, Mac - yield from reftests_from_expected_color( - ["skip-if(!cocoaWidget&&!winWidget)"], correct_color - ) - # Lin, Android - yield from reftests_from_expected_color( - ["skip-if(cocoaWidget||winWidget) "], expected_color_srgb - ) - elif test_config["e_context"] == "webgl": - # Mac - yield from reftests_from_expected_color( - ["skip-if(!cocoaWidget)"], correct_color - ) - # Win, Lin, Android - yield from reftests_from_expected_color( - ["skip-if(cocoaWidget) "], expected_color_srgb - ) - else: - assert False, test_config["e_context"] + # Mac + yield from reftests_from_expected_color(["skip-if(!cocoaWidget)"], correct_color) + # Win, Lin, Android + yield from reftests_from_expected_color( + ["skip-if(cocoaWidget) "], expected_color_srgb + ) # - @@ -297,7 +279,7 @@ def amended_notes_from_reftest(reftest: ColorReftest) -> list[str]: is_green_only = ref_rgb_vals == (0, ref_rgb_vals[1], 0) if ( "fails" in reftest.notes - and reftest.test_config["e_context"].startswith("webgl") + and reftest.test_config["e_context"] == "webgl" and reftest.test_config["e_cspace"] == "display-p3" and is_green_only ): diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl index 15cf4ee7a868..00585a06bf66 100644 --- a/dom/webidl/WebGLRenderingContext.webidl +++ b/dom/webidl/WebGLRenderingContext.webidl @@ -546,11 +546,6 @@ interface mixin WebGLRenderingContextBase { readonly attribute GLsizei drawingBufferWidth; readonly attribute GLsizei drawingBufferHeight; - /* Upon context creation, drawingBufferColorSpace and unpackColorSpace both - default to the value "srgb". */ - attribute PredefinedColorSpace drawingBufferColorSpace; - //attribute PredefinedColorSpace unpackColorSpace; - [WebGLHandlesContextLoss] WebGLContextAttributes? getContextAttributes(); [WebGLHandlesContextLoss] boolean isContextLost(); diff --git a/gfx/gl/AutoMappable.h b/gfx/gl/AutoMappable.h index e8683bd5afe0..f93b2ccb5738 100644 --- a/gfx/gl/AutoMappable.h +++ b/gfx/gl/AutoMappable.h @@ -8,13 +8,38 @@ // Here be dragons. #include -#include -namespace mozilla { +namespace mozilla::gfx { template -size_t StdHash(const T& t) { - return std::hash()(t); +size_t Hash(const T&); + +template +struct StaticStdHasher { + static auto HashImpl(const T& v) { return std::hash()(v); } +}; + +template +struct StaticHasher { + static auto HashImpl(const T& v) { return v.hash(); } +}; +template +struct StaticHasher> { + static size_t HashImpl(const std::optional& v) { + if (!v) return 0; + return Hash(*v); + } +}; +template <> +struct StaticHasher : public StaticStdHasher {}; +template <> +struct StaticHasher : public StaticStdHasher {}; +template <> +struct StaticHasher : public StaticStdHasher {}; + +template +size_t Hash(const T& v) { + return StaticHasher::HashImpl(v); } //- @@ -27,61 +52,97 @@ inline size_t HashCombine(size_t seed, const size_t hash) { } // - +// See +// https://codereview.stackexchange.com/questions/136770/hashing-a-tuple-in-c17 -namespace detail { template -size_t StdHashTupleN(const std::tuple& tup, - const std::index_sequence&) { +size_t HashTupleN(const std::tuple& tup, + const std::index_sequence&) { size_t seed = 0; - for (const auto& hash : {StdHash(std::get(tup))...}) { + for (const auto& hash : {Hash(std::get(tup))...}) { seed = HashCombine(seed, hash); } return seed; } -} // namespace detail - -// - - -template -struct StdHashMembers { - size_t operator()(const T& t) const { - const auto members = t.Members(); - return StdHash(members); - } -}; - -// - - -#define MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(OP, T) \ - constexpr bool operator OP(const T& rhs) const { \ - return Members() OP rhs.Members(); \ - } - -#define MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(T) \ - MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(==, T) \ - MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(!=, T) \ - MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(<, T) \ - MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(<=, T) \ - MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(>, T) \ - MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(>=, T) - -template -struct DeriveCmpOpMembers { - private: - auto Members() const { return reinterpret_cast(this)->Members(); } - - public: - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(T) -}; - -} // namespace mozilla template -struct std::hash> { - size_t operator()(const std::tuple& t) const { - return mozilla::detail::StdHashTupleN( - t, std::make_index_sequence()); - } +size_t HashTuple(const std::tuple& tup) { + return HashTupleN(tup, std::make_index_sequence()); +} + +// - + +template +auto MembersEq(const T& a, const T& b) { + const auto atup = a.Members(); + const auto btup = b.Members(); + return atup == btup; +} + +template +auto MembersLt(const T& a, const T& b) { + const auto atup = a.Members(); + const auto btup = b.Members(); + return atup == btup; +} + +template +auto MembersHash(const T& a) { + const auto atup = a.Members(); + return HashTuple(atup); +} + +template +struct MembersHasher final { + auto operator()(const T& v) const { return v.hash(); } }; +/** E.g.: +struct Foo { + int i; + bool b; + + auto Members() const { return std::tie(i, b); } + INLINE_AUTO_MAPPABLE(Foo) +}; +std::unordered_set easy; +**/ +#define INLINE_DERIVE_MEMBERS_EQ(T) \ + friend bool operator==(const T& a, const T& b) { \ + return mozilla::gfx::MembersEq(a, b); \ + } \ + friend bool operator!=(const T& a, const T& b) { return !operator==(a, b); } +#define INLINE_AUTO_MAPPABLE(T) \ + friend bool operator<(const T& a, const T& b) { \ + return mozilla::gfx::MembersLt(a, b); \ + } \ + INLINE_DERIVE_MEMBERS_EQ(T) \ + size_t hash() const { \ + return mozilla::gfx::MembersHash(*reinterpret_cast(this)); \ + } \ + using Hasher = mozilla::gfx::MembersHasher; + +// - + +/** E.g.: +``` +struct Foo : public AutoMappable { + int i; + bool b; + + auto Members() const { return std::tie(i, b); } +}; +std::unordered_set easy; +``` +`easy.insert({{}, 2, true});` +The initial {} is needed for aggregate initialization of AutoMappable. +Use INLINE_AUTO_MAPPABLE if this is too annoying. +**/ +template +struct AutoMappable { + INLINE_AUTO_MAPPABLE(T) +}; + +} // namespace mozilla::gfx + #endif // MOZILLA_AUTO_MAPPABLE_H diff --git a/gfx/gl/Colorspaces.h b/gfx/gl/Colorspaces.h index 062897d2dd0e..8f36854d2d4f 100644 --- a/gfx/gl/Colorspaces.h +++ b/gfx/gl/Colorspaces.h @@ -42,27 +42,19 @@ typedef struct _qcms_profile qcms_profile; namespace mozilla::color { -// - - struct YuvLumaCoeffs final { float r = 0.2126; float g = 0.7152; float b = 0.0722; auto Members() const { return std::tie(r, g, b); } - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(YuvLumaCoeffs) + INLINE_AUTO_MAPPABLE(YuvLumaCoeffs) static constexpr auto Rec709() { return YuvLumaCoeffs(); } static constexpr auto Rec2020() { - return YuvLumaCoeffs{ - .r = 0.2627, - .g = 0.6780, - .b = 0.0593, - }; + return YuvLumaCoeffs{0.2627, 0.6780, 0.0593}; } - - static constexpr auto Gbr() { return YuvLumaCoeffs{.r = 0, .g = 1, .b = 0}; } }; struct PiecewiseGammaDesc final { @@ -76,26 +68,26 @@ struct PiecewiseGammaDesc final { float k = 12.92; auto Members() const { return std::tie(a, b, g, k); } - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(PiecewiseGammaDesc) + INLINE_AUTO_MAPPABLE(PiecewiseGammaDesc) static constexpr auto Srgb() { return PiecewiseGammaDesc(); } static constexpr auto DisplayP3() { return Srgb(); } static constexpr auto Rec709() { return PiecewiseGammaDesc{ - .a = 1.099, - .b = 0.018, - .g = 1.0 / 0.45, // ~2.222 - .k = 4.5, + 1.099, + 0.018, + 1.0 / 0.45, // ~2.222 + 4.5, }; } // FYI: static constexpr auto Rec2020_10bit() { return Rec709(); } static constexpr auto Rec2020_12bit() { return PiecewiseGammaDesc{ - .a = 1.0993, - .b = 0.0181, - .g = 1.0 / 0.45, // ~2.222 - .k = 4.5, + 1.0993, + 0.0181, + 1.0 / 0.45, // ~2.222 + 4.5, }; } }; @@ -107,21 +99,21 @@ struct YcbcrDesc final { float uPlusHalf = 240 / 255.0; auto Members() const { return std::tie(y0, y1, u0, uPlusHalf); } - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(YcbcrDesc) + INLINE_AUTO_MAPPABLE(YcbcrDesc) static constexpr auto Narrow8() { // AKA limited/studio/tv return YcbcrDesc(); } static constexpr auto Full8() { // AKA pc return YcbcrDesc{ - .y0 = 0 / 255.0, - .y1 = 255 / 255.0, - .u0 = 128 / 255.0, - .uPlusHalf = 254 / 255.0, + 0 / 255.0, + 255 / 255.0, + 128 / 255.0, + 254 / 255.0, }; } static constexpr auto Float() { // Best for a LUT - return YcbcrDesc{.y0 = 0.0, .y1 = 1.0, .u0 = 0.5, .uPlusHalf = 1.0}; + return YcbcrDesc{0.0, 1.0, 0.5, 1.0}; } }; @@ -137,7 +129,7 @@ struct Chromaticities final { static constexpr float wy = 0.3290; auto Members() const { return std::tie(rx, ry, gx, gy, bx, by); } - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(Chromaticities) + INLINE_AUTO_MAPPABLE(Chromaticities) // - @@ -153,32 +145,23 @@ struct Chromaticities final { } static constexpr auto Rec601_525_Ntsc() { return Chromaticities{ - .rx = 0.630, - .ry = 0.340, // r - .gx = 0.310, - .gy = 0.595, // g - .bx = 0.155, - .by = 0.070, // b + 0.630, 0.340, // r + 0.310, 0.595, // g + 0.155, 0.070, // b }; } static constexpr auto Rec2020() { return Chromaticities{ - .rx = 0.708, - .ry = 0.292, // r - .gx = 0.170, - .gy = 0.797, // g - .bx = 0.131, - .by = 0.046, // b + 0.708, 0.292, // r + 0.170, 0.797, // g + 0.131, 0.046, // b }; } static constexpr auto DisplayP3() { return Chromaticities{ - .rx = 0.680, - .ry = 0.320, // r - .gx = 0.265, - .gy = 0.690, // g - .bx = 0.150, - .by = 0.060, // b + 0.680, 0.320, // r + 0.265, 0.690, // g + 0.150, 0.060, // b }; } }; @@ -190,7 +173,7 @@ struct YuvDesc final { YcbcrDesc ycbcr; auto Members() const { return std::tie(yCoeffs, ycbcr); } - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(YuvDesc) + INLINE_AUTO_MAPPABLE(YuvDesc); }; struct ColorspaceDesc final { @@ -199,30 +182,11 @@ struct ColorspaceDesc final { std::optional yuv; auto Members() const { return std::tie(chrom, tf, yuv); } - MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(ColorspaceDesc) + INLINE_AUTO_MAPPABLE(ColorspaceDesc); }; // - -} // namespace mozilla::color - -#define _(X) \ - template <> \ - struct std::hash : mozilla::StdHashMembers {}; - -_(mozilla::color::YuvLumaCoeffs) -_(mozilla::color::PiecewiseGammaDesc) -_(mozilla::color::YcbcrDesc) -_(mozilla::color::Chromaticities) -_(mozilla::color::YuvDesc) -_(mozilla::color::ColorspaceDesc) - -#undef _ - -namespace mozilla::color { - -// - - template struct avec final { using T = TT; @@ -371,11 +335,6 @@ auto max(const avec& a, const avec& b) { return ret; } -template -auto clamp(const avec& v, const avec& lo, const avec& hi) { - return max(lo, min(v, hi)); -} - template auto floor(const avec& a) { auto ret = avec{}; @@ -445,11 +404,6 @@ struct mat final { } } - constexpr bool operator==(const mat& rhs) const { - return this->rows == rhs.rows; - } - constexpr bool operator!=(const mat& rhs) const { return !(*this == rhs); } - const auto& at(const int x, const int y) const { return rows.at(y)[x]; } auto& at(const int x, const int y) { return rows.at(y)[x]; } @@ -768,19 +722,17 @@ inline float SampleOutByIn(const C& outByIn, const float in) { return outByIn.at(0); } MOZ_ASSERT(outByIn.size() >= 2); + const auto begin = outByIn.begin(); - // Estimate based on nearest (first) derivative: - // Find the nearest point to `in` in `outByIn`. - const auto inId = in * (outByIn.size() - 1); - const auto inId0F = std::clamp(floorf(inId), 0.f, float(outByIn.size() - 2)); - const auto inId0 = size_t(inId0F); - const auto out0 = outByIn.at(inId0 + 0); - const auto out1 = outByIn.at(inId0 + 1); - const auto d_inId0 = float(1); - const auto d_out0 = out1 - out0; - const auto d_inId = inId - inId0; + const auto in0i = size_t(floorf(in * (outByIn.size() - 1))); + const auto out0_itr = begin + std::min(in0i, outByIn.size() - 2); - const auto out = out0 + (d_out0 / d_inId0) * d_inId; + const auto in0 = float(out0_itr - begin) / (outByIn.size() - 1); + const auto out0 = *out0_itr; + const auto d_in = float(1) / (outByIn.size() - 1); + const auto d_out = *(out0_itr + 1) - *out0_itr; + + const auto out = out0 + (d_out / d_in) * (in - in0); // printf("SampleOutByIn(%f)->%f\n", in, out); return out; } @@ -1011,7 +963,7 @@ struct ColorProfileConversionDesc { }; static ColorProfileConversionDesc From(const FromDesc&); - vec3 DstFromSrc(const vec3 src) const { + vec3 Apply(const vec3 src) const { const auto srcRgb = vec3(srcRgbFromSrcYuv * vec4(src, 1)); const auto srcLinear = vec3{{ SampleOutByIn(srcLinearFromSrcTf.r, srcRgb.x()), diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index fdecbfda9927..c5c8995dab7e 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -19,7 +19,6 @@ #include "mozilla/Preferences.h" #include "mozilla/StaticPrefs_gfx.h" #include "mozilla/UniquePtr.h" -#include "mozilla/gfx/BuildConstants.h" #include "mozilla/gfx/Logging.h" #include "mozilla/gfx/Matrix.h" #include "mozilla/layers/ImageDataSerializer.h" @@ -190,16 +189,16 @@ const char* const kFragConvert_ColorMatrix = R"( return (uColorMatrix * vec4(src, 1)).rgb; } )"; -const char* const kFragConvert_ColorLut3d = R"( +const char* const kFragConvert_ColorLut = R"( uniform PRECISION sampler3D uColorLut; vec3 metaConvert(vec3 src) { // Half-texel filtering hazard! // E.g. For texture size of 2, - // E.g. x=0.25 is still sampling 100% of texel x=0, 0% of texel x=1. - // For the LUT, we need r=0.25 to filter 75/25 from texel 0 and 1. - // That is, we need to adjust our sampling point such that it starts in the - // center of texel 0, and ends in the center of texel N-1. + // E.g. 0.5/2=0.25 is still sampling 100% of texel 0, 0% of texel 1. + // For the LUT, we need 0.5/2=0.25 to filter 25/75 texel 0 and 1. + // That is, we need to adjust our sampling point such that it's 0.25 of the + // way from texel 0's center to texel 1's center. // We need, for N=2: // v=0.0|N=2 => v'=0.5/2 // v=1.0|N=2 => v'=1.5/2 @@ -212,44 +211,6 @@ const char* const kFragConvert_ColorLut3d = R"( return texture(uColorLut, src).rgb; } )"; -// Delete if unused after 2024-10-01: -const char* const kFragConvert_ColorLut2d = R"( - uniform PRECISION sampler2D uColorLut; - uniform mediump vec3 uColorLut3dSize; - - vec3 metaConvert(vec3 src) { - // Half-texel filtering hazard! - // E.g. For texture size of 2, - // E.g. x=0.25 is still sampling 100% of texel x=0, 0% of texel x=1. - // For the LUT, we need r=0.25 to filter 75/25 from texel 0 and 1. - // That is, we need to adjust our sampling point such that it starts in the - // center of texel 0, and ends in the center of texel N-1. - // We need, for N=2: - // v=0.0|N=2 => v'=0.5/2 - // v=1.0|N=2 => v'=1.5/2 - // For N=3: - // v=0.0|N=3 => v'=0.5/3 - // v=1.0|N=3 => v'=2.5/3 - // => v' = ( 0.5 + v * (3 - 1) )/3 - src = clamp(src, vec3(0,0,0), vec3(1,1,1)); - vec3 lut3dSize = uColorLut3dSize; - vec2 lut2dSize = vec2(lut3dSize.x, lut3dSize.y * lut3dSize.z); - vec3 texelSrc3d = 0.5 + src * (lut3dSize - 1.0); - - vec3 texelSrc3d_zFloor = texelSrc3d; - texelSrc3d_zFloor.z = floor(texelSrc3d_zFloor.z); - vec3 texelSrc3d_zNext = texelSrc3d_zFloor + vec3(0,0,1); - texelSrc3d_zNext.z = min(texelSrc3d_zNext.z, lut3dSize.z - 1.0); - - vec2 texelSrc2d_zFloor = texelSrc3d_zFloor.xy + vec2(0, texelSrc3d_zFloor.z * lut3dSize.y); - vec2 texelSrc2d_zNext = texelSrc3d_zNext.xy + vec2(0, texelSrc3d_zNext.z * lut3dSize.y); - - vec4 dst_zFloor = texture(uColorLut, texelSrc2d_zFloor / lut2dSize); - vec4 dst_zNext = texture(uColorLut, texelSrc2d_zNext / lut2dSize); - - return mix(dst_zFloor, dst_zNext, texelSrc3d.z - texelSrc3d_zFloor.z); - } -)"; // - @@ -316,13 +277,13 @@ Mat3 SubRectMat3(const gfx::IntRect& bigSubrect, const gfx::IntSize& smallSize, // -- ScopedSaveMultiTex::ScopedSaveMultiTex(GLContext* const gl, - const size_t texUnits, + const std::vector& texUnits, const GLenum texTarget) : mGL(*gl), mTexUnits(texUnits), mTexTarget(texTarget), mOldTexUnit(mGL.GetIntAs(LOCAL_GL_ACTIVE_TEXTURE)) { - MOZ_RELEASE_ASSERT(texUnits >= 1); + MOZ_RELEASE_ASSERT(texUnits.size() >= 1); GLenum texBinding; switch (mTexTarget) { @@ -343,11 +304,12 @@ ScopedSaveMultiTex::ScopedSaveMultiTex(GLContext* const gl, MOZ_CRASH(); } - for (const auto i : IntegerRange(mTexUnits)) { - mGL.fActiveTexture(LOCAL_GL_TEXTURE0 + i); + for (const auto i : IntegerRange(mTexUnits.size())) { + const auto& unit = mTexUnits[i]; + mGL.fActiveTexture(LOCAL_GL_TEXTURE0 + unit); if (mGL.IsSupported(GLFeature::sampler_objects)) { mOldTexSampler[i] = mGL.GetIntAs(LOCAL_GL_SAMPLER_BINDING); - mGL.fBindSampler(i, 0); + mGL.fBindSampler(unit, 0); } mOldTex[i] = mGL.GetIntAs(texBinding); } @@ -357,10 +319,11 @@ ScopedSaveMultiTex::~ScopedSaveMultiTex() { // Unbind in reverse order, in case we have repeats. // Order matters because we unbound samplers during ctor, so now we have to // make sure we rebind them in the right order. - for (const auto i : Reversed(IntegerRange(mTexUnits))) { - mGL.fActiveTexture(LOCAL_GL_TEXTURE0 + i); + for (const auto i : Reversed(IntegerRange(mTexUnits.size()))) { + const auto& unit = mTexUnits[i]; + mGL.fActiveTexture(LOCAL_GL_TEXTURE0 + unit); if (mGL.IsSupported(GLFeature::sampler_objects)) { - mGL.fBindSampler(i, mOldTexSampler[i]); + mGL.fBindSampler(unit, mOldTexSampler[i]); } mGL.fBindTexture(mTexTarget, mOldTex[i]); } @@ -557,6 +520,11 @@ void DrawBlitProg::Draw(const BaseArgs& args, gl->fUniformMatrix3fv(mLoc_uDestMatrix, 1, false, destMatrix.m); gl->fUniformMatrix3fv(mLoc_uTexMatrix0, 1, false, args.texMatrix0.m); + if (args.texUnitForColorLut) { + gl->fUniform1i(mLoc_uColorLut, + AssertedCast(*args.texUnitForColorLut)); + } + MOZ_ASSERT(bool(argsYUV) == (mLoc_uColorMatrix != -1)); if (argsYUV) { gl->fUniformMatrix3fv(mLoc_uTexMatrix1, 1, false, argsYUV->texMatrix1.m); @@ -716,6 +684,10 @@ GLBlitHelper::GLBlitHelper(GLContext* const gl) } GLBlitHelper::~GLBlitHelper() { + for (const auto& pair : mDrawBlitProgs) { + const auto& ptr = pair.second; + delete ptr; + } mDrawBlitProgs.clear(); if (!mGL->MakeCurrent()) return; @@ -730,16 +702,18 @@ GLBlitHelper::~GLBlitHelper() { // -- -const DrawBlitProg& GLBlitHelper::GetDrawBlitProg( +const DrawBlitProg* GLBlitHelper::GetDrawBlitProg( const DrawBlitProg::Key& key) const { - auto& ret = mDrawBlitProgs[key]; - if (!ret) { - ret = CreateDrawBlitProg(key); + const auto& res = mDrawBlitProgs.insert({key, nullptr}); + auto& pair = *(res.first); + const auto& didInsert = res.second; + if (didInsert) { + pair.second = CreateDrawBlitProg(pair.first); } - return *ret; + return pair.second; } -std::unique_ptr GLBlitHelper::CreateDrawBlitProg( +const DrawBlitProg* GLBlitHelper::CreateDrawBlitProg( const DrawBlitProg::Key& key) const { const auto precisionPref = StaticPrefs::gfx_blithelper_precision(); const char* precision; @@ -816,7 +790,7 @@ std::unique_ptr GLBlitHelper::CreateDrawBlitProg( mGL->fUniform1i(loc, i); } - return std::make_unique(this, prog); + return new DrawBlitProg(this, prog); } GLuint progLogLen = 0; @@ -1023,7 +997,7 @@ bool GLBlitHelper::Blit(const java::GeckoSurfaceTexture::Ref& surfaceTexture, {kFragHeader_TexExt, {kFragSample_OnePlane, kFragConvert_None}}); const DrawBlitProg::BaseArgs baseArgs = {transform3, yFlip, destSize, Nothing()}; - prog.Draw(baseArgs, nullptr); + prog->Draw(baseArgs, nullptr); if (surfaceTexture->IsSingleBuffer()) { surfaceTexture->ReleaseTexImage(); @@ -1113,7 +1087,7 @@ bool GLBlitHelper::BlitPlanarYCbCr(const PlanarYCbCrData& yuvData, // -- - const ScopedSaveMultiTex saveTex(mGL, 3, LOCAL_GL_TEXTURE_2D); + const ScopedSaveMultiTex saveTex(mGL, {0, 1, 2}, LOCAL_GL_TEXTURE_2D); const ResetUnpackState reset(mGL); const gfx::IntSize yTexSize(yuvData.mYStride, yuvData.YDataSize().height); const gfx::IntSize uvTexSize(yuvData.mCbCrStride, @@ -1165,7 +1139,7 @@ bool GLBlitHelper::BlitPlanarYCbCr(const PlanarYCbCrData& yuvData, yFlip, destSize, Nothing()}; const DrawBlitProg::YUVArgs yuvArgs = { SubRectMat3(clipRect, uvTexSize, divisors), Some(yuvData.mYUVColorSpace)}; - prog.Draw(baseArgs, &yuvArgs); + prog->Draw(baseArgs, &yuvArgs); return true; } @@ -1223,7 +1197,11 @@ bool GLBlitHelper::BlitImage(MacIOSurface* const iosurf, const GLenum texTarget = LOCAL_GL_TEXTURE_RECTANGLE; - const ScopedSaveMultiTex saveTex(mGL, planes, texTarget); + std::vector texUnits; + for (uint8_t i = 0; i < planes; i++) { + texUnits.push_back(i); + } + const ScopedSaveMultiTex saveTex(mGL, texUnits, texTarget); const ScopedTexture tex0(mGL); const ScopedTexture tex1(mGL); const ScopedTexture tex2(mGL); @@ -1304,7 +1282,7 @@ bool GLBlitHelper::BlitImage(MacIOSurface* const iosurf, kFragHeader_Tex2DRect, {fragSample, kFragConvert_ColorMatrix}, }); - prog.Draw(baseArgs, pYuvArgs); + prog->Draw(baseArgs, pYuvArgs); return true; } #endif @@ -1337,14 +1315,14 @@ void GLBlitHelper::DrawBlitTextureToFramebuffer(const GLuint srcTex, {kFragSample_OnePlane, fragConvert}, }); - const ScopedSaveMultiTex saveTex(mGL, 1, srcTarget); + const ScopedSaveMultiTex saveTex(mGL, {0}, srcTarget); mGL->fActiveTexture(LOCAL_GL_TEXTURE0); mGL->fBindTexture(srcTarget, srcTex); const bool yFlip = false; const DrawBlitProg::BaseArgs baseArgs = {texMatrix0, yFlip, destSize, Nothing()}; - prog.Draw(baseArgs); + prog->Draw(baseArgs); } // ----------------------------------------------------------------------------- @@ -1541,7 +1519,11 @@ bool GLBlitHelper::Blit(DMABufSurface* surface, const gfx::IntSize& destSize, const GLenum texTarget = LOCAL_GL_TEXTURE_2D; - const ScopedSaveMultiTex saveTex(mGL, planes, texTarget); + std::vector texUnits; + for (uint8_t i = 0; i < planes; i++) { + texUnits.push_back(i); + } + const ScopedSaveMultiTex saveTex(mGL, texUnits, texTarget); const auto pixelFormat = surface->GetSurfaceType(); const char* fragSample; @@ -1578,7 +1560,7 @@ bool GLBlitHelper::Blit(DMABufSurface* surface, const gfx::IntSize& destSize, const auto& prog = GetDrawBlitProg({kFragHeader_Tex2D, {fragSample, fragConvert}}); - prog.Draw(baseArgs, pYuvArgs); + prog->Draw(baseArgs, pYuvArgs); return true; } @@ -1621,205 +1603,23 @@ static uint32_t toRgb10A2(const color::vec4& val) { return ret; } -// - - -color::ColorspaceDesc ToColorspaceDesc(const gfx::YUVRangedColorSpace cs) { - switch (cs) { - case gfx::YUVRangedColorSpace::BT601_Narrow: - return { - .chrom = color::Chromaticities::Rec601_525_Ntsc(), - .tf = color::PiecewiseGammaDesc::Rec709(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Rec709(), - .ycbcr = color::YcbcrDesc::Narrow8(), - }, - }; - case gfx::YUVRangedColorSpace::BT601_Full: - return { - .chrom = color::Chromaticities::Rec601_525_Ntsc(), - .tf = color::PiecewiseGammaDesc::Rec709(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Rec709(), - .ycbcr = color::YcbcrDesc::Full8(), - }, - }; - case gfx::YUVRangedColorSpace::BT709_Narrow: - return { - .chrom = color::Chromaticities::Rec709(), - .tf = color::PiecewiseGammaDesc::Rec709(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Rec709(), - .ycbcr = color::YcbcrDesc::Narrow8(), - }, - }; - case gfx::YUVRangedColorSpace::BT709_Full: - return { - .chrom = color::Chromaticities::Rec709(), - .tf = color::PiecewiseGammaDesc::Rec709(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Rec709(), - .ycbcr = color::YcbcrDesc::Full8(), - }, - }; - case gfx::YUVRangedColorSpace::BT2020_Narrow: - return { - .chrom = color::Chromaticities::Rec2020(), - .tf = color::PiecewiseGammaDesc::Rec2020_12bit(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Rec709(), - .ycbcr = color::YcbcrDesc::Narrow8(), - }, - }; - case gfx::YUVRangedColorSpace::BT2020_Full: - return { - .chrom = color::Chromaticities::Rec2020(), - .tf = color::PiecewiseGammaDesc::Rec2020_12bit(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Rec2020(), - .ycbcr = color::YcbcrDesc::Full8(), - }, - }; - case gfx::YUVRangedColorSpace::GbrIdentity: - return { - .chrom = color::Chromaticities::Rec709(), - .tf = color::PiecewiseGammaDesc::Rec709(), - .yuv = - color::YuvDesc{ - .yCoeffs = color::YuvLumaCoeffs::Gbr(), - .ycbcr = color::YcbcrDesc::Full8(), - }, - }; - } - MOZ_CRASH("Bad YUVRangedColorSpace."); -} - -static std::optional ToColorProfileDesc( - gfx::ColorSpace2); - -} // namespace gl -namespace gfx { - -color::ColorProfileDesc QueryOutputColorProfile(); - -} // namespace gfx -namespace gl { - -// - - -static std::optional ToColorProfileDesc( - const gfx::ColorSpace2 cspace) { - color::ColorspaceDesc cspaceDesc; - switch (cspace) { - case gfx::ColorSpace2::Display: - if (kIsWindows) { -#ifdef XP_WIN - return gfx::QueryOutputColorProfile(); -#endif - } - return {}; - - case gfx::ColorSpace2::SRGB: - cspaceDesc = {.chrom = color::Chromaticities::Srgb(), - .tf = color::PiecewiseGammaDesc::Srgb()}; - break; - case gfx::ColorSpace2::DISPLAY_P3: - cspaceDesc = {.chrom = color::Chromaticities::DisplayP3(), - .tf = color::PiecewiseGammaDesc::DisplayP3()}; - break; - case gfx::ColorSpace2::BT601_525: // aka smpte170m NTSC - cspaceDesc = {.chrom = color::Chromaticities::Rec601_525_Ntsc(), - .tf = color::PiecewiseGammaDesc::Rec709()}; - break; - case gfx::ColorSpace2::BT709: // Same gamut as SRGB, but different gamma. - cspaceDesc = {.chrom = color::Chromaticities::Rec709(), - .tf = color::PiecewiseGammaDesc::Rec709()}; - break; - case gfx::ColorSpace2::BT2020: - cspaceDesc = {.chrom = color::Chromaticities::Rec2020(), - .tf = color::PiecewiseGammaDesc::Rec2020_12bit()}; - break; - } - const auto profileDesc = color::ColorProfileDesc::From(cspaceDesc); - return profileDesc; -} - -// - - -// For std::visit -template -struct overloaded : Ts... { - using Ts::operator()...; -}; -// explicit deduction guide (not needed as of C++20) -template -overloaded(Ts...) -> overloaded; - -// - - -template -inline auto MaybeFind(C& container, const K& key) - -> decltype(&(container.find(key)->second)) { - const auto itr = container.find(key); - if (itr == container.end()) return nullptr; - return &(itr->second); -} - -// - - std::shared_ptr GLBlitHelper::GetColorLutTex( - const ColorLutKey& request) const { - if (const auto found = MaybeFind(mColorLutTexMap, request)) { - return *found; // Might be *Some(nullptr) -> nullptr! - } - - return mColorLutTexMap[request] = [&]() -> std::shared_ptr { + const ColorLutKey& key) const { + auto& weak = mColorLutTexMap[key]; + auto strong = weak.lock(); + if (!strong) { auto& gl = *mGL; - const auto tex = std::make_shared(gl); + strong = std::make_shared(gl); + weak = strong; - // - - - const std::optional srcProfile = - std::visit(overloaded{ - [&](const gfx::ColorSpace2& cs) - -> std::optional { - MOZ_ASSERT(cs != request.dst); - const auto cpd = ToColorProfileDesc(cs); - return cpd; - }, - [&](const gfx::YUVRangedColorSpace& cs) - -> std::optional { - const auto csd = ToColorspaceDesc(cs); - const auto cpd = color::ColorProfileDesc::From(csd); - return cpd; - }, - }, - request.src); - MOZ_ASSERT(srcProfile); - - const auto dstProfile = ToColorProfileDesc(request.dst); - if (kIsWindows) { - MOZ_ASSERT(dstProfile); - } - if (!srcProfile || !dstProfile) return nullptr; - const auto conversion = color::ColorProfileConversionDesc::From({ - .src = *srcProfile, - .dst = *dstProfile, - }); + const auto ct = color::ColorspaceTransform::Create(key.src, key.dst); // - const auto minLutSize = color::ivec3{2}; const auto maxLutSize = color::ivec3{256}; auto lutSize = minLutSize; - const bool isYcbcr = - (conversion.srcRgbFromSrcYuv != color::mat4::Identity()); - if (isYcbcr) { + if (ct.srcSpace.yuv) { lutSize.x(int(StaticPrefs::gfx_blithelper_lut_size_ycbcr_y())); lutSize.y(int(StaticPrefs::gfx_blithelper_lut_size_ycbcr_cb())); lutSize.z(int(StaticPrefs::gfx_blithelper_lut_size_ycbcr_cr())); @@ -1828,20 +1628,15 @@ std::shared_ptr GLBlitHelper::GetColorLutTex( lutSize.y(int(StaticPrefs::gfx_blithelper_lut_size_rgb_g())); lutSize.z(int(StaticPrefs::gfx_blithelper_lut_size_rgb_b())); } - lutSize = clamp(lutSize, minLutSize, maxLutSize); + lutSize = max(minLutSize, min(lutSize, maxLutSize)); // Clamp - const auto lut = [&]() { - auto lut = color::Lut3::Create(lutSize); - lut.SetMap( - [&](const color::vec3& src) { return conversion.DstFromSrc(src); }); - return lut; - }(); + const auto lut = ct.ToLut3(lutSize); const auto& size = lut.size; // - constexpr GLenum target = LOCAL_GL_TEXTURE_3D; - const auto bind = gl::ScopedBindTexture(&gl, tex->name, target); + const auto bind = gl::ScopedBindTexture(&gl, strong->name, target); gl.fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); gl.fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); gl.fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_R, LOCAL_GL_CLAMP_TO_EDGE); @@ -1878,8 +1673,8 @@ std::shared_ptr GLBlitHelper::GetColorLutTex( LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV, uploadData.data()); } - return tex; - }(); + } + return strong; } } // namespace gl diff --git a/gfx/gl/GLBlitHelper.h b/gfx/gl/GLBlitHelper.h index a92e8ac83dad..83915090979a 100644 --- a/gfx/gl/GLBlitHelper.h +++ b/gfx/gl/GLBlitHelper.h @@ -12,7 +12,6 @@ #include #include #include -#include #include "Colorspaces.h" #include "GLConsts.h" #include "GLContextTypes.h" @@ -127,8 +126,6 @@ Mat3 SubRectMat3(const gfx::IntRect& bigSubrect, const gfx::IntSize& smallSize, class DrawBlitProg final { const GLBlitHelper& mParent; - - public: const GLuint mProg; const GLint mLoc_uDestMatrix; const GLint mLoc_uTexMatrix0; @@ -157,6 +154,7 @@ class DrawBlitProg final { gfx::IntSize destSize; // Always needed for (at least) setting the viewport. Maybe destRect; + Maybe texUnitForColorLut; }; struct YUVArgs final { Mat3 texMatrix1; @@ -168,14 +166,15 @@ class DrawBlitProg final { class ScopedSaveMultiTex final { GLContext& mGL; - const size_t mTexUnits; + const std::vector mTexUnits; const GLenum mTexTarget; const GLuint mOldTexUnit; GLuint mOldTexSampler[3]; GLuint mOldTex[3]; public: - ScopedSaveMultiTex(GLContext* gl, size_t texUnits, GLenum texTarget); + ScopedSaveMultiTex(GLContext* gl, const std::vector& texUnits, + GLenum texTarget); ~ScopedSaveMultiTex(); }; @@ -186,8 +185,7 @@ class GLBlitHelper final { friend class GLContext; GLContext* const mGL; - mutable std::map> - mDrawBlitProgs; + mutable std::map mDrawBlitProgs; GLuint mQuadVAO = 0; GLuint mQuadVBO = 0; @@ -199,17 +197,16 @@ class GLBlitHelper final { gfx::IntSize mYuvUploads_UVSize = {0, 0}; public: - struct ColorLutKey : DeriveCmpOpMembers { - std::variant src; - gfx::ColorSpace2 dst; + struct ColorLutKey { + color::ColorspaceDesc src; + color::ColorspaceDesc dst; auto Members() const { return std::tie(src, dst); } - - struct Hasher : mozilla::StdHashMembers {}; + INLINE_AUTO_MAPPABLE(ColorLutKey) }; private: - mutable std::unordered_map, + mutable std::unordered_map, ColorLutKey::Hasher> mColorLutTexMap; @@ -222,11 +219,10 @@ class GLBlitHelper final { ID3D11Device* GetD3D11() const; #endif - const DrawBlitProg& GetDrawBlitProg(const DrawBlitProg::Key& key) const; + const DrawBlitProg* GetDrawBlitProg(const DrawBlitProg::Key& key) const; private: - std::unique_ptr CreateDrawBlitProg( - const DrawBlitProg::Key& key) const; + const DrawBlitProg* CreateDrawBlitProg(const DrawBlitProg::Key& key) const; public: bool BlitPlanarYCbCr(const layers::PlanarYCbCrData&, @@ -330,8 +326,7 @@ extern const char* const kFragSample_ThreePlane; extern const char* const kFragConvert_None; extern const char* const kFragConvert_BGR; extern const char* const kFragConvert_ColorMatrix; -extern const char* const kFragConvert_ColorLut3d; -extern const char* const kFragConvert_ColorLut2d; +extern const char* const kFragConvert_ColorLut; extern const char* const kFragMixin_AlphaMultColors; extern const char* const kFragMixin_AlphaClampColors; diff --git a/gfx/gl/GLBlitHelperD3D.cpp b/gfx/gl/GLBlitHelperD3D.cpp index 1c101d8980af..ae6362e278e8 100644 --- a/gfx/gl/GLBlitHelperD3D.cpp +++ b/gfx/gl/GLBlitHelperD3D.cpp @@ -95,7 +95,16 @@ class BindAnglePlanes final { const EGLAttrib* const* postAttribsList = nullptr) : mParent(*parent), mNumPlanes(numPlanes), - mMultiTex(mParent.mGL, mNumPlanes, LOCAL_GL_TEXTURE_EXTERNAL), + mMultiTex( + mParent.mGL, + [&]() { + std::vector ret; + for (int i = 0; i < numPlanes; i++) { + ret.push_back(i); + } + return ret; + }(), + LOCAL_GL_TEXTURE_EXTERNAL), mTempTexs{0}, mStreams{0}, mSuccess(true) { @@ -327,7 +336,7 @@ bool GLBlitHelper::BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc, const auto& prog = GetDrawBlitProg( {kFragHeader_TexExt, {kFragSample_TwoPlane, kFragConvert_ColorMatrix}}); - prog.Draw(baseArgs, &yuvArgs); + prog->Draw(baseArgs, &yuvArgs); return true; } @@ -382,7 +391,7 @@ bool GLBlitHelper::BlitAngleYCbCr(const WindowsHandle (&handleList)[3], const auto& prog = GetDrawBlitProg( {kFragHeader_TexExt, {kFragSample_ThreePlane, kFragConvert_ColorMatrix}}); - prog.Draw(baseArgs, &yuvArgs); + prog->Draw(baseArgs, &yuvArgs); return true; } diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 4ee256b0530a..eea26024ae40 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -45,12 +45,6 @@ #include "mozilla/GenericRefCounted.h" #include "mozilla/WeakPtr.h" -template -constexpr inline std::array make_array( - ElemT&& arg1, More&&... more) { - return {std::forward(arg1), std::forward(more)...}; -} - #ifdef MOZ_WIDGET_ANDROID # include "mozilla/ProfilerLabels.h" #endif @@ -803,15 +797,8 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { AFTER_GL_CALL; } - void InvalidateFramebuffer(GLenum target) { - constexpr auto ATTACHMENTS = make_array(GLenum{LOCAL_GL_COLOR_ATTACHMENT0}, - LOCAL_GL_DEPTH_STENCIL_ATTACHMENT); - fInvalidateFramebuffer(target, ATTACHMENTS.size(), ATTACHMENTS.data()); - } - void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) { - if (!mSymbols.fInvalidateFramebuffer) return; BeforeGLDrawCall(); BEFORE_GL_CALL; ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer); @@ -823,7 +810,6 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) { - if (!mSymbols.fInvalidateSubFramebuffer) return; BeforeGLDrawCall(); BEFORE_GL_CALL; ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer); @@ -839,13 +825,6 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { AFTER_GL_CALL; } - void BindSamplerTexture(GLuint texUnitId, GLuint samplerHandle, - GLenum texTarget, GLuint texHandle) { - fBindSampler(texUnitId, samplerHandle); - fActiveTexture(LOCAL_GL_TEXTURE0 + texUnitId); - fBindTexture(texTarget, texHandle); - } - void fBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { BEFORE_GL_CALL; mSymbols.fBlendColor(red, green, blue, alpha); @@ -2049,11 +2028,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { public: bool mElideDuplicateBindFramebuffers = false; - // If e.g. GL_DRAW_FRAMEBUFFER isn't supported, will bind GL_FRAMEBUFFER. - void fBindFramebuffer(GLenum target, const GLuint fb) const { - if (!IsSupported(gl::GLFeature::framebuffer_blit)) { - target = LOCAL_GL_FRAMEBUFFER; - } + void fBindFramebuffer(const GLenum target, const GLuint fb) const { if (mElideDuplicateBindFramebuffers) { MOZ_ASSERT(mCachedDrawFb == GetIntAs(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING)); @@ -3886,30 +3861,6 @@ class Texture final { } }; -// - - -class Sampler final { - public: - const WeakPtr weakGl; - const GLuint name; - - private: - static GLuint Create(GLContext& gl) { - GLuint ret = 0; - gl.fGenSamplers(1, &ret); - return ret; - } - - public: - explicit Sampler(GLContext& gl) : weakGl(&gl), name(Create(gl)) {} - - ~Sampler() { - const RefPtr gl = weakGl.get(); - if (!gl || !gl->MakeCurrent()) return; - gl->fDeleteSamplers(1, &name); - } -}; - /** * Helper function that creates a 2D texture aSize.width x aSize.height with * storage type specified by aFormats. Returns GL texture object id. diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h index 12aace9e9e28..4168de69a2bc 100644 --- a/gfx/gl/SharedSurface.h +++ b/gfx/gl/SharedSurface.h @@ -182,13 +182,8 @@ class SurfaceFactory { const SharedSurfaceDesc&) = 0; public: - virtual bool SupportsCspaces() const { return false; } - UniquePtr CreateShared(const gfx::IntSize& size, gfx::ColorSpace2 cs) { - if (!SupportsCspaces()) { - cs = gfx::ColorSpace2::Display; - } return CreateSharedImpl({mDesc, size, cs}); } }; diff --git a/gfx/gl/SharedSurfaceIO.h b/gfx/gl/SharedSurfaceIO.h index 94804e3d0cec..938173b9823e 100644 --- a/gfx/gl/SharedSurfaceIO.h +++ b/gfx/gl/SharedSurfaceIO.h @@ -47,8 +47,6 @@ class SurfaceFactory_IOSurface : public SurfaceFactory { explicit SurfaceFactory_IOSurface(GLContext& gl); - bool SupportsCspaces() const override { return true; } - virtual UniquePtr CreateSharedImpl( const SharedSurfaceDesc& desc) override { if (desc.size.width > mMaxDims.width || diff --git a/gfx/gl/gtest/TestColorspaces.cpp b/gfx/gl/gtest/TestColorspaces.cpp index 31a907115fa1..c437e204af02 100644 --- a/gfx/gl/gtest/TestColorspaces.cpp +++ b/gfx/gl/gtest/TestColorspaces.cpp @@ -650,7 +650,7 @@ TEST(Colorspaces, ColorProfileConversionDesc_SrgbFromRec709) .dst = srgb, }); auto src = vec3(16.0); - auto dst = conv.DstFromSrc(src / 255) * 255; + auto dst = conv.Apply(src / 255) * 255; const auto tfa = PiecewiseGammaDesc::Srgb(); const auto tfb = PiecewiseGammaDesc::Srgb(); @@ -667,7 +667,7 @@ TEST(Colorspaces, ColorProfileConversionDesc_SrgbFromRec709) .dst = rec709, }); auto src = vec3(16.0); - auto dst = conv.DstFromSrc(src / 255) * 255; + auto dst = conv.Apply(src / 255) * 255; const auto tfa = PiecewiseGammaDesc::Rec709(); const auto tfb = PiecewiseGammaDesc::Rec709(); @@ -684,7 +684,7 @@ TEST(Colorspaces, ColorProfileConversionDesc_SrgbFromRec709) .dst = srgb, }); auto src = vec3(16.0); - auto dst = conv.DstFromSrc(src / 255) * 255; + auto dst = conv.Apply(src / 255) * 255; const auto tfa = PiecewiseGammaDesc::Rec709(); const auto tfb = PiecewiseGammaDesc::Srgb(); @@ -696,9 +696,3 @@ TEST(Colorspaces, ColorProfileConversionDesc_SrgbFromRec709) EXPECT_LT(Stats::Diff(dst.data, vec3(expected).data), (Stats::Error{0.12})); } } - -TEST(Colorspaces, SampleOutByIn_NegativeInputs) -{ - const auto tf = MakeGamma(1.0 / 2.2, 256); - EXPECT_LT(SampleOutByIn(tf, -0.1f), 0.0f); -} diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index d6e0f0ec4932..ccc58213efd4 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -2083,7 +2083,7 @@ Maybe>& gfxPlatform::GetCMSOutputProfileData() { CMSMode GfxColorManagementMode() { const auto mode = StaticPrefs::gfx_color_management_mode(); - if (mode >= 0 && mode <= UnderlyingValue(CMSMode::_ENUM_MAX)) { + if (mode >= 0 && mode < UnderlyingValue(CMSMode::AllCount)) { return CMSMode(mode); } return CMSMode::Off; diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 37d6ec918713..452e7208b424 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -82,7 +82,7 @@ enum class CMSMode : int32_t { Off = 0, // No color management All = 1, // Color manage everything TaggedOnly = 2, // Color manage tagged Images Only - _ENUM_MAX = TaggedOnly + AllCount = 3 }; enum eGfxLog { diff --git a/gfx/webrender_bindings/DCLayerTree.cpp b/gfx/webrender_bindings/DCLayerTree.cpp index 237e729bfdb9..49ca8ee77b02 100644 --- a/gfx/webrender_bindings/DCLayerTree.cpp +++ b/gfx/webrender_bindings/DCLayerTree.cpp @@ -751,9 +751,9 @@ DCSurface* DCExternalSurfaceWrapper::EnsureSurfaceForExternalImage( auto cprofileOut = mDCLayerTree->OutputColorProfile(); bool pretendSrgb = true; if (pretendSrgb) { - cprofileOut = color::ColorProfileDesc::From(color::ColorspaceDesc{ - .chrom = color::Chromaticities::Srgb(), - .tf = color::PiecewiseGammaDesc::Srgb(), + cprofileOut = color::ColorProfileDesc::From({ + color::Chromaticities::Srgb(), + color::PiecewiseGammaDesc::Srgb(), }); } const auto conversion = color::ColorProfileConversionDesc::From({ @@ -2072,10 +2072,7 @@ void DCLayerTree::DestroyEGLSurface() { // - -} // namespace wr -namespace gfx { - -color::ColorProfileDesc QueryOutputColorProfile() { +color::ColorProfileDesc DCLayerTree::QueryOutputColorProfile() { // GPU process can't simply init gfxPlatform, (and we don't need most of it) // but we do need gfxPlatform::GetCMSOutputProfile(). // So we steal what we need through the window: @@ -2129,9 +2126,6 @@ color::ColorProfileDesc QueryOutputColorProfile() { return ret; } -} // namespace gfx -namespace wr { - inline D2D1_MATRIX_5X4_F to_D2D1_MATRIX_5X4_F(const color::mat4& m) { return D2D1_MATRIX_5X4_F{{{ m.rows[0][0], diff --git a/gfx/webrender_bindings/DCLayerTree.h b/gfx/webrender_bindings/DCLayerTree.h index 8289eaf50d37..d5ade5781e1e 100644 --- a/gfx/webrender_bindings/DCLayerTree.h +++ b/gfx/webrender_bindings/DCLayerTree.h @@ -44,10 +44,6 @@ struct IDCompositionVirtualSurface; namespace mozilla { -namespace gfx { -color::ColorProfileDesc QueryOutputColorProfile(); -} - namespace gl { class GLContext; } @@ -252,6 +248,8 @@ class DCLayerTree { bool mPendingCommit; + static color::ColorProfileDesc QueryOutputColorProfile(); + mutable Maybe mOutputColorProfile; DCompOverlayTypes mUsedOverlayTypesInFrame = DCompOverlayTypes::NO_OVERLAY; @@ -260,7 +258,7 @@ class DCLayerTree { public: const color::ColorProfileDesc& OutputColorProfile() const { if (!mOutputColorProfile) { - mOutputColorProfile = Some(gfx::QueryOutputColorProfile()); + mOutputColorProfile = Some(QueryOutputColorProfile()); } return *mOutputColorProfile; }