/* -*- 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 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 ByteRange() const { if (!IsShmem()) { return {}; } return {mShmem.get(), mShmem.Size()}; } mozilla::ipc::Shmem Extract() { auto ret = mShmem; mShmem = {}; reset(); return ret; } }; using Int32Vector = std::vector; } // namespace webgl namespace ipc { template <> struct IPDLParamTraits 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 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 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; } // namespace webgl } // namespace mozilla namespace IPC { template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::webgl::AttribBaseType, mozilla::webgl::AttribBaseType::Boolean, mozilla::webgl::AttribBaseType::Uint> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::webgl::ContextLossReason, mozilla::webgl::ContextLossReason::None, mozilla::webgl::ContextLossReason::Guilty> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< gfxAlphaType, gfxAlphaType::Opaque, gfxAlphaType::NonPremult> {}; // - template bool ValidateParam(const T& val) { return ParamTraits::Validate(val); } template struct ValidatedPlainOldDataSerializer : public PlainOldDataSerializer { static void Write(MessageWriter* const writer, const T& in) { MOZ_ASSERT(ValidateParam(in)); PlainOldDataSerializer::Write(writer, in); } static bool Read(MessageReader* const reader, T* const out) { if (!PlainOldDataSerializer::Read(reader, out)) return false; return ValidateParam(*out); } // static bool Validate(const T&) = 0; }; // - template <> struct ParamTraits final : public ValidatedPlainOldDataSerializer { using T = mozilla::webgl::InitContextDesc; static bool Validate(const T& val) { return ValidateParam(val.options) && (val.size.x && val.size.y); } }; template <> struct ParamTraits final : public ValidatedPlainOldDataSerializer { 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 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 final : public ValidatedPlainOldDataSerializer< mozilla::dom::PredefinedColorSpace> { using T = mozilla::dom::PredefinedColorSpace; static bool Validate(const T& val) { return val < T::EndGuard_; } }; template <> struct ParamTraits final : public PlainOldDataSerializer { }; // - template <> struct ParamTraits : public ContiguousEnumSerializerInclusive { }; template struct ParamTraits> final : public PlainOldDataSerializer> {}; template <> struct ParamTraits 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 final : public PlainOldDataSerializer {}; template <> struct ParamTraits final : public PlainOldDataSerializer {}; template <> struct ParamTraits final : public PlainOldDataSerializer {}; template <> struct ParamTraits final : public PlainOldDataSerializer {}; // - template <> struct ParamTraits 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 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 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 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 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 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 final { using T = mozilla::webgl::ActiveAttribInfo; static void Write(MessageWriter* const writer, const T& in) { WriteParam(writer, static_cast(in)); WriteParam(writer, in.location); WriteParam(writer, in.baseType); } static bool Read(MessageReader* const reader, T* const out) { return ReadParam(reader, static_cast(out)) && ReadParam(reader, &out->location) && ReadParam(reader, &out->baseType); } }; // - template <> struct ParamTraits final { using T = mozilla::webgl::ActiveUniformInfo; static void Write(MessageWriter* const writer, const T& in) { WriteParam(writer, static_cast(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(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 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 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 struct ParamTraits final { using T = U[N]; static constexpr size_t kByteSize = sizeof(U) * N; static_assert(std::is_trivial::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 final { using T = mozilla::webgl::GetUniformData; static void Write(MessageWriter* const writer, const T& in) { ParamTraits::Write(writer, in.data); WriteParam(writer, in.type); } static bool Read(MessageReader* const reader, T* const out) { return ParamTraitsdata)>::Read(reader, &out->data) && ReadParam(reader, &out->type); } }; // - template struct ParamTraits> final { using T = mozilla::avec2; 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 struct ParamTraits> final { using T = mozilla::avec3; 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