1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "ipc/EnumSerializer.h"
11 #include "ipc/IPCMessageUtils.h"
12 #include "mozilla/GfxMessageUtils.h"
13 #include "mozilla/ipc/IPDLParamTraits.h"
14 #include "mozilla/ipc/Shmem.h"
15 #include "mozilla/layers/LayersSurfaces.h"
16 #include "WebGLTypes.h"
21 // TODO: This should probably replace Shmem, or at least this should move to
24 class RaiiShmem final
{
25 RefPtr
<mozilla::ipc::ActorLifecycleProxy
> mWeakRef
;
26 mozilla::ipc::Shmem mShmem
= {};
29 /// Returns zeroed data.
30 static RaiiShmem
Alloc(mozilla::ipc::IProtocol
* const allocator
,
32 mozilla::ipc::Shmem shmem
;
33 if (!allocator
->AllocShmem(size
, &shmem
)) return {};
34 return {allocator
, shmem
};
37 static RaiiShmem
AllocUnsafe(mozilla::ipc::IProtocol
* const allocator
,
39 mozilla::ipc::Shmem shmem
;
40 if (!allocator
->AllocUnsafeShmem(size
, &shmem
)) return {};
41 return {allocator
, shmem
};
46 RaiiShmem() = default;
48 RaiiShmem(mozilla::ipc::IProtocol
* const allocator
,
49 const mozilla::ipc::Shmem
& shmem
) {
50 if (!allocator
|| !allocator
->CanSend()) {
54 // Shmems are handled by the top-level, so use that or we might leak after
56 mWeakRef
= allocator
->ToplevelProtocol()->GetLifecycleProxy();
58 if (!mWeakRef
|| !mWeakRef
->Get() || !IsShmem()) {
65 const auto& allocator
= mWeakRef
->Get();
67 allocator
->DeallocShmem(mShmem
);
74 ~RaiiShmem() { reset(); }
78 RaiiShmem(RaiiShmem
&& rhs
) { *this = std::move(rhs
); }
79 RaiiShmem
& operator=(RaiiShmem
&& rhs
) {
81 mWeakRef
= rhs
.mWeakRef
;
82 mShmem
= rhs
.Extract();
88 bool IsShmem() const { return mShmem
.IsReadable(); }
90 explicit operator bool() const { return IsShmem(); }
94 const auto& Shmem() const {
95 MOZ_ASSERT(IsShmem());
99 Range
<uint8_t> ByteRange() const {
103 return {mShmem
.get
<uint8_t>(), mShmem
.Size
<uint8_t>()};
106 mozilla::ipc::Shmem
Extract() {
114 using Int32Vector
= std::vector
<int32_t>;
121 struct IPDLParamTraits
<mozilla::webgl::FrontBufferSnapshotIpc
> final
{
122 using T
= mozilla::webgl::FrontBufferSnapshotIpc
;
124 static void Write(IPC::MessageWriter
* const writer
, IProtocol
* actor
, T
& in
) {
125 WriteParam(writer
, in
.surfSize
);
126 WriteIPDLParam(writer
, actor
, std::move(in
.shmem
));
129 static bool Read(IPC::MessageReader
* const reader
, IProtocol
* actor
,
131 return ReadParam(reader
, &out
->surfSize
) &&
132 ReadIPDLParam(reader
, actor
, &out
->shmem
);
139 struct IPDLParamTraits
<mozilla::webgl::ReadPixelsResultIpc
> final
{
140 using T
= mozilla::webgl::ReadPixelsResultIpc
;
142 static void Write(IPC::MessageWriter
* const writer
, IProtocol
* actor
, T
& in
) {
143 WriteParam(writer
, in
.subrect
);
144 WriteParam(writer
, in
.byteStride
);
145 WriteIPDLParam(writer
, actor
, std::move(in
.shmem
));
148 static bool Read(IPC::MessageReader
* const reader
, IProtocol
* actor
,
150 return ReadParam(reader
, &out
->subrect
) &&
151 ReadParam(reader
, &out
->byteStride
) &&
152 ReadIPDLParam(reader
, actor
, &out
->shmem
);
159 struct IPDLParamTraits
<mozilla::webgl::TexUnpackBlobDesc
> final
{
160 using T
= mozilla::webgl::TexUnpackBlobDesc
;
162 static void Write(IPC::MessageWriter
* const writer
, IProtocol
* actor
,
164 WriteParam(writer
, in
.imageTarget
);
165 WriteParam(writer
, in
.size
);
166 WriteParam(writer
, in
.srcAlphaType
);
167 MOZ_RELEASE_ASSERT(!in
.cpuData
);
168 MOZ_RELEASE_ASSERT(!in
.pboOffset
);
169 WriteParam(writer
, in
.structuredSrcSize
);
170 MOZ_RELEASE_ASSERT(!in
.image
);
171 WriteIPDLParam(writer
, actor
, std::move(in
.sd
));
172 MOZ_RELEASE_ASSERT(!in
.dataSurf
);
173 WriteParam(writer
, in
.unpacking
);
174 WriteParam(writer
, in
.applyUnpackTransforms
);
177 static bool Read(IPC::MessageReader
* const reader
, IProtocol
* actor
,
179 return ReadParam(reader
, &out
->imageTarget
) &&
180 ReadParam(reader
, &out
->size
) &&
181 ReadParam(reader
, &out
->srcAlphaType
) &&
182 ReadParam(reader
, &out
->structuredSrcSize
) &&
183 ReadIPDLParam(reader
, actor
, &out
->sd
) &&
184 ReadParam(reader
, &out
->unpacking
) &&
185 ReadParam(reader
, &out
->applyUnpackTransforms
);
192 using Int32Vector
= std::vector
<int32_t>;
194 } // namespace mozilla
199 struct ParamTraits
<mozilla::webgl::AttribBaseType
>
200 : public ContiguousEnumSerializerInclusive
<
201 mozilla::webgl::AttribBaseType
,
202 mozilla::webgl::AttribBaseType::Boolean
,
203 mozilla::webgl::AttribBaseType::Uint
> {};
206 struct ParamTraits
<mozilla::webgl::ContextLossReason
>
207 : public ContiguousEnumSerializerInclusive
<
208 mozilla::webgl::ContextLossReason
,
209 mozilla::webgl::ContextLossReason::None
,
210 mozilla::webgl::ContextLossReason::Guilty
> {};
213 struct ParamTraits
<gfxAlphaType
>
214 : public ContiguousEnumSerializerInclusive
<
215 gfxAlphaType
, gfxAlphaType::Opaque
, gfxAlphaType::NonPremult
> {};
219 template <typename T
>
220 bool ValidateParam(const T
& val
) {
221 return ParamTraits
<T
>::Validate(val
);
224 template <typename T
>
225 struct ValidatedPlainOldDataSerializer
: public PlainOldDataSerializer
<T
> {
226 static void Write(MessageWriter
* const writer
, const T
& in
) {
227 MOZ_ASSERT(ValidateParam(in
));
228 PlainOldDataSerializer
<T
>::Write(writer
, in
);
231 static bool Read(MessageReader
* const reader
, T
* const out
) {
232 if (!PlainOldDataSerializer
<T
>::Read(reader
, out
)) return false;
233 return ValidateParam(*out
);
236 // static bool Validate(const T&) = 0;
242 struct ParamTraits
<mozilla::webgl::InitContextDesc
> final
243 : public ValidatedPlainOldDataSerializer
<mozilla::webgl::InitContextDesc
> {
244 using T
= mozilla::webgl::InitContextDesc
;
246 static bool Validate(const T
& val
) {
247 return ValidateParam(val
.options
) && (val
.size
.x
&& val
.size
.y
);
252 struct ParamTraits
<mozilla::WebGLContextOptions
> final
253 : public ValidatedPlainOldDataSerializer
<mozilla::WebGLContextOptions
> {
254 using T
= mozilla::WebGLContextOptions
;
256 static bool Validate(const T
& val
) {
258 ok
&= ValidateParam(val
.powerPreference
);
259 ok
&= ValidateParam(val
.colorSpace
);
265 struct ParamTraits
<mozilla::dom::WebGLPowerPreference
> final
266 : public ValidatedPlainOldDataSerializer
<
267 mozilla::dom::WebGLPowerPreference
> {
268 using T
= mozilla::dom::WebGLPowerPreference
;
270 static bool Validate(const T
& val
) { return val
<= T::High_performance
; }
274 struct ParamTraits
<mozilla::dom::PredefinedColorSpace
> final
275 : public ValidatedPlainOldDataSerializer
<
276 mozilla::dom::PredefinedColorSpace
> {
277 using T
= mozilla::dom::PredefinedColorSpace
;
279 static bool Validate(const T
& val
) { return val
< T::EndGuard_
; }
283 struct ParamTraits
<mozilla::webgl::OpaqueFramebufferOptions
> final
284 : public PlainOldDataSerializer
<mozilla::webgl::OpaqueFramebufferOptions
> {
290 struct ParamTraits
<mozilla::gl::GLVendor
>
291 : public ContiguousEnumSerializerInclusive
<mozilla::gl::GLVendor
,
292 mozilla::gl::GLVendor::Intel
,
293 mozilla::gl::kHighestGLVendor
> {
296 template <typename T
>
297 struct ParamTraits
<mozilla::webgl::EnumMask
<T
>> final
298 : public PlainOldDataSerializer
<mozilla::webgl::EnumMask
<T
>> {};
301 struct ParamTraits
<mozilla::webgl::InitContextResult
> final
{
302 using T
= mozilla::webgl::InitContextResult
;
304 static void Write(MessageWriter
* const writer
, const T
& in
) {
305 WriteParam(writer
, in
.error
);
306 WriteParam(writer
, in
.options
);
307 WriteParam(writer
, in
.limits
);
308 WriteParam(writer
, in
.uploadableSdTypes
);
309 WriteParam(writer
, in
.vendor
);
312 static bool Read(MessageReader
* const reader
, T
* const out
) {
313 return ReadParam(reader
, &out
->error
) && ReadParam(reader
, &out
->options
) &&
314 ReadParam(reader
, &out
->limits
) &&
315 ReadParam(reader
, &out
->uploadableSdTypes
) &&
316 ReadParam(reader
, &out
->vendor
);
321 struct ParamTraits
<mozilla::webgl::ExtensionBits
> final
322 : public PlainOldDataSerializer
<mozilla::webgl::ExtensionBits
> {};
325 struct ParamTraits
<mozilla::webgl::Limits
> final
326 : public PlainOldDataSerializer
<mozilla::webgl::Limits
> {};
329 struct ParamTraits
<mozilla::webgl::PixelPackingState
> final
330 : public PlainOldDataSerializer
<mozilla::webgl::PixelPackingState
> {};
332 struct ParamTraits
<mozilla::webgl::PixelUnpackStateWebgl
> final
333 : public PlainOldDataSerializer
<mozilla::webgl::PixelUnpackStateWebgl
> {};
338 struct ParamTraits
<mozilla::webgl::ReadPixelsDesc
> final
{
339 using T
= mozilla::webgl::ReadPixelsDesc
;
341 static void Write(MessageWriter
* const writer
, const T
& in
) {
342 WriteParam(writer
, in
.srcOffset
);
343 WriteParam(writer
, in
.size
);
344 WriteParam(writer
, in
.pi
);
345 WriteParam(writer
, in
.packState
);
348 static bool Read(MessageReader
* const reader
, T
* const out
) {
349 return ReadParam(reader
, &out
->srcOffset
) &&
350 ReadParam(reader
, &out
->size
) && ReadParam(reader
, &out
->pi
) &&
351 ReadParam(reader
, &out
->packState
);
358 struct ParamTraits
<mozilla::webgl::PackingInfo
> final
{
359 using T
= mozilla::webgl::PackingInfo
;
361 static void Write(MessageWriter
* const writer
, const T
& in
) {
362 WriteParam(writer
, in
.format
);
363 WriteParam(writer
, in
.type
);
366 static bool Read(MessageReader
* const reader
, T
* const out
) {
367 return ReadParam(reader
, &out
->format
) && ReadParam(reader
, &out
->type
);
374 struct ParamTraits
<mozilla::webgl::CompileResult
> final
{
375 using T
= mozilla::webgl::CompileResult
;
377 static void Write(MessageWriter
* const writer
, const T
& in
) {
378 WriteParam(writer
, in
.pending
);
379 WriteParam(writer
, in
.log
);
380 WriteParam(writer
, in
.translatedSource
);
381 WriteParam(writer
, in
.success
);
384 static bool Read(MessageReader
* const reader
, T
* const out
) {
385 return ReadParam(reader
, &out
->pending
) && ReadParam(reader
, &out
->log
) &&
386 ReadParam(reader
, &out
->translatedSource
) &&
387 ReadParam(reader
, &out
->success
);
394 struct ParamTraits
<mozilla::webgl::LinkResult
> final
{
395 using T
= mozilla::webgl::LinkResult
;
397 static void Write(MessageWriter
* const writer
, const T
& in
) {
398 WriteParam(writer
, in
.pending
);
399 WriteParam(writer
, in
.log
);
400 WriteParam(writer
, in
.success
);
401 WriteParam(writer
, in
.active
);
402 WriteParam(writer
, in
.tfBufferMode
);
405 static bool Read(MessageReader
* const reader
, T
* const out
) {
406 return ReadParam(reader
, &out
->pending
) && ReadParam(reader
, &out
->log
) &&
407 ReadParam(reader
, &out
->success
) &&
408 ReadParam(reader
, &out
->active
) &&
409 ReadParam(reader
, &out
->tfBufferMode
);
416 struct ParamTraits
<mozilla::webgl::LinkActiveInfo
> final
{
417 using T
= mozilla::webgl::LinkActiveInfo
;
419 static void Write(MessageWriter
* const writer
, const T
& in
) {
420 WriteParam(writer
, in
.activeAttribs
);
421 WriteParam(writer
, in
.activeUniforms
);
422 WriteParam(writer
, in
.activeUniformBlocks
);
423 WriteParam(writer
, in
.activeTfVaryings
);
426 static bool Read(MessageReader
* const reader
, T
* const out
) {
427 return ReadParam(reader
, &out
->activeAttribs
) &&
428 ReadParam(reader
, &out
->activeUniforms
) &&
429 ReadParam(reader
, &out
->activeUniformBlocks
) &&
430 ReadParam(reader
, &out
->activeTfVaryings
);
437 struct ParamTraits
<mozilla::webgl::ActiveInfo
> final
{
438 using T
= mozilla::webgl::ActiveInfo
;
440 static void Write(MessageWriter
* const writer
, const T
& in
) {
441 WriteParam(writer
, in
.elemType
);
442 WriteParam(writer
, in
.elemCount
);
443 WriteParam(writer
, in
.name
);
446 static bool Read(MessageReader
* const reader
, T
* const out
) {
447 return ReadParam(reader
, &out
->elemType
) &&
448 ReadParam(reader
, &out
->elemCount
) && ReadParam(reader
, &out
->name
);
455 struct ParamTraits
<mozilla::webgl::ActiveAttribInfo
> final
{
456 using T
= mozilla::webgl::ActiveAttribInfo
;
458 static void Write(MessageWriter
* const writer
, const T
& in
) {
459 WriteParam(writer
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
460 WriteParam(writer
, in
.location
);
461 WriteParam(writer
, in
.baseType
);
464 static bool Read(MessageReader
* const reader
, T
* const out
) {
465 return ReadParam(reader
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
466 ReadParam(reader
, &out
->location
) &&
467 ReadParam(reader
, &out
->baseType
);
474 struct ParamTraits
<mozilla::webgl::ActiveUniformInfo
> final
{
475 using T
= mozilla::webgl::ActiveUniformInfo
;
477 static void Write(MessageWriter
* const writer
, const T
& in
) {
478 WriteParam(writer
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
479 WriteParam(writer
, in
.locByIndex
);
480 WriteParam(writer
, in
.block_index
);
481 WriteParam(writer
, in
.block_offset
);
482 WriteParam(writer
, in
.block_arrayStride
);
483 WriteParam(writer
, in
.block_matrixStride
);
484 WriteParam(writer
, in
.block_isRowMajor
);
487 static bool Read(MessageReader
* const reader
, T
* const out
) {
488 return ReadParam(reader
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
489 ReadParam(reader
, &out
->locByIndex
) &&
490 ReadParam(reader
, &out
->block_index
) &&
491 ReadParam(reader
, &out
->block_offset
) &&
492 ReadParam(reader
, &out
->block_arrayStride
) &&
493 ReadParam(reader
, &out
->block_matrixStride
) &&
494 ReadParam(reader
, &out
->block_isRowMajor
);
501 struct ParamTraits
<mozilla::webgl::ActiveUniformBlockInfo
> final
{
502 using T
= mozilla::webgl::ActiveUniformBlockInfo
;
504 static void Write(MessageWriter
* const writer
, const T
& in
) {
505 WriteParam(writer
, in
.name
);
506 WriteParam(writer
, in
.dataSize
);
507 WriteParam(writer
, in
.activeUniformIndices
);
508 WriteParam(writer
, in
.referencedByVertexShader
);
509 WriteParam(writer
, in
.referencedByFragmentShader
);
512 static bool Read(MessageReader
* const reader
, T
* const out
) {
513 return ReadParam(reader
, &out
->name
) && ReadParam(reader
, &out
->dataSize
) &&
514 ReadParam(reader
, &out
->activeUniformIndices
) &&
515 ReadParam(reader
, &out
->referencedByVertexShader
) &&
516 ReadParam(reader
, &out
->referencedByFragmentShader
);
523 struct ParamTraits
<mozilla::webgl::ShaderPrecisionFormat
> final
{
524 using T
= mozilla::webgl::ShaderPrecisionFormat
;
526 static void Write(MessageWriter
* const writer
, const T
& in
) {
527 WriteParam(writer
, in
.rangeMin
);
528 WriteParam(writer
, in
.rangeMax
);
529 WriteParam(writer
, in
.precision
);
532 static bool Read(MessageReader
* const reader
, T
* const out
) {
533 return ReadParam(reader
, &out
->rangeMin
) &&
534 ReadParam(reader
, &out
->rangeMax
) &&
535 ReadParam(reader
, &out
->precision
);
541 template <typename U
, size_t N
>
542 struct ParamTraits
<U
[N
]> final
{
544 static constexpr size_t kByteSize
= sizeof(U
) * N
;
546 static_assert(std::is_trivial
<U
>::value
);
548 static void Write(MessageWriter
* const writer
, const T
& in
) {
549 writer
->WriteBytes(in
, kByteSize
);
552 static bool Read(MessageReader
* const reader
, T
* const out
) {
553 if (!reader
->HasBytesAvailable(kByteSize
)) {
556 return reader
->ReadBytesInto(*out
, kByteSize
);
563 struct ParamTraits
<mozilla::webgl::GetUniformData
> final
{
564 using T
= mozilla::webgl::GetUniformData
;
566 static void Write(MessageWriter
* const writer
, const T
& in
) {
567 ParamTraits
<decltype(in
.data
)>::Write(writer
, in
.data
);
568 WriteParam(writer
, in
.type
);
571 static bool Read(MessageReader
* const reader
, T
* const out
) {
572 return ParamTraits
<decltype(out
->data
)>::Read(reader
, &out
->data
) &&
573 ReadParam(reader
, &out
->type
);
579 template <typename U
>
580 struct ParamTraits
<mozilla::avec2
<U
>> final
{
581 using T
= mozilla::avec2
<U
>;
583 static void Write(MessageWriter
* const writer
, const T
& in
) {
584 WriteParam(writer
, in
.x
);
585 WriteParam(writer
, in
.y
);
588 static bool Read(MessageReader
* const reader
, T
* const out
) {
589 return ReadParam(reader
, &out
->x
) && ReadParam(reader
, &out
->y
);
595 template <typename U
>
596 struct ParamTraits
<mozilla::avec3
<U
>> final
{
597 using T
= mozilla::avec3
<U
>;
599 static void Write(MessageWriter
* const writer
, const T
& in
) {
600 WriteParam(writer
, in
.x
);
601 WriteParam(writer
, in
.y
);
602 WriteParam(writer
, in
.z
);
605 static bool Read(MessageReader
* const reader
, T
* const out
) {
606 return ReadParam(reader
, &out
->x
) && ReadParam(reader
, &out
->y
) &&
607 ReadParam(reader
, &out
->z
);