mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1879228 - MethodDispatcher::DispatchCommand less noisy in stack traces. r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D201033
This commit is contained in:
parent
d44d931081
commit
58332487d1
@ -171,6 +171,11 @@ inline Maybe<uint16_t> Deserialize(RangeConsumerView& view,
|
||||
|
||||
} // namespace webgl
|
||||
|
||||
// -
|
||||
|
||||
template <class R, class... Args>
|
||||
using fn_t = R(Args...);
|
||||
|
||||
// The MethodDispatcher setup uses a CommandSink to read parameters, call the
|
||||
// given method using the given synchronization protocol, and provide
|
||||
// compile-time lookup of the ID by class method.
|
||||
@ -200,13 +205,9 @@ template <template <size_t> typename Derived>
|
||||
class EmptyMethodDispatcher {
|
||||
public:
|
||||
template <typename ObjectT>
|
||||
static MOZ_ALWAYS_INLINE bool DispatchCommand(ObjectT&, const size_t id,
|
||||
webgl::RangeConsumerView&) {
|
||||
const nsPrintfCString cstr(
|
||||
"MethodDispatcher<%i> not found. Please file a bug!", int(id));
|
||||
const auto str = ToString(cstr);
|
||||
gfxCriticalError() << str;
|
||||
return false;
|
||||
static constexpr fn_t<bool, ObjectT&, webgl::RangeConsumerView&>*
|
||||
DispatchCommandFuncById(const size_t id) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@ -225,22 +226,26 @@ std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...> ArgsTuple(
|
||||
}
|
||||
|
||||
// Derived type must be parameterized by the ID.
|
||||
template <template <size_t> typename Derived, size_t ID, typename MethodType,
|
||||
MethodType method>
|
||||
template <template <size_t> typename Derived, size_t _Id, typename MethodType,
|
||||
MethodType _Method>
|
||||
class MethodDispatcher {
|
||||
static constexpr size_t kId = ID;
|
||||
using DerivedType = Derived<ID>;
|
||||
using NextDispatcher = Derived<ID + 1>;
|
||||
static constexpr auto Id = _Id;
|
||||
static constexpr auto Method = _Method;
|
||||
using DerivedType = Derived<Id>;
|
||||
|
||||
public:
|
||||
template <typename ObjectT>
|
||||
static MOZ_ALWAYS_INLINE bool DispatchCommand(
|
||||
ObjectT& obj, const size_t id, webgl::RangeConsumerView& view) {
|
||||
if (id == kId) {
|
||||
auto argsTuple = ArgsTuple(method);
|
||||
template <class ObjectT>
|
||||
static constexpr fn_t<bool, ObjectT&, webgl::RangeConsumerView&>*
|
||||
DispatchCommandFuncById(const size_t targetId) {
|
||||
if (targetId != Id)
|
||||
return Derived<Id + 1>::template DispatchCommandFuncById<ObjectT>(
|
||||
targetId);
|
||||
|
||||
return [](ObjectT& obj, webgl::RangeConsumerView& view) -> bool {
|
||||
const auto viewWas = view;
|
||||
(void)viewWas; // For debugging.
|
||||
|
||||
auto argsTuple = ArgsTuple(Method);
|
||||
return std::apply(
|
||||
[&](auto&... args) {
|
||||
const auto badArgId = webgl::Deserialize(view, 1, args...);
|
||||
@ -250,16 +255,12 @@ class MethodDispatcher {
|
||||
<< " arg " << *badArgId;
|
||||
return false;
|
||||
}
|
||||
(obj.*method)(args...);
|
||||
(obj.*Method)(args...);
|
||||
return true;
|
||||
},
|
||||
argsTuple);
|
||||
}
|
||||
return Derived<kId + 1>::DispatchCommand(obj, id, view);
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr size_t Id() { return kId; }
|
||||
static constexpr MethodType Method() { return method; }
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -56,23 +56,41 @@ IPCResult WebGLParent::RecvDispatchCommands(BigBuffer&& shmem,
|
||||
MOZ_ALWAYS_TRUE(!initialOffset);
|
||||
}
|
||||
|
||||
std::optional<std::string> fatalError;
|
||||
|
||||
while (true) {
|
||||
view.AlignTo(kUniversalAlignment);
|
||||
size_t id = 0;
|
||||
if (!view.ReadParam(&id)) break;
|
||||
|
||||
const auto ok = WebGLMethodDispatcher<0>::DispatchCommand(*mHost, id, view);
|
||||
// We split this up so that we don't end up in a long callstack chain of
|
||||
// WebGLMethodDispatcher<i>|i=0->N. First get the lambda for dispatch, then
|
||||
// invoke the lambda with our args.
|
||||
const auto pfn =
|
||||
WebGLMethodDispatcher<0>::DispatchCommandFuncById<HostWebGLContext>(id);
|
||||
if (!pfn) {
|
||||
const nsPrintfCString cstr(
|
||||
"MethodDispatcher<%zu> not found. Please file a bug!", id);
|
||||
fatalError = ToString(cstr);
|
||||
gfxCriticalError() << *fatalError;
|
||||
break;
|
||||
};
|
||||
|
||||
const auto ok = (*pfn)(*mHost, view);
|
||||
if (!ok) {
|
||||
const nsPrintfCString cstr(
|
||||
"DispatchCommand(id: %i) failed. Please file a bug!", int(id));
|
||||
const auto str = ToString(cstr);
|
||||
gfxCriticalError() << str;
|
||||
mHost->JsWarning(str);
|
||||
mHost->OnContextLoss(webgl::ContextLossReason::None);
|
||||
"DispatchCommand(id: %zu) failed. Please file a bug!", id);
|
||||
fatalError = ToString(cstr);
|
||||
gfxCriticalError() << *fatalError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fatalError) {
|
||||
mHost->JsWarning(*fatalError);
|
||||
mHost->OnContextLoss(webgl::ContextLossReason::None);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user