mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1275398 - Use shmem for sending image data in IPCDataTransfer. r=nical
MozReview-Commit-ID: 9XETnSBXxEW
This commit is contained in:
parent
3115f628a1
commit
28706c5d87
@ -7343,7 +7343,7 @@ nsresult
|
||||
nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
|
||||
imgIContainer** aContainer)
|
||||
{
|
||||
MOZ_ASSERT(aItem.data().type() == IPCDataTransferData::TnsCString);
|
||||
MOZ_ASSERT(aItem.data().type() == IPCDataTransferData::TShmem);
|
||||
MOZ_ASSERT(IsFlavorImage(aItem.flavor()));
|
||||
|
||||
const IPCDataTransferImage& imageDetails = aItem.imageDetails();
|
||||
@ -7352,12 +7352,12 @@ nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const nsCString& text = aItem.data().get_nsCString();
|
||||
Shmem data = aItem.data().get_Shmem();
|
||||
|
||||
RefPtr<DataSourceSurface> image =
|
||||
CreateDataSourceSurfaceFromData(size,
|
||||
static_cast<SurfaceFormat>(imageDetails.format()),
|
||||
reinterpret_cast<const uint8_t*>(text.BeginReading()),
|
||||
data.get<uint8_t>(),
|
||||
imageDetails.stride());
|
||||
|
||||
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(image, size);
|
||||
@ -7378,6 +7378,31 @@ nsContentUtils::IsFlavorImage(const nsACString& aFlavor)
|
||||
aFlavor.EqualsLiteral(kGIFImageMime);
|
||||
}
|
||||
|
||||
static Shmem
|
||||
ConvertToShmem(mozilla::dom::nsIContentChild* aChild,
|
||||
mozilla::dom::nsIContentParent* aParent,
|
||||
const nsACString& aInput)
|
||||
{
|
||||
MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
|
||||
|
||||
IShmemAllocator* allocator =
|
||||
aChild ? static_cast<IShmemAllocator*>(aChild)
|
||||
: static_cast<IShmemAllocator*>(aParent);
|
||||
|
||||
Shmem result;
|
||||
if (!allocator->AllocShmem(aInput.Length() + 1,
|
||||
SharedMemory::TYPE_BASIC,
|
||||
&result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(result.get<char>(),
|
||||
aInput.BeginReading(),
|
||||
aInput.Length() + 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
IPCDataTransfer* aIPCDataTransfer,
|
||||
@ -7422,7 +7447,13 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
ctext->GetData(dataAsString);
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = dataAsString;
|
||||
|
||||
Shmem dataAsShmem = ConvertToShmem(aChild, aParent, dataAsString);
|
||||
if (!dataAsShmem.IsReadable() || !dataAsShmem.Size<char>()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item->data() = dataAsShmem;
|
||||
} else {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> sip =
|
||||
do_QueryInterface(data);
|
||||
@ -7438,7 +7469,13 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
|
||||
nsCString imageData;
|
||||
NS_ConsumeStream(stream, UINT32_MAX, imageData);
|
||||
item->data() = imageData;
|
||||
|
||||
Shmem imageDataShmem = ConvertToShmem(aChild, aParent, imageData);
|
||||
if (!imageDataShmem.IsReadable() || !imageDataShmem.Size<char>()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item->data() = imageDataShmem;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -7458,15 +7495,17 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
}
|
||||
size_t length;
|
||||
int32_t stride;
|
||||
mozilla::UniquePtr<char[]> surfaceData =
|
||||
nsContentUtils::GetSurfaceData(WrapNotNull(dataSurface), &length,
|
||||
&stride);
|
||||
Shmem surfaceData;
|
||||
IShmemAllocator* allocator = aChild ? static_cast<IShmemAllocator*>(aChild)
|
||||
: static_cast<IShmemAllocator*>(aParent);
|
||||
GetSurfaceData(dataSurface, &length, &stride,
|
||||
allocator,
|
||||
&surfaceData);
|
||||
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = flavorStr;
|
||||
// Turn item->data() into an nsCString prior to accessing it.
|
||||
item->data() = EmptyCString();
|
||||
item->data().get_nsCString().Adopt(surfaceData.release(), length);
|
||||
item->data() = surfaceData;
|
||||
|
||||
IPCDataTransferImage& imageDetails = item->imageDetails();
|
||||
mozilla::gfx::IntSize size = dataSurface->GetSize();
|
||||
@ -7494,7 +7533,9 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
item->flavor() = type;
|
||||
nsAutoCString data;
|
||||
SlurpFileToString(file, data);
|
||||
item->data() = data;
|
||||
|
||||
Shmem dataAsShmem = ConvertToShmem(aChild, aParent, data);
|
||||
item->data() = dataAsShmem;
|
||||
}
|
||||
|
||||
continue;
|
||||
@ -7553,7 +7594,7 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
// Empty element, transfer only the flavor
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = flavorStr;
|
||||
item->data() = EmptyCString();
|
||||
item->data() = nsString();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) override;
|
||||
|
||||
FORWARD_SHMEM_ALLOCATOR_TO(PContentBridgeChild)
|
||||
|
||||
protected:
|
||||
virtual ~ContentBridgeChild();
|
||||
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) override;
|
||||
|
||||
FORWARD_SHMEM_ALLOCATOR_TO(PContentBridgeParent)
|
||||
|
||||
jsipc::CPOWManager* GetCPOWManager() override;
|
||||
|
||||
virtual ContentParentId ChildID() const override
|
||||
|
@ -3320,9 +3320,10 @@ ContentChild::RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
|
||||
if (item.data().type() == IPCDataTransferData::TnsString) {
|
||||
const nsString& data = item.data().get_nsString();
|
||||
variant->SetAsAString(data);
|
||||
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
|
||||
const nsCString& data = item.data().get_nsCString();
|
||||
variant->SetAsACString(data);
|
||||
} else if (item.data().type() == IPCDataTransferData::TShmem) {
|
||||
Shmem data = item.data().get_Shmem();
|
||||
variant->SetAsACString(nsDependentCString(data.get<char>(), data.Size<char>()));
|
||||
Unused << DeallocShmem(data);
|
||||
} else if (item.data().type() == IPCDataTransferData::TPBlobChild) {
|
||||
BlobChild* blob = static_cast<BlobChild*>(item.data().get_PBlobChild());
|
||||
RefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
||||
|
@ -592,6 +592,8 @@ public:
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) override;
|
||||
|
||||
FORWARD_SHMEM_ALLOCATOR_TO(PContentChild)
|
||||
|
||||
void GetAvailableDictionaries(InfallibleTArray<nsString>& aDictionaries);
|
||||
|
||||
PBrowserOrId
|
||||
|
@ -2763,7 +2763,7 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
|
||||
text.Length() * sizeof(char16_t));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
|
||||
} else if (item.data().type() == IPCDataTransferData::TShmem) {
|
||||
if (nsContentUtils::IsFlavorImage(item.flavor())) {
|
||||
nsCOMPtr<imgIContainer> imageContainer;
|
||||
rv = nsContentUtils::DataTransferItemToImage(item,
|
||||
@ -2783,7 +2783,10 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
|
||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
const nsCString& text = item.data().get_nsCString();
|
||||
// The buffer contains the terminating null.
|
||||
Shmem itemData = item.data().get_Shmem();
|
||||
const nsDependentCString text(itemData.get<char>(),
|
||||
itemData.Size<char>());
|
||||
rv = dataWrapper->SetData(text);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
@ -2791,6 +2794,8 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
}
|
||||
|
||||
Unused << DeallocShmem(item.data().get_Shmem());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,6 +619,8 @@ private:
|
||||
const bool& aIsForBrowser) override;
|
||||
using PContentParent::SendPTestShellConstructor;
|
||||
|
||||
FORWARD_SHMEM_ALLOCATOR_TO(PContentParent)
|
||||
|
||||
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
|
||||
// true.
|
||||
ContentParent(mozIApplication* aApp,
|
||||
|
@ -144,7 +144,7 @@ union BlobConstructorParams
|
||||
union IPCDataTransferData
|
||||
{
|
||||
nsString; // text
|
||||
nsCString; // images
|
||||
Shmem; // images using Shmem
|
||||
PBlob; // files
|
||||
};
|
||||
|
||||
|
@ -3321,7 +3321,7 @@ TabParent::AddInitialDnDDataTo(DataTransfer* aDataTransfer)
|
||||
auto* parent = static_cast<BlobParent*>(item.data().get_PBlobParent());
|
||||
RefPtr<BlobImpl> impl = parent->GetBlobImpl();
|
||||
variant->SetAsISupports(impl);
|
||||
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
|
||||
} else if (item.data().type() == IPCDataTransferData::TShmem) {
|
||||
if (nsContentUtils::IsFlavorImage(item.flavor())) {
|
||||
// An image! Get the imgIContainer for it and set it in the variant.
|
||||
nsCOMPtr<imgIContainer> imageContainer;
|
||||
@ -3333,8 +3333,11 @@ TabParent::AddInitialDnDDataTo(DataTransfer* aDataTransfer)
|
||||
}
|
||||
variant->SetAsISupports(imageContainer);
|
||||
} else {
|
||||
variant->SetAsACString(item.data().get_nsCString());
|
||||
Shmem data = item.data().get_Shmem();
|
||||
variant->SetAsACString(nsDependentCString(data.get<char>(), data.Size<char>()));
|
||||
}
|
||||
|
||||
mozilla::Unused << DeallocShmem(item.data().get_Shmem());
|
||||
}
|
||||
|
||||
// Using system principal here, since once the data is on parent process
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsISupports.h"
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
#include "mozilla/dom/CPOWManagerGetter.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
|
||||
#define NS_ICONTENTCHILD_IID \
|
||||
@ -25,6 +26,9 @@ class Principal;
|
||||
} // namespace IPC
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class Shmem;
|
||||
} // namespace ipc
|
||||
|
||||
namespace jsipc {
|
||||
class PJavaScriptChild;
|
||||
@ -44,6 +48,7 @@ class PBrowserChild;
|
||||
|
||||
class nsIContentChild : public nsISupports
|
||||
, public CPOWManagerGetter
|
||||
, public mozilla::ipc::IShmemAllocator
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTCHILD_IID)
|
||||
@ -63,6 +68,7 @@ public:
|
||||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) = 0;
|
||||
|
||||
protected:
|
||||
virtual jsipc::PJavaScriptChild* AllocPJavaScriptChild();
|
||||
virtual bool DeallocPJavaScriptChild(jsipc::PJavaScriptChild*);
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsISupports.h"
|
||||
@ -46,6 +47,7 @@ class PBrowserParent;
|
||||
class nsIContentParent : public nsISupports
|
||||
, public mozilla::dom::ipc::MessageManagerCallback
|
||||
, public CPOWManagerGetter
|
||||
, public mozilla::ipc::IShmemAllocator
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTPARENT_IID)
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
id_t aIPDLId,
|
||||
size_t aSize,
|
||||
SharedMemory::SharedMemoryType aType) :
|
||||
IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_NORMAL)
|
||||
IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_URGENT)
|
||||
{
|
||||
IPC::WriteParam(this, aIPDLId);
|
||||
IPC::WriteParam(this, aSize);
|
||||
|
@ -3,6 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsClipboardProxy.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -80,15 +81,18 @@ nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboar
|
||||
rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
|
||||
data.Length() * sizeof(char16_t));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
|
||||
} else if (item.data().type() == IPCDataTransferData::TShmem) {
|
||||
// If this is an image, convert it into an nsIInputStream.
|
||||
nsCString flavor = item.flavor();
|
||||
mozilla::ipc::Shmem data = item.data().get_Shmem();
|
||||
if (flavor.EqualsLiteral(kJPEGImageMime) ||
|
||||
flavor.EqualsLiteral(kJPGImageMime) ||
|
||||
flavor.EqualsLiteral(kPNGImageMime) ||
|
||||
flavor.EqualsLiteral(kGIFImageMime)) {
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
NS_NewCStringInputStream(getter_AddRefs(stream), item.data().get_nsCString());
|
||||
|
||||
NS_NewCStringInputStream(getter_AddRefs(stream),
|
||||
nsDependentCString(data.get<char>(), data.Size<char>()));
|
||||
|
||||
rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -99,14 +103,15 @@ nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboar
|
||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString data = item.data().get_nsCString();
|
||||
rv = dataWrapper->SetData(data);
|
||||
rv = dataWrapper->SetData(nsDependentCString(data.get<char>(), data.Size<char>()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
|
||||
data.Length());
|
||||
data.Size<char>());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mozilla::Unused << ContentChild::GetSingleton()->DeallocShmem(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user