Bug 1215438 - Part 2: Add transfer support for ImageBitmap. r=baku

--HG--
extra : commitid : 79U2wpZIJ6W
This commit is contained in:
Morris Tseng 2015-12-18 14:52:16 +08:00
parent 0d4ac3243e
commit 8181a0e4ec
3 changed files with 60 additions and 10 deletions

View File

@ -28,6 +28,7 @@
#include "mozilla/dom/SubtleCryptoBinding.h" #include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/ToJSValue.h" #include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/WebCryptoCommon.h" #include "mozilla/dom/WebCryptoCommon.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundUtils.h" #include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h" #include "mozilla/ipc/PBackgroundSharedTypes.h"
@ -306,7 +307,7 @@ StructuredCloneHolder::Read(nsISupports* aParent,
// If we are tranferring something, we cannot call 'Read()' more than once. // If we are tranferring something, we cannot call 'Read()' more than once.
if (mSupportsTransferring) { if (mSupportsTransferring) {
mBlobImplArray.Clear(); mBlobImplArray.Clear();
mClonedImages.Clear(); mClonedSurfaces.Clear();
Clear(); Clear();
} }
} }
@ -976,7 +977,7 @@ StructuredCloneHolder::CustomReadHandler(JSContext* aCx,
nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(mParent); nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(mParent);
// aIndex is the index of the cloned image. // aIndex is the index of the cloned image.
return ImageBitmap::ReadStructuredClone(aCx, aReader, return ImageBitmap::ReadStructuredClone(aCx, aReader,
parent, GetImages(), aIndex); parent, GetSurfaces(), aIndex);
} }
return ReadFullySerializableObjects(aCx, aReader, aTag); return ReadFullySerializableObjects(aCx, aReader, aTag);
@ -1021,7 +1022,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
ImageBitmap* imageBitmap = nullptr; ImageBitmap* imageBitmap = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, aObj, imageBitmap))) { if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, aObj, imageBitmap))) {
return ImageBitmap::WriteStructuredClone(aWriter, return ImageBitmap::WriteStructuredClone(aWriter,
GetImages(), GetSurfaces(),
imageBitmap); imageBitmap);
} }
} }
@ -1085,6 +1086,26 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx,
return true; return true;
} }
if (aTag == SCTAG_DOM_IMAGEBITMAP) {
MOZ_ASSERT(mSupportedContext == SameProcessSameThread ||
mSupportedContext == SameProcessDifferentThread);
MOZ_ASSERT(aContent);
ImageBitmapCloneData* data =
static_cast<ImageBitmapCloneData*>(aContent);
nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(mParent);
RefPtr<ImageBitmap> bitmap = ImageBitmap::CreateFromCloneData(parent, data);
delete data;
JS::Rooted<JS::Value> value(aCx);
if (!GetOrCreateDOMReflector(aCx, bitmap, &value)) {
JS_ClearPendingException(aCx);
return false;
}
aReturnObject.set(&value.toObject());
return true;
}
return false; return false;
} }
@ -1133,6 +1154,21 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
return true; return true;
} }
ImageBitmap* bitmap = nullptr;
rv = UNWRAP_OBJECT(ImageBitmap, aObj, bitmap);
if (NS_SUCCEEDED(rv)) {
MOZ_ASSERT(bitmap);
*aExtraData = 0;
*aTag = SCTAG_DOM_IMAGEBITMAP;
*aOwnership = JS::SCTAG_TMO_CUSTOM;
*aContent = bitmap->ToCloneData();
MOZ_ASSERT(*aContent);
bitmap->Close();
return true;
}
} }
} }
@ -1163,6 +1199,16 @@ StructuredCloneHolder::CustomFreeTransferHandler(uint32_t aTag,
delete data; delete data;
return; return;
} }
if (aTag == SCTAG_DOM_IMAGEBITMAP) {
MOZ_ASSERT(mSupportedContext == SameProcessSameThread ||
mSupportedContext == SameProcessDifferentThread);
MOZ_ASSERT(aContent);
ImageBitmapCloneData* data =
static_cast<ImageBitmapCloneData*>(aContent);
delete data;
return;
}
} }
} // dom namespace } // dom namespace

View File

@ -22,6 +22,10 @@ namespace layers {
class Image; class Image;
} }
namespace gfx {
class DataSourceSurface;
}
namespace dom { namespace dom {
class StructuredCloneHolderBase class StructuredCloneHolderBase
@ -181,7 +185,7 @@ public:
bool HasClonedDOMObjects() const bool HasClonedDOMObjects() const
{ {
return !mBlobImplArray.IsEmpty() || return !mBlobImplArray.IsEmpty() ||
!mClonedImages.IsEmpty(); !mClonedSurfaces.IsEmpty();
} }
nsTArray<RefPtr<BlobImpl>>& BlobImpls() nsTArray<RefPtr<BlobImpl>>& BlobImpls()
@ -212,9 +216,9 @@ public:
return mPortIdentifiers; return mPortIdentifiers;
} }
nsTArray<RefPtr<layers::Image>>& GetImages() nsTArray<RefPtr<gfx::DataSourceSurface>>& GetSurfaces()
{ {
return mClonedImages; return mClonedSurfaces;
} }
// Implementations of the virtual methods to allow cloning of objects which // Implementations of the virtual methods to allow cloning of objects which
@ -291,10 +295,10 @@ protected:
nsTArray<RefPtr<BlobImpl>> mBlobImplArray; nsTArray<RefPtr<BlobImpl>> mBlobImplArray;
// This is used for sharing the backend of ImageBitmaps. // This is used for sharing the backend of ImageBitmaps.
// The layers::Image object must be thread-safely reference-counted. // The DataSourceSurface object must be thread-safely reference-counted.
// The layers::Image object will not be written ever via any ImageBitmap // The DataSourceSurface object will not be written ever via any ImageBitmap
// instance, so no race condition will occur. // instance, so no race condition will occur.
nsTArray<RefPtr<layers::Image>> mClonedImages; nsTArray<RefPtr<gfx::DataSourceSurface>> mClonedSurfaces;
// This raw pointer is only set within ::Read() and is unset by the end. // This raw pointer is only set within ::Read() and is unset by the end.
nsISupports* MOZ_NON_OWNING_REF mParent; nsISupports* MOZ_NON_OWNING_REF mParent;

View File

@ -44,7 +44,7 @@ StructuredCloneData::Copy(const StructuredCloneData& aData)
MOZ_ASSERT(BlobImpls().IsEmpty()); MOZ_ASSERT(BlobImpls().IsEmpty());
BlobImpls().AppendElements(aData.BlobImpls()); BlobImpls().AppendElements(aData.BlobImpls());
MOZ_ASSERT(GetImages().IsEmpty()); MOZ_ASSERT(GetSurfaces().IsEmpty());
return true; return true;
} }