mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 709490 - Part 3: Transfer OffscreenCanvas from mainthread to workers., r=baku, r=sfink
This commit is contained in:
parent
6c5f27cc66
commit
d0af7852c8
@ -21,6 +21,8 @@
|
||||
#include "mozilla/dom/StructuredClone.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/MessagePortBinding.h"
|
||||
#include "mozilla/dom/OffscreenCanvas.h"
|
||||
#include "mozilla/dom/OffscreenCanvasBinding.h"
|
||||
#include "mozilla/dom/PMessagePort.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/SubtleCryptoBinding.h"
|
||||
@ -1062,6 +1064,25 @@ StructuredCloneHelper::ReadTransferCallback(JSContext* aCx,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_CANVAS) {
|
||||
MOZ_ASSERT(mContext == SameProcessSameThread ||
|
||||
mContext == SameProcessDifferentThread);
|
||||
MOZ_ASSERT(aContent);
|
||||
OffscreenCanvasCloneData* data =
|
||||
static_cast<OffscreenCanvasCloneData*>(aContent);
|
||||
nsRefPtr<OffscreenCanvas> canvas = OffscreenCanvas::CreateFromCloneData(data);
|
||||
delete data;
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!GetOrCreateDOMReflector(aCx, canvas, &value)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
return false;
|
||||
}
|
||||
|
||||
aReturnObject.set(&value.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1093,6 +1114,24 @@ StructuredCloneHelper::WriteTransferCallback(JSContext* aCx,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mContext == SameProcessSameThread ||
|
||||
mContext == SameProcessDifferentThread) {
|
||||
OffscreenCanvas* canvas = nullptr;
|
||||
rv = UNWRAP_OBJECT(OffscreenCanvas, aObj, canvas);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_ASSERT(canvas);
|
||||
|
||||
*aExtraData = 0;
|
||||
*aTag = SCTAG_DOM_CANVAS;
|
||||
*aOwnership = JS::SCTAG_TMO_CUSTOM;
|
||||
*aContent = canvas->ToCloneData();
|
||||
MOZ_ASSERT(*aContent);
|
||||
canvas->SetNeutered();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1110,6 +1149,17 @@ StructuredCloneHelper::FreeTransferCallback(uint32_t aTag,
|
||||
MOZ_ASSERT(!aContent);
|
||||
MOZ_ASSERT(aExtraData < mPortIdentifiers.Length());
|
||||
MessagePort::ForceClose(mPortIdentifiers[aExtraData]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_CANVAS) {
|
||||
MOZ_ASSERT(mContext == SameProcessSameThread ||
|
||||
mContext == SameProcessDifferentThread);
|
||||
MOZ_ASSERT(aContent);
|
||||
OffscreenCanvasCloneData* data =
|
||||
static_cast<OffscreenCanvasCloneData*>(aContent);
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,9 @@ enum StructuredCloneTags {
|
||||
|
||||
SCTAG_DOM_FORMDATA,
|
||||
|
||||
// This tag is for OffscreenCanvas.
|
||||
SCTAG_DOM_CANVAS,
|
||||
|
||||
SCTAG_DOM_MAX
|
||||
};
|
||||
|
||||
|
@ -195,17 +195,20 @@ class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
|
||||
void clear(const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr);
|
||||
|
||||
// Copy some memory. It will be automatically freed by the destructor.
|
||||
bool copy(const uint64_t* data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION);
|
||||
bool copy(const uint64_t* data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION,
|
||||
const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr);
|
||||
|
||||
// Adopt some memory. It will be automatically freed by the destructor.
|
||||
// data must have been allocated by the JS engine (e.g., extracted via
|
||||
// JSAutoStructuredCloneBuffer::steal).
|
||||
void adopt(uint64_t* data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION);
|
||||
void adopt(uint64_t* data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION,
|
||||
const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr);
|
||||
|
||||
// Release the buffer and transfer ownership to the caller. The caller is
|
||||
// responsible for calling JS_ClearStructuredClone or feeding the memory
|
||||
// back to JSAutoStructuredCloneBuffer::adopt.
|
||||
void steal(uint64_t** datap, size_t* nbytesp, uint32_t* versionp=nullptr);
|
||||
void steal(uint64_t** datap, size_t* nbytesp, uint32_t* versionp=nullptr,
|
||||
const JSStructuredCloneCallbacks** callbacks=nullptr, void** closure=nullptr);
|
||||
|
||||
// Abandon ownership of any transferable objects stored in the buffer,
|
||||
// without freeing the buffer itself. Useful when copying the data out into
|
||||
|
@ -2054,7 +2054,7 @@ JS_StructuredClone(JSContext* cx, HandleValue value, MutableHandleValue vp,
|
||||
JSAutoStructuredCloneBuffer::JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer&& other)
|
||||
{
|
||||
ownTransferables_ = other.ownTransferables_;
|
||||
other.steal(&data_, &nbytes_, &version_);
|
||||
other.steal(&data_, &nbytes_, &version_, &callbacks_, &closure_);
|
||||
}
|
||||
|
||||
JSAutoStructuredCloneBuffer&
|
||||
@ -2063,7 +2063,7 @@ JSAutoStructuredCloneBuffer::operator=(JSAutoStructuredCloneBuffer&& other)
|
||||
MOZ_ASSERT(&other != this);
|
||||
clear();
|
||||
ownTransferables_ = other.ownTransferables_;
|
||||
other.steal(&data_, &nbytes_, &version_);
|
||||
other.steal(&data_, &nbytes_, &version_, &callbacks_, &closure_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -2088,7 +2088,9 @@ JSAutoStructuredCloneBuffer::clear(const JSStructuredCloneCallbacks* optionalCal
|
||||
}
|
||||
|
||||
bool
|
||||
JSAutoStructuredCloneBuffer::copy(const uint64_t* srcData, size_t nbytes, uint32_t version)
|
||||
JSAutoStructuredCloneBuffer::copy(const uint64_t* srcData, size_t nbytes, uint32_t version,
|
||||
const JSStructuredCloneCallbacks* callbacks,
|
||||
void* closure)
|
||||
{
|
||||
// transferable objects cannot be copied
|
||||
if (StructuredCloneHasTransferObjects(data_, nbytes_))
|
||||
@ -2104,31 +2106,45 @@ JSAutoStructuredCloneBuffer::copy(const uint64_t* srcData, size_t nbytes, uint32
|
||||
data_ = newData;
|
||||
nbytes_ = nbytes;
|
||||
version_ = version;
|
||||
callbacks_ = callbacks;
|
||||
closure_ = closure;
|
||||
ownTransferables_ = NoTransferables;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
JSAutoStructuredCloneBuffer::adopt(uint64_t* data, size_t nbytes, uint32_t version)
|
||||
JSAutoStructuredCloneBuffer::adopt(uint64_t* data, size_t nbytes, uint32_t version,
|
||||
const JSStructuredCloneCallbacks* callbacks,
|
||||
void* closure)
|
||||
{
|
||||
clear();
|
||||
data_ = data;
|
||||
nbytes_ = nbytes;
|
||||
version_ = version;
|
||||
callbacks_ = callbacks;
|
||||
closure_ = closure;
|
||||
ownTransferables_ = OwnsTransferablesIfAny;
|
||||
}
|
||||
|
||||
void
|
||||
JSAutoStructuredCloneBuffer::steal(uint64_t** datap, size_t* nbytesp, uint32_t* versionp)
|
||||
JSAutoStructuredCloneBuffer::steal(uint64_t** datap, size_t* nbytesp, uint32_t* versionp,
|
||||
const JSStructuredCloneCallbacks** callbacks,
|
||||
void** closure)
|
||||
{
|
||||
*datap = data_;
|
||||
*nbytesp = nbytes_;
|
||||
if (versionp)
|
||||
*versionp = version_;
|
||||
if (callbacks)
|
||||
*callbacks = callbacks_;
|
||||
if (closure)
|
||||
*closure = closure_;
|
||||
|
||||
data_ = nullptr;
|
||||
nbytes_ = 0;
|
||||
version_ = 0;
|
||||
callbacks_ = 0;
|
||||
closure_ = 0;
|
||||
ownTransferables_ = NoTransferables;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user