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 "mozilla/GfxMessageUtils.h"
12 #include "mozilla/ipc/IPDLParamTraits.h"
13 #include "mozilla/ipc/Shmem.h"
14 #include "mozilla/layers/LayersSurfaces.h"
15 #include "WebGLTypes.h"
20 // TODO: This should probably replace Shmem, or at least this should move to
23 class RaiiShmem final
{
24 RefPtr
<mozilla::ipc::ActorLifecycleProxy
> mWeakRef
;
25 mozilla::ipc::Shmem mShmem
= {};
28 /// Returns zeroed data.
29 static RaiiShmem
Alloc(
30 mozilla::ipc::IProtocol
* const allocator
, const size_t size
,
31 const mozilla::ipc::SharedMemory::SharedMemoryType type
) {
32 mozilla::ipc::Shmem shmem
;
33 if (!allocator
->AllocShmem(size
, type
, &shmem
)) return {};
34 return {allocator
, shmem
};
39 RaiiShmem() = default;
41 RaiiShmem(mozilla::ipc::IProtocol
* const allocator
,
42 const mozilla::ipc::Shmem
& shmem
) {
43 if (!allocator
|| !allocator
->CanSend()) {
47 // Shmems are handled by the top-level, so use that or we might leak after
49 mWeakRef
= allocator
->ToplevelProtocol()->GetLifecycleProxy();
51 if (!mWeakRef
|| !mWeakRef
->Get() || !IsShmem()) {
58 const auto& allocator
= mWeakRef
->Get();
60 allocator
->DeallocShmem(mShmem
);
67 ~RaiiShmem() { reset(); }
71 RaiiShmem(RaiiShmem
&& rhs
) { *this = std::move(rhs
); }
72 RaiiShmem
& operator=(RaiiShmem
&& rhs
) {
74 mWeakRef
= rhs
.mWeakRef
;
75 mShmem
= rhs
.Extract();
81 bool IsShmem() const { return mShmem
.IsReadable(); }
83 explicit operator bool() const { return IsShmem(); }
87 const auto& Shmem() const {
88 MOZ_ASSERT(IsShmem());
92 Range
<uint8_t> ByteRange() const {
96 return {mShmem
.get
<uint8_t>(), mShmem
.Size
<uint8_t>()};
99 mozilla::ipc::Shmem
Extract() {
107 using Int32Vector
= std::vector
<int32_t>;
114 struct IPDLParamTraits
<mozilla::webgl::FrontBufferSnapshotIpc
> final
{
115 using T
= mozilla::webgl::FrontBufferSnapshotIpc
;
117 static void Write(IPC::Message
* const msg
, IProtocol
* actor
, T
& in
) {
118 WriteParam(msg
, in
.surfSize
);
119 WriteIPDLParam(msg
, actor
, std::move(in
.shmem
));
122 static bool Read(const IPC::Message
* const msg
, PickleIterator
* const itr
,
123 IProtocol
* actor
, T
* const out
) {
124 return ReadParam(msg
, itr
, &out
->surfSize
) &&
125 ReadIPDLParam(msg
, itr
, actor
, &out
->shmem
);
132 struct IPDLParamTraits
<mozilla::webgl::ReadPixelsResultIpc
> final
{
133 using T
= mozilla::webgl::ReadPixelsResultIpc
;
135 static void Write(IPC::Message
* const msg
, IProtocol
* actor
, T
& in
) {
136 WriteParam(msg
, in
.subrect
);
137 WriteParam(msg
, in
.byteStride
);
138 WriteIPDLParam(msg
, actor
, std::move(in
.shmem
));
141 static bool Read(const IPC::Message
* const msg
, PickleIterator
* const itr
,
142 IProtocol
* actor
, T
* const out
) {
143 return ReadParam(msg
, itr
, &out
->subrect
) &&
144 ReadParam(msg
, itr
, &out
->byteStride
) &&
145 ReadIPDLParam(msg
, itr
, actor
, &out
->shmem
);
152 struct IPDLParamTraits
<mozilla::webgl::TexUnpackBlobDesc
> final
{
153 using T
= mozilla::webgl::TexUnpackBlobDesc
;
155 static void Write(IPC::Message
* const msg
, IProtocol
* actor
, T
&& in
) {
156 WriteParam(msg
, in
.imageTarget
);
157 WriteParam(msg
, in
.size
);
158 WriteParam(msg
, in
.srcAlphaType
);
159 MOZ_RELEASE_ASSERT(!in
.cpuData
);
160 MOZ_RELEASE_ASSERT(!in
.pboOffset
);
161 WriteParam(msg
, in
.imageSize
);
162 MOZ_RELEASE_ASSERT(!in
.image
);
163 WriteIPDLParam(msg
, actor
, std::move(in
.sd
));
164 MOZ_RELEASE_ASSERT(!in
.dataSurf
);
165 WriteParam(msg
, in
.unpacking
);
166 WriteParam(msg
, in
.applyUnpackTransforms
);
169 static bool Read(const IPC::Message
* const msg
, PickleIterator
* const itr
,
170 IProtocol
* actor
, T
* const out
) {
171 return ReadParam(msg
, itr
, &out
->imageTarget
) &&
172 ReadParam(msg
, itr
, &out
->size
) &&
173 ReadParam(msg
, itr
, &out
->srcAlphaType
) &&
174 ReadParam(msg
, itr
, &out
->imageSize
) &&
175 ReadIPDLParam(msg
, itr
, actor
, &out
->sd
) &&
176 ReadParam(msg
, itr
, &out
->unpacking
) &&
177 ReadParam(msg
, itr
, &out
->applyUnpackTransforms
);
184 using Int32Vector
= std::vector
<int32_t>;
186 } // namespace mozilla
191 struct ParamTraits
<mozilla::webgl::AttribBaseType
>
192 : public ContiguousEnumSerializerInclusive
<
193 mozilla::webgl::AttribBaseType
,
194 mozilla::webgl::AttribBaseType::Boolean
,
195 mozilla::webgl::AttribBaseType::Uint
> {};
198 struct ParamTraits
<mozilla::webgl::ContextLossReason
>
199 : public ContiguousEnumSerializerInclusive
<
200 mozilla::webgl::ContextLossReason
,
201 mozilla::webgl::ContextLossReason::None
,
202 mozilla::webgl::ContextLossReason::Guilty
> {};
205 struct ParamTraits
<gfxAlphaType
>
206 : public ContiguousEnumSerializerInclusive
<
207 gfxAlphaType
, gfxAlphaType::Opaque
, gfxAlphaType::NonPremult
> {};
211 template <typename T
>
212 bool ValidateParam(const T
& val
) {
213 return ParamTraits
<T
>::Validate(val
);
216 template <typename T
>
217 struct ValidatedPlainOldDataSerializer
: public PlainOldDataSerializer
<T
> {
218 static void Write(Message
* const msg
, const T
& in
) {
219 MOZ_ASSERT(ValidateParam(in
));
220 PlainOldDataSerializer
<T
>::Write(msg
, in
);
223 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
225 if (!PlainOldDataSerializer
<T
>::Read(msg
, itr
, out
)) return false;
226 return ValidateParam(*out
);
229 // static bool Validate(const T&) = 0;
235 struct ParamTraits
<mozilla::webgl::InitContextDesc
> final
236 : public ValidatedPlainOldDataSerializer
<mozilla::webgl::InitContextDesc
> {
237 using T
= mozilla::webgl::InitContextDesc
;
239 static bool Validate(const T
& val
) {
240 return ValidateParam(val
.options
) && (val
.size
.x
&& val
.size
.y
);
245 struct ParamTraits
<mozilla::WebGLContextOptions
> final
246 : public ValidatedPlainOldDataSerializer
<mozilla::WebGLContextOptions
> {
247 using T
= mozilla::WebGLContextOptions
;
249 static bool Validate(const T
& val
) {
250 return ValidateParam(val
.powerPreference
);
255 struct ParamTraits
<mozilla::dom::WebGLPowerPreference
> final
256 : public ValidatedPlainOldDataSerializer
<
257 mozilla::dom::WebGLPowerPreference
> {
258 using T
= mozilla::dom::WebGLPowerPreference
;
260 static bool Validate(const T
& val
) { return val
<= T::High_performance
; }
264 struct ParamTraits
<mozilla::webgl::OpaqueFramebufferOptions
> final
265 : public PlainOldDataSerializer
<mozilla::webgl::OpaqueFramebufferOptions
> {
270 template <typename T
>
271 struct ParamTraits
<mozilla::webgl::EnumMask
<T
>> final
272 : public PlainOldDataSerializer
<mozilla::webgl::EnumMask
<T
>> {};
275 struct ParamTraits
<mozilla::webgl::InitContextResult
> final
{
276 using T
= mozilla::webgl::InitContextResult
;
278 static void Write(Message
* const msg
, const T
& in
) {
279 WriteParam(msg
, in
.error
);
280 WriteParam(msg
, in
.options
);
281 WriteParam(msg
, in
.limits
);
282 WriteParam(msg
, in
.uploadableSdTypes
);
285 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
287 return ReadParam(msg
, itr
, &out
->error
) &&
288 ReadParam(msg
, itr
, &out
->options
) &&
289 ReadParam(msg
, itr
, &out
->limits
) &&
290 ReadParam(msg
, itr
, &out
->uploadableSdTypes
);
295 struct ParamTraits
<mozilla::webgl::ExtensionBits
> final
296 : public PlainOldDataSerializer
<mozilla::webgl::ExtensionBits
> {};
299 struct ParamTraits
<mozilla::webgl::Limits
> final
300 : public PlainOldDataSerializer
<mozilla::webgl::Limits
> {};
303 struct ParamTraits
<mozilla::WebGLPixelStore
> final
304 : public PlainOldDataSerializer
<mozilla::WebGLPixelStore
> {};
309 struct ParamTraits
<mozilla::webgl::ReadPixelsDesc
> final
{
310 using T
= mozilla::webgl::ReadPixelsDesc
;
312 static void Write(Message
* const msg
, const T
& in
) {
313 WriteParam(msg
, in
.srcOffset
);
314 WriteParam(msg
, in
.size
);
315 WriteParam(msg
, in
.pi
);
316 WriteParam(msg
, in
.packState
);
319 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
321 return ReadParam(msg
, itr
, &out
->srcOffset
) &&
322 ReadParam(msg
, itr
, &out
->size
) && ReadParam(msg
, itr
, &out
->pi
) &&
323 ReadParam(msg
, itr
, &out
->packState
);
330 struct ParamTraits
<mozilla::webgl::PixelPackState
> final
{
331 using T
= mozilla::webgl::PixelPackState
;
333 static void Write(Message
* const msg
, const T
& in
) {
334 WriteParam(msg
, in
.alignment
);
335 WriteParam(msg
, in
.rowLength
);
336 WriteParam(msg
, in
.skipRows
);
337 WriteParam(msg
, in
.skipPixels
);
340 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
342 return ReadParam(msg
, itr
, &out
->alignment
) &&
343 ReadParam(msg
, itr
, &out
->rowLength
) &&
344 ReadParam(msg
, itr
, &out
->skipRows
) &&
345 ReadParam(msg
, itr
, &out
->skipPixels
);
352 struct ParamTraits
<mozilla::webgl::PackingInfo
> final
{
353 using T
= mozilla::webgl::PackingInfo
;
355 static void Write(Message
* const msg
, const T
& in
) {
356 WriteParam(msg
, in
.format
);
357 WriteParam(msg
, in
.type
);
360 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
362 return ReadParam(msg
, itr
, &out
->format
) && ReadParam(msg
, itr
, &out
->type
);
369 struct ParamTraits
<mozilla::webgl::CompileResult
> final
{
370 using T
= mozilla::webgl::CompileResult
;
372 static void Write(Message
* const msg
, const T
& in
) {
373 WriteParam(msg
, in
.pending
);
374 WriteParam(msg
, in
.log
);
375 WriteParam(msg
, in
.translatedSource
);
376 WriteParam(msg
, in
.success
);
379 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
381 return ReadParam(msg
, itr
, &out
->pending
) &&
382 ReadParam(msg
, itr
, &out
->log
) &&
383 ReadParam(msg
, itr
, &out
->translatedSource
) &&
384 ReadParam(msg
, itr
, &out
->success
);
391 struct ParamTraits
<mozilla::webgl::LinkResult
> final
{
392 using T
= mozilla::webgl::LinkResult
;
394 static void Write(Message
* const msg
, const T
& in
) {
395 WriteParam(msg
, in
.pending
);
396 WriteParam(msg
, in
.log
);
397 WriteParam(msg
, in
.success
);
398 WriteParam(msg
, in
.active
);
399 WriteParam(msg
, in
.tfBufferMode
);
402 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
404 return ReadParam(msg
, itr
, &out
->pending
) &&
405 ReadParam(msg
, itr
, &out
->log
) &&
406 ReadParam(msg
, itr
, &out
->success
) &&
407 ReadParam(msg
, itr
, &out
->active
) &&
408 ReadParam(msg
, itr
, &out
->tfBufferMode
);
415 struct ParamTraits
<mozilla::webgl::LinkActiveInfo
> final
{
416 using T
= mozilla::webgl::LinkActiveInfo
;
418 static void Write(Message
* const msg
, const T
& in
) {
419 WriteParam(msg
, in
.activeAttribs
);
420 WriteParam(msg
, in
.activeUniforms
);
421 WriteParam(msg
, in
.activeUniformBlocks
);
422 WriteParam(msg
, in
.activeTfVaryings
);
425 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
427 return ReadParam(msg
, itr
, &out
->activeAttribs
) &&
428 ReadParam(msg
, itr
, &out
->activeUniforms
) &&
429 ReadParam(msg
, itr
, &out
->activeUniformBlocks
) &&
430 ReadParam(msg
, itr
, &out
->activeTfVaryings
);
437 struct ParamTraits
<mozilla::webgl::ActiveInfo
> final
{
438 using T
= mozilla::webgl::ActiveInfo
;
440 static void Write(Message
* const msg
, const T
& in
) {
441 WriteParam(msg
, in
.elemType
);
442 WriteParam(msg
, in
.elemCount
);
443 WriteParam(msg
, in
.name
);
446 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
448 return ReadParam(msg
, itr
, &out
->elemType
) &&
449 ReadParam(msg
, itr
, &out
->elemCount
) &&
450 ReadParam(msg
, itr
, &out
->name
);
457 struct ParamTraits
<mozilla::webgl::ActiveAttribInfo
> final
{
458 using T
= mozilla::webgl::ActiveAttribInfo
;
460 static void Write(Message
* const msg
, const T
& in
) {
461 WriteParam(msg
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
462 WriteParam(msg
, in
.location
);
463 WriteParam(msg
, in
.baseType
);
466 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
468 return ReadParam(msg
, itr
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
469 ReadParam(msg
, itr
, &out
->location
) &&
470 ReadParam(msg
, itr
, &out
->baseType
);
477 struct ParamTraits
<mozilla::webgl::ActiveUniformInfo
> final
{
478 using T
= mozilla::webgl::ActiveUniformInfo
;
480 static void Write(Message
* const msg
, const T
& in
) {
481 WriteParam(msg
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
482 WriteParam(msg
, in
.locByIndex
);
483 WriteParam(msg
, in
.block_index
);
484 WriteParam(msg
, in
.block_offset
);
485 WriteParam(msg
, in
.block_arrayStride
);
486 WriteParam(msg
, in
.block_matrixStride
);
487 WriteParam(msg
, in
.block_isRowMajor
);
490 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
492 return ReadParam(msg
, itr
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
493 ReadParam(msg
, itr
, &out
->locByIndex
) &&
494 ReadParam(msg
, itr
, &out
->block_index
) &&
495 ReadParam(msg
, itr
, &out
->block_offset
) &&
496 ReadParam(msg
, itr
, &out
->block_arrayStride
) &&
497 ReadParam(msg
, itr
, &out
->block_matrixStride
) &&
498 ReadParam(msg
, itr
, &out
->block_isRowMajor
);
505 struct ParamTraits
<mozilla::webgl::ActiveUniformBlockInfo
> final
{
506 using T
= mozilla::webgl::ActiveUniformBlockInfo
;
508 static void Write(Message
* const msg
, const T
& in
) {
509 WriteParam(msg
, in
.name
);
510 WriteParam(msg
, in
.dataSize
);
511 WriteParam(msg
, in
.activeUniformIndices
);
512 WriteParam(msg
, in
.referencedByVertexShader
);
513 WriteParam(msg
, in
.referencedByFragmentShader
);
516 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
518 return ReadParam(msg
, itr
, &out
->name
) &&
519 ReadParam(msg
, itr
, &out
->dataSize
) &&
520 ReadParam(msg
, itr
, &out
->activeUniformIndices
) &&
521 ReadParam(msg
, itr
, &out
->referencedByVertexShader
) &&
522 ReadParam(msg
, itr
, &out
->referencedByFragmentShader
);
529 struct ParamTraits
<mozilla::webgl::ShaderPrecisionFormat
> final
{
530 using T
= mozilla::webgl::ShaderPrecisionFormat
;
532 static void Write(Message
* const msg
, const T
& in
) {
533 WriteParam(msg
, in
.rangeMin
);
534 WriteParam(msg
, in
.rangeMax
);
535 WriteParam(msg
, in
.precision
);
538 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
540 return ReadParam(msg
, itr
, &out
->rangeMin
) &&
541 ReadParam(msg
, itr
, &out
->rangeMax
) &&
542 ReadParam(msg
, itr
, &out
->precision
);
548 template <typename U
, size_t N
>
549 struct ParamTraits
<U
[N
]> final
{
551 static constexpr size_t kByteSize
= sizeof(U
) * N
;
553 static_assert(std::is_trivial
<U
>::value
);
555 static void Write(Message
* const msg
, const T
& in
) {
556 msg
->WriteBytes(in
, kByteSize
);
559 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
561 if (!msg
->HasBytesAvailable(itr
, kByteSize
)) {
564 return msg
->ReadBytesInto(itr
, *out
, kByteSize
);
571 struct ParamTraits
<mozilla::webgl::GetUniformData
> final
{
572 using T
= mozilla::webgl::GetUniformData
;
574 static void Write(Message
* const msg
, const T
& in
) {
575 ParamTraits
<decltype(in
.data
)>::Write(msg
, in
.data
);
576 WriteParam(msg
, in
.type
);
579 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
581 return ParamTraits
<decltype(out
->data
)>::Read(msg
, itr
, &out
->data
) &&
582 ReadParam(msg
, itr
, &out
->type
);
588 template <typename U
>
589 struct ParamTraits
<mozilla::avec2
<U
>> final
{
590 using T
= mozilla::avec2
<U
>;
592 static void Write(Message
* const msg
, const T
& in
) {
593 WriteParam(msg
, in
.x
);
594 WriteParam(msg
, in
.y
);
597 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
599 return ReadParam(msg
, itr
, &out
->x
) && ReadParam(msg
, itr
, &out
->y
);
605 template <typename U
>
606 struct ParamTraits
<mozilla::avec3
<U
>> final
{
607 using T
= mozilla::avec3
<U
>;
609 static void Write(Message
* const msg
, const T
& in
) {
610 WriteParam(msg
, in
.x
);
611 WriteParam(msg
, in
.y
);
612 WriteParam(msg
, in
.z
);
615 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
617 return ReadParam(msg
, itr
, &out
->x
) && ReadParam(msg
, itr
, &out
->y
) &&
618 ReadParam(msg
, itr
, &out
->z
);