diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:37 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:37 +0000 |
commit | a90a5cba08fdf6c0ceb95101c275108a152a3aed (patch) | |
tree | 532507288f3defd7f4dcf1af49698bcb76034855 /dom/canvas | |
parent | Adding debian version 126.0.1-1. (diff) | |
download | firefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.tar.xz firefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas')
22 files changed, 713 insertions, 355 deletions
diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp index 358e057265..cef9f1ee2d 100644 --- a/dom/canvas/CanvasImageCache.cpp +++ b/dom/canvas/CanvasImageCache.cpp @@ -9,7 +9,6 @@ #include "imgIRequest.h" #include "mozilla/dom/Element.h" #include "nsTHashtable.h" -#include "mozilla/dom/HTMLCanvasElement.h" #include "nsContentUtils.h" #include "mozilla/Preferences.h" #include "mozilla/UniquePtr.h" @@ -26,11 +25,11 @@ using namespace gfx; * due to CORS security. */ struct ImageCacheKey { - ImageCacheKey(imgIContainer* aImage, HTMLCanvasElement* aCanvas, + ImageCacheKey(imgIContainer* aImage, CanvasRenderingContext2D* aContext, BackendType aBackendType) - : mImage(aImage), mCanvas(aCanvas), mBackendType(aBackendType) {} + : mImage(aImage), mContext(aContext), mBackendType(aBackendType) {} nsCOMPtr<imgIContainer> mImage; - HTMLCanvasElement* mCanvas; + CanvasRenderingContext2D* mContext; BackendType mBackendType; }; @@ -41,7 +40,7 @@ struct ImageCacheKey { struct ImageCacheEntryData { ImageCacheEntryData(const ImageCacheEntryData& aOther) : mImage(aOther.mImage), - mCanvas(aOther.mCanvas), + mContext(aOther.mContext), mBackendType(aOther.mBackendType), mSourceSurface(aOther.mSourceSurface), mSize(aOther.mSize), @@ -49,7 +48,7 @@ struct ImageCacheEntryData { mCropRect(aOther.mCropRect) {} explicit ImageCacheEntryData(const ImageCacheKey& aKey) : mImage(aKey.mImage), - mCanvas(aKey.mCanvas), + mContext(aKey.mContext), mBackendType(aKey.mBackendType) {} nsExpirationState* GetExpirationState() { return &mState; } @@ -57,7 +56,7 @@ struct ImageCacheEntryData { // Key nsCOMPtr<imgIContainer> mImage; - HTMLCanvasElement* mCanvas; + CanvasRenderingContext2D* mContext; BackendType mBackendType; // Value RefPtr<SourceSurface> mSourceSurface; @@ -79,13 +78,13 @@ class ImageCacheEntry : public PLDHashEntryHdr { ~ImageCacheEntry() = default; bool KeyEquals(KeyTypePointer key) const { - return mData->mImage == key->mImage && mData->mCanvas == key->mCanvas && + return mData->mImage == key->mImage && mData->mContext == key->mContext && mData->mBackendType == key->mBackendType; } static KeyTypePointer KeyToPointer(KeyType& key) { return &key; } static PLDHashNumber HashKey(KeyTypePointer key) { - return HashGeneric(key->mImage.get(), key->mCanvas, key->mBackendType); + return HashGeneric(key->mImage.get(), key->mContext, key->mBackendType); } enum { ALLOW_MEMMOVE = true }; @@ -152,7 +151,7 @@ class ImageCache final : public nsExpirationTracker<ImageCacheEntryData, 4> { AllCanvasImageCacheKey(aObject->mImage, aObject->mBackendType)); // Deleting the entry will delete aObject since the entry owns aObject. - mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mCanvas, + mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mContext, aObject->mBackendType)); } @@ -264,11 +263,33 @@ static already_AddRefed<imgIContainer> GetImageContainer(dom::Element* aImage) { return imgContainer.forget(); } +void CanvasImageCache::NotifyCanvasDestroyed( + CanvasRenderingContext2D* aContext) { + MOZ_ASSERT(aContext); + + if (!NS_IsMainThread() || !gImageCache) { + return; + } + + for (auto i = gImageCache->mCache.Iter(); !i.Done(); i.Next()) { + ImageCacheEntryData* data = i.Get()->mData.get(); + if (data->mContext == aContext) { + gImageCache->RemoveObject(data); + gImageCache->mAllCanvasCache.RemoveEntry( + AllCanvasImageCacheKey(data->mImage, data->mBackendType)); + i.Remove(); + } + } +} + void CanvasImageCache::NotifyDrawImage( - Element* aImage, HTMLCanvasElement* aCanvas, DrawTarget* aTarget, + Element* aImage, CanvasRenderingContext2D* aContext, DrawTarget* aTarget, SourceSurface* aSource, const IntSize& aSize, const IntSize& aIntrinsicSize, const Maybe<IntRect>& aCropRect) { - if (!aTarget) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aContext); + + if (!aTarget || !aContext) { return; } @@ -285,7 +306,7 @@ void CanvasImageCache::NotifyDrawImage( BackendType backendType = aTarget->GetBackendType(); AllCanvasImageCacheKey allCanvasCacheKey(imgContainer, backendType); - ImageCacheKey canvasCacheKey(imgContainer, aCanvas, backendType); + ImageCacheKey canvasCacheKey(imgContainer, aContext, backendType); ImageCacheEntry* entry = gImageCache->mCache.PutEntry(canvasCacheKey); if (entry) { @@ -311,6 +332,8 @@ void CanvasImageCache::NotifyDrawImage( SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage, DrawTarget* aTarget) { + MOZ_ASSERT(NS_IsMainThread()); + if (!gImageCache || !aTarget) { return nullptr; } @@ -329,12 +352,13 @@ SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage, return entry->mSourceSurface; } -SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage, - HTMLCanvasElement* aCanvas, - DrawTarget* aTarget, - IntSize* aSizeOut, - IntSize* aIntrinsicSizeOut, - Maybe<IntRect>* aCropRectOut) { +SourceSurface* CanvasImageCache::LookupCanvas( + Element* aImage, CanvasRenderingContext2D* aContext, DrawTarget* aTarget, + IntSize* aSizeOut, IntSize* aIntrinsicSizeOut, + Maybe<IntRect>* aCropRectOut) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aContext); + if (!gImageCache || !aTarget) { return nullptr; } @@ -351,7 +375,7 @@ SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage, // optimized surface given to a Skia backend would cause a readback. For // details, see bug 1794442. ImageCacheEntry* entry = gImageCache->mCache.GetEntry( - ImageCacheKey(imgContainer, aCanvas, aTarget->GetBackendType())); + ImageCacheKey(imgContainer, aContext, aTarget->GetBackendType())); if (!entry) { return nullptr; } diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h index 7aecb1fbe4..f3d21dcd7e 100644 --- a/dom/canvas/CanvasImageCache.h +++ b/dom/canvas/CanvasImageCache.h @@ -14,7 +14,7 @@ namespace mozilla { namespace dom { class Element; -class HTMLCanvasElement; +class CanvasRenderingContext2D; } // namespace dom namespace gfx { class DrawTarget; @@ -30,19 +30,24 @@ class CanvasImageCache { public: /** - * Notify that image element aImage was drawn to aCanvas element + * Notify that image element aImage was drawn to aContext canvas * using the first frame of aRequest's image. The data for the surface is * in aSurface, and the image size is in aSize. aIntrinsicSize is the size * the surface is intended to be rendered at. */ static void NotifyDrawImage(dom::Element* aImage, - dom::HTMLCanvasElement* aCanvas, + dom::CanvasRenderingContext2D* aContext, gfx::DrawTarget* aTarget, SourceSurface* aSource, const gfx::IntSize& aSize, const gfx::IntSize& aIntrinsicSize, const Maybe<gfx::IntRect>& aCropRect); /** + * Notify that aContext is being destroyed. + */ + static void NotifyCanvasDestroyed(dom::CanvasRenderingContext2D* aContext); + + /** * Check whether aImage has recently been drawn any canvas. If we return * a non-null surface, then the same image was recently drawn into a canvas. */ @@ -50,11 +55,11 @@ class CanvasImageCache { gfx::DrawTarget* aTarget); /** - * Like the top above, but restricts the lookup to only aCanvas. This is + * Like the top above, but restricts the lookup to only aContext. This is * required for CORS security. */ static SourceSurface* LookupCanvas(dom::Element* aImage, - dom::HTMLCanvasElement* aCanvas, + dom::CanvasRenderingContext2D* aContext, gfx::DrawTarget* aTarget, gfx::IntSize* aSizeOut, gfx::IntSize* aIntrinsicSizeOut, diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 54711aa981..3b9ca585e2 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -972,6 +972,7 @@ CanvasRenderingContext2D::ContextState::ContextState(const ContextState& aOther) textRendering(aOther.textRendering), letterSpacing(aOther.letterSpacing), wordSpacing(aOther.wordSpacing), + fontLineHeight(aOther.fontLineHeight), letterSpacingStr(aOther.letterSpacingStr), wordSpacingStr(aOther.wordSpacingStr), shadowColor(aOther.shadowColor), @@ -1089,6 +1090,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D( } CanvasRenderingContext2D::~CanvasRenderingContext2D() { + CanvasImageCache::NotifyCanvasDestroyed(this); RemovePostRefreshObserver(); RemoveShutdownObserver(); ResetBitmap(); @@ -2886,10 +2888,16 @@ void CanvasRenderingContext2D::ParseSpacing(const nsACString& aSpacing, class CanvasUserSpaceMetrics : public UserSpaceMetricsWithSize { public: CanvasUserSpaceMetrics(const gfx::IntSize& aSize, const nsFont& aFont, + const StyleLineHeight& aLineHeight, + RefPtr<nsAtom> aFontLanguage, + bool aFontExplicitLanguage, const ComputedStyle* aCanvasStyle, nsPresContext* aPresContext) : mSize(aSize), mFont(aFont), + mLineHeight(aLineHeight), + mFontLanguage(std::move(aFontLanguage)), + mFontExplicitLanguage(aFontExplicitLanguage), mCanvasStyle(aCanvasStyle), mPresContext(aPresContext) {} @@ -2911,6 +2919,26 @@ class CanvasUserSpaceMetrics : public UserSpaceMetricsWithSize { return GetCSSViewportSizeFromContext(mPresContext); } + float GetLineHeight(Type aType) const override { + // This is used if a filter is added through `url()`, and if the SVG + // filter being referred to is using line-height units. + switch (aType) { + case Type::This: { + const auto wm = GetWritingModeForType(aType); + const auto lh = ReflowInput::CalcLineHeightForCanvas( + mLineHeight, mFont, mFontLanguage, mFontExplicitLanguage, + mPresContext, wm); + return nsPresContext::AppUnitsToFloatCSSPixels(lh); + } + case Type::Root: { + return SVGContentUtils::GetLineHeight( + mPresContext->Document()->GetRootElement()); + } + } + MOZ_ASSERT_UNREACHABLE("Was a new value added to the enumeration?"); + return 1.0f; + } + private: GeckoFontMetrics GetFontMetricsForType(Type aType) const override { switch (aType) { @@ -2946,6 +2974,9 @@ class CanvasUserSpaceMetrics : public UserSpaceMetricsWithSize { gfx::IntSize mSize; const nsFont& mFont; + StyleLineHeight mLineHeight; + RefPtr<nsAtom> mFontLanguage; + bool mFontExplicitLanguage; RefPtr<const ComputedStyle> mCanvasStyle; nsPresContext* mPresContext; }; @@ -3001,8 +3032,10 @@ void CanvasRenderingContext2D::UpdateFilter(bool aFlushIfNeeded) { CurrentState().filter = FilterInstance::GetFilterDescription( mCanvasElement, CurrentState().filterChain.AsSpan(), CurrentState().autoSVGFiltersObserver, writeOnly, - CanvasUserSpaceMetrics(GetSize(), CurrentState().fontFont, canvasStyle, - presContext), + CanvasUserSpaceMetrics( + GetSize(), CurrentState().fontFont, CurrentState().fontLineHeight, + CurrentState().fontLanguage, CurrentState().fontExplicitLanguage, + canvasStyle, presContext), gfxRect(0, 0, mWidth, mHeight), CurrentState().filterAdditionalImages); CurrentState().filterSourceGraphicTainted = writeOnly; } @@ -4043,6 +4076,7 @@ bool CanvasRenderingContext2D::SetFontInternal(const nsACString& aFont, CurrentState().fontFont.size = fontStyle->mSize; CurrentState().fontLanguage = fontStyle->mLanguage; CurrentState().fontExplicitLanguage = fontStyle->mExplicitLanguage; + CurrentState().fontLineHeight = data.mStyle->StyleFont()->mLineHeight; return true; } @@ -4251,6 +4285,8 @@ bool CanvasRenderingContext2D::SetFontInternalDisconnected( CurrentState().fontFont.variantCaps = fontStyle.variantCaps; CurrentState().fontLanguage = nullptr; CurrentState().fontExplicitLanguage = false; + // We don't have any computed style, assume normal height. + CurrentState().fontLineHeight = StyleLineHeight::Normal(); return true; } @@ -5392,6 +5428,10 @@ MaybeGetSurfaceDescriptorForRemoteCanvas( if (subdescType == layers::RemoteDecoderVideoSubDescriptor::Tnull_t) { return sd; } + if (subdescType == layers::RemoteDecoderVideoSubDescriptor:: + TSurfaceDescriptorMacIOSurface) { + return sd; + } } return Nothing(); @@ -5502,9 +5542,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, element = video; } - srcSurf = - CanvasImageCache::LookupCanvas(element, mCanvasElement, mTarget, - &imgSize, &intrinsicImgSize, &cropRect); + srcSurf = CanvasImageCache::LookupCanvas(element, this, mTarget, &imgSize, + &intrinsicImgSize, &cropRect); } DirectDrawInfo drawInfo; @@ -5578,9 +5617,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, if (srcSurf) { if (res.mImageRequest) { - CanvasImageCache::NotifyDrawImage(element, mCanvasElement, mTarget, - srcSurf, imgSize, intrinsicImgSize, - cropRect); + CanvasImageCache::NotifyDrawImage(element, this, mTarget, srcSurf, + imgSize, intrinsicImgSize, cropRect); } } else { drawInfo = res.mDrawInfo; diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index bfcbfccec2..3b25a1235e 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -1051,6 +1051,8 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, gfx::Float letterSpacing = 0.0f; gfx::Float wordSpacing = 0.0f; + mozilla::StyleLineHeight fontLineHeight = + mozilla::StyleLineHeight::Normal(); nsCString letterSpacingStr; nsCString wordSpacingStr; diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index 236ea916d0..5c92ba003d 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -736,6 +736,21 @@ 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<RPROC(SetDrawingBufferColorSpace)>(mDrawingBufferColorSpace); +} + void ClientWebGLContext::GetContextAttributes( dom::Nullable<dom::WebGLContextAttributes>& retval) { retval.SetNull(); @@ -1058,9 +1073,7 @@ 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 e736235361..e870d5860a 100644 --- a/dom/canvas/ClientWebGLContext.h +++ b/dom/canvas/ClientWebGLContext.h @@ -1052,6 +1052,20 @@ 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<dom::WebGLContextAttributes>& retval); private: diff --git a/dom/canvas/HostWebGLContext.h b/dom/canvas/HostWebGLContext.h index 23b836f9db..7d8fe29cd8 100644 --- a/dom/canvas/HostWebGLContext.h +++ b/dom/canvas/HostWebGLContext.h @@ -201,6 +201,9 @@ 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/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp index 28641a1c68..6c479be978 100644 --- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -61,7 +61,8 @@ static ImageBitmapShutdownObserver* sShutdownObserver = nullptr; class SendShutdownToWorkerThread : public MainThreadWorkerControlRunnable { public: explicit SendShutdownToWorkerThread(ImageBitmap* aImageBitmap) - : MainThreadWorkerControlRunnable(GetCurrentThreadWorkerPrivate()), + : MainThreadWorkerControlRunnable("SendShutdownToWorkerThread"), + mWorkerPrivate(GetCurrentThreadWorkerPrivate()), mImageBitmap(aImageBitmap) { MOZ_ASSERT(GetCurrentThreadWorkerPrivate()); } @@ -74,6 +75,7 @@ class SendShutdownToWorkerThread : public MainThreadWorkerControlRunnable { return true; } + WorkerPrivate* mWorkerPrivate; ImageBitmap* mImageBitmap; }; @@ -146,7 +148,7 @@ ImageBitmapShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic, for (const auto& bitmap : mBitmaps) { const auto& runnable = bitmap->mShutdownRunnable; if (runnable) { - runnable->Dispatch(); + runnable->Dispatch(runnable->mWorkerPrivate); } else { bitmap->OnShutdown(); } @@ -1578,8 +1580,7 @@ class FulfillImageBitmapPromiseWorkerTask final public: FulfillImageBitmapPromiseWorkerTask(Promise* aPromise, ImageBitmap* aImageBitmap) - : WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate(), - "FulfillImageBitmapPromiseWorkerTask"), + : WorkerSameThreadRunnable("FulfillImageBitmapPromiseWorkerTask"), FulfillImageBitmapPromise(aPromise, aImageBitmap) {} bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { @@ -1597,7 +1598,8 @@ static void AsyncFulfillImageBitmapPromise(Promise* aPromise, } else { RefPtr<FulfillImageBitmapPromiseWorkerTask> task = new FulfillImageBitmapPromiseWorkerTask(aPromise, aImageBitmap); - task->Dispatch(); // Actually, to the current worker-thread. + task->Dispatch(GetCurrentThreadWorkerPrivate()); // Actually, to the + // current worker-thread. } } @@ -1700,13 +1702,13 @@ class CreateImageBitmapFromBlob final : public DiscardableRunnable, NS_IMPL_ISUPPORTS_INHERITED(CreateImageBitmapFromBlob, DiscardableRunnable, imgIContainerCallback, nsIInputStreamCallback) -class CreateImageBitmapFromBlobRunnable final : public WorkerRunnable { +class CreateImageBitmapFromBlobRunnable final : public WorkerThreadRunnable { public: explicit CreateImageBitmapFromBlobRunnable(WorkerPrivate* aWorkerPrivate, CreateImageBitmapFromBlob* aTask, layers::Image* aImage, nsresult aStatus) - : WorkerRunnable(aWorkerPrivate, "CreateImageBitmapFromBlobRunnable"), + : WorkerThreadRunnable("CreateImageBitmapFromBlobRunnable"), mTask(aTask), mImage(aImage), mStatus(aStatus) {} @@ -2287,7 +2289,7 @@ void CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedMainThread( RefPtr<CreateImageBitmapFromBlobRunnable> r = new CreateImageBitmapFromBlobRunnable(mWorkerRef->Private(), this, aImage, aStatus); - r->Dispatch(); + r->Dispatch(mWorkerRef->Private()); return; } diff --git a/dom/canvas/OffscreenCanvas.cpp b/dom/canvas/OffscreenCanvas.cpp index 208d78daec..1cdccf55ff 100644 --- a/dom/canvas/OffscreenCanvas.cpp +++ b/dom/canvas/OffscreenCanvas.cpp @@ -358,6 +358,21 @@ UniquePtr<OffscreenCanvasCloneData> OffscreenCanvas::ToCloneData( return nullptr; } + // Check if we are using HTMLCanvasElement::captureStream. This is not + // defined by the spec yet, so it is better to fail now than implement + // something not compliant: + // https://github.com/w3c/mediacapture-fromelement/issues/65 + // https://github.com/w3c/mediacapture-extensions/pull/26 + // https://github.com/web-platform-tests/wpt/issues/21102 + if (mDisplay && NS_WARN_IF(mDisplay->UsingElementCaptureStream())) { + ErrorResult rv; + rv.ThrowNotSupportedError( + "Cannot transfer OffscreenCanvas bound to element using " + "captureStream."); + MOZ_ALWAYS_TRUE(rv.MaybeSetPendingException(aCx)); + return nullptr; + } + auto cloneData = MakeUnique<OffscreenCanvasCloneData>( mDisplay, mWidth, mHeight, mCompositorBackendType, mTextureType, mNeutered, mIsWriteOnly, mExpandedReader); diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.cpp b/dom/canvas/OffscreenCanvasDisplayHelper.cpp index 9e1cbb3e75..972fa468d2 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.cpp +++ b/dom/canvas/OffscreenCanvasDisplayHelper.cpp @@ -61,6 +61,22 @@ void OffscreenCanvasDisplayHelper::DestroyCanvas() { mWorkerRef = nullptr; } +bool OffscreenCanvasDisplayHelper::CanElementCaptureStream() const { + MutexAutoLock lock(mMutex); + return !!mWorkerRef; +} + +bool OffscreenCanvasDisplayHelper::UsingElementCaptureStream() const { + MutexAutoLock lock(mMutex); + + if (NS_WARN_IF(!NS_IsMainThread())) { + MOZ_ASSERT_UNREACHABLE("Should not call off main-thread!"); + return !!mCanvasElement; + } + + return mCanvasElement && mCanvasElement->UsingCaptureStream(); +} + CanvasContextType OffscreenCanvasDisplayHelper::GetContextType() const { MutexAutoLock lock(mMutex); return mType; @@ -116,11 +132,11 @@ void OffscreenCanvasDisplayHelper::FlushForDisplay() { return; } - class FlushWorkerRunnable final : public WorkerRunnable { + class FlushWorkerRunnable final : public WorkerThreadRunnable { public: FlushWorkerRunnable(WorkerPrivate* aWorkerPrivate, OffscreenCanvasDisplayHelper* aDisplayHelper) - : WorkerRunnable(aWorkerPrivate, "FlushWorkerRunnable"), + : WorkerThreadRunnable("FlushWorkerRunnable"), mDisplayHelper(aDisplayHelper) {} bool WorkerRun(JSContext*, WorkerPrivate*) override { @@ -148,7 +164,7 @@ void OffscreenCanvasDisplayHelper::FlushForDisplay() { // Otherwise we are calling from the main thread during painting to a canvas // on a worker thread. auto task = MakeRefPtr<FlushWorkerRunnable>(mWorkerRef->Private(), this); - task->Dispatch(); + task->Dispatch(mWorkerRef->Private()); } bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor( @@ -418,7 +434,7 @@ OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() { public: SnapshotWorkerRunnable(WorkerPrivate* aWorkerPrivate, OffscreenCanvasDisplayHelper* aDisplayHelper) - : MainThreadWorkerRunnable(aWorkerPrivate, "SnapshotWorkerRunnable"), + : MainThreadWorkerRunnable("SnapshotWorkerRunnable"), mMonitor("SnapshotWorkerRunnable::mMonitor"), mDisplayHelper(aDisplayHelper) {} @@ -498,7 +514,7 @@ OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() { if (mWorkerRef) { workerRunnable = MakeRefPtr<SnapshotWorkerRunnable>(mWorkerRef->Private(), this); - workerRunnable->Dispatch(); + workerRunnable->Dispatch(mWorkerRef->Private()); } } diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.h b/dom/canvas/OffscreenCanvasDisplayHelper.h index 502d23066a..ae6d23821c 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.h +++ b/dom/canvas/OffscreenCanvasDisplayHelper.h @@ -57,6 +57,9 @@ class OffscreenCanvasDisplayHelper final { void DestroyCanvas(); void DestroyElement(); + bool CanElementCaptureStream() const; + bool UsingElementCaptureStream() const; + already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(); already_AddRefed<mozilla::layers::Image> GetAsImage(); UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aOutFormat, diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 4bd189c46c..669e131bd4 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -894,63 +894,62 @@ void WebGLContext::BlitBackbufferToCurDriverFB( if (mScissorTestEnabled) { gl->fDisable(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 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; - } + const auto cleanup = MakeScopeExit([&]() { + if (mScissorTestEnabled) { + gl->fEnable(LOCAL_GL_SCISSOR_TEST); } + }); - GLuint colorTex = 0; - if (srcAsWebglFb) { - const auto& attach = srcAsWebglFb->ColorAttachment0(); - MOZ_ASSERT(attach.Texture()); - colorTex = attach.Texture()->mGLName; - } else { - colorTex = mozFb->ColorTex(); + // 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 (mDefaultFB->mSamples && + gl->IsExtensionSupported( + gl::GLContext::APPLE_framebuffer_multisample)) { + gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fbo); + gl->fResolveMultisampleFramebufferAPPLE(); + return; + } + } - // DrawBlit handles ColorMask itself. - gl->BlitHelper()->DrawBlitTextureToFramebuffer( - colorTex, size, size, LOCAL_GL_TEXTURE_2D, srcIsBGRA); - }(); - - if (mScissorTestEnabled) { - gl->fEnable(LOCAL_GL_SCISSOR_TEST); + 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); } // - @@ -960,19 +959,34 @@ constexpr auto MakeArray(Args... args) -> std::array<T, sizeof...(Args)> { return {{static_cast<T>(args)...}}; } -inline gfx::ColorSpace2 ToColorSpace2(const WebGLContextOptions& options) { - auto ret = gfx::ColorSpace2::UNKNOWN; - if (true) { - ret = gfx::ColorSpace2::SRGB; - } - if (!options.ignoreColorSpace) { - ret = gfx::ToColorSpace2(options.colorSpace); +inline gfx::ColorSpace2 ToColorSpace2ForOutput( + const std::optional<dom::PredefinedColorSpace> 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; } - return ret; + return gfx::ToColorSpace2(*chosenCspace); } // - +template <class T> +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) { @@ -980,46 +994,100 @@ bool WebGLContext::PresentInto(gl::SwapChain& swapChain) { if (!ValidateAndInitFB(nullptr)) return false; - { - const auto colorSpace = ToColorSpace2(mOptions); - auto presenter = swapChain.Acquire(mDefaultFB->mSize, colorSpace); + const auto size = mDefaultFB->mSize; + + const auto error = [&]() -> std::optional<std::string> { + const auto canvasCspace = ToColorSpace2ForOutput(mOptions.colorSpace); + auto presenter = swapChain.Acquire(size, canvasCspace); if (!presenter) { - GenerateWarning("Swap chain surface creation failed."); - LoseContext(); - return false; + return "Swap chain surface creation failed."; } - + const auto outputCspace = presenter->BackBuffer()->mDesc.colorSpace; const auto destFb = presenter->Fb(); - gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, destFb); - BlitBackbufferToCurDriverFB(); + // - - if (!mOptions.preserveDrawingBuffer) { - if (gl->IsSupported(gl::GLFeature::invalidate_framebuffer)) { - gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, mDefaultFB->mFB); - constexpr auto attachments = MakeArray<GLenum>( - LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT); - gl->fInvalidateFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, - attachments.size(), attachments.data()); - } - mDefaultFB_IsInvalid = true; + 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; } -#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); + auto colorLut = std::shared_ptr<gl::Texture>{}; + if (colorManage) { + MOZ_ASSERT(canvasCspace != gfx::ColorSpace2::Display); + colorLut = gl->BlitHelper()->GetColorLutTex(gl::GLBlitHelper::ColorLutKey{ + .src = canvasCspace, .dst = outputCspace}); + if (!colorLut) { + NS_WARNING("GetColorLutTex() -> nullptr => colorManage = false."); + colorManage = false; } - uint32_t pixel = 0xffbadbad; - gl->fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, - &pixel); - MOZ_ASSERT((pixel & 0xff000000) == 0xff000000); } -#endif + + if (!colorManage) { + gl->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, destFb); + BlitBackbufferToCurDriverFB(); + return {}; + } + + // - + + 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; } return true; @@ -1029,7 +1097,7 @@ bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& fb) { OnEndOfFrame(); - const auto colorSpace = ToColorSpace2(mOptions); + const auto colorSpace = ToColorSpace2ForOutput(mOptions.colorSpace); auto presenter = swapChain.Acquire(fb.mSize, colorSpace); if (!presenter) { GenerateWarning("Swap chain surface creation failed."); @@ -1058,7 +1126,7 @@ bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain, // Initialize a swap chain's surface factory given the desired surface type. void InitSwapChain(gl::GLContext& gl, gl::SwapChain& swapChain, - const layers::TextureType consumerType) { + const layers::TextureType consumerType, bool useAsync) { if (!swapChain.mFactory) { auto typedFactory = gl::SurfaceFactory::Create(&gl, consumerType); if (typedFactory) { @@ -1070,6 +1138,11 @@ void InitSwapChain(gl::GLContext& gl, gl::SwapChain& swapChain, swapChain.mFactory = MakeUnique<gl::SurfaceFactory_Basic>(gl); } MOZ_ASSERT(swapChain.mFactory); + if (useAsync) { + // RemoteTextureMap will handle recycling any surfaces, so don't rely on the + // SwapChain's internal pooling. + swapChain.DisablePool(); + } } void WebGLContext::Present(WebGLFramebuffer* const xrFb, @@ -1090,7 +1163,10 @@ void WebGLContext::Present(WebGLFramebuffer* const xrFb, mResolvedDefaultFB = nullptr; } - InitSwapChain(*gl, *swapChain, consumerType); + bool useAsync = options.remoteTextureOwnerId.IsValid() && + options.remoteTextureId.IsValid(); + + InitSwapChain(*gl, *swapChain, consumerType, useAsync); bool valid = maybeFB ? PresentIntoXR(*swapChain, *maybeFB) : PresentInto(*swapChain); @@ -1099,8 +1175,6 @@ void WebGLContext::Present(WebGLFramebuffer* const xrFb, return; } - bool useAsync = options.remoteTextureOwnerId.IsValid() && - options.remoteTextureId.IsValid(); if (useAsync) { PushRemoteTexture(nullptr, *swapChain, swapChain->FrontBuffer(), options); } @@ -1137,10 +1211,11 @@ bool WebGLContext::CopyToSwapChain( } gfx::IntSize size(info->width, info->height); - InitSwapChain(*gl, srcFb->mSwapChain, consumerType); - bool useAsync = options.remoteTextureOwnerId.IsValid() && options.remoteTextureId.IsValid(); + + InitSwapChain(*gl, srcFb->mSwapChain, consumerType, useAsync); + // If we're using async present and if there is no way to serialize surfaces, // then a readback is required to do the copy. In this case, there's no reason // to copy into a separate shared surface for the front buffer. Just directly @@ -1153,7 +1228,7 @@ bool WebGLContext::CopyToSwapChain( { // ColorSpace will need to be part of SwapChainOptions for DTWebgl. - const auto colorSpace = ToColorSpace2(mOptions); + const auto colorSpace = ToColorSpace2ForOutput(mOptions.colorSpace); auto presenter = srcFb->mSwapChain.Acquire(size, colorSpace); if (!presenter) { GenerateWarning("Swap chain surface creation failed."); @@ -1697,12 +1772,12 @@ bool WebGLContext::BindCurFBForColorRead( return true; } -bool WebGLContext::BindDefaultFBForRead() { - if (!ValidateAndInitFB(nullptr)) return false; +const gl::MozFramebuffer* WebGLContext::GetDefaultFBForRead( + const GetDefaultFBForReadDesc& desc) { + if (!ValidateAndInitFB(nullptr)) return nullptr; if (!mDefaultFB->mSamples) { - gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mDefaultFB->mFB); - return true; + return mDefaultFB.get(); } if (!mResolvedDefaultFB) { @@ -1710,14 +1785,24 @@ bool WebGLContext::BindDefaultFBForRead() { gl::MozFramebuffer::Create(gl, mDefaultFB->mSize, 0, false); if (!mResolvedDefaultFB) { gfxCriticalNote << FuncName() << ": Failed to create mResolvedDefaultFB."; - return false; + return nullptr; } } - gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mResolvedDefaultFB->mFB); + gl->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, mResolvedDefaultFB->mFB); BlitBackbufferToCurDriverFB(); - gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mResolvedDefaultFB->mFB); + 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); return true; } @@ -2351,7 +2436,7 @@ webgl::LinkActiveInfo GetLinkActiveInfo( ret.activeUniforms.push_back(std::move(info)); } // for i - } // anon + } // anon if (webgl2) { // ------------------------------------- @@ -2397,7 +2482,7 @@ webgl::LinkActiveInfo GetLinkActiveInfo( ret.activeUniformBlocks.push_back(std::move(info)); } // for i - } // anon + } // anon // ------------------------------------- // active tf varyings @@ -2661,4 +2746,21 @@ webgl::ExplicitPixelPackingState::ForUseWith( return {{state, metrics}}; } +GLuint WebGLContext::SamplerLinear() const { + if (!mSamplerLinear) { + mSamplerLinear = std::make_unique<gl::Sampler>(*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 d144584f4f..69cff4e7dd 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -10,6 +10,7 @@ #include <memory> #include <stdarg.h> +#include "Colorspaces.h" #include "GLContextTypes.h" #include "GLDefs.h" #include "GLScreenBuffer.h" @@ -96,6 +97,7 @@ namespace gl { class GLScreenBuffer; class MozFramebuffer; class SharedSurface; +class Sampler; class Texture; } // namespace gl @@ -536,6 +538,12 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebuffer*, const bool webvr); + std::optional<color::ColorProfileDesc> mDisplayProfile; + + void SetDrawingBufferColorSpace(const dom::PredefinedColorSpace val) { + mOptions.colorSpace = val; + } + void ClearVRSwapChain(); void RunContextLossTimer(); @@ -1156,6 +1164,10 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { nsTArray<RefPtr<WebGLTexture>> mBound2DArrayTextures; nsTArray<RefPtr<WebGLSampler>> mBoundSamplers; + mutable std::unique_ptr<gl::Sampler> mSamplerLinear; + + GLuint SamplerLinear() const; + void ResolveTexturesForDraw() const; RefPtr<WebGLProgram> mCurrentProgram; @@ -1265,6 +1277,10 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { mutable bool mDefaultFB_IsInvalid = false; mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB; + mutable std::unordered_map<std::tuple<gfx::ColorSpace2, gfx::ColorSpace2>, + std::shared_ptr<gl::Texture>> + mLutTexByColorMapping; + gl::SwapChain mSwapChain; gl::SwapChain mWebVRSwapChain; @@ -1303,6 +1319,15 @@ 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 e65533ec94..2bc56f4b05 100644 --- a/dom/canvas/WebGLContextTextures.cpp +++ b/dom/canvas/WebGLContextTextures.cpp @@ -96,7 +96,7 @@ void WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex) { return; } - const TexTarget texTarget(rawTarget); + const auto texTarget = TexTarget(rawTarget); if (newTex) { if (!newTex->BindTexture(texTarget)) return; } else { diff --git a/dom/canvas/WebGLIpdl.h b/dom/canvas/WebGLIpdl.h index 45a5c5ad64..4c81393b70 100644 --- a/dom/canvas/WebGLIpdl.h +++ b/dom/canvas/WebGLIpdl.h @@ -18,6 +18,8 @@ #include "TupleUtils.h" #include "WebGLTypes.h" +#include <memory> + namespace mozilla { namespace webgl { @@ -652,6 +654,32 @@ struct ParamTraits<mozilla::avec3<U>> final { } }; +// - + +template <class U> +struct ParamTraits<std::optional<U>> final { + using T = std::optional<U>; + + 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 4bf67deb08..e55b19d0b4 100644 --- a/dom/canvas/WebGLMethodDispatcher.h +++ b/dom/canvas/WebGLMethodDispatcher.h @@ -93,6 +93,7 @@ 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 3c74f08750..136316433f 100644 --- a/dom/canvas/WebGLQueueParamTraits.h +++ b/dom/canvas/WebGLQueueParamTraits.h @@ -61,25 +61,6 @@ struct QueueParamTraits<avec3<T>> : QueueParamTraits_TiedFields<avec3<T>> {}; // --------------------------------------------------------------------- // 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: @@ -91,16 +72,14 @@ inline constexpr bool IsEnumCase(const webgl::AttribBaseType raw) { return false; } -static_assert(IsEnumCase(dom::WebGLPowerPreference(2))); -static_assert(!IsEnumCase(dom::WebGLPowerPreference(3))); -static_assert(!IsEnumCase(dom::WebGLPowerPreference(5))); +static_assert(IsEnumCase(webgl::AttribBaseType(3))); +static_assert(!IsEnumCase(webgl::AttribBaseType(4))); +static_assert(!IsEnumCase(webgl::AttribBaseType(5))); #define USE_IS_ENUM_CASE(T) \ template <> \ struct QueueParamTraits<T> : QueueParamTraits_IsEnumCase<T> {}; -USE_IS_ENUM_CASE(dom::WebGLPowerPreference) -USE_IS_ENUM_CASE(dom::PredefinedColorSpace) USE_IS_ENUM_CASE(webgl::AttribBaseType) USE_IS_ENUM_CASE(webgl::ProvokingVertex) @@ -283,6 +262,20 @@ struct QueueParamTraits<gfxAlphaType> : public ContiguousEnumSerializerInclusive< gfxAlphaType, gfxAlphaType::Opaque, gfxAlphaType::NonPremult> {}; +// - + +template <class Enum> +using WebIDLEnumQueueSerializer = + ContiguousEnumSerializerInclusive<Enum, ContiguousEnumValues<Enum>::min, + ContiguousEnumValues<Enum>::max>; + +template <> +struct QueueParamTraits<dom::WebGLPowerPreference> + : public WebIDLEnumQueueSerializer<dom::WebGLPowerPreference> {}; +template <> +struct QueueParamTraits<dom::PredefinedColorSpace> + : public WebIDLEnumQueueSerializer<dom::PredefinedColorSpace> {}; + } // namespace webgl } // namespace mozilla diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index f5f78e98cb..2f1d9331a7 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -362,8 +362,7 @@ struct WebGLContextOptions final { dom::WebGLPowerPreference powerPreference = dom::WebGLPowerPreference::Default; - bool ignoreColorSpace = true; - dom::PredefinedColorSpace colorSpace = dom::PredefinedColorSpace::Srgb; + std::optional<dom::PredefinedColorSpace> colorSpace; bool shouldResistFingerprinting = true; bool enableDebugRendererInfo = false; @@ -383,7 +382,6 @@ struct WebGLContextOptions final { powerPreference, colorSpace, - ignoreColorSpace, shouldResistFingerprinting, enableDebugRendererInfo); diff --git a/dom/canvas/crashtests/crashtests.list b/dom/canvas/crashtests/crashtests.list index e1920b20ee..725e7ed92b 100644 --- a/dom/canvas/crashtests/crashtests.list +++ b/dom/canvas/crashtests/crashtests.list @@ -16,7 +16,7 @@ skip-if(ThreadSanitizer) load 780392-1.html skip-if(ThreadSanitizer) skip-if(gtkWidget&&isDebugBuild) skip-if(winWidget&&(!is64Bit)) load 789933-1.html # bug 1155252 for linux skip-if(ThreadSanitizer) load 794463-1.html skip-if(ThreadSanitizer) load 802926-1.html -skip-if(wayland) skip-if(ThreadSanitizer) load 844280.html # wayland: bug 1856365, intermittent OOMs on Win7 debug +skip-if(ThreadSanitizer) load 844280.html load 896047-1.html load 916128-1.html load 934939-1.html diff --git a/dom/canvas/test/reftest/colors/_generated_reftest.list b/dom/canvas/test/reftest/colors/_generated_reftest.list index 29761e3df8..df5fa98847 100644 --- a/dom/canvas/test/reftest/colors/_generated_reftest.list +++ b/dom/canvas/test/reftest/colors/_generated_reftest.list @@ -17,160 +17,217 @@ 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) - ### 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) - ### 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) - ### 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) - ### 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) - ### 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) - ### 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) - ### 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) - ### 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) == 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) 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) - ### 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) - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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. ### - == 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":"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":"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":"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":"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":"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":"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":"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":"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":"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) +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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) + ### 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) diff --git a/dom/canvas/test/reftest/colors/color_canvas.html b/dom/canvas/test/reftest/colors/color_canvas.html index 7abbc86255..53314f2714 100644 --- a/dom/canvas/test/reftest/colors/color_canvas.html +++ b/dom/canvas/test/reftest/colors/color_canvas.html @@ -29,6 +29,7 @@ <option value=css selected>css</option> <option value=2d>2d</option> <option value=webgl>webgl</option> + <option value=webgl2>webgl2</option> </select> <br> Options: <input id=e_options type=text value={}> 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 8c1e5f3788..ad04d9a524 100644 --- a/dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py +++ b/dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py @@ -120,9 +120,8 @@ WEBGL_FORMATS = keyed_alternatives( #'RGBA16F', ], ) -WEBGL = cross_combine( - [{"e_context": "webgl"}], WEBGL_FORMATS, CANVAS_CSPACES, WEBGL_COLORS -) +WEBGL_VERSIONS = keyed_alternatives("e_context", ["webgl", "webgl2"]) +WEBGL = cross_combine(WEBGL_VERSIONS, WEBGL_FORMATS, CANVAS_CSPACES, WEBGL_COLORS) # - @@ -212,7 +211,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"] == "webgl": + if test_config["e_context"].startswith("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 @@ -231,12 +230,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"] == "2d": + if test_config["e_context"] in ["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"] == "webgl", test_config["e_context"] + assert test_config["e_context"].startswith("webgl"), test_config["e_context"] # - @@ -249,6 +248,11 @@ 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) @@ -261,12 +265,26 @@ 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) - # 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 - ) + 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"] # - @@ -279,7 +297,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"] == "webgl" + and reftest.test_config["e_context"].startswith("webgl") and reftest.test_config["e_cspace"] == "display-p3" and is_green_only ): |