Bug 1848875 - Throw InvalidStateError when cloning OffscreenCanvas with context. r=gfx-reviewers,lsalzman

This patch makes us follow the standard and pass WPT tests regarding the
cloning of OffscreenCanvas with a context. It also makes us throw a less
generic message when attempting to clone an OffscreenCanvas that has
already been cloned/transferred to a worker.

Differential Revision: https://phabricator.services.mozilla.com/D186265
This commit is contained in:
Andrew Osmond 2023-08-16 12:06:34 +00:00
parent a7398fe592
commit 518cc7ad58
5 changed files with 28 additions and 19 deletions

View File

@ -1472,16 +1472,17 @@ StructuredCloneHolder::CustomWriteTransferHandler(
if (NS_SUCCEEDED(rv)) {
MOZ_ASSERT(canvas);
if (!canvas->MayNeuter()) {
UniquePtr<OffscreenCanvasCloneData> clonedCanvas =
canvas->ToCloneData(aCx);
if (!clonedCanvas) {
return false;
}
*aExtraData = 0;
*aTag = SCTAG_DOM_CANVAS;
*aContent = canvas->ToCloneData();
*aContent = clonedCanvas.release();
MOZ_ASSERT(*aContent);
*aOwnership = JS::SCTAG_TMO_CUSTOM;
canvas->SetNeutered();
return true;
}

View File

@ -305,10 +305,28 @@ void OffscreenCanvas::CommitFrameToCompositor() {
mDisplay->CommitFrameToCompositor(mCurrentContext, mTextureType, update);
}
OffscreenCanvasCloneData* OffscreenCanvas::ToCloneData() {
return new OffscreenCanvasCloneData(mDisplay, mWidth, mHeight,
mCompositorBackendType, mTextureType,
mNeutered, mIsWriteOnly, mExpandedReader);
UniquePtr<OffscreenCanvasCloneData> OffscreenCanvas::ToCloneData(
JSContext* aCx) {
if (NS_WARN_IF(mNeutered)) {
ErrorResult rv;
rv.ThrowDataCloneError(
"Cannot clone placeholder canvas that is already transferred.");
MOZ_ALWAYS_TRUE(rv.MaybeSetPendingException(aCx));
return nullptr;
}
if (NS_WARN_IF(mCurrentContext)) {
ErrorResult rv;
rv.ThrowInvalidStateError("Cannot clone canvas with context.");
MOZ_ALWAYS_TRUE(rv.MaybeSetPendingException(aCx));
return nullptr;
}
auto cloneData = MakeUnique<OffscreenCanvasCloneData>(
mDisplay, mWidth, mHeight, mCompositorBackendType, mTextureType,
mNeutered, mIsWriteOnly, mExpandedReader);
SetNeutered();
return cloneData;
}
already_AddRefed<ImageBitmap> OffscreenCanvas::TransferToImageBitmap(

View File

@ -15,6 +15,7 @@
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsCycleCollectionParticipant.h"
struct JSContext;
@ -124,7 +125,7 @@ class OffscreenCanvas final : public DOMEventTargetHelper,
// on worker thread.
static bool PrefEnabledOnWorkerThread(JSContext* aCx, JSObject* aObj);
OffscreenCanvasCloneData* ToCloneData();
UniquePtr<OffscreenCanvasCloneData> ToCloneData(JSContext* aCx);
void UpdateDisplayData(const OffscreenCanvasDisplayData& aData);

View File

@ -1,3 +0,0 @@
[offscreencanvas.transferrable.html]
[Test that transfer an OffscreenCanvas that already have a 2d context throws exception.]
expected: FAIL

View File

@ -1,8 +0,0 @@
[offscreencanvas.transferrable.w.html]
expected:
if (os == "linux") and not debug and fission: [OK, CRASH]
[Test that transfer an OffscreenCanvas that has a webgl context throws exception in a worker.]
expected: FAIL
[Test that transfer an OffscreenCanvas that has a 2d context throws exception in a worker.]
expected: FAIL