зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1621762 - Part 1: Basic refactoring of ProducerConsumerQueue & CommandQueue r=jgilbert
A lot of simple changes to prepare for later patches in the series: * PcqCommand -> QueueCommand, PcqStatus -> QueueStatus, PcqParamTraits -> QueueParamTraits * Consolidate BasicSink/Source into CommandSink/Source * SyncCommandSource::mConsumer -> mResponseSink, SyncCommandSink::mProducer -> mResponseSource, CommandSource::mProducer -> mSource, CommandSink::mConsumer -> mSink * Rename WebGLPcqParamTraits.h to WebGLQueueParamTraits.h * ProducerConsumerQueue struct -> class. * ProducerConsumerQueue::mProducer/mConsumer access -> ProducerConsumerQueue::TakeProducer/TakeConsumer * Rename QueueStatus enum elements to follow style convention. * Rename Status() to GetStatus() in ProducerView and ConsumerView to appease Linux. * Rename CommandResult enum values to fit convention (and avoid Linux conflict with Success). Differential Revision: https://phabricator.services.mozilla.com/D68256
This commit is contained in:
Родитель
16a940c040
Коммит
ac84c81927
|
@ -737,9 +737,9 @@ bool ClientWebGLContext::CreateHostContext(const uvec2& requestedSize) {
|
|||
}
|
||||
|
||||
outOfProcess.mCommandSource = MakeUnique<ClientWebGLCommandSource>(
|
||||
std::move(commandPcq->mProducer), std::move(responsePcq->mConsumer));
|
||||
auto sink = MakeUnique<HostWebGLCommandSink>(
|
||||
std::move(commandPcq->mConsumer), std::move(responsePcq->mProducer));
|
||||
commandPcq->TakeProducer(), responsePcq->TakeConsumer());
|
||||
auto sink = MakeUnique<HostWebGLCommandSink>(commandPcq->TakeConsumer(),
|
||||
responsePcq->TakeProducer());
|
||||
|
||||
// Use the error/warning and command queues to construct a
|
||||
// ClientWebGLContext in this process and a HostWebGLContext
|
||||
|
|
|
@ -2081,9 +2081,9 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
|
|||
template <size_t command, typename... Args>
|
||||
void DispatchAsync(Args&&... aArgs) const {
|
||||
const auto& oop = *mNotLost->outOfProcess;
|
||||
PcqStatus status = oop.mCommandSource->RunAsyncCommand(command, aArgs...);
|
||||
if (!IsSuccess(status)) {
|
||||
if (status == PcqStatus::PcqOOMError) {
|
||||
QueueStatus status = oop.mCommandSource->RunAsyncCommand(command,
|
||||
aArgs...);
|
||||
if (!IsSuccess(status)) { if (status == QueueStatus::kOOMError) {
|
||||
JsWarning("Ran out-of-memory during WebGL IPC.");
|
||||
}
|
||||
// Not much to do but shut down. Since this was a Pcq failure and
|
||||
|
@ -2098,11 +2098,11 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
|
|||
ReturnType DispatchSync(Args&&... aArgs) const {
|
||||
const auto& oop = *mNotLost->outOfProcess;
|
||||
ReturnType returnValue;
|
||||
PcqStatus status =
|
||||
QueueStatus status =
|
||||
oop.mCommandSource->RunSyncCommand(command, returnValue, aArgs...);
|
||||
|
||||
if (!IsSuccess(status)) {
|
||||
if (status == PcqStatus::PcqOOMError) {
|
||||
if (status == QueueStatus::kOOMError) {
|
||||
JsWarning("Ran out-of-memory during WebGL IPC.");
|
||||
}
|
||||
// Not much to do but shut down. Since this was a Pcq failure and
|
||||
|
@ -2120,7 +2120,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
|
|||
const auto status =
|
||||
oop.mCommandSource->RunVoidSyncCommand(command, aArgs...);
|
||||
if (!IsSuccess(status)) {
|
||||
if (status == PcqStatus::PcqOOMError) {
|
||||
if (status == QueueStatus::kOOMError) {
|
||||
JsWarning("Ran out-of-memory during WebGL IPC.");
|
||||
}
|
||||
// Not much to do but shut down. Since this was a Pcq failure and
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -22,49 +22,17 @@ namespace mozilla {
|
|||
|
||||
using mozilla::ipc::IPDLParamTraits;
|
||||
using mozilla::webgl::Consumer;
|
||||
using mozilla::webgl::PcqStatus;
|
||||
using mozilla::webgl::Producer;
|
||||
using mozilla::webgl::ProducerConsumerQueue;
|
||||
using mozilla::webgl::QueueStatus;
|
||||
|
||||
template <typename Derived, typename SinkType>
|
||||
struct MethodDispatcher;
|
||||
|
||||
enum CommandResult { Success, TimeExpired, QueueEmpty, Error };
|
||||
enum CommandResult { kSuccess, kTimeExpired, kQueueEmpty, kError };
|
||||
|
||||
enum CommandSyncType { ASYNC, SYNC };
|
||||
|
||||
class BasicSource {
|
||||
public:
|
||||
explicit BasicSource(UniquePtr<Producer>&& aProducer)
|
||||
: mProducer(std::move(aProducer)) {
|
||||
MOZ_ASSERT(mProducer);
|
||||
}
|
||||
virtual ~BasicSource() = default;
|
||||
|
||||
// For IPDL:
|
||||
BasicSource() = default;
|
||||
friend struct mozilla::ipc::IPDLParamTraits<BasicSource>;
|
||||
|
||||
protected:
|
||||
UniquePtr<Producer> mProducer;
|
||||
};
|
||||
|
||||
class BasicSink {
|
||||
public:
|
||||
explicit BasicSink(UniquePtr<Consumer>&& aConsumer)
|
||||
: mConsumer(std::move(aConsumer)) {
|
||||
MOZ_ASSERT(mConsumer);
|
||||
}
|
||||
virtual ~BasicSink() = default;
|
||||
|
||||
// For IPDL:
|
||||
BasicSink() = default;
|
||||
friend struct mozilla::ipc::IPDLParamTraits<BasicSink>;
|
||||
|
||||
protected:
|
||||
UniquePtr<Consumer> mConsumer;
|
||||
};
|
||||
|
||||
/**
|
||||
* A CommandSource is obtained from a CommandQueue. Use it by inserting a
|
||||
* command (represented by type Command) using InsertCommand, which also
|
||||
|
@ -73,29 +41,35 @@ class BasicSink {
|
|||
* to execute it.
|
||||
*/
|
||||
template <typename Command>
|
||||
class CommandSource : public BasicSource {
|
||||
class CommandSource {
|
||||
public:
|
||||
explicit CommandSource(UniquePtr<Producer>&& aProducer)
|
||||
: BasicSource(std::move(aProducer)) {}
|
||||
|
||||
template <typename... Args>
|
||||
PcqStatus InsertCommand(Command aCommand, Args&&... aArgs) {
|
||||
return this->mProducer->TryWaitInsert(Nothing() /* wait forever */,
|
||||
aCommand, aArgs...);
|
||||
}
|
||||
|
||||
PcqStatus InsertCommand(Command aCommand) {
|
||||
return this->mProducer->TryWaitInsert(Nothing() /* wait forever */,
|
||||
aCommand);
|
||||
explicit CommandSource(UniquePtr<Producer>&& aSource)
|
||||
: mSource(std::move(aSource)) {
|
||||
MOZ_ASSERT(mSource);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
PcqStatus RunCommand(Command aCommand, Args&&... aArgs) {
|
||||
QueueStatus InsertCommand(Command aCommand, Args&&... aArgs) {
|
||||
return this->mSource->TryWaitInsert(Nothing() /* wait forever */, aCommand,
|
||||
aArgs...);
|
||||
}
|
||||
|
||||
QueueStatus InsertCommand(Command aCommand) {
|
||||
return this->mSource->TryWaitInsert(Nothing() /* wait forever */, aCommand);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
QueueStatus RunCommand(Command aCommand, Args&&... aArgs) {
|
||||
return InsertCommand(aCommand, std::forward<Args>(aArgs)...);
|
||||
}
|
||||
|
||||
// For IPDL:
|
||||
CommandSource() = default;
|
||||
|
||||
protected:
|
||||
friend struct IPDLParamTraits<mozilla::CommandSource<Command>>;
|
||||
|
||||
UniquePtr<Producer> mSource;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -109,35 +83,36 @@ class CommandSource : public BasicSource {
|
|||
* queue by calling the Dispatch methods in this class.
|
||||
*/
|
||||
template <typename Command>
|
||||
class CommandSink : public BasicSink {
|
||||
class CommandSink {
|
||||
public:
|
||||
explicit CommandSink(UniquePtr<Consumer>&& aConsumer)
|
||||
: BasicSink(std::move(aConsumer)) {}
|
||||
explicit CommandSink(UniquePtr<Consumer>&& aSink) : mSink(std::move(aSink)) {
|
||||
MOZ_ASSERT(mSink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to process the next command in the queue, if one is available.
|
||||
*/
|
||||
CommandResult ProcessOne(const Maybe<TimeDuration>& aTimeout) {
|
||||
Command command;
|
||||
PcqStatus status = (aTimeout.isNothing() || aTimeout.value())
|
||||
? this->mConsumer->TryWaitRemove(aTimeout, command)
|
||||
: this->mConsumer->TryRemove(command);
|
||||
QueueStatus status = (aTimeout.isNothing() || aTimeout.value())
|
||||
? this->mSink->TryWaitRemove(aTimeout, command)
|
||||
: this->mSink->TryRemove(command);
|
||||
|
||||
if (status == PcqStatus::Success) {
|
||||
if (status == QueueStatus::kSuccess) {
|
||||
if (DispatchCommand(command)) {
|
||||
return CommandResult::Success;
|
||||
return CommandResult::kSuccess;
|
||||
}
|
||||
return CommandResult::Error;
|
||||
return CommandResult::kError;
|
||||
}
|
||||
|
||||
if (status == PcqStatus::PcqNotReady) {
|
||||
return CommandResult::QueueEmpty;
|
||||
if (status == QueueStatus::kNotReady) {
|
||||
return CommandResult::kQueueEmpty;
|
||||
}
|
||||
|
||||
if (status == PcqStatus::PcqOOMError) {
|
||||
if (status == QueueStatus::kOOMError) {
|
||||
ReportOOM();
|
||||
}
|
||||
return CommandResult::Error;
|
||||
return CommandResult::kError;
|
||||
}
|
||||
|
||||
CommandResult ProcessOneNow() { return ProcessOne(Some(TimeDuration(0))); }
|
||||
|
@ -152,7 +127,7 @@ class CommandSink : public BasicSink {
|
|||
CommandResult result;
|
||||
do {
|
||||
result = ProcessOneNow();
|
||||
} while (result == CommandResult::Success);
|
||||
} while (result == CommandResult::kSuccess);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -169,7 +144,8 @@ class CommandSink : public BasicSink {
|
|||
do {
|
||||
result = ProcessOne(Some(aDuration - (now - start)));
|
||||
now = TimeStamp::Now();
|
||||
} while ((result == CommandResult::Success) && ((now - start) < aDuration));
|
||||
} while ((result == CommandResult::kSuccess) &&
|
||||
((now - start) < aDuration));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -224,6 +200,8 @@ class CommandSink : public BasicSink {
|
|||
}
|
||||
|
||||
protected:
|
||||
friend struct IPDLParamTraits<mozilla::CommandSink<Command>>;
|
||||
|
||||
/**
|
||||
* Implementations will usually be something like a big switch statement
|
||||
* that calls one of the Dispatch methods in this class.
|
||||
|
@ -237,19 +215,19 @@ class CommandSink : public BasicSink {
|
|||
virtual void ReportOOM() {}
|
||||
|
||||
template <typename... Args, size_t... Indices>
|
||||
PcqStatus CallTryRemove(std::tuple<Args...>& aArgs,
|
||||
std::index_sequence<Indices...>) {
|
||||
PcqStatus status = mConsumer->TryRemove(std::get<Indices>(aArgs)...);
|
||||
QueueStatus CallTryRemove(std::tuple<Args...>& aArgs,
|
||||
std::index_sequence<Indices...>) {
|
||||
QueueStatus status = mSink->TryRemove(std::get<Indices>(aArgs)...);
|
||||
// The CommandQueue inserts the command and the args together as an atomic
|
||||
// operation. We already read the command so the args must also be
|
||||
// available.
|
||||
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
|
||||
MOZ_ASSERT(status != QueueStatus::kNotReady);
|
||||
return status;
|
||||
}
|
||||
|
||||
PcqStatus CallTryRemove(std::tuple<>& aArgs,
|
||||
std::make_integer_sequence<size_t, 0>) {
|
||||
return PcqStatus::Success;
|
||||
QueueStatus CallTryRemove(std::tuple<>& aArgs,
|
||||
std::make_integer_sequence<size_t, 0>) {
|
||||
return QueueStatus::kSuccess;
|
||||
}
|
||||
|
||||
template <typename T, typename MethodType, typename... Args,
|
||||
|
@ -269,9 +247,12 @@ class CommandSink : public BasicSink {
|
|||
|
||||
template <typename... Args>
|
||||
bool ReadArgs(std::tuple<Args...>& aArgs) {
|
||||
PcqStatus status = CallTryRemove(aArgs, std::index_sequence_for<Args...>{});
|
||||
QueueStatus status =
|
||||
CallTryRemove(aArgs, std::index_sequence_for<Args...>{});
|
||||
return IsSuccess(status);
|
||||
}
|
||||
|
||||
UniquePtr<Consumer> mSink;
|
||||
};
|
||||
|
||||
enum SyncResponse : uint8_t { RESPONSE_NAK, RESPONSE_ACK };
|
||||
|
@ -289,23 +270,24 @@ class SyncCommandSource : public CommandSource<Command> {
|
|||
SyncCommandSource(UniquePtr<Producer>&& aProducer,
|
||||
UniquePtr<Consumer>&& aResponseConsumer)
|
||||
: CommandSource<Command>(std::move(aProducer)),
|
||||
mConsumer(std::move(aResponseConsumer)) {}
|
||||
mResponseSink(std::move(aResponseConsumer)) {}
|
||||
|
||||
template <typename... Args>
|
||||
PcqStatus RunAsyncCommand(Command aCommand, Args&&... aArgs) {
|
||||
QueueStatus RunAsyncCommand(Command aCommand, Args&&... aArgs) {
|
||||
return this->RunCommand(aCommand, std::forward<Args>(aArgs)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
PcqStatus RunVoidSyncCommand(Command aCommand, Args&&... aArgs) {
|
||||
PcqStatus status = RunAsyncCommand(aCommand, std::forward<Args>(aArgs)...);
|
||||
QueueStatus RunVoidSyncCommand(Command aCommand, Args&&... aArgs) {
|
||||
QueueStatus status =
|
||||
RunAsyncCommand(aCommand, std::forward<Args>(aArgs)...);
|
||||
return IsSuccess(status) ? this->ReadSyncResponse() : status;
|
||||
}
|
||||
|
||||
template <typename ResultType, typename... Args>
|
||||
PcqStatus RunSyncCommand(Command aCommand, ResultType& aReturn,
|
||||
Args&&... aArgs) {
|
||||
PcqStatus status =
|
||||
QueueStatus RunSyncCommand(Command aCommand, ResultType& aReturn,
|
||||
Args&&... aArgs) {
|
||||
QueueStatus status =
|
||||
RunVoidSyncCommand(aCommand, std::forward<Args>(aArgs)...);
|
||||
return IsSuccess(status) ? this->ReadResult(aReturn) : status;
|
||||
}
|
||||
|
@ -315,28 +297,28 @@ class SyncCommandSource : public CommandSource<Command> {
|
|||
friend struct mozilla::ipc::IPDLParamTraits<SyncCommandSource<Command>>;
|
||||
|
||||
protected:
|
||||
PcqStatus ReadSyncResponse() {
|
||||
QueueStatus ReadSyncResponse() {
|
||||
SyncResponse response;
|
||||
PcqStatus status =
|
||||
mConsumer->TryWaitRemove(Nothing() /* wait forever */, response);
|
||||
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
|
||||
QueueStatus status =
|
||||
mResponseSink->TryWaitRemove(Nothing() /* wait forever */, response);
|
||||
MOZ_ASSERT(status != QueueStatus::kNotReady);
|
||||
|
||||
if (IsSuccess(status) && response != RESPONSE_ACK) {
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PcqStatus ReadResult(T& aResult) {
|
||||
PcqStatus status = mConsumer->TryRemove(aResult);
|
||||
QueueStatus ReadResult(T& aResult) {
|
||||
QueueStatus status = mResponseSink->TryRemove(aResult);
|
||||
// The Sink posts the response code and result as an atomic transaction. We
|
||||
// already read the response code so the result must be available.
|
||||
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
|
||||
MOZ_ASSERT(status != QueueStatus::kNotReady);
|
||||
return status;
|
||||
}
|
||||
|
||||
UniquePtr<Consumer> mConsumer;
|
||||
UniquePtr<Consumer> mResponseSink;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -352,9 +334,9 @@ class SyncCommandSink : public CommandSink<Command> {
|
|||
|
||||
public:
|
||||
SyncCommandSink(UniquePtr<Consumer>&& aConsumer,
|
||||
UniquePtr<Producer>&& aResponseProducer)
|
||||
UniquePtr<Producer>&& aResponseSource)
|
||||
: CommandSink<Command>(std::move(aConsumer)),
|
||||
mProducer(std::move(aResponseProducer)) {}
|
||||
mResponseSource(std::move(aResponseSource)) {}
|
||||
|
||||
// for IPDL:
|
||||
SyncCommandSink() = default;
|
||||
|
@ -491,7 +473,7 @@ class SyncCommandSink : public CommandSink<Command> {
|
|||
protected:
|
||||
template <typename... Args>
|
||||
bool WriteArgs(const Args&... aArgs) {
|
||||
return IsSuccess(mProducer->TryInsert(aArgs...));
|
||||
return IsSuccess(mResponseSource->TryInsert(aArgs...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
@ -505,7 +487,7 @@ class SyncCommandSink : public CommandSink<Command> {
|
|||
return WriteArgs(nak);
|
||||
}
|
||||
|
||||
UniquePtr<Producer> mProducer;
|
||||
UniquePtr<Producer> mResponseSource;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -536,27 +518,30 @@ struct MethodDispatcher {
|
|||
using SinkType = _SinkType;
|
||||
template <CommandSyncType syncType>
|
||||
struct DispatchMethod;
|
||||
/*
|
||||
// Specialization for dispatching asynchronous methods
|
||||
template <CommandSyncType SyncType>
|
||||
struct DispatchMethod {
|
||||
template <typename MethodType, typename ObjectType>
|
||||
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType mMethod,
|
||||
ObjectType& aObj) {
|
||||
return aSink.DispatchMethod<SyncType>(aObj, mMethod);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Specialization for dispatching synchronous methods
|
||||
template <>
|
||||
struct DispatchMethod<CommandSyncType::SYNC> {
|
||||
template <typename MethodType, typename ObjectType>
|
||||
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType aMethod,
|
||||
ObjectType& aObj) {
|
||||
return aSink.DispatchSyncMethod(aObj, aMethod);
|
||||
}
|
||||
};
|
||||
*/
|
||||
// Specialization for dispatching asynchronous methods
|
||||
template <typename Derived, typename _SinkType>
|
||||
template <>
|
||||
struct MethodDispatcher<Derived,
|
||||
_SinkType>::DispatchMethod<CommandSyncType::ASYNC> {
|
||||
template <typename MethodType, typename ObjectType>
|
||||
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType mMethod,
|
||||
ObjectType& aObj) {
|
||||
return aSink.DispatchAsyncMethod(aObj, mMethod);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for dispatching synchronous methods
|
||||
template <typename Derived, typename _SinkType>
|
||||
template <>
|
||||
struct MethodDispatcher<Derived,
|
||||
_SinkType>::DispatchMethod<CommandSyncType::SYNC> {
|
||||
template <typename MethodType, typename ObjectType>
|
||||
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType aMethod,
|
||||
ObjectType& aObj) {
|
||||
return aSink.DispatchSyncMethod(aObj, aMethod);
|
||||
}
|
||||
};
|
||||
|
||||
// Declares a MethodDispatcher with the given name and CommandSink type.
|
||||
|
@ -612,60 +597,46 @@ namespace ipc {
|
|||
template <typename T>
|
||||
struct IPDLParamTraits;
|
||||
|
||||
template <>
|
||||
struct IPDLParamTraits<mozilla::BasicSource> {
|
||||
template <typename Command>
|
||||
struct IPDLParamTraits<mozilla::CommandSource<Command>> {
|
||||
public:
|
||||
typedef mozilla::BasicSource paramType;
|
||||
typedef mozilla::CommandSource<Command> paramType;
|
||||
|
||||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
const paramType& aParam) {
|
||||
MOZ_ASSERT(aParam.mProducer);
|
||||
WriteIPDLParam(aMsg, aActor, *aParam.mProducer.get());
|
||||
MOZ_ASSERT(aParam.mSource);
|
||||
WriteIPDLParam(aMsg, aActor, *aParam.mSource.get());
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, paramType* aResult) {
|
||||
Producer* producer = new Producer;
|
||||
bool ret = ReadIPDLParam(aMsg, aIter, aActor, producer);
|
||||
aResult->mProducer.reset(producer);
|
||||
aResult->mSource.reset(producer);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IPDLParamTraits<mozilla::BasicSink> {
|
||||
template <typename Command>
|
||||
struct IPDLParamTraits<mozilla::CommandSink<Command>> {
|
||||
public:
|
||||
typedef mozilla::BasicSink paramType;
|
||||
typedef mozilla::CommandSink<Command> paramType;
|
||||
|
||||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
const paramType& aParam) {
|
||||
MOZ_ASSERT(aParam.mConsumer);
|
||||
WriteIPDLParam(aMsg, aActor, *aParam.mConsumer.get());
|
||||
MOZ_ASSERT(aParam.mSink);
|
||||
WriteIPDLParam(aMsg, aActor, *aParam.mSink.get());
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, paramType* aResult) {
|
||||
Consumer* consumer = new Consumer;
|
||||
bool ret = ReadIPDLParam(aMsg, aIter, aActor, consumer);
|
||||
aResult->mConsumer.reset(consumer);
|
||||
aResult->mSink.reset(consumer);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Command>
|
||||
struct IPDLParamTraits<mozilla::CommandSource<Command>>
|
||||
: public IPDLParamTraits<mozilla::BasicSource> {
|
||||
public:
|
||||
typedef mozilla::CommandSource<Command> paramType;
|
||||
};
|
||||
|
||||
template <typename Command>
|
||||
struct IPDLParamTraits<mozilla::CommandSink<Command>>
|
||||
: public IPDLParamTraits<mozilla::BasicSink> {
|
||||
public:
|
||||
typedef mozilla::CommandSink<Command> paramType;
|
||||
};
|
||||
|
||||
template <typename Command>
|
||||
struct IPDLParamTraits<mozilla::SyncCommandSource<Command>>
|
||||
: public IPDLParamTraits<mozilla::CommandSource<Command>> {
|
||||
|
@ -676,14 +647,14 @@ struct IPDLParamTraits<mozilla::SyncCommandSource<Command>>
|
|||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
const paramType& aParam) {
|
||||
WriteIPDLParam(aMsg, aActor, static_cast<const paramBaseType&>(aParam));
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mConsumer);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mResponseSink);
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, paramType* aParam) {
|
||||
bool result =
|
||||
ReadIPDLParam(aMsg, aIter, aActor, static_cast<paramBaseType*>(aParam));
|
||||
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mConsumer);
|
||||
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mResponseSink);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -697,14 +668,15 @@ struct IPDLParamTraits<mozilla::SyncCommandSink<Command>>
|
|||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
const paramType& aParam) {
|
||||
WriteIPDLParam(aMsg, aActor, static_cast<const paramBaseType&>(aParam));
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mProducer);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mResponseSource);
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, paramType* aParam) {
|
||||
bool result =
|
||||
ReadIPDLParam(aMsg, aIter, aActor, static_cast<paramBaseType*>(aParam));
|
||||
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mProducer);
|
||||
return result &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aParam->mResponseSource);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ using ClientWebGLCommandSource = SyncCommandSource<size_t>;
|
|||
* then uses for executing methods. Add new commands to DispatchCommand using
|
||||
* the WEBGL_SYNC_COMMAND and WEBGL_ASYNC_COMMAND macros.
|
||||
*/
|
||||
class HostWebGLCommandSink : public SyncCommandSink<size_t> {
|
||||
class HostWebGLCommandSink final : public SyncCommandSink<size_t> {
|
||||
public:
|
||||
HostWebGLCommandSink(UniquePtr<Consumer>&& aConsumer,
|
||||
UniquePtr<Producer>&& aResponseProducer)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "TexUnpackBlob.h"
|
||||
#include "WebGLCrossProcessCommandQueue.h"
|
||||
#include "HostWebGLContext.h"
|
||||
#include "WebGLPcqParamTraits.h"
|
||||
#include "WebGLQueueParamTraits.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef WEBGLPCQPARAMTRAITS_H_
|
||||
#define WEBGLPCQPARAMTRAITS_H_
|
||||
#ifndef WEBGLQUEUEPARAMTRAITS_H_
|
||||
#define WEBGLQUEUEPARAMTRAITS_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace mozilla {
|
|||
|
||||
namespace webgl {
|
||||
template <typename T>
|
||||
struct PcqParamTraits;
|
||||
struct QueueParamTraits;
|
||||
|
||||
template <>
|
||||
struct IsTriviallySerializable<FloatOrInt> : std::true_type {};
|
||||
|
@ -58,10 +58,10 @@ template <>
|
|||
struct IsTriviallySerializable<webgl::TexUnpackBlob> : std::true_type {};
|
||||
/*
|
||||
template <>
|
||||
struct PcqParamTraits<WebGLActiveInfo> {
|
||||
struct QueueParamTraits<WebGLActiveInfo> {
|
||||
using ParamType = WebGLActiveInfo;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
aProducerView.WriteParam(aArg.mElemCount);
|
||||
aProducerView.WriteParam(aArg.mElemType);
|
||||
aProducerView.WriteParam(aArg.mBaseUserName);
|
||||
|
@ -71,7 +71,7 @@ struct PcqParamTraits<WebGLActiveInfo> {
|
|||
return aProducerView.WriteParam(aArg.mBaseType);
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
aConsumerView.ReadParam(aArg ? &aArg->mElemCount : nullptr);
|
||||
aConsumerView.ReadParam(aArg ? &aArg->mElemType : nullptr);
|
||||
aConsumerView.ReadParam(aArg ? &aArg->mBaseUserName : nullptr);
|
||||
|
@ -94,21 +94,21 @@ struct PcqParamTraits<WebGLActiveInfo> {
|
|||
};
|
||||
*/
|
||||
template <typename T>
|
||||
struct PcqParamTraits<RawBuffer<T>> {
|
||||
struct QueueParamTraits<RawBuffer<T>> {
|
||||
using ParamType = RawBuffer<T>;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
aProducerView.WriteParam(aArg.mLength);
|
||||
return (aArg.mLength > 0)
|
||||
? aProducerView.Write(aArg.mData, aArg.mLength * sizeof(T))
|
||||
: aProducerView.Status();
|
||||
: aProducerView.GetStatus();
|
||||
}
|
||||
|
||||
template <
|
||||
typename ElementType = std::remove_cv_t<typename ParamType::ElementType>>
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
size_t len;
|
||||
PcqStatus status = aConsumerView.ReadParam(&len);
|
||||
QueueStatus status = aConsumerView.ReadParam(&len);
|
||||
if (!status) {
|
||||
return status;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ struct PcqParamTraits<RawBuffer<T>> {
|
|||
aArg->mLength = 0;
|
||||
aArg->mData = nullptr;
|
||||
}
|
||||
return PcqStatus::Success;
|
||||
return QueueStatus::kSuccess;
|
||||
}
|
||||
|
||||
if (!aArg) {
|
||||
|
@ -126,17 +126,17 @@ struct PcqParamTraits<RawBuffer<T>> {
|
|||
}
|
||||
|
||||
struct RawBufferReadMatcher {
|
||||
PcqStatus operator()(RefPtr<mozilla::ipc::SharedMemoryBasic>& smem) {
|
||||
QueueStatus operator()(RefPtr<mozilla::ipc::SharedMemoryBasic>& smem) {
|
||||
if (!smem) {
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
}
|
||||
mArg->mSmem = smem;
|
||||
mArg->mData = static_cast<ElementType*>(smem->memory());
|
||||
mArg->mLength = mLength;
|
||||
mArg->mOwnsData = false;
|
||||
return PcqStatus::Success;
|
||||
return QueueStatus::kSuccess;
|
||||
}
|
||||
PcqStatus operator()() {
|
||||
QueueStatus operator()() {
|
||||
mArg->mSmem = nullptr;
|
||||
ElementType* buf = new ElementType[mLength];
|
||||
mArg->mData = buf;
|
||||
|
@ -165,16 +165,16 @@ struct PcqParamTraits<RawBuffer<T>> {
|
|||
enum TexUnpackTypes : uint8_t { Bytes, Surface, Image, Pbo };
|
||||
|
||||
template <>
|
||||
struct PcqParamTraits<webgl::TexUnpackBytes> {
|
||||
struct QueueParamTraits<webgl::TexUnpackBytes> {
|
||||
using ParamType = webgl::TexUnpackBytes;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
// Write TexUnpackBlob base class, then the RawBuffer.
|
||||
aProducerView.WriteParam(static_cast<const webgl::TexUnpackBlob&>(aArg));
|
||||
return aProducerView.WriteParam(aArg.mPtr);
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
// Read TexUnpackBlob base class, then the RawBuffer.
|
||||
aConsumerView.ReadParam(static_cast<webgl::TexUnpackBlob*>(aArg));
|
||||
return aConsumerView.ReadParam(aArg ? &aArg->mPtr : nullptr);
|
||||
|
@ -188,10 +188,10 @@ struct PcqParamTraits<webgl::TexUnpackBytes> {
|
|||
};
|
||||
|
||||
template <>
|
||||
struct PcqParamTraits<webgl::TexUnpackSurface> {
|
||||
struct QueueParamTraits<webgl::TexUnpackSurface> {
|
||||
using ParamType = webgl::TexUnpackSurface;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
aProducerView.WriteParam(static_cast<const webgl::TexUnpackBlob&>(aArg));
|
||||
aProducerView.WriteParam(aArg.mSize);
|
||||
aProducerView.WriteParam(aArg.mFormat);
|
||||
|
@ -199,7 +199,7 @@ struct PcqParamTraits<webgl::TexUnpackSurface> {
|
|||
return aProducerView.WriteParam(aArg.mStride);
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
aConsumerView.ReadParam(static_cast<webgl::TexUnpackBlob*>(aArg));
|
||||
aConsumerView.ReadParam(aArg ? &aArg->mSize : nullptr);
|
||||
aConsumerView.ReadParam(aArg ? &aArg->mFormat : nullptr);
|
||||
|
@ -217,28 +217,28 @@ struct PcqParamTraits<webgl::TexUnpackSurface> {
|
|||
}
|
||||
};
|
||||
|
||||
// Specialization of PcqParamTraits that adapts the TexUnpack type in order to
|
||||
// Specialization of QueueParamTraits that adapts the TexUnpack type in order to
|
||||
// efficiently convert types. For example, a TexUnpackSurface may deserialize
|
||||
// as a TexUnpackBytes.
|
||||
template <>
|
||||
struct PcqParamTraits<WebGLTexUnpackVariant> {
|
||||
struct QueueParamTraits<WebGLTexUnpackVariant> {
|
||||
using ParamType = WebGLTexUnpackVariant;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
struct TexUnpackWriteMatcher {
|
||||
PcqStatus operator()(const UniquePtr<webgl::TexUnpackBytes>& x) {
|
||||
QueueStatus operator()(const UniquePtr<webgl::TexUnpackBytes>& x) {
|
||||
mProducerView.WriteParam(TexUnpackTypes::Bytes);
|
||||
return mProducerView.WriteParam(x);
|
||||
}
|
||||
PcqStatus operator()(const UniquePtr<webgl::TexUnpackSurface>& x) {
|
||||
QueueStatus operator()(const UniquePtr<webgl::TexUnpackSurface>& x) {
|
||||
mProducerView.WriteParam(TexUnpackTypes::Surface);
|
||||
return mProducerView.WriteParam(x);
|
||||
}
|
||||
PcqStatus operator()(const UniquePtr<webgl::TexUnpackImage>& x) {
|
||||
QueueStatus operator()(const UniquePtr<webgl::TexUnpackImage>& x) {
|
||||
MOZ_ASSERT_UNREACHABLE("TODO:");
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
}
|
||||
PcqStatus operator()(const WebGLTexPboOffset& x) {
|
||||
QueueStatus operator()(const WebGLTexPboOffset& x) {
|
||||
mProducerView.WriteParam(TexUnpackTypes::Pbo);
|
||||
return mProducerView.WriteParam(x);
|
||||
}
|
||||
|
@ -247,14 +247,14 @@ struct PcqParamTraits<WebGLTexUnpackVariant> {
|
|||
return aArg.match(TexUnpackWriteMatcher{aProducerView});
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
if (!aArg) {
|
||||
// Not a great estimate but we can't do much better.
|
||||
return aConsumerView.template ReadParam<TexUnpackTypes>();
|
||||
}
|
||||
TexUnpackTypes unpackType;
|
||||
if (!aConsumerView.ReadParam(&unpackType)) {
|
||||
return aConsumerView.Status();
|
||||
return aConsumerView.GetStatus();
|
||||
}
|
||||
switch (unpackType) {
|
||||
case TexUnpackTypes::Bytes:
|
||||
|
@ -267,13 +267,13 @@ struct PcqParamTraits<WebGLTexUnpackVariant> {
|
|||
&aArg->as<UniquePtr<webgl::TexUnpackSurface>>());
|
||||
case TexUnpackTypes::Image:
|
||||
MOZ_ASSERT_UNREACHABLE("TODO:");
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
case TexUnpackTypes::Pbo:
|
||||
*aArg = AsVariant(WebGLTexPboOffset());
|
||||
return aConsumerView.ReadParam(&aArg->as<WebGLTexPboOffset>());
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Illegal texture unpack type");
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
}
|
||||
|
||||
template <typename View>
|
||||
|
@ -304,20 +304,20 @@ struct PcqParamTraits<WebGLTexUnpackVariant> {
|
|||
};
|
||||
*/
|
||||
template <>
|
||||
struct PcqParamTraits<webgl::ContextLossReason> {
|
||||
struct QueueParamTraits<webgl::ContextLossReason> {
|
||||
using ParamType = webgl::ContextLossReason;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
|
||||
return aProducerView.WriteParam(static_cast<uint8_t>(aArg));
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
|
||||
uint8_t val;
|
||||
auto status = aConsumerView.ReadParam(&val);
|
||||
if (!status) return status;
|
||||
if (!ReadContextLossReason(val, aArg)) {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid ContextLossReason");
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -329,10 +329,10 @@ struct PcqParamTraits<webgl::ContextLossReason> {
|
|||
};
|
||||
|
||||
template <typename V, typename E>
|
||||
struct PcqParamTraits<Result<V, E>> {
|
||||
struct QueueParamTraits<Result<V, E>> {
|
||||
using T = Result<V, E>;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
const auto ok = aArg.isOk();
|
||||
auto status = aProducerView.WriteParam(ok);
|
||||
if (!status) return status;
|
||||
|
@ -344,7 +344,7 @@ struct PcqParamTraits<Result<V, E>> {
|
|||
return status;
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
bool ok;
|
||||
auto status = aConsumerView.ReadParam(&ok);
|
||||
if (!status) return status;
|
||||
|
@ -377,24 +377,24 @@ struct PcqParamTraits<Result<V, E>> {
|
|||
};
|
||||
|
||||
template <>
|
||||
struct PcqParamTraits<std::string> {
|
||||
struct QueueParamTraits<std::string> {
|
||||
using T = std::string;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
auto status = aProducerView.WriteParam(aArg.size());
|
||||
if (!status) return status;
|
||||
status = aProducerView.Write(aArg.data(), aArg.size());
|
||||
return status;
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
size_t size;
|
||||
auto status = aConsumerView.ReadParam(&size);
|
||||
if (!status) return status;
|
||||
|
||||
const UniqueBuffer temp = malloc(size);
|
||||
const auto dest = static_cast<char*>(temp.get());
|
||||
if (!dest) return PcqStatus::PcqFatalError;
|
||||
if (!dest) return QueueStatus::kFatalError;
|
||||
|
||||
status = aConsumerView.Read(dest, size);
|
||||
if (aArg) {
|
||||
|
@ -414,17 +414,17 @@ struct PcqParamTraits<std::string> {
|
|||
};
|
||||
|
||||
template <typename U>
|
||||
struct PcqParamTraits<std::vector<U>> {
|
||||
struct QueueParamTraits<std::vector<U>> {
|
||||
using T = std::string;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
auto status = aProducerView.WriteParam(aArg.size());
|
||||
if (!status) return status;
|
||||
status = aProducerView.Write(aArg.data(), aArg.size());
|
||||
return status;
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
MOZ_CRASH("no way to fallibly resize vectors without exceptions");
|
||||
size_t size;
|
||||
auto status = aConsumerView.ReadParam(&size);
|
||||
|
@ -446,21 +446,21 @@ struct PcqParamTraits<std::vector<U>> {
|
|||
};
|
||||
|
||||
template <>
|
||||
struct PcqParamTraits<WebGLExtensionID> {
|
||||
struct QueueParamTraits<WebGLExtensionID> {
|
||||
using T = WebGLExtensionID;
|
||||
|
||||
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
|
||||
return aProducerView.WriteParam(mozilla::EnumValue(aArg));
|
||||
}
|
||||
|
||||
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
PcqStatus status = PcqStatus::Success;
|
||||
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
|
||||
QueueStatus status = QueueStatus::kSuccess;
|
||||
if (aArg) {
|
||||
status = aConsumerView.ReadParam(
|
||||
reinterpret_cast<typename std::underlying_type<T>::type*>(aArg));
|
||||
if (*aArg >= WebGLExtensionID::Max) {
|
||||
MOZ_ASSERT(false);
|
||||
return PcqStatus::PcqFatalError;
|
||||
return QueueStatus::kFatalError;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
|
@ -475,4 +475,4 @@ struct PcqParamTraits<WebGLExtensionID> {
|
|||
} // namespace webgl
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WEBGLPCQPARAMTRAITS_H_
|
||||
#endif // WEBGLQUEUEPARAMTRAITS_H_
|
|
@ -96,7 +96,7 @@ inline auto AutoAssertCast(const From val) {
|
|||
|
||||
namespace ipc {
|
||||
template <typename T>
|
||||
struct PcqParamTraits;
|
||||
struct QueueParamTraits;
|
||||
}
|
||||
|
||||
namespace webgl {
|
||||
|
@ -733,7 +733,7 @@ class RawBuffer {
|
|||
// true if we should delete[] the mData on destruction
|
||||
bool mOwnsData = false;
|
||||
|
||||
friend mozilla::ipc::PcqParamTraits<RawBuffer>;
|
||||
friend mozilla::ipc::QueueParamTraits<RawBuffer>;
|
||||
|
||||
public:
|
||||
using ElementType = T;
|
||||
|
|
Загрузка…
Ссылка в новой задаче