From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- dom/canvas/WebGLCommandQueue.h | 267 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 dom/canvas/WebGLCommandQueue.h (limited to 'dom/canvas/WebGLCommandQueue.h') diff --git a/dom/canvas/WebGLCommandQueue.h b/dom/canvas/WebGLCommandQueue.h new file mode 100644 index 0000000000..bbbb1034c1 --- /dev/null +++ b/dom/canvas/WebGLCommandQueue.h @@ -0,0 +1,267 @@ +/* -*- 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 WEBGLCOMMANDQUEUE_H_ +#define WEBGLCOMMANDQUEUE_H_ + +#include +#include "mozilla/FunctionTypeTraits.h" +#include "mozilla/gfx/Logging.h" +#include "mozilla/ipc/IPDLParamTraits.h" +#include "QueueParamTraits.h" +#include "WebGLTypes.h" + +namespace mozilla { + +namespace webgl { + +class RangeConsumerView final : public webgl::ConsumerView { + RangedPtr mSrcItr; + const RangedPtr mSrcEnd; + + public: + auto Remaining() const { return *MaybeAs(mSrcEnd - mSrcItr); } + + explicit RangeConsumerView(const Range range) + : ConsumerView(this), mSrcItr(range.begin()), mSrcEnd(range.end()) { + (void)Remaining(); // assert size non-negative + } + + void AlignTo(const size_t alignment) { + const auto padToAlign = AlignmentOffset(alignment, mSrcItr.get()); + if (MOZ_UNLIKELY(padToAlign > Remaining())) { + mSrcItr = mSrcEnd; + return; + } + mSrcItr += padToAlign; + } + + template + Maybe> ReadRange(const size_t elemCount) { + constexpr auto alignment = alignof(T); + AlignTo(alignment); + + constexpr auto elemSize = sizeof(T); + const auto byteSizeChecked = CheckedInt(elemCount) * elemSize; + MOZ_RELEASE_ASSERT(byteSizeChecked.isValid()); + const auto& byteSize = byteSizeChecked.value(); + + const auto remaining = Remaining(); + if (MOZ_UNLIKELY(byteSize > remaining)) return {}; + + const auto begin = reinterpret_cast(mSrcItr.get()); + mSrcItr += byteSize; + return Some(Range{begin, elemCount}); + } +}; + +// - + +namespace details { + +class SizeOnlyProducerView final + : public webgl::ProducerView { + struct Info { + size_t requiredByteCount = 0; + size_t alignmentOverhead = 0; + }; + Info mInfo; + + public: + SizeOnlyProducerView() : ProducerView(this) {} + + template + bool WriteFromRange(const Range& src) { + constexpr auto alignment = alignof(T); + const size_t byteSize = ByteSize(src); + // printf_stderr("SizeOnlyProducerView: @%zu +%zu\n", alignment, byteSize); + + const auto padToAlign = AlignmentOffset(alignment, mInfo.requiredByteCount); + mInfo.alignmentOverhead += padToAlign; + + mInfo.requiredByteCount += padToAlign; + mInfo.requiredByteCount += byteSize; + return true; + } + + const auto& Info() const { return mInfo; } +}; + +// - + +class RangeProducerView final : public webgl::ProducerView { + const RangedPtr mDestBegin; + const RangedPtr mDestEnd; + RangedPtr mDestItr; + + public: + auto Remaining() const { return *MaybeAs(mDestEnd - mDestItr); } + + explicit RangeProducerView(const Range range) + : ProducerView(this), + mDestBegin(range.begin()), + mDestEnd(range.end()), + mDestItr(mDestBegin) { + (void)Remaining(); // assert size non-negative + } + + template + bool WriteFromRange(const Range& src) { + // uint32_t/float data may masquerade as a Range. + constexpr auto alignment = alignof(T); + const size_t byteSize = ByteSize(src); + // printf_stderr("RangeProducerView: @%zu +%zu\n", alignment, byteSize); + + const auto padToAlign = AlignmentOffset(alignment, mDestItr.get()); + mDestItr += padToAlign; + + MOZ_ASSERT(byteSize <= Remaining()); + if (MOZ_LIKELY(byteSize)) { + memcpy(mDestItr.get(), src.begin().get(), byteSize); + } + mDestItr += byteSize; + return true; + } +}; + +// - + +template +inline void Serialize(ProducerViewT&) {} + +template +inline void Serialize(ProducerViewT& view, const Arg& arg, + const Args&... args) { + MOZ_ALWAYS_TRUE(view.WriteParam(arg)); + Serialize(view, args...); +} + +} // namespace details + +// - + +template +auto SerializationInfo(const Args&... args) { + webgl::details::SizeOnlyProducerView sizeView; + webgl::details::Serialize(sizeView, args...); + return sizeView.Info(); +} + +template +void Serialize(Range dest, const Args&... args) { + webgl::details::RangeProducerView view(dest); + webgl::details::Serialize(view, args...); +} + +// - + +inline Maybe Deserialize(RangeConsumerView&, size_t) { return {}; } + +template +inline Maybe Deserialize(RangeConsumerView& view, + const uint16_t argId, Arg& arg, + Args&... args) { + if (!webgl::QueueParamTraits::Read(view, &arg)) { + return Some(argId); + } + return Deserialize(view, argId + 1, args...); +} + +} // namespace webgl + +// 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. +// To use this system, first define a dispatcher subclass of +// EmptyMethodDispatcher. This class must be parameterized by command ID. +// +// Example: +// template class MyDispatcher +// : public EmptyMethodDispatcher {}; +// +// Then, for each command handled, specialize this to subclass MethodDispatcher. +// The subclass must define the Method. It may optionally define isSync for +// synchronous methods. +// +// Example: +// template <> +// class MyDispatcher<0> +// : public MethodDispatcher {}; +// +// The method may then be called from the source and run on the sink. +// +// Example: +// int result = Run(param1, std::move(param2)); + +template