diff options
Diffstat (limited to 'dom/canvas/WebGLIpdl.h')
-rw-r--r-- | dom/canvas/WebGLIpdl.h | 613 |
1 files changed, 613 insertions, 0 deletions
diff --git a/dom/canvas/WebGLIpdl.h b/dom/canvas/WebGLIpdl.h new file mode 100644 index 0000000000..6665920115 --- /dev/null +++ b/dom/canvas/WebGLIpdl.h @@ -0,0 +1,613 @@ +/* -*- 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 WEBGLIPDL_H_ +#define WEBGLIPDL_H_ + +#include "gfxTypes.h" +#include "ipc/EnumSerializer.h" +#include "ipc/IPCMessageUtils.h" +#include "mozilla/GfxMessageUtils.h" +#include "mozilla/ipc/IPDLParamTraits.h" +#include "mozilla/ipc/Shmem.h" +#include "mozilla/layers/LayersSurfaces.h" +#include "WebGLTypes.h" + +namespace mozilla { +namespace webgl { + +// TODO: This should probably replace Shmem, or at least this should move to +// ipc/glue. + +class RaiiShmem final { + RefPtr<mozilla::ipc::ActorLifecycleProxy> mWeakRef; + mozilla::ipc::Shmem mShmem = {}; + + public: + /// Returns zeroed data. + static RaiiShmem Alloc(mozilla::ipc::IProtocol* const allocator, + const size_t size) { + mozilla::ipc::Shmem shmem; + if (!allocator->AllocShmem(size, &shmem)) return {}; + return {allocator, shmem}; + } + + static RaiiShmem AllocUnsafe(mozilla::ipc::IProtocol* const allocator, + const size_t size) { + mozilla::ipc::Shmem shmem; + if (!allocator->AllocUnsafeShmem(size, &shmem)) return {}; + return {allocator, shmem}; + } + + // - + + RaiiShmem() = default; + + RaiiShmem(mozilla::ipc::IProtocol* const allocator, + const mozilla::ipc::Shmem& shmem) { + if (!allocator || !allocator->CanSend()) { + return; + } + + // Shmems are handled by the top-level, so use that or we might leak after + // the actor dies. + mWeakRef = allocator->ToplevelProtocol()->GetLifecycleProxy(); + mShmem = shmem; + if (!mWeakRef || !mWeakRef->Get() || !IsShmem()) { + reset(); + } + } + + void reset() { + if (IsShmem()) { + const auto& allocator = mWeakRef->Get(); + if (allocator) { + allocator->DeallocShmem(mShmem); + } + } + mWeakRef = nullptr; + mShmem = {}; + } + + ~RaiiShmem() { reset(); } + + // - + + RaiiShmem(RaiiShmem&& rhs) { *this = std::move(rhs); } + RaiiShmem& operator=(RaiiShmem&& rhs) { + reset(); + mWeakRef = rhs.mWeakRef; + mShmem = rhs.Extract(); + return *this; + } + + // - + + bool IsShmem() const { return mShmem.IsReadable(); } + + explicit operator bool() const { return IsShmem(); } + + // - + + const auto& Shmem() const { + MOZ_ASSERT(IsShmem()); + return mShmem; + } + + Range<uint8_t> ByteRange() const { + if (!IsShmem()) { + return {}; + } + return {mShmem.get<uint8_t>(), mShmem.Size<uint8_t>()}; + } + + mozilla::ipc::Shmem Extract() { + auto ret = mShmem; + mShmem = {}; + reset(); + return ret; + } +}; + +using Int32Vector = std::vector<int32_t>; + +} // namespace webgl + +namespace ipc { + +template <> +struct IPDLParamTraits<mozilla::webgl::FrontBufferSnapshotIpc> final { + using T = mozilla::webgl::FrontBufferSnapshotIpc; + + static void Write(IPC::MessageWriter* const writer, IProtocol* actor, T& in) { + WriteParam(writer, in.surfSize); + WriteIPDLParam(writer, actor, std::move(in.shmem)); + } + + static bool Read(IPC::MessageReader* const reader, IProtocol* actor, + T* const out) { + return ReadParam(reader, &out->surfSize) && + ReadIPDLParam(reader, actor, &out->shmem); + } +}; + +// - + +template <> +struct IPDLParamTraits<mozilla::webgl::ReadPixelsResultIpc> final { + using T = mozilla::webgl::ReadPixelsResultIpc; + + static void Write(IPC::MessageWriter* const writer, IProtocol* actor, T& in) { + WriteParam(writer, in.subrect); + WriteParam(writer, in.byteStride); + WriteIPDLParam(writer, actor, std::move(in.shmem)); + } + + static bool Read(IPC::MessageReader* const reader, IProtocol* actor, + T* const out) { + return ReadParam(reader, &out->subrect) && + ReadParam(reader, &out->byteStride) && + ReadIPDLParam(reader, actor, &out->shmem); + } +}; + +// - + +template <> +struct IPDLParamTraits<mozilla::webgl::TexUnpackBlobDesc> final { + using T = mozilla::webgl::TexUnpackBlobDesc; + + static void Write(IPC::MessageWriter* const writer, IProtocol* actor, + T&& in) { + WriteParam(writer, in.imageTarget); + WriteParam(writer, in.size); + WriteParam(writer, in.srcAlphaType); + MOZ_RELEASE_ASSERT(!in.cpuData); + MOZ_RELEASE_ASSERT(!in.pboOffset); + WriteParam(writer, in.structuredSrcSize); + MOZ_RELEASE_ASSERT(!in.image); + WriteIPDLParam(writer, actor, std::move(in.sd)); + MOZ_RELEASE_ASSERT(!in.dataSurf); + WriteParam(writer, in.unpacking); + WriteParam(writer, in.applyUnpackTransforms); + } + + static bool Read(IPC::MessageReader* const reader, IProtocol* actor, + T* const out) { + return ReadParam(reader, &out->imageTarget) && + ReadParam(reader, &out->size) && + ReadParam(reader, &out->srcAlphaType) && + ReadParam(reader, &out->structuredSrcSize) && + ReadIPDLParam(reader, actor, &out->sd) && + ReadParam(reader, &out->unpacking) && + ReadParam(reader, &out->applyUnpackTransforms); + } +}; + +} // namespace ipc + +namespace webgl { +using Int32Vector = std::vector<int32_t>; +} // namespace webgl +} // namespace mozilla + +namespace IPC { + +template <> +struct ParamTraits<mozilla::webgl::AttribBaseType> + : public ContiguousEnumSerializerInclusive< + mozilla::webgl::AttribBaseType, + mozilla::webgl::AttribBaseType::Boolean, + mozilla::webgl::AttribBaseType::Uint> {}; + +template <> +struct ParamTraits<mozilla::webgl::ContextLossReason> + : public ContiguousEnumSerializerInclusive< + mozilla::webgl::ContextLossReason, + mozilla::webgl::ContextLossReason::None, + mozilla::webgl::ContextLossReason::Guilty> {}; + +template <> +struct ParamTraits<gfxAlphaType> + : public ContiguousEnumSerializerInclusive< + gfxAlphaType, gfxAlphaType::Opaque, gfxAlphaType::NonPremult> {}; + +// - + +template <typename T> +bool ValidateParam(const T& val) { + return ParamTraits<T>::Validate(val); +} + +template <typename T> +struct ValidatedPlainOldDataSerializer : public PlainOldDataSerializer<T> { + static void Write(MessageWriter* const writer, const T& in) { + MOZ_ASSERT(ValidateParam(in)); + PlainOldDataSerializer<T>::Write(writer, in); + } + + static bool Read(MessageReader* const reader, T* const out) { + if (!PlainOldDataSerializer<T>::Read(reader, out)) return false; + return ValidateParam(*out); + } + + // static bool Validate(const T&) = 0; +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::InitContextDesc> final + : public ValidatedPlainOldDataSerializer<mozilla::webgl::InitContextDesc> { + using T = mozilla::webgl::InitContextDesc; + + static bool Validate(const T& val) { + return ValidateParam(val.options) && (val.size.x && val.size.y); + } +}; + +template <> +struct ParamTraits<mozilla::WebGLContextOptions> final + : public ValidatedPlainOldDataSerializer<mozilla::WebGLContextOptions> { + using T = mozilla::WebGLContextOptions; + + static bool Validate(const T& val) { + bool ok = true; + ok &= ValidateParam(val.powerPreference); + ok &= ValidateParam(val.colorSpace); + return ok; + } +}; + +template <> +struct ParamTraits<mozilla::dom::WebGLPowerPreference> final + : public ValidatedPlainOldDataSerializer< + mozilla::dom::WebGLPowerPreference> { + using T = mozilla::dom::WebGLPowerPreference; + + static bool Validate(const T& val) { return val <= T::High_performance; } +}; + +template <> +struct ParamTraits<mozilla::dom::PredefinedColorSpace> final + : public ValidatedPlainOldDataSerializer< + mozilla::dom::PredefinedColorSpace> { + using T = mozilla::dom::PredefinedColorSpace; + + static bool Validate(const T& val) { return val < T::EndGuard_; } +}; + +template <> +struct ParamTraits<mozilla::webgl::OpaqueFramebufferOptions> final + : public PlainOldDataSerializer<mozilla::webgl::OpaqueFramebufferOptions> { +}; + +// - + +template <> +struct ParamTraits<mozilla::gl::GLVendor> + : public ContiguousEnumSerializerInclusive<mozilla::gl::GLVendor, + mozilla::gl::GLVendor::Intel, + mozilla::gl::kHighestGLVendor> { +}; + +template <typename T> +struct ParamTraits<mozilla::webgl::EnumMask<T>> final + : public PlainOldDataSerializer<mozilla::webgl::EnumMask<T>> {}; + +template <> +struct ParamTraits<mozilla::webgl::InitContextResult> final { + using T = mozilla::webgl::InitContextResult; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.error); + WriteParam(writer, in.options); + WriteParam(writer, in.limits); + WriteParam(writer, in.uploadableSdTypes); + WriteParam(writer, in.vendor); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->error) && ReadParam(reader, &out->options) && + ReadParam(reader, &out->limits) && + ReadParam(reader, &out->uploadableSdTypes) && + ReadParam(reader, &out->vendor); + } +}; + +template <> +struct ParamTraits<mozilla::webgl::ExtensionBits> final + : public PlainOldDataSerializer<mozilla::webgl::ExtensionBits> {}; + +template <> +struct ParamTraits<mozilla::webgl::Limits> final + : public PlainOldDataSerializer<mozilla::webgl::Limits> {}; + +template <> +struct ParamTraits<mozilla::webgl::PixelPackingState> final + : public PlainOldDataSerializer<mozilla::webgl::PixelPackingState> {}; +template <> +struct ParamTraits<mozilla::webgl::PixelUnpackStateWebgl> final + : public PlainOldDataSerializer<mozilla::webgl::PixelUnpackStateWebgl> {}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::ReadPixelsDesc> final { + using T = mozilla::webgl::ReadPixelsDesc; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.srcOffset); + WriteParam(writer, in.size); + WriteParam(writer, in.pi); + WriteParam(writer, in.packState); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->srcOffset) && + ReadParam(reader, &out->size) && ReadParam(reader, &out->pi) && + ReadParam(reader, &out->packState); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::PackingInfo> final { + using T = mozilla::webgl::PackingInfo; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.format); + WriteParam(writer, in.type); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->format) && ReadParam(reader, &out->type); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::CompileResult> final { + using T = mozilla::webgl::CompileResult; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.pending); + WriteParam(writer, in.log); + WriteParam(writer, in.translatedSource); + WriteParam(writer, in.success); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->pending) && ReadParam(reader, &out->log) && + ReadParam(reader, &out->translatedSource) && + ReadParam(reader, &out->success); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::LinkResult> final { + using T = mozilla::webgl::LinkResult; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.pending); + WriteParam(writer, in.log); + WriteParam(writer, in.success); + WriteParam(writer, in.active); + WriteParam(writer, in.tfBufferMode); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->pending) && ReadParam(reader, &out->log) && + ReadParam(reader, &out->success) && + ReadParam(reader, &out->active) && + ReadParam(reader, &out->tfBufferMode); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::LinkActiveInfo> final { + using T = mozilla::webgl::LinkActiveInfo; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.activeAttribs); + WriteParam(writer, in.activeUniforms); + WriteParam(writer, in.activeUniformBlocks); + WriteParam(writer, in.activeTfVaryings); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->activeAttribs) && + ReadParam(reader, &out->activeUniforms) && + ReadParam(reader, &out->activeUniformBlocks) && + ReadParam(reader, &out->activeTfVaryings); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::ActiveInfo> final { + using T = mozilla::webgl::ActiveInfo; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.elemType); + WriteParam(writer, in.elemCount); + WriteParam(writer, in.name); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->elemType) && + ReadParam(reader, &out->elemCount) && ReadParam(reader, &out->name); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::ActiveAttribInfo> final { + using T = mozilla::webgl::ActiveAttribInfo; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, static_cast<const mozilla::webgl::ActiveInfo&>(in)); + WriteParam(writer, in.location); + WriteParam(writer, in.baseType); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, static_cast<mozilla::webgl::ActiveInfo*>(out)) && + ReadParam(reader, &out->location) && + ReadParam(reader, &out->baseType); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::ActiveUniformInfo> final { + using T = mozilla::webgl::ActiveUniformInfo; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, static_cast<const mozilla::webgl::ActiveInfo&>(in)); + WriteParam(writer, in.locByIndex); + WriteParam(writer, in.block_index); + WriteParam(writer, in.block_offset); + WriteParam(writer, in.block_arrayStride); + WriteParam(writer, in.block_matrixStride); + WriteParam(writer, in.block_isRowMajor); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, static_cast<mozilla::webgl::ActiveInfo*>(out)) && + ReadParam(reader, &out->locByIndex) && + ReadParam(reader, &out->block_index) && + ReadParam(reader, &out->block_offset) && + ReadParam(reader, &out->block_arrayStride) && + ReadParam(reader, &out->block_matrixStride) && + ReadParam(reader, &out->block_isRowMajor); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::ActiveUniformBlockInfo> final { + using T = mozilla::webgl::ActiveUniformBlockInfo; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.name); + WriteParam(writer, in.dataSize); + WriteParam(writer, in.activeUniformIndices); + WriteParam(writer, in.referencedByVertexShader); + WriteParam(writer, in.referencedByFragmentShader); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->name) && ReadParam(reader, &out->dataSize) && + ReadParam(reader, &out->activeUniformIndices) && + ReadParam(reader, &out->referencedByVertexShader) && + ReadParam(reader, &out->referencedByFragmentShader); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::ShaderPrecisionFormat> final { + using T = mozilla::webgl::ShaderPrecisionFormat; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.rangeMin); + WriteParam(writer, in.rangeMax); + WriteParam(writer, in.precision); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->rangeMin) && + ReadParam(reader, &out->rangeMax) && + ReadParam(reader, &out->precision); + } +}; + +// - + +template <typename U, size_t N> +struct ParamTraits<U[N]> final { + using T = U[N]; + static constexpr size_t kByteSize = sizeof(U) * N; + + static_assert(std::is_trivial<U>::value); + + static void Write(MessageWriter* const writer, const T& in) { + writer->WriteBytes(in, kByteSize); + } + + static bool Read(MessageReader* const reader, T* const out) { + if (!reader->HasBytesAvailable(kByteSize)) { + return false; + } + return reader->ReadBytesInto(*out, kByteSize); + } +}; + +// - + +template <> +struct ParamTraits<mozilla::webgl::GetUniformData> final { + using T = mozilla::webgl::GetUniformData; + + static void Write(MessageWriter* const writer, const T& in) { + ParamTraits<decltype(in.data)>::Write(writer, in.data); + WriteParam(writer, in.type); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ParamTraits<decltype(out->data)>::Read(reader, &out->data) && + ReadParam(reader, &out->type); + } +}; + +// - + +template <typename U> +struct ParamTraits<mozilla::avec2<U>> final { + using T = mozilla::avec2<U>; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.x); + WriteParam(writer, in.y); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->x) && ReadParam(reader, &out->y); + } +}; + +// - + +template <typename U> +struct ParamTraits<mozilla::avec3<U>> final { + using T = mozilla::avec3<U>; + + static void Write(MessageWriter* const writer, const T& in) { + WriteParam(writer, in.x); + WriteParam(writer, in.y); + WriteParam(writer, in.z); + } + + static bool Read(MessageReader* const reader, T* const out) { + return ReadParam(reader, &out->x) && ReadParam(reader, &out->y) && + ReadParam(reader, &out->z); + } +}; + +} // namespace IPC + +#endif |