зеркало из https://github.com/mozilla/gecko-dev.git
Bug 709490 - Part 3: Transfer OffscreenCanvas from mainthread to workers. r=baku, r=sfink
Thanks Jon Morton [:jmorton] (jonanin@gmail.com) for polishing patches. --HG-- extra : rebase_source : 5cbf8b9f53b7d1978c6371dbdb3771f80b94a171
This commit is contained in:
Родитель
d5147a9b2a
Коммит
6c0c249c5a
|
@ -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"
|
||||
|
@ -1014,6 +1016,25 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_CANVAS) {
|
||||
MOZ_ASSERT(mSupportedContext == SameProcessSameThread ||
|
||||
mSupportedContext == 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;
|
||||
}
|
||||
|
||||
|
@ -1045,6 +1066,24 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mSupportedContext == SameProcessSameThread ||
|
||||
mSupportedContext == 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;
|
||||
|
@ -1062,6 +1101,17 @@ StructuredCloneHolder::CustomFreeTransferHandler(uint32_t aTag,
|
|||
MOZ_ASSERT(!aContent);
|
||||
MOZ_ASSERT(aExtraData < mPortIdentifiers.Length());
|
||||
MessagePort::ForceClose(mPortIdentifiers[aExtraData]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_CANVAS) {
|
||||
MOZ_ASSERT(mSupportedContext == SameProcessSameThread ||
|
||||
mSupportedContext == 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
|
||||
|
|
|
@ -2049,7 +2049,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&
|
||||
|
@ -2058,7 +2058,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;
|
||||
}
|
||||
|
||||
|
@ -2083,7 +2083,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_))
|
||||
|
@ -2099,31 +2101,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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче