summaryrefslogtreecommitdiffstats
path: root/dom/canvas
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
commita90a5cba08fdf6c0ceb95101c275108a152a3aed (patch)
tree532507288f3defd7f4dcf1af49698bcb76034855 /dom/canvas
parentAdding debian version 126.0.1-1. (diff)
downloadfirefox-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')
-rw-r--r--dom/canvas/CanvasImageCache.cpp64
-rw-r--r--dom/canvas/CanvasImageCache.h15
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp54
-rw-r--r--dom/canvas/CanvasRenderingContext2D.h2
-rw-r--r--dom/canvas/ClientWebGLContext.cpp17
-rw-r--r--dom/canvas/ClientWebGLContext.h14
-rw-r--r--dom/canvas/HostWebGLContext.h3
-rw-r--r--dom/canvas/ImageBitmap.cpp18
-rw-r--r--dom/canvas/OffscreenCanvas.cpp15
-rw-r--r--dom/canvas/OffscreenCanvasDisplayHelper.cpp26
-rw-r--r--dom/canvas/OffscreenCanvasDisplayHelper.h3
-rw-r--r--dom/canvas/WebGLContext.cpp318
-rw-r--r--dom/canvas/WebGLContext.h25
-rw-r--r--dom/canvas/WebGLContextTextures.cpp2
-rw-r--r--dom/canvas/WebGLIpdl.h28
-rw-r--r--dom/canvas/WebGLMethodDispatcher.h1
-rw-r--r--dom/canvas/WebGLQueueParamTraits.h41
-rw-r--r--dom/canvas/WebGLTypes.h4
-rw-r--r--dom/canvas/crashtests/crashtests.list2
-rw-r--r--dom/canvas/test/reftest/colors/_generated_reftest.list371
-rw-r--r--dom/canvas/test/reftest/colors/color_canvas.html1
-rw-r--r--dom/canvas/test/reftest/colors/generate_color_canvas_reftests.py44
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
):