/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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 WEBGLQUEUEPARAMTRAITS_H_ #define WEBGLQUEUEPARAMTRAITS_H_ #include #include "mozilla/dom/ProducerConsumerQueue.h" #include "TexUnpackBlob.h" #include "WebGLContext.h" #include "WebGLTypes.h" namespace mozilla { namespace webgl { template struct QueueParamTraits; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type { }; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template struct IsTriviallySerializable> : std::true_type {}; template struct IsTriviallySerializable> : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type {}; template <> struct IsTriviallySerializable : std::true_type { }; template <> struct IsTriviallySerializable : std::true_type {}; template struct QueueParamTraits> { using ParamType = RawBuffer; template static QueueStatus Write(ProducerView& view, const ParamType& in) { const auto range = in.Data(); const auto elemCount = range.length(); auto status = view.WriteParam(elemCount); if (!status) return status; if (!elemCount) return status; const bool hasData = bool(range.begin().get()); status = view.WriteParam(hasData); if (!status) return status; if (!hasData) return status; status = view.Write(range.begin().get(), range.end().get()); return status; } template static QueueStatus Read(ConsumerView& view, ParamType* const out) { size_t elemCount = 0; auto status = view.ReadParam(&elemCount); if (!status) return status; if (!elemCount) { *out = {}; return QueueStatus::kSuccess; } bool hasData = false; status = view.ReadParam(&hasData); if (!status) return status; if (!hasData) { auto temp = RawBuffer{Range{nullptr, elemCount}}; *out = std::move(temp); return QueueStatus::kSuccess; } auto buffer = UniqueBuffer::Alloc(elemCount * sizeof(T)); if (!buffer) return QueueStatus::kOOMError; using MutT = std::remove_cv_t; const auto begin = reinterpret_cast(buffer.get()); const auto range = Range{begin, elemCount}; auto temp = RawBuffer{range, std::move(buffer)}; *out = std::move(temp); return view.Read(range.begin().get(), range.end().get()); } }; template <> struct QueueParamTraits : public ContiguousEnumSerializerInclusive< webgl::ContextLossReason, webgl::ContextLossReason::None, webgl::ContextLossReason::Guilty> {}; template struct QueueParamTraits> { using T = Result; template static QueueStatus Write(ProducerView& aProducerView, const T& aArg) { const auto ok = aArg.isOk(); auto status = aProducerView.WriteParam(ok); if (!status) return status; if (ok) { status = aProducerView.WriteParam(aArg.unwrap()); } else { status = aProducerView.WriteParam(aArg.unwrapErr()); } return status; } template static QueueStatus Read(ConsumerView& aConsumerView, T* aArg) { bool ok; auto status = aConsumerView.ReadParam(&ok); if (!status) return status; if (ok) { V val; status = aConsumerView.ReadParam(&val); *aArg = val; } else { E val; status = aConsumerView.ReadParam(&val); *aArg = Err(val); } return status; } }; template <> struct QueueParamTraits { using T = std::string; template static QueueStatus Write(ProducerView& aProducerView, const T& aArg) { auto status = aProducerView.WriteParam(aArg.size()); if (!status) return status; status = aProducerView.Write(aArg.data(), aArg.data() + aArg.size()); return status; } template static QueueStatus Read(ConsumerView& aConsumerView, T* aArg) { size_t size; auto status = aConsumerView.ReadParam(&size); if (!status) return status; const UniqueBuffer temp = malloc(size); const auto dest = static_cast(temp.get()); if (!dest) return QueueStatus::kFatalError; status = aConsumerView.Read(dest, dest + size); aArg->assign(dest, size); return status; } }; template struct QueueParamTraits> { using T = std::vector; template static QueueStatus Write(ProducerView& aProducerView, const T& aArg) { auto status = aProducerView.WriteParam(aArg.size()); if (!status) return status; status = aProducerView.Write(aArg.data(), aArg.data() + aArg.size()); return status; } template static QueueStatus Read(ConsumerView& aConsumerView, T* aArg) { MOZ_CRASH("no way to fallibly resize vectors without exceptions"); size_t size; auto status = aConsumerView.ReadParam(&size); if (!status) return status; aArg->resize(size); status = aConsumerView.Read(aArg->data(), aArg->data() + size); return status; } }; template <> struct QueueParamTraits : public ContiguousEnumSerializer {}; template <> struct QueueParamTraits { using T = CompileResult; template static QueueStatus Write(ProducerView& aProducerView, const T& aArg) { aProducerView.WriteParam(aArg.pending); aProducerView.WriteParam(aArg.log); aProducerView.WriteParam(aArg.translatedSource); return aProducerView.WriteParam(aArg.success); } template static QueueStatus Read(ConsumerView& aConsumerView, T* aArg) { aConsumerView.ReadParam(&aArg->pending); aConsumerView.ReadParam(&aArg->log); aConsumerView.ReadParam(&aArg->translatedSource); return aConsumerView.ReadParam(&aArg->success); } }; } // namespace webgl } // namespace mozilla #endif // WEBGLQUEUEPARAMTRAITS_H_